diff --git a/src/DebugJunk.ts b/src/DebugJunk.ts index 5b7b4847f..2278e71b5 100644 --- a/src/DebugJunk.ts +++ b/src/DebugJunk.ts @@ -2,7 +2,7 @@ import { ReadonlyMat4, ReadonlyVec3, ReadonlyVec4, mat4, vec3, vec4 } from "gl-matrix"; import ArrayBufferSlice from "./ArrayBufferSlice.js"; -import { ScreenSpaceProjection, divideByW } from "./Camera.js"; +import { divideByW } from "./Camera.js"; import { Blue, Color, Green, Magenta, OpaqueBlack, Red, colorToCSS } from "./Color.js"; import { downloadBuffer, downloadBufferSlice } from "./DownloadUtils.js"; import { AABB } from "./Geometry.js"; @@ -317,18 +317,6 @@ export function drawScreenSpaceBox(ctx: CanvasRenderingContext2D, x1: number, y1 ctx.stroke(); } -export function drawScreenSpaceProjection(ctx: CanvasRenderingContext2D, proj: ScreenSpaceProjection, color: Color = Magenta): void { - const cw = ctx.canvas.width; - const ch = ctx.canvas.height; - - const x1 = (proj.projectedMinX + 1) * cw / 2; - const x2 = (proj.projectedMaxX + 1) * cw / 2; - const y1 = (-proj.projectedMinY + 1) * ch / 2; - const y2 = (-proj.projectedMaxY + 1) * ch / 2; - - drawScreenSpaceBox(ctx, x1, y1, x2, y2, color); -} - function flashItem(item: any, fieldName: string, step: number = 0) { item[fieldName] = step % 2 === 1; if (step < 7) diff --git a/src/PaperMarioTTYD/render.ts b/src/PaperMarioTTYD/render.ts index 897c94736..34122fa5a 100644 --- a/src/PaperMarioTTYD/render.ts +++ b/src/PaperMarioTTYD/render.ts @@ -1,5 +1,5 @@ -import { BasicGXRendererHelper, ColorKind, DrawParams, fillSceneParams, fillSceneParamsData, fillSceneParamsDataOnTemplate, GXMaterialHelperGfx, GXShapeHelperGfx, GXTextureHolder, loadedDataCoalescerComboGfx, MaterialParams, SceneParams, translateWrapModeGfx, ub_SceneParamsBufferSize } from '../gx/gx_render.js'; +import { BasicGXRendererHelper, calcLODBias, ColorKind, DrawParams, fillSceneParamsData, fillSceneParamsDataOnTemplate, GXMaterialHelperGfx, GXShapeHelperGfx, GXTextureHolder, loadedDataCoalescerComboGfx, MaterialParams, SceneParams, translateWrapModeGfx, ub_SceneParamsBufferSize } from '../gx/gx_render.js'; import * as TPL from './tpl.js'; import { AnimationEntry, Batch, bindMaterialAnimator, bindMeshAnimator, CollisionFlags, DrawModeFlags, Material, MaterialAnimator, MaterialLayer, MeshAnimator, Sampler, SceneGraphNode, SceneGraphPart, TTYDWorld } from './world.js'; @@ -321,6 +321,8 @@ class NodeInstance { template.setMegaStateFlags(this.megaStateFlags); if (this.isDecal) { + // TODO(jstpierre): Fix this math. + // // The game will actually adjust the projection matrix based on the child index, if the decal flag // is set. This happens in _mapDispMapObj. // @@ -340,7 +342,8 @@ class NodeInstance { if (depthBias !== 1.0) { let offs = template.allocateUniformBuffer(GX_Program.ub_SceneParams, ub_SceneParamsBufferSize); const d = template.mapUniformBufferF32(GX_Program.ub_SceneParams); - fillSceneParams(sceneParams, viewerInput.camera.projectionMatrix, viewerInput.backbufferWidth, viewerInput.backbufferHeight); + mat4.copy(sceneParams.u_Projection, viewerInput.camera.projectionMatrix); + sceneParams.u_SceneTextureLODBias = calcLODBias(viewerInput.backbufferWidth, viewerInput.backbufferHeight); projectionMatrixConvertClipSpaceNearZ(sceneParams.u_Projection, GfxClipSpaceNearZ.Zero, camera.clipSpaceNearZ); sceneParams.u_Projection[10] *= depthBias; diff --git a/src/SourceEngine/BSPFile.ts b/src/SourceEngine/BSPFile.ts index b9be8576d..3c202213e 100644 --- a/src/SourceEngine/BSPFile.ts +++ b/src/SourceEngine/BSPFile.ts @@ -978,10 +978,7 @@ class ResizableArrayBuffer { if (byteSize > this.byteCapacity) { this.byteCapacity = Math.max(byteSize, this.byteCapacity * 2); - const oldBuffer = this.buffer; - const newBuffer = new ArrayBuffer(this.byteCapacity); - new Uint8Array(newBuffer).set(new Uint8Array(oldBuffer)); - this.buffer = newBuffer; + this.buffer = this.buffer.transfer(this.byteCapacity); } } diff --git a/src/StarFoxAdventures/Sky.ts b/src/StarFoxAdventures/Sky.ts index f28cba1a2..c8f98eef3 100644 --- a/src/StarFoxAdventures/Sky.ts +++ b/src/StarFoxAdventures/Sky.ts @@ -6,7 +6,7 @@ import { TDDraw } from "../SuperMarioGalaxy/DDraw.js"; import * as GX from '../gx/gx_enum.js'; import * as GX_Material from '../gx/gx_material.js'; import { GXMaterialBuilder } from '../gx/GXMaterialBuilder.js'; -import { DrawParams, GXMaterialHelperGfx, MaterialParams, fillSceneParamsDataOnTemplate, SceneParams, fillSceneParams, fillSceneParamsData, GXRenderHelperGfx } from '../gx/gx_render.js'; +import { DrawParams, GXMaterialHelperGfx, MaterialParams, fillSceneParamsDataOnTemplate, SceneParams, fillSceneParamsData, GXRenderHelperGfx, calcLODBias } from '../gx/gx_render.js'; import { getMatrixAxisZ } from '../MathHelpers.js'; import { ObjectRenderContext } from './objects.js'; @@ -55,7 +55,8 @@ export class Sky { const template = renderHelper.pushTemplateRenderInst(); // Setup to draw in clip space - fillSceneParams(scratchSceneParams, mat4.create(), sceneCtx.viewerInput.backbufferWidth, sceneCtx.viewerInput.backbufferHeight); + mat4.identity(scratchSceneParams.u_Projection); + scratchSceneParams.u_SceneTextureLODBias = calcLODBias(sceneCtx.viewerInput.backbufferWidth, sceneCtx.viewerInput.backbufferHeight); projectionMatrixConvertClipSpaceNearZ(scratchSceneParams.u_Projection, device.queryVendorInfo().clipSpaceNearZ, GfxClipSpaceNearZ.NegativeOne); let offs = template.getUniformBufferOffset(GX_Material.GX_Program.ub_SceneParams); const d = template.mapUniformBufferF32(GX_Material.GX_Program.ub_SceneParams); diff --git a/src/StarFoxAdventures/SphereMaps.ts b/src/StarFoxAdventures/SphereMaps.ts index 065b6efb2..8941ca68f 100644 --- a/src/StarFoxAdventures/SphereMaps.ts +++ b/src/StarFoxAdventures/SphereMaps.ts @@ -7,7 +7,7 @@ import { GfxrAttachmentSlot, GfxrGraphBuilder, GfxrPass, GfxrPassScope, GfxrRend import { GfxRenderInstList, GfxRenderInstManager } from '../gfx/render/GfxRenderInstManager.js'; import * as GX from '../gx/gx_enum.js'; import * as GX_Material from '../gx/gx_material.js'; -import { ColorKind, DrawParams, fillSceneParams, fillSceneParamsData, gxBindingLayouts, GXRenderHelperGfx, MaterialParams, SceneParams, ub_SceneParamsBufferSize } from '../gx/gx_render.js'; +import { ColorKind, DrawParams, fillSceneParamsData, gxBindingLayouts, GXRenderHelperGfx, MaterialParams, SceneParams, ub_SceneParamsBufferSize } from '../gx/gx_render.js'; import { projectionMatrixForCuboid, setMatrixTranslation, Vec3Zero } from '../MathHelpers.js'; import { TSDraw } from "../SuperMarioGalaxy/DDraw.js"; import { TextureMapping } from '../TextureHolder.js'; @@ -55,8 +55,6 @@ function setSpecularLightAtten(light: GX_Material.Light, atten: number) { } const SPHERE_MAP_DIM = 32; -const SPHERE_MAP_PROJECTION_MTX = mat4.create(); -projectionMatrixForCuboid(SPHERE_MAP_PROJECTION_MTX, 1.0, -1.0, -1.0, 1.0, 1.0, 15.0); // Yes, left and right are meant to be 1 and -1, respectively. function createHemisphericProbeMaterial(materialFactory: MaterialFactory): SFAMaterialBuilder { const mb = new SFAMaterialBuilder('Ambient Hemispheric Probe Material'); @@ -282,7 +280,8 @@ export class SphereMapManager { renderInst.setBindingLayouts(gxBindingLayouts); // Setup to draw in clip space - fillSceneParams(scratchSceneParams, SPHERE_MAP_PROJECTION_MTX, SPHERE_MAP_DIM, SPHERE_MAP_DIM); + projectionMatrixForCuboid(scratchSceneParams.u_Projection, 1.0, -1.0, -1.0, 1.0, 1.0, 15.0); // Yes, left and right are meant to be 1 and -1, respectively. + scratchSceneParams.u_SceneTextureLODBias = 0; projectionMatrixConvertClipSpaceNearZ(scratchSceneParams.u_Projection, device.queryVendorInfo().clipSpaceNearZ, GfxClipSpaceNearZ.NegativeOne); let offs = renderInst.allocateUniformBuffer(GX_Material.GX_Program.ub_SceneParams, ub_SceneParamsBufferSize); const d = renderInst.mapUniformBufferF32(GX_Material.GX_Program.ub_SceneParams); diff --git a/src/StarFoxAdventures/render.ts b/src/StarFoxAdventures/render.ts index 348bc388d..66a8eb540 100644 --- a/src/StarFoxAdventures/render.ts +++ b/src/StarFoxAdventures/render.ts @@ -7,7 +7,7 @@ import { GfxrAttachmentSlot, GfxrGraphBuilder, GfxrPass, GfxrPassScope, GfxrRend import { GfxRenderInst, GfxRenderInstList, GfxRenderInstManager } from "../gfx/render/GfxRenderInstManager.js"; import * as GX from '../gx/gx_enum.js'; import * as GX_Material from '../gx/gx_material.js'; -import { DrawParams, fillSceneParams, fillSceneParamsData, GXMaterialHelperGfx, GXRenderHelperGfx, MaterialParams, SceneParams } from '../gx/gx_render.js'; +import { DrawParams, fillSceneParamsData, fillSceneParamsDataOnTemplate, GXMaterialHelperGfx, GXRenderHelperGfx, MaterialParams, SceneParams } from '../gx/gx_render.js'; import { TDDraw } from '../SuperMarioGalaxy/DDraw.js'; import { TextureMapping } from '../TextureHolder.js'; import { nArray } from '../util.js'; @@ -38,9 +38,6 @@ export interface SceneRenderContext { const BACKGROUND_COLOR = colorNewFromRGBA8(0xCCCCCCFF); -const SCREENSPACE_ORTHO_MTX = mat4.create(); -mat4.ortho(SCREENSPACE_ORTHO_MTX, 0.0, 640.0, 0.0, 480.0, 1.0, 100.0); - export interface SFARenderLists { skyscape: GfxRenderInstList; world: GfxRenderInstList[/* 3 */]; @@ -142,11 +139,12 @@ export class SFARenderer implements Viewer.SceneGfx { const template = this.renderHelper.pushTemplateRenderInst(); // Setup to draw in screen space - fillSceneParams(scratchSceneParams, SCREENSPACE_ORTHO_MTX, sceneCtx.viewerInput.backbufferWidth, sceneCtx.viewerInput.backbufferHeight); + mat4.ortho(scratchSceneParams.u_Projection, 0.0, 640.0, 0.0, 480.0, 1.0, 100.0); + scratchSceneParams.u_SceneTextureLODBias = 0; let offs = template.getUniformBufferOffset(GX_Material.GX_Program.ub_SceneParams); const d = template.mapUniformBufferF32(GX_Material.GX_Program.ub_SceneParams); fillSceneParamsData(d, offs, scratchSceneParams); - + // Extract pitch const cameraFwd = scratchVec0; getMatrixAxisZ(cameraFwd, sceneCtx.viewerInput.camera.worldMatrix); diff --git a/src/SuperMarioGalaxy/Actors/GalaxyMap.ts b/src/SuperMarioGalaxy/Actors/GalaxyMap.ts index b9c6319be..b6ff72c81 100644 --- a/src/SuperMarioGalaxy/Actors/GalaxyMap.ts +++ b/src/SuperMarioGalaxy/Actors/GalaxyMap.ts @@ -6,7 +6,7 @@ import { GfxClipSpaceNearZ, GfxFormat } from "../../gfx/platform/GfxPlatform.js" import { GfxRenderInstList, GfxRenderInstManager } from "../../gfx/render/GfxRenderInstManager.js"; import { GfxrAttachmentSlot, GfxrRenderTargetDescription, GfxrRenderTargetID } from "../../gfx/render/GfxRenderGraph.js"; import { GX_Program } from "../../gx/gx_material.js"; -import { fillSceneParams, fillSceneParamsData, SceneParams, ub_SceneParamsBufferSize } from "../../gx/gx_render.js"; +import { calcLODBias, fillSceneParamsData, SceneParams, ub_SceneParamsBufferSize } from "../../gx/gx_render.js"; import { projectionMatrixForCuboid, getMatrixTranslation } from "../../MathHelpers.js"; import { assertExists } from "../../util.js"; import { connectToScene } from "../ActorUtil.js"; @@ -396,15 +396,15 @@ export class GalaxyMapController extends LayoutActor { const template = renderInstManager.pushTemplate(); - let offs = template.allocateUniformBuffer(GX_Program.ub_SceneParams, ub_SceneParamsBufferSize); - const d = template.mapUniformBufferF32(GX_Program.ub_SceneParams); + const d = template.allocateUniformBufferF32(GX_Program.ub_SceneParams, ub_SceneParamsBufferSize); + const sceneParams = new SceneParams(); const w = 604, h = 456; - projectionMatrixForCuboid(scratchMatrix, -w / 2, w / 2, -h / 2, h / 2, -10000.0, 10000.0); + projectionMatrixForCuboid(sceneParams.u_Projection, -w / 2, w / 2, -h / 2, h / 2, -10000.0, 10000.0); const clipSpaceNearZ = renderInstManager.gfxRenderCache.device.queryVendorInfo().clipSpaceNearZ; - projectionMatrixConvertClipSpaceNearZ(scratchMatrix, clipSpaceNearZ, GfxClipSpaceNearZ.NegativeOne); - fillSceneParams(sceneParams, scratchMatrix, desc.width, desc.height); - fillSceneParamsData(d, offs, sceneParams); + projectionMatrixConvertClipSpaceNearZ(sceneParams.u_Projection, clipSpaceNearZ, GfxClipSpaceNearZ.NegativeOne); + sceneParams.u_SceneTextureLODBias = calcLODBias(desc.width, desc.height); + fillSceneParamsData(d, 0, sceneParams); scratchDrawInfo.aspectAdjust = true; scratchDrawInfo.aspectAdjustScaleX = 0.75; diff --git a/src/SuperMarioGalaxy/ClipArea.ts b/src/SuperMarioGalaxy/ClipArea.ts index fa3a4ed9a..e254d75f9 100644 --- a/src/SuperMarioGalaxy/ClipArea.ts +++ b/src/SuperMarioGalaxy/ClipArea.ts @@ -709,9 +709,8 @@ export class FallOutFieldDraw extends NameObj { } private allocateParameterBuffer(renderInst: GfxRenderInst) { - let offs = renderInst.allocateUniformBuffer(0, 8); - const d = renderInst.mapUniformBufferF32(0); - + const d = renderInst.allocateUniformBufferF32(0, 8); + let offs = 0; offs += fillColor(d, offs, this.edgeColor); offs += fillVec4(d, offs, this.invert ? 1.0 : 0.0); } diff --git a/src/SuperMarioGalaxy/ImageEffect.ts b/src/SuperMarioGalaxy/ImageEffect.ts index 9c464702a..7abd8799b 100644 --- a/src/SuperMarioGalaxy/ImageEffect.ts +++ b/src/SuperMarioGalaxy/ImageEffect.ts @@ -246,14 +246,14 @@ export class BloomEffect extends ImageEffectBase { } private allocateParameterBuffer(renderInst: GfxRenderInst) { - let offs = renderInst.allocateUniformBuffer(0, 4); - const d = renderInst.mapUniformBufferF32(0); + const d = renderInst.allocateUniformBufferF32(0, 4); const bloomIntensity = (this.bloomIntensity * this.strength) / 0xFF; const threshold = this.threshold / 0xFF; const intensity1 = this.intensity1 / 0xFF; const intensity2 = this.intensity2 / 0xFF; + let offs = 0; offs += fillVec4(d, offs, bloomIntensity, threshold, intensity1, intensity2); } @@ -490,13 +490,13 @@ export class BloomEffectSimple extends ImageEffectBase { } private allocateParameterBuffer(renderInst: GfxRenderInst) { - let offs = renderInst.allocateUniformBuffer(0, 4); - const d = renderInst.mapUniformBufferF32(0); + const d = renderInst.allocateUniformBufferF32(0, 4); const maskFilter = this.maskFilter; const threshold = this.threshold / 0xFF; const intensity = (this.intensity * this.strength); + let offs = 0; offs += fillVec4(d, offs, maskFilter, threshold, intensity); } @@ -656,12 +656,13 @@ export class DepthOfFieldBlur extends ImageEffectBase { } private allocateParameterBuffer(renderInst: GfxRenderInst) { - let offs = renderInst.allocateUniformBuffer(0, 4); - const d = renderInst.mapUniformBufferF32(0); + const d = renderInst.allocateUniformBufferF32(0, 4); const intensity = this.intensity * this.strength; const blurMaxDist = fallback(this.blurMaxDist, 0xF8) / 0xFF; const blurMinDist = fallback(this.blurMinDist, 0xF2) / 0xFF; + + let offs = 0; offs += fillVec4(d, offs, intensity, blurMaxDist, blurMinDist, IsDepthReversed ? 1.0 : 0.0); } diff --git a/src/SuperMarioGalaxy/Main.ts b/src/SuperMarioGalaxy/Main.ts index 1a49d3174..a74f7a3fc 100644 --- a/src/SuperMarioGalaxy/Main.ts +++ b/src/SuperMarioGalaxy/Main.ts @@ -19,7 +19,7 @@ import { setBackbufferDescSimple, standardFullClearRenderPassDescriptor } from ' import { gfxDeviceNeedsFlipY } from '../gfx/helpers/GfxDeviceHelpers.js'; import { projectionMatrixConvertClipSpaceNearZ } from '../gfx/helpers/ProjectionHelpers.js'; -import { SceneParams, fillSceneParams, ub_SceneParamsBufferSize, fillSceneParamsData } from '../gx/gx_render.js'; +import { SceneParams, ub_SceneParamsBufferSize, fillSceneParamsData, calcLODBias } from '../gx/gx_render.js'; import { EFB_WIDTH, EFB_HEIGHT, GX_Program } from '../gx/gx_material.js'; import { GXRenderHelperGfx } from '../gx/gx_render.js'; @@ -427,16 +427,17 @@ export class SMGRenderer implements Viewer.SceneGfx { this.executeMovementList(); this.executeCalcAnimList(); + sceneParams.u_SceneTextureLODBias = calcLODBias(viewerInput.backbufferWidth, viewerInput.backbufferHeight); + // Prepare our two scene params buffers. const sceneParamsOffs3D = this.renderHelper.uniformBuffer.allocateChunk(ub_SceneParamsBufferSize); - fillSceneParams(sceneParams, viewerInput.camera.projectionMatrix, viewerInput.backbufferWidth, viewerInput.backbufferHeight); + mat4.copy(sceneParams.u_Projection, viewerInput.camera.projectionMatrix); fillSceneParamsData(this.renderHelper.uniformBuffer.mapBufferF32(), sceneParamsOffs3D, sceneParams); sceneObjHolder.renderParams.sceneParamsOffs3D = sceneParamsOffs3D; const sceneParamsOffs2D = this.renderHelper.uniformBuffer.allocateChunk(ub_SceneParamsBufferSize); - projectionMatrixForCuboid(scratchMatrix, 0, viewerInput.backbufferWidth, 0, viewerInput.backbufferHeight, -10000.0, 10000.0); - projectionMatrixConvertClipSpaceNearZ(scratchMatrix, viewerInput.camera.clipSpaceNearZ, GfxClipSpaceNearZ.NegativeOne); - fillSceneParams(sceneParams, scratchMatrix, viewerInput.backbufferWidth, viewerInput.backbufferHeight); + projectionMatrixForCuboid(sceneParams.u_Projection, 0, viewerInput.backbufferWidth, 0, viewerInput.backbufferHeight, -10000.0, 10000.0); + projectionMatrixConvertClipSpaceNearZ(sceneParams.u_Projection, viewerInput.camera.clipSpaceNearZ, GfxClipSpaceNearZ.NegativeOne); fillSceneParamsData(this.renderHelper.uniformBuffer.mapBufferF32(), sceneParamsOffs2D, sceneParams); sceneObjHolder.renderParams.sceneParamsOffs2D = sceneParamsOffs2D; diff --git a/src/SuperMarioGalaxy/Shadow.ts b/src/SuperMarioGalaxy/Shadow.ts index 1671b975b..fec4007e4 100644 --- a/src/SuperMarioGalaxy/Shadow.ts +++ b/src/SuperMarioGalaxy/Shadow.ts @@ -1082,8 +1082,8 @@ class AlphaShadow extends NameObj { // Blend onto main screen. const renderInst = renderInstManager.newRenderInst(); - const sceneParamsOffs = renderInst.allocateUniformBuffer(GX_Program.ub_SceneParams, ub_SceneParamsBufferSize); - fillSceneParamsData(renderInst.mapUniformBufferF32(GX_Program.ub_SceneParams), sceneParamsOffs, this.orthoSceneParams); + const d = renderInst.allocateUniformBufferF32(GX_Program.ub_SceneParams, ub_SceneParamsBufferSize); + fillSceneParamsData(d, 0, this.orthoSceneParams); this.materialHelperDrawAlpha.setOnRenderInst(renderInstManager.gfxRenderCache, renderInst); this.materialHelperDrawAlpha.allocateMaterialParamsDataOnInst(renderInst, materialParams); renderInst.setSamplerBindingsFromTextureMappings(materialParams.m_TextureMapping); diff --git a/src/ZeldaTwilightPrincess/d_kankyo_wether.ts b/src/ZeldaTwilightPrincess/d_kankyo_wether.ts index 1381923a7..b29e58fd5 100644 --- a/src/ZeldaTwilightPrincess/d_kankyo_wether.ts +++ b/src/ZeldaTwilightPrincess/d_kankyo_wether.ts @@ -1533,7 +1533,7 @@ function dKyr_sun_move(globals: dGlobals, deltaTimeFrames: number): void { if (sunCanGlare) { // Original game projects the vector into viewport space, and gets distance to 320, 240. - mDoLib_project(scratchVec3, pkt.sunPos, globals.camera); + mDoLib_project(scratchVec3, pkt.sunPos, globals.camera.clipFromWorldMatrix); const peekZ = globals.dlst.peekZ; diff --git a/src/ZeldaWindWaker/Grass.ts b/src/ZeldaWindWaker/Grass.ts index ce55e61f4..a0ad022bb 100644 --- a/src/ZeldaWindWaker/Grass.ts +++ b/src/ZeldaWindWaker/Grass.ts @@ -366,14 +366,12 @@ export class FlowerPacket { } private drawFlowers(globals: dGlobals, roomIdx: number, type: FlowerType, model: DynamicModel, renderInstManager: GfxRenderInstManager, viewerInput: ViewerRenderInput): void { - const camera = viewerInput.camera; - - getMatrixTranslation(scratchVec3a, camera.worldMatrix); + const camera = globals.camera; const template = renderInstManager.pushTemplate(); template.setSamplerBindingsFromTextureMappings(model.textureMapping); setColorFromRoomNo(globals, materialParams, roomIdx); - dKy_GxFog_set(globals.g_env_light, materialParams.u_FogBlock, viewerInput.camera); + dKy_GxFog_set(globals.g_env_light, materialParams.u_FogBlock, camera); model.materialHelper.allocateMaterialParamsDataOnInst(template, materialParams); model.materialHelper.setOnRenderInst(renderInstManager.gfxRenderCache, template); @@ -383,12 +381,12 @@ export class FlowerPacket { if (data.flags & FlowerFlags.IsFrustumCulled || data.type !== type) continue; - if (distanceCull(scratchVec3a, data.pos)) + if (distanceCull(camera.cameraPos, data.pos)) continue; const renderInst = renderInstManager.newRenderInst(); model.shapes[0].setOnRenderInst(renderInst); - mat4.mul(drawParams.u_PosMtx[0], camera.viewMatrix, data.modelMatrix); + mat4.mul(drawParams.u_PosMtx[0], camera.viewFromWorldMatrix, data.modelMatrix); model.materialHelper.allocateDrawParamsDataOnInst(renderInst, drawParams); renderInstManager.submitRenderInst(renderInst); } @@ -726,8 +724,7 @@ export class TreePacket { if (room.length === 0) return; - const worldToView = viewerInput.camera.viewMatrix; - const worldCamPos = mat4.getTranslation(scratchVec3b, viewerInput.camera.worldMatrix); + const camera = globals.camera; // Draw shadows { @@ -735,7 +732,7 @@ export class TreePacket { const template = renderInstManager.pushTemplate(); template.sortKey = makeSortKey(GfxRendererLayer.TRANSLUCENT); setColorFromRoomNo(globals, materialParams, roomIdx); - dKy_GxFog_set(globals.g_env_light, materialParams.u_FogBlock, viewerInput.camera); + dKy_GxFog_set(globals.g_env_light, materialParams.u_FogBlock, camera); // Set the shadow color. Pulled from d_tree::l_shadowColor$4656 colorFromRGBA(materialParams.u_Color[ColorKind.C0], 0, 0, 0, 0x64/0xFF); this.treeModel.shadow.materialHelper.allocateMaterialParamsDataOnInst(template, materialParams); @@ -744,12 +741,12 @@ export class TreePacket { for (let i = 0; i < room.length; i++) { const data = room[i]; - if (distanceCull(worldCamPos, data.pos)) + if (distanceCull(camera.cameraPos, data.pos)) continue; const shadowRenderInst = renderInstManager.newRenderInst(); this.treeModel.shadow.shapes[0].setOnRenderInst(shadowRenderInst); - mat4.mul(drawParams.u_PosMtx[0], worldToView, data.shadowModelMtx); + mat4.mul(drawParams.u_PosMtx[0], camera.viewFromWorldMatrix, data.shadowModelMtx); this.treeModel.shadow.materialHelper.allocateDrawParamsDataOnInst(shadowRenderInst, drawParams); renderInstManager.submitRenderInst(shadowRenderInst); } @@ -760,7 +757,7 @@ export class TreePacket { { const template = renderInstManager.pushTemplate(); setColorFromRoomNo(globals, materialParams, roomIdx); - dKy_GxFog_set(globals.g_env_light, materialParams.u_FogBlock, viewerInput.camera); + dKy_GxFog_set(globals.g_env_light, materialParams.u_FogBlock, camera); // Set the tree alpha. This fades after the tree is cut. This is multiplied with the texture alpha at the end of TEV stage 1. colorFromRGBA(materialParams.u_Color[ColorKind.C2], 0, 0, 0, 1); this.treeModel.main.materialHelper.allocateMaterialParamsDataOnInst(template, materialParams); @@ -772,18 +769,18 @@ export class TreePacket { if (data.flags & TreeFlags.IsFrustumCulled) continue; - if (distanceCull(worldCamPos, data.pos)) + if (distanceCull(camera.cameraPos, data.pos)) continue; const trunkRenderInst = renderInstManager.newRenderInst(); this.treeModel.main.shapes[0].setOnRenderInst(trunkRenderInst); - mat4.mul(drawParams.u_PosMtx[0], worldToView, data.trunkModelMtx); + mat4.mul(drawParams.u_PosMtx[0], camera.viewFromWorldMatrix, data.trunkModelMtx); this.treeModel.main.materialHelper.allocateDrawParamsDataOnInst(trunkRenderInst, drawParams); renderInstManager.submitRenderInst(trunkRenderInst); const topRenderInst = renderInstManager.newRenderInst(); this.treeModel.main.shapes[1].setOnRenderInst(topRenderInst); - mat4.mul(drawParams.u_PosMtx[0], worldToView, data.topModelMtx); + mat4.mul(drawParams.u_PosMtx[0], camera.viewFromWorldMatrix, data.topModelMtx); this.treeModel.main.materialHelper.allocateDrawParamsDataOnInst(topRenderInst, drawParams); renderInstManager.submitRenderInst(topRenderInst); } @@ -1024,13 +1021,12 @@ export class GrassPacket { if (room.length === 0) return; - const worldToView = viewerInput.camera.viewMatrix; - const worldCamPos = mat4.getTranslation(scratchVec3b, viewerInput.camera.worldMatrix); + const camera = globals.camera; const template = renderInstManager.pushTemplate(); template.setSamplerBindingsFromTextureMappings(this.grassModel.textureMapping); setColorFromRoomNo(globals, materialParams, roomIdx); - dKy_GxFog_set(globals.g_env_light, materialParams.u_FogBlock, viewerInput.camera); + dKy_GxFog_set(globals.g_env_light, materialParams.u_FogBlock, camera); this.grassModel.materialHelper.allocateMaterialParamsDataOnInst(template, materialParams); this.grassModel.materialHelper.setOnRenderInst(renderInstManager.gfxRenderCache, template); @@ -1039,12 +1035,12 @@ export class GrassPacket { if (data.flags & GrassFlags.IsFrustumCulled) continue; - if (distanceCull(worldCamPos, data.pos)) + if (distanceCull(camera.cameraPos, data.pos)) continue; const renderInst = renderInstManager.newRenderInst(); this.grassModel.shapes[0].setOnRenderInst(renderInst); - mat4.mul(drawParams.u_PosMtx[0], worldToView, data.modelMtx); + mat4.mul(drawParams.u_PosMtx[0], camera.viewFromWorldMatrix, data.modelMtx); this.grassModel.materialHelper.allocateDrawParamsDataOnInst(renderInst, drawParams); renderInstManager.submitRenderInst(renderInst); } diff --git a/src/ZeldaWindWaker/LegacyActor.ts b/src/ZeldaWindWaker/LegacyActor.ts index 5497d3830..d7cb48f2e 100644 --- a/src/ZeldaWindWaker/LegacyActor.ts +++ b/src/ZeldaWindWaker/LegacyActor.ts @@ -86,7 +86,7 @@ class d_a_noclip_legacy extends fopAc_ac_c { if (this.objectRenderers.length === 0) return; - if (!this.cullingCheck(viewerInput.camera)) + if (!this.cullingCheck(globals.camera)) return; const device = globals.modelCache.device; @@ -367,7 +367,7 @@ function spawnLegacyActor(globals: dGlobals, legacy: d_a_noclip_legacy, actor: f else if (actorName === 'Hi1') fetchArchive(`Hi`).then((rarc) => buildModel(rarc, `bdlm/hi.bdl`).bindANK1(parseBCK(rarc, `bcks/hi_wait01.bck`))); // Princess Zelda else if (actorName === 'p_zelda') fetchArchive(`Pz`).then((rarc) => { - const m = buildModel(rarc, `bdlm/pz.bdl`); + const m = buildModel(rarc, `bdlm/pz.bdl`); m.setMaterialColorWriteEnabled("m_pz_eyeLdamA", false); m.setMaterialColorWriteEnabled("m_pz_eyeLdamB", false); m.setMaterialColorWriteEnabled("m_pz_mayuLdamA", false); @@ -1257,7 +1257,7 @@ function spawnLegacyActor(globals: dGlobals, legacy: d_a_noclip_legacy, actor: f else if (actorName === 'Oq') fetchArchive(`Oq`).then((rarc) => buildModel(rarc, `bmdm/oq.bmd`).bindANK1(parseBCK(rarc, `bck/nom_wait.bck`))); else if (actorName === 'Oqw') fetchArchive(`Oq`).then((rarc) => buildModel(rarc, `bmdm/red_oq.bmd`).bindANK1(parseBCK(rarc, `bck/umi_new_wait.bck`))); else if (actorName === 'Daiocta') fetchArchive(`Daiocta`).then((rarc) => buildModel(rarc, `bdlm/do_main1.bdl`).bindANK1(parseBCK(rarc, `bck/wait1.bck`))); - else if (actorName === 'Fmastr1' || actorName === 'Fmastr2') fetchArchive(`fm`).then((rarc) => { + else if (actorName === 'Fmastr1' || actorName === 'Fmastr2') fetchArchive(`fm`).then((rarc) => { buildModel(rarc, `bdl/fm.bdl`).bindANK1(parseBCK(rarc, `bcks/wait.bck`)); const holeModel = buildModel(rarc, `bdlm/ypit00.bdl`); holeModel.bindTTK1(parseBTK(rarc, `btk/ypit00.btk`)); @@ -1270,7 +1270,7 @@ function spawnLegacyActor(globals: dGlobals, legacy: d_a_noclip_legacy, actor: f const m = buildModel(rarc, `bdlm/bl.bdl`); const bubbleType = (actor.parameters & 0x000000FF); - + if (bubbleType === 0x80) { m.bindTTK1(parseBTK(rarc, 'btk/off.btk')); } else { @@ -1286,7 +1286,7 @@ function spawnLegacyActor(globals: dGlobals, legacy: d_a_noclip_legacy, actor: f else if (actorName === 'Tn') fetchArchive(`Tn`).then(async (rarc) => { const equipmentType = (actor.rot![0] & 0x00E0) >>> 5; const armorColor = (actor.parameters & 0x000000F0) >>> 4; - + const mainModel = buildModel(rarc, `bmdm/tn_main.bmd`); const mainAnim = parseBCK(rarc, `bck/aniou1.bck`); mainModel.bindTRK1(parseBRK(rarc, `brk/tn_main.brk`), animFrame(armorColor)); @@ -1295,7 +1295,7 @@ function spawnLegacyActor(globals: dGlobals, legacy: d_a_noclip_legacy, actor: f const swordModel = buildChildModel(weaponRarc, `bdlc/tn_ken1.bdl`); swordModel.setParentJoint(mainModel, `j_tn_item_r1`); mat4.translate(swordModel.modelMatrix, swordModel.modelMatrix, [0, 0, 85]); - + const armorModel = buildChildModel(rarc, `bmdm/tn_yoroi1.bmd`); armorModel.setParentJoint(mainModel, `j_tn_mune1`); armorModel.bindTRK1(parseBRK(rarc, `brk/tn_yoroi1.brk`), animFrame(armorColor)); @@ -1873,16 +1873,16 @@ export class BMDObjectRenderer { mat4.getTranslation(scratchVec3a, this.modelMatrix); settingTevStruct(globals, this.lightTevColorType, scratchVec3a, this.tevstr); - setLightTevColorType(globals, this.modelInstance, this.tevstr, viewerInput.camera); + setLightTevColorType(globals, this.modelInstance, this.tevstr, globals.camera); - if( morf ) { + if (morf) { morf.calc(); morf.entryDL(globals, renderInstManager, viewerInput); } else { this.setExtraTextures(globals.renderer.extraTextures); this.modelInstance.prepareToRender(device, renderInstManager, viewerInput); } - + for (let i = 0; i < this.childObjects.length; i++) this.childObjects[i].prepareToRender(globals, null, device, renderInstManager, viewerInput); } diff --git a/src/ZeldaWindWaker/Main.ts b/src/ZeldaWindWaker/Main.ts index eac39cf83..0d7a9103e 100644 --- a/src/ZeldaWindWaker/Main.ts +++ b/src/ZeldaWindWaker/Main.ts @@ -1,5 +1,5 @@ -import { mat4, vec3 } from 'gl-matrix'; +import { mat4, vec3, vec4 } from 'gl-matrix'; import ArrayBufferSlice from '../ArrayBufferSlice.js'; import { DataFetcher } from '../DataFetcher.js'; @@ -17,15 +17,15 @@ import { J3DModelInstance } from '../Common/JSYSTEM/J3D/J3DGraphBase.js'; import * as JPA from '../Common/JSYSTEM/JPA.js'; import { BTIData } from '../Common/JSYSTEM/JUTTexture.js'; import { dfRange } from '../DebugFloaters.js'; -import { MathConstants, getMatrixAxisZ, range } from '../MathHelpers.js'; +import { MathConstants, getMatrixAxisZ, getMatrixTranslation, range } from '../MathHelpers.js'; import { SceneContext } from '../SceneBase.js'; import { TextureMapping } from '../TextureHolder.js'; import { setBackbufferDescSimple, standardFullClearRenderPassDescriptor } from '../gfx/helpers/RenderGraphHelpers.js'; -import { GfxDevice, GfxFormat, GfxRenderPass, GfxTexture, makeTextureDescriptor2D } from '../gfx/platform/GfxPlatform.js'; +import { GfxClipSpaceNearZ, GfxDevice, GfxFormat, GfxRenderPass, GfxTexture, makeTextureDescriptor2D } from '../gfx/platform/GfxPlatform.js'; import { GfxRenderCache } from '../gfx/render/GfxRenderCache.js'; import { GfxrAttachmentSlot, GfxrRenderTargetDescription } from '../gfx/render/GfxRenderGraph.js'; import { GfxRenderInstList, GfxRenderInstManager } from '../gfx/render/GfxRenderInstManager.js'; -import { GXRenderHelperGfx, fillSceneParamsDataOnTemplate } from '../gx/gx_render.js'; +import { GXRenderHelperGfx, SceneParams, calcLODBias, fillSceneParamsData } from '../gx/gx_render.js'; import { FlowerPacket, GrassPacket, TreePacket } from './Grass.js'; import { LegacyActor__RegisterFallbackConstructor } from './LegacyActor.js'; import { dDlst_2DStatic_c, d_a__RegisterConstructors } from './d_a.js'; @@ -43,6 +43,8 @@ import { fopAcM_create, fopAcM_searchFromName, fopAc_ac_c } from './f_op_actor.j import { cPhs__Status, fGlobals, fopDw_Draw, fopScn, fpcCt_Handler, fpcLy_SetCurrentLayer, fpcM_Management, fpcPf__Register, fpcSCtRq_Request, fpc_pc__ProfileList } from './framework.js'; import { dDemo_manager_c, EDemoCamFlags, EDemoMode } from './d_demo.js'; import { d_pn__RegisterConstructors, Placename, PlacenameState, dPn__update } from './d_place_name.js'; +import { GX_Program } from '../gx/gx_material.js'; +import { Frustum } from '../Geometry.js'; type SymbolData = { Filename: string, SymbolName: string, Data: ArrayBufferSlice }; type SymbolMapData = { SymbolData: SymbolData[] }; @@ -122,6 +124,8 @@ class RenderHacks { public renderHacksChanged = false; } +const sceneParams = new SceneParams(); + export class dGlobals { public g_env_light = new dScnKy_env_light_c(); public dlst: dDlst_list_c; @@ -137,12 +141,10 @@ export class dGlobals { // "Current" room number. public mStayNo: number = 0; - // g_dComIfG_gameInfo.mPlay.mpPlayer.mPos3 + // g_dComIfG_gameInfo.mPlay.mpPlayer.mPos public playerPosition = vec3.create(); // g_dComIfG_gameInfo.mPlay.mCameraInfo[0].mpCamera - public camera: Camera; - public cameraPosition = vec3.create(); - public cameraFwd = vec3.create(); + public camera = new dCamera_c(); public resCtrl: dRes_control_c; // TODO(jstpierre): Remove @@ -157,7 +159,7 @@ export class dGlobals { public sea: d_a_sea | null = null; - constructor(public context: SceneContext, public modelCache: ModelCache, private extraSymbolData: SymbolMap, public frameworkGlobals: fGlobals) { + constructor(public sceneContext: SceneContext, public modelCache: ModelCache, private extraSymbolData: SymbolMap, public frameworkGlobals: fGlobals) { this.resCtrl = this.modelCache.resCtrl; this.relNameTable = createRelNameTable(extraSymbolData); @@ -202,6 +204,131 @@ export class dGlobals { } } +const enum CameraMode { + Default, + Cinematic +} + +export class dCamera_c { + public viewFromWorldMatrix = mat4.create(); // aka viewMatrix + public worldFromViewMatrix = mat4.create(); // aka worldMatrix + public clipFromWorldMatrix = mat4.create(); + public clipFromViewMatrix = mat4.create(); // aka projectionMatrix + + public clipSpaceNearZ: GfxClipSpaceNearZ; + + // Frustum is stored in Wind Waker engine world space. + public frustum = new Frustum(); + public aspect = 1.0; + public fovY = 0.0; + public near = 0.0; + public far = 0.0; + + // The current camera position, in Wind Waker engine world space. + public cameraPos = vec3.create(); + public cameraFwd = vec3.create(); + public cameraUp = vec3.fromValues(0, 1, 0); + public roll = 0.0; + + // For people to play around with. + public frozen = false; + + private trimHeight = 0; + private cameraMode: CameraMode = CameraMode.Default; + private scissor = vec4.create(); + + private static trimHeightCinematic = 65.0; + + public finishSetup(): void { + mat4.invert(this.worldFromViewMatrix, this.viewFromWorldMatrix); + mat4.mul(this.clipFromWorldMatrix, this.clipFromViewMatrix, this.viewFromWorldMatrix); + getMatrixTranslation(this.cameraPos, this.worldFromViewMatrix); + getMatrixAxisZ(this.cameraFwd, this.worldFromViewMatrix); + this.frustum.updateClipFrustum(this.clipFromWorldMatrix, this.clipSpaceNearZ); + } + + public setupFromCamera(camera: Camera): void { + this.clipSpaceNearZ = camera.clipSpaceNearZ; + this.aspect = camera.aspect; + this.fovY = camera.fovY; + + mat4.copy(this.viewFromWorldMatrix, camera.viewMatrix); + mat4.copy(this.clipFromViewMatrix, camera.projectionMatrix); + this.finishSetup(); + } + + public execute(globals: dGlobals, viewerInput: Viewer.ViewerRenderInput) { + // Near/far planes are decided by the stage data. + const stag = globals.dStage_dt.stag; + + // Pull in the near plane to decrease Z-fighting, some stages set it far too close... + let near = Math.max(stag.nearPlane, 5); + let far = stag.farPlane; + + // noclip modification: if this is the sea map, push our far plane out a bit. + if (globals.stageName === 'sea') + far *= 2; + + // noclip modification: if we're paused, allow noclip camera control during demos + const isPaused = viewerInput.deltaTime === 0; + + // dCamera_c::Store() sets the camera params if the demo camera is active + const demoCam = globals.scnPlay.demo.getSystem().getCamera(); + if (demoCam && !isPaused) { + const targetPos = vec3.add(scratchVec3a, this.cameraPos, this.cameraFwd); + + // TODO: Blend between these camera params when switching camera modes, instead of the sudden snap. + + if (demoCam.flags & EDemoCamFlags.HasTargetPos) { vec3.copy(targetPos, demoCam.targetPosition); } + if (demoCam.flags & EDemoCamFlags.HasEyePos) { vec3.copy(this.cameraPos, demoCam.viewPosition); } + if (demoCam.flags & EDemoCamFlags.HasUpVec) { vec3.copy(this.cameraUp, demoCam.upVector); } + if (demoCam.flags & EDemoCamFlags.HasFovY) { this.fovY = demoCam.fovY * MathConstants.DEG_TO_RAD; } + if (demoCam.flags & EDemoCamFlags.HasRoll) { this.roll = demoCam.roll * MathConstants.DEG_TO_RAD; } + if (demoCam.flags & EDemoCamFlags.HasAspect) { debugger; /* Untested. Remove once confirmed working */ } + if (demoCam.flags & EDemoCamFlags.HasNearZ) { near = demoCam.projNear; } + if (demoCam.flags & EDemoCamFlags.HasFarZ) { far = demoCam.projFar; } + + // TODO: Clean this up + mat4.targetTo(this.worldFromViewMatrix, this.cameraPos, targetPos, this.cameraUp); + mat4.rotateZ(this.worldFromViewMatrix, this.worldFromViewMatrix, this.roll); + + this.cameraMode = CameraMode.Cinematic; + globals.sceneContext.inputManager.isMouseEnabled = false; + } else { + this.cameraMode = CameraMode.Default; + globals.sceneContext.inputManager.isMouseEnabled = true; + } + + // TODO: Clean this up + viewerInput.camera.setClipPlanes(near, far); + this.near = near; + this.far = far; + this.setupFromCamera(viewerInput.camera); + this.finishSetup(); + + // From dCamera_c::CalcTrimSize() + // Animate up to the trim size for the current mode. + if (this.cameraMode === CameraMode.Cinematic) { + this.trimHeight += (dCamera_c.trimHeightCinematic - this.trimHeight) * 0.25; + } else { + this.trimHeight += -this.trimHeight * 0.25; + } + + const trimPx = (this.trimHeight / 480) * viewerInput.backbufferHeight; + vec4.set(this.scissor, 0, trimPx, viewerInput.backbufferWidth, viewerInput.backbufferHeight - 2 * trimPx); + + if (!this.frozen) { + // Update the "player position" from the camera. + // TODO: Move this out of here + vec3.copy(globals.playerPosition, this.cameraPos); + } + } + + public applyScissor(pass: GfxRenderPass) { + pass.setScissor(this.scissor[0], this.scissor[1], this.scissor[2], this.scissor[3]); + } +} + function gain(v: number, k: number): number { const a = 0.5 * Math.pow(2*((v < 0.5) ? v : 1.0 - v), k); return v < 0.5 ? a : 1.0 - a; @@ -317,7 +444,6 @@ const enum EffectDrawGroup { const scratchMatrix = mat4.create(); const scratchVec3a = vec3.create(); -const scratchVec3b = vec3.create(); export class WindWakerRenderer implements Viewer.SceneGfx { private mainColorDesc = new GfxrRenderTargetDescription(GfxFormat.U8_RGBA_RT); private mainDepthDesc = new GfxrRenderTargetDescription(GfxFormat.D32F); @@ -402,9 +528,6 @@ export class WindWakerRenderer implements Viewer.SceneGfx { return [roomsPanel, scenarioPanel, renderHacksPanel]; } - // For people to play around with. - public cameraFrozen = false; - private getRoomStatus(ac: fopAc_ac_c): dStage_roomStatus_c | null { if (ac.roomNo === -1) return null; @@ -425,16 +548,18 @@ export class WindWakerRenderer implements Viewer.SceneGfx { } private executeDrawAll(device: GfxDevice, viewerInput: Viewer.ViewerRenderInput): void { + const globals = this.globals; + this.time = viewerInput.time; // noclip hack: if only one room is visible, make it the mStayNo const singleRoomVisibleNo = this.getSingleRoomVisible(); if (singleRoomVisibleNo !== -1) - this.globals.mStayNo = singleRoomVisibleNo; + globals.mStayNo = singleRoomVisibleNo; // Update actor visibility from settings. // TODO(jstpierre): Figure out a better place to put this? - const fwGlobals = this.globals.frameworkGlobals; + const fwGlobals = globals.frameworkGlobals; for (let i = 0; i < fwGlobals.dwQueue.length; i++) { for (let j = 0; j < fwGlobals.dwQueue[i].length; j++) { const ac = fwGlobals.dwQueue[i][j]; @@ -444,104 +569,57 @@ export class WindWakerRenderer implements Viewer.SceneGfx { ac.roomVisible = roomVisible && objectLayerVisible(this.roomLayerMask, ac.roomLayer); - if (ac.roomVisible && !this.globals.renderHacks.objectsVisible && fpcIsObject(ac.processName)) + if (ac.roomVisible && !globals.renderHacks.objectsVisible && fpcIsObject(ac.processName)) ac.roomVisible = false; } } } - // Near/far planes are decided by the stage data. - const stag = this.globals.dStage_dt.stag; - - // Pull in the near plane to decrease Z-fighting, some stages set it far too close... - let nearPlane = Math.max(stag.nearPlane, 5); - let farPlane = stag.farPlane; - - // noclip modification: if this is the sea map, push our far plane out a bit. - if (this.globals.stageName === 'sea') - farPlane *= 2; - - viewerInput.camera.setClipPlanes(nearPlane, farPlane); - - // noclip modification: if we're paused, allow noclip camera control during demos - const isPaused = viewerInput.deltaTime === 0; - - // TODO: Determine the correct place for this - // dCamera_c::Store() sets the camera params if the demo camera is active - const demoCam = this.globals.scnPlay.demo.getSystem().getCamera(); - if (demoCam && !isPaused) { - let viewPos = this.globals.cameraPosition; - let targetPos = vec3.add(scratchVec3a, this.globals.cameraPosition, this.globals.cameraFwd); - let upVec = vec3.set(scratchVec3b, 0, 1, 0); - let roll = 0.0; - - if (demoCam.flags & EDemoCamFlags.HasTargetPos) { targetPos = demoCam.targetPosition; } - if (demoCam.flags & EDemoCamFlags.HasEyePos) { viewPos = demoCam.viewPosition; } - if (demoCam.flags & EDemoCamFlags.HasUpVec) { upVec = demoCam.upVector; } - if (demoCam.flags & EDemoCamFlags.HasFovY) { viewerInput.camera.fovY = demoCam.fovY * MathConstants.DEG_TO_RAD; } - if (demoCam.flags & EDemoCamFlags.HasRoll) { roll = demoCam.roll * MathConstants.DEG_TO_RAD; } - if (demoCam.flags & EDemoCamFlags.HasAspect) { debugger; /* Untested. Remove once confirmed working */ } - if (demoCam.flags & EDemoCamFlags.HasNearZ) { viewerInput.camera.near = demoCam.projNear; } - if (demoCam.flags & EDemoCamFlags.HasFarZ) { viewerInput.camera.far = demoCam.projFar; } - - mat4.targetTo(viewerInput.camera.worldMatrix, viewPos, targetPos, upVec); - mat4.rotateZ(viewerInput.camera.worldMatrix, viewerInput.camera.worldMatrix, roll); - viewerInput.camera.setClipPlanes(viewerInput.camera.near, viewerInput.camera.far); - viewerInput.camera.worldMatrixUpdated(); - - this.globals.context.inputManager.isMouseEnabled = false; - } else { - this.globals.context.inputManager.isMouseEnabled = true; - } - - if (!this.cameraFrozen) { - mat4.getTranslation(this.globals.cameraPosition, viewerInput.camera.worldMatrix); - getMatrixAxisZ(this.globals.cameraFwd, viewerInput.camera.worldMatrix); - vec3.negate(this.globals.cameraFwd, this.globals.cameraFwd); - // Update the "player position" from the camera. - vec3.copy(this.globals.playerPosition, this.globals.cameraPosition); - } - - this.globals.camera = viewerInput.camera; + globals.camera.execute(globals, viewerInput); // Not sure exactly where this is ordered... - dKy_setLight(this.globals); + dKy_setLight(globals); const template = this.renderHelper.pushTemplateRenderInst(); const renderInstManager = this.renderHelper.renderInstManager; - if (this.globals.renderHacks.wireframe) + if (globals.renderHacks.wireframe) template.setMegaStateFlags({ wireframe: true }); - fillSceneParamsDataOnTemplate(template, viewerInput); + mat4.copy(sceneParams.u_Projection, globals.camera.clipFromViewMatrix); + sceneParams.u_SceneTextureLODBias = calcLODBias(viewerInput.backbufferWidth, viewerInput.backbufferHeight); + let offs = template.getUniformBufferOffset(GX_Program.ub_SceneParams); + const d = template.mapUniformBufferF32(GX_Program.ub_SceneParams); + fillSceneParamsData(d, offs, sceneParams); + this.extraTextures.prepareToRender(device); - fpcM_Management(this.globals.frameworkGlobals, this.globals, renderInstManager, viewerInput); + fpcM_Management(globals.frameworkGlobals, globals, renderInstManager, viewerInput); - const dlst = this.globals.dlst; + const dlst = globals.dlst; renderInstManager.setCurrentList(dlst.alphaModel); - dlst.alphaModel0.draw(this.globals, renderInstManager, viewerInput); + dlst.alphaModel0.draw(globals, renderInstManager, viewerInput); renderInstManager.setCurrentList(dlst.bg[0]); { - this.globals.particleCtrl.calc(viewerInput); + globals.particleCtrl.calc(globals, viewerInput); for (let group = EffectDrawGroup.Main; group <= EffectDrawGroup.Indirect; group++) { let texPrjMtx: mat4 | null = null; if (group === EffectDrawGroup.Indirect) { texPrjMtx = scratchMatrix; - texProjCameraSceneTex(texPrjMtx, viewerInput.camera.projectionMatrix, 1); + texProjCameraSceneTex(texPrjMtx, globals.camera.clipFromViewMatrix, 1); } - this.globals.particleCtrl.setDrawInfo(viewerInput.camera.viewMatrix, viewerInput.camera.projectionMatrix, texPrjMtx, viewerInput.camera.frustum); + globals.particleCtrl.setDrawInfo(globals.camera.viewFromWorldMatrix, globals.camera.clipFromViewMatrix, texPrjMtx, globals.camera.frustum); renderInstManager.setCurrentList(dlst.effect[group]); - this.globals.particleCtrl.draw(device, this.renderHelper.renderInstManager, group); + globals.particleCtrl.draw(device, this.renderHelper.renderInstManager, group); } } this.renderHelper.renderInstManager.popTemplate(); - this.globals.renderHacks.renderHacksChanged = false; + globals.renderHacks.renderHacksChanged = false; } private executeList(passRenderer: GfxRenderPass, list: GfxRenderInstList): void { diff --git a/src/ZeldaWindWaker/d_a.ts b/src/ZeldaWindWaker/d_a.ts index 7e82c827f..1b105d419 100644 --- a/src/ZeldaWindWaker/d_a.ts +++ b/src/ZeldaWindWaker/d_a.ts @@ -267,7 +267,7 @@ class d_a_ep extends fopAc_ac_c { public override draw(globals: dGlobals, renderInstManager: GfxRenderInstManager, viewerInput: ViewerRenderInput): void { if (this.type === 0 || this.type === 3) { settingTevStruct(globals, LightType.BG0, this.pos, this.tevStr); - setLightTevColorType(globals, this.model, this.tevStr, viewerInput.camera); + setLightTevColorType(globals, this.model, this.tevStr, globals.camera); mDoExt_modelUpdateDL(globals, this.model, renderInstManager, viewerInput); // TODO(jstpierre): ga @@ -500,7 +500,7 @@ class d_a_bg extends fopAc_ac_c { public override draw(globals: dGlobals, renderInstManager: GfxRenderInstManager, viewerInput: ViewerRenderInput): void { // TODO(jstpierre): Proper culling check - // if (!this.cullingCheck(viewerInput.camera)) + // if (!this.cullingCheck(globals.camera)) // return; // force far plane to 100000.0 ? @@ -510,7 +510,7 @@ class d_a_bg extends fopAc_ac_c { continue; settingTevStruct(globals, LightType.BG0 + i, null, this.bgTevStr[i]!); - setLightTevColorType(globals, this.bgModel[i]!, this.bgTevStr[i]!, viewerInput.camera); + setLightTevColorType(globals, this.bgModel[i]!, this.bgTevStr[i]!, globals.camera); // this is actually mDoExt_modelEntryDL mDoExt_modelUpdateDL(globals, this.bgModel[i]!, renderInstManager, viewerInput); } @@ -621,11 +621,11 @@ class d_a_vrbox extends fopAc_ac_c { if (fili !== null) skyboxOffsY = fili.skyboxY; - MtxTrans(globals.cameraPosition, false); - calc_mtx[13] -= 0.09 * (globals.cameraPosition[1] - skyboxOffsY); + MtxTrans(globals.camera.cameraPos, false); + calc_mtx[13] -= 0.09 * (globals.camera.cameraPos[1] - skyboxOffsY); mat4.copy(this.model.modelMatrix, calc_mtx); - dKy_setLight__OnModelInstance(envLight, this.model, viewerInput.camera); + dKy_setLight__OnModelInstance(envLight, this.model, globals.camera); mDoExt_modelUpdateDL(globals, this.model, renderInstManager, viewerInput, globals.dlst.sky); } } @@ -676,7 +676,7 @@ class d_a_vrbox2 extends fopAc_ac_c { } // Camera forward in XZ plane - vec3.copy(scratchVec3a, globals.cameraFwd); + vec3.copy(scratchVec3a, globals.camera.cameraFwd); scratchVec3a[1] = 0; vec3.normalize(scratchVec3a, scratchVec3a); @@ -738,8 +738,8 @@ class d_a_vrbox2 extends fopAc_ac_c { if (fili !== null) skyboxOffsY = fili.skyboxY; - MtxTrans(globals.cameraPosition, false); - calc_mtx[13] -= 0.09 * (globals.cameraPosition[1] - skyboxOffsY); + MtxTrans(globals.camera.cameraPos, false); + calc_mtx[13] -= 0.09 * (globals.camera.cameraPos[1] - skyboxOffsY); if (this.usoUmi !== null) { mat4.copy(this.usoUmi.modelMatrix, calc_mtx); @@ -818,10 +818,10 @@ class d_a_kytag00 extends fopAc_ac_c { private get_check_pos(globals: dGlobals): vec3 { // Return the closer of the two. - if (this.alwaysCheckPlayerPos || vec3.distance(this.pos, globals.playerPosition) < vec3.distance(this.pos, globals.cameraPosition)) + if (this.alwaysCheckPlayerPos || vec3.distance(this.pos, globals.playerPosition) < vec3.distance(this.pos, globals.camera.cameraPos)) return globals.playerPosition; else - return globals.cameraPosition; + return globals.camera.cameraPos; } private wether_tag_efect_move(globals: dGlobals): void { @@ -1078,11 +1078,11 @@ class d_a_obj_Ygush00 extends fopAc_ac_c { } public override draw(globals: dGlobals, renderInstManager: GfxRenderInstManager, viewerInput: ViewerRenderInput): void { - if (!this.cullingCheck(viewerInput.camera)) + if (!this.cullingCheck(globals.camera)) return; settingTevStruct(globals, LightType.BG1, this.pos, this.tevStr); - setLightTevColorType(globals, this.model, this.tevStr, viewerInput.camera); + setLightTevColorType(globals, this.model, this.tevStr, globals.camera); this.btkAnm.entry(this.model); this.bckAnm.entry(this.model); @@ -1169,11 +1169,11 @@ class d_a_obj_lpalm extends fopAc_ac_c { } public override draw(globals: dGlobals, renderInstManager: GfxRenderInstManager, viewerInput: ViewerRenderInput): void { - if (!this.cullingCheck(viewerInput.camera)) + if (!this.cullingCheck(globals.camera)) return; settingTevStruct(globals, LightType.BG0, this.pos, this.tevStr); - setLightTevColorType(globals, this.model, this.tevStr, viewerInput.camera); + setLightTevColorType(globals, this.model, this.tevStr, globals.camera); mDoExt_modelUpdateDL(globals, this.model, renderInstManager, viewerInput); } } @@ -1199,7 +1199,7 @@ function dDlst_texSpecmapST(dst: mat4, globals: dGlobals, pos: ReadonlyVec3, tev mat4.mul(dst, dst, scratchMat4a); // Half-vector lookAt transform. - vec3.sub(scratchVec3a, pos, globals.cameraPosition); + vec3.sub(scratchVec3a, pos, globals.camera.cameraPos); dKyr_get_vectle_calc(tevStr.lightObj.Position, pos, scratchVec3b); vecHalfAngle(scratchVec3a, scratchVec3a, scratchVec3b); mat4.lookAt(scratchMat4a, Vec3Zero, scratchVec3a, Vec3UnitY); @@ -1253,11 +1253,11 @@ class d_a_obj_zouK extends fopAc_ac_c { } public override draw(globals: dGlobals, renderInstManager: GfxRenderInstManager, viewerInput: ViewerRenderInput): void { - if (!this.cullingCheck(viewerInput.camera)) + if (!this.cullingCheck(globals.camera)) return; settingTevStruct(globals, LightType.Actor, this.pos, this.tevStr); - setLightTevColorType(globals, this.model, this.tevStr, viewerInput.camera); + setLightTevColorType(globals, this.model, this.tevStr, globals.camera); this.setEffectMtx(globals, this.pos, 0.5); this.bckAnm.entry(this.model); mDoExt_modelUpdateDL(globals, this.model, renderInstManager, viewerInput); @@ -1304,11 +1304,11 @@ class d_a_swhit0 extends fopAc_ac_c { } public override draw(globals: dGlobals, renderInstManager: GfxRenderInstManager, viewerInput: ViewerRenderInput): void { - if (!this.cullingCheck(viewerInput.camera)) + if (!this.cullingCheck(globals.camera)) return; settingTevStruct(globals, LightType.BG0, this.pos, this.tevStr); - setLightTevColorType(globals, this.model, this.tevStr, viewerInput.camera); + setLightTevColorType(globals, this.model, this.tevStr, globals.camera); this.model.setColorOverride(ColorKind.C1, d_a_swhit0.color1Normal); this.model.setColorOverride(ColorKind.C2, d_a_swhit0.color2Normal); @@ -1524,7 +1524,7 @@ class dDlst_2DObject_c extends dDlst_2DBase_c { this.materialHelper.allocateMaterialParamsDataOnInst(renderInst, materialParams); renderInst.setSamplerBindingsFromTextureMappings(materialParams.m_TextureMapping); - mat4.mul(drawParams.u_PosMtx[0], viewerInput.camera.viewMatrix, this.modelMatrix); + mat4.mul(drawParams.u_PosMtx[0], globals.camera.viewFromWorldMatrix, this.modelMatrix); this.materialHelper.allocateDrawParamsDataOnInst(renderInst, drawParams); renderInstManager.submitRenderInst(renderInst); @@ -1574,7 +1574,7 @@ class dDlst_2DNumber_c extends dDlst_2DBase_c { vec3.set(scratchVec3a, x, 0, 0); mat4.translate(scratchMat4a, this.modelMatrix, scratchVec3a); - mat4.mul(drawParams.u_PosMtx[0], viewerInput.camera.viewMatrix, scratchMat4a); + mat4.mul(drawParams.u_PosMtx[0], globals.camera.viewFromWorldMatrix, scratchMat4a); x -= this.spacing * 2; this.materialHelper.allocateDrawParamsDataOnInst(renderInst, drawParams); @@ -1910,7 +1910,7 @@ class d_a_mgameboard extends fopAc_ac_c { } private MinigameMain(globals: dGlobals): void { - const inputManager = globals.context.inputManager; + const inputManager = globals.sceneContext.inputManager; if (inputManager.isKeyDownEventTriggered('ArrowDown')) this.down(); if (inputManager.isKeyDownEventTriggered('ArrowUp')) @@ -1945,7 +1945,7 @@ class d_a_mgameboard extends fopAc_ac_c { } public override execute(globals: dGlobals, deltaTimeFrames: number): void { - const inputManager = globals.context.inputManager; + const inputManager = globals.sceneContext.inputManager; if (this.minigameResetTimer >= 0) { this.minigameResetTimer -= deltaTimeFrames; if (this.minigameResetTimer <= 0 || inputManager.isKeyDownEventTriggered('KeyF')) @@ -1962,28 +1962,28 @@ class d_a_mgameboard extends fopAc_ac_c { } public override draw(globals: dGlobals, renderInstManager: GfxRenderInstManager, viewerInput: ViewerRenderInput): void { - if (!this.cullingCheck(viewerInput.camera)) + if (!this.cullingCheck(globals.camera)) return; settingTevStruct(globals, LightType.Actor, this.pos, this.tevStr); - setLightTevColorType(globals, this.boardModel, this.tevStr, viewerInput.camera); + setLightTevColorType(globals, this.boardModel, this.tevStr, globals.camera); mDoExt_modelUpdateDL(globals, this.boardModel, renderInstManager, viewerInput); if (!this.minigameActive) return; - setLightTevColorType(globals, this.cursorModel, this.tevStr, viewerInput.camera); + setLightTevColorType(globals, this.cursorModel, this.tevStr, globals.camera); mDoExt_modelUpdateDL(globals, this.cursorModel, renderInstManager, viewerInput, globals.dlst.ui); for (let i = 0; i < this.hitModelCount; i++) { const model = this.hitModels[i]; - setLightTevColorType(globals, model, this.tevStr, viewerInput.camera); + setLightTevColorType(globals, model, this.tevStr, globals.camera); mDoExt_modelUpdateDL(globals, model, renderInstManager, viewerInput, globals.dlst.ui); } for (let i = 0; i < this.missModelCount; i++) { const model = this.missModels[i]; - setLightTevColorType(globals, model, this.tevStr, viewerInput.camera); + setLightTevColorType(globals, model, this.tevStr, globals.camera); mDoExt_modelUpdateDL(globals, model, renderInstManager, viewerInput, globals.dlst.ui); } @@ -1991,7 +1991,7 @@ class d_a_mgameboard extends fopAc_ac_c { if (this.minigame.bulletNum === 0) { for (let i = 0; i < this.minigame.ships.length; i++) { const model = this.shipModels[i]; - setLightTevColorType(globals, model, this.tevStr, viewerInput.camera); + setLightTevColorType(globals, model, this.tevStr, globals.camera); mDoExt_modelUpdateDL(globals, model, renderInstManager, viewerInput, globals.dlst.ui); } } @@ -2288,14 +2288,14 @@ class dCloth_packet_c { for (let fly = 0; fly < this.flyGridSize; fly++) { transformVec3Mat4w1(scratchVec3a, this.mtx, this.posArr[this.curArr][this.getIndex(fly, hoist)]); transformVec3Mat4w0(scratchVec3b, this.mtx, this.nrmArr[this.getIndex(fly, hoist)]); - drawWorldSpaceVector(ctx, viewerInput.camera.clipFromWorldMatrix, scratchVec3a, scratchVec3b, 50); + drawWorldSpaceVector(ctx, globals.camera.clipFromWorldMatrix, scratchVec3a, scratchVec3b, 50); } } */ const template = renderInstManager.pushTemplate(); - dKy_setLight__OnMaterialParams(globals.g_env_light, materialParams, viewerInput.camera); + dKy_setLight__OnMaterialParams(globals.g_env_light, materialParams, globals.camera); this.flagTex.fillTextureMapping(materialParams.m_TextureMapping[0]); this.toonTex.fillTextureMapping(materialParams.m_TextureMapping[1]); template.setSamplerBindingsFromTextureMappings(materialParams.m_TextureMapping); @@ -2303,7 +2303,7 @@ class dCloth_packet_c { colorCopy(materialParams.u_Color[ColorKind.C0], this.tevStr.colorC0); colorCopy(materialParams.u_Color[ColorKind.C1], this.tevStr.colorK0); colorCopy(materialParams.u_Color[ColorKind.C2], this.tevStr.colorK1); - mat4.mul(drawParams.u_PosMtx[0], viewerInput.camera.viewMatrix, this.mtx); + mat4.mul(drawParams.u_PosMtx[0], globals.camera.viewFromWorldMatrix, this.mtx); this.materialHelper.allocateDrawParamsDataOnInst(template, drawParams); const ddraw = this.ddraw; @@ -2376,12 +2376,12 @@ class d_a_sie_flag extends fopAc_ac_c { } public override draw(globals: dGlobals, renderInstManager: GfxRenderInstManager, viewerInput: ViewerRenderInput): void { - if (!this.cullingCheck(viewerInput.camera)) + if (!this.cullingCheck(globals.camera)) return; settingTevStruct(globals, LightType.BG0, this.pos, this.tevStr); settingTevStruct(globals, LightType.Actor, this.pos, this.clothTevStr); - setLightTevColorType(globals, this.model, this.tevStr, viewerInput.camera); + setLightTevColorType(globals, this.model, this.tevStr, globals.camera); mDoExt_modelUpdateDL(globals, this.model, renderInstManager, viewerInput); this.cloth.cloth_draw(globals, renderInstManager, viewerInput); } @@ -2462,12 +2462,12 @@ class d_a_tori_flag extends fopAc_ac_c { } public override draw(globals: dGlobals, renderInstManager: GfxRenderInstManager, viewerInput: ViewerRenderInput): void { - if (!this.cullingCheck(viewerInput.camera)) + if (!this.cullingCheck(globals.camera)) return; settingTevStruct(globals, LightType.BG0, this.pos, this.tevStr); settingTevStruct(globals, LightType.Actor, this.pos, this.clothTevStr); - setLightTevColorType(globals, this.model, this.tevStr, viewerInput.camera); + setLightTevColorType(globals, this.model, this.tevStr, globals.camera); mDoExt_modelUpdateDL(globals, this.model, renderInstManager, viewerInput); this.cloth.cloth_draw(globals, renderInstManager, viewerInput); } @@ -2762,15 +2762,15 @@ class d_a_majuu_flag extends fopAc_ac_c { } public override draw(globals: dGlobals, renderInstManager: GfxRenderInstManager, viewerInput: ViewerRenderInput): void { - if (!this.cullingCheck(viewerInput.camera)) + if (!this.cullingCheck(globals.camera)) return; // For reference. /* for (let i = 0; i < this.pointCount; i++) { transformVec3Mat4w1(scratchVec3a, this.mtx, this.posArr[0][i]); - drawWorldSpacePoint(getDebugOverlayCanvas2D(), viewerInput.camera.clipFromWorldMatrix, scratchVec3a); - drawWorldSpaceText(getDebugOverlayCanvas2D(), viewerInput.camera.clipFromWorldMatrix, scratchVec3a, '' + i); + drawWorldSpacePoint(getDebugOverlayCanvas2D(), globals.camera.clipFromWorldMatrix, scratchVec3a); + drawWorldSpaceText(getDebugOverlayCanvas2D(), globals.camera.clipFromWorldMatrix, scratchVec3a, '' + i); } */ @@ -2783,7 +2783,7 @@ class d_a_majuu_flag extends fopAc_ac_c { const template = renderInstManager.pushTemplate(); - dKy_setLight__OnMaterialParams(globals.g_env_light, materialParams, viewerInput.camera); + dKy_setLight__OnMaterialParams(globals.g_env_light, materialParams, globals.camera); this.flagTex.fillTextureMapping(materialParams.m_TextureMapping[0]); this.toonTex.fillTextureMapping(materialParams.m_TextureMapping[1]); template.setSamplerBindingsFromTextureMappings(materialParams.m_TextureMapping); @@ -2791,7 +2791,7 @@ class d_a_majuu_flag extends fopAc_ac_c { colorCopy(materialParams.u_Color[ColorKind.C0], this.tevStr.colorC0); colorCopy(materialParams.u_Color[ColorKind.C1], this.tevStr.colorK0); colorCopy(materialParams.u_Color[ColorKind.C2], this.tevStr.colorK1); - mat4.mul(drawParams.u_PosMtx[0], viewerInput.camera.viewMatrix, this.mtx); + mat4.mul(drawParams.u_PosMtx[0], globals.camera.viewFromWorldMatrix, this.mtx); this.materialHelper.allocateDrawParamsDataOnInst(template, drawParams); const ddraw = this.ddraw; @@ -3183,16 +3183,16 @@ class d_a_kamome extends fopAc_ac_c { if (this.noDraw || this.switch_id !== 0) return; - if (!this.cullingCheck(viewerInput.camera)) + if (!this.cullingCheck(globals.camera)) return; settingTevStruct(globals, LightType.Actor, this.pos, this.tevStr); - setLightTevColorType(globals, this.morf.model, this.tevStr, viewerInput.camera); + setLightTevColorType(globals, this.morf.model, this.tevStr, globals.camera); this.morf.entryDL(globals, renderInstManager, viewerInput); - // drawWorldSpaceLine(getDebugOverlayCanvas2D(), viewerInput.camera.clipFromWorldMatrix, this.pos, this.targetPos, Green, 2); - // drawWorldSpacePoint(getDebugOverlayCanvas2D(), viewerInput.camera.clipFromWorldMatrix, this.pos, Magenta, 8); - // drawWorldSpacePoint(getDebugOverlayCanvas2D(), viewerInput.camera.clipFromWorldMatrix, this.targetPos, Yellow, 6); + // drawWorldSpaceLine(getDebugOverlayCanvas2D(), globals.camera.clipFromWorldMatrix, this.pos, this.targetPos, Green, 2); + // drawWorldSpacePoint(getDebugOverlayCanvas2D(), globals.camera.clipFromWorldMatrix, this.pos, Magenta, 8); + // drawWorldSpacePoint(getDebugOverlayCanvas2D(), globals.camera.clipFromWorldMatrix, this.targetPos, Yellow, 6); // shadow } @@ -3437,11 +3437,11 @@ class d_a_obj_ikada extends fopAc_ac_c implements ModeFuncExec { ]; private changeModeByRange(globals: dGlobals): void { - const dist = cLib_distanceXZ(this.pos, globals.cameraPosition); + const dist = cLib_distanceXZ(this.pos, globals.camera.cameraPos); let mode = this.curMode; if (dist < 2500.0) mode = d_a_oship_mode.rangeA; @@ -3829,7 +3829,7 @@ class d_a_oship extends fopAc_ac_c implements ModeFuncExec { private modeAttackInit(globals: dGlobals): void { this.attackTimer = -1; - vec3.copy(this.targetPos, globals.cameraPosition); + vec3.copy(this.targetPos, globals.camera.cameraPos); // Aim at our target. @@ -3907,7 +3907,7 @@ class d_a_oship extends fopAc_ac_c implements ModeFuncExec { } private rangeTargetCommon(globals: dGlobals, deltaTimeFrames: number): void { - vec3.copy(this.targetPos, globals.cameraPosition); + vec3.copy(this.targetPos, globals.camera.cameraPos); this.calcY(globals); if (this.checkTgHit(globals)) @@ -3968,29 +3968,29 @@ class d_a_oship extends fopAc_ac_c implements ModeFuncExec { }; public override draw(globals: dGlobals, renderInstManager: GfxRenderInstManager, viewerInput: ViewerRenderInput): void { - if (!this.cullingCheck(viewerInput.camera)) + if (!this.cullingCheck(globals.camera)) return; settingTevStruct(globals, LightType.Actor, this.pos, this.tevStr); - setLightTevColorType(globals, this.model, this.tevStr, viewerInput.camera); + setLightTevColorType(globals, this.model, this.tevStr, globals.camera); const specScale = 0.75; dDlst_texSpecmapST(this.effectMtx, globals, this.pos, this.tevStr, specScale); mDoExt_modelEntryDL(globals, this.model, renderInstManager, viewerInput); /* - drawWorldSpaceText(getDebugOverlayCanvas2D(), viewerInput.camera.clipFromWorldMatrix, this.pos, `PId: ${this.processId}`, 0, White, { outline: 2 }); - drawWorldSpaceText(getDebugOverlayCanvas2D(), viewerInput.camera.clipFromWorldMatrix, this.pos, `Mode: ${d_a_oship_mode[this.curMode]}`, 14, White, { outline: 2 }); - drawWorldSpaceText(getDebugOverlayCanvas2D(), viewerInput.camera.clipFromWorldMatrix, this.pos, `Aim : ${hexzero0x(this.aimRotX, 4)} ${hexzero0x(this.aimRotY, 4)}`, 14*2, White, { outline: 2 }); - drawWorldSpaceText(getDebugOverlayCanvas2D(), viewerInput.camera.clipFromWorldMatrix, this.pos, `Aim T: ${hexzero0x(this.aimRotXTarget, 4)} ${hexzero0x(this.aimRotYTarget, 4)}`, 14*3, White, { outline: 2 }); - drawWorldSpaceText(getDebugOverlayCanvas2D(), viewerInput.camera.clipFromWorldMatrix, this.pos, `Tgt : ${this.targetPos[0].toFixed(2)} ${this.targetPos[1].toFixed(2)} ${this.targetPos[2].toFixed(2)}`, 14*4, White, { outline: 2 }); - drawWorldSpacePoint(getDebugOverlayCanvas2D(), viewerInput.camera.clipFromWorldMatrix, this.targetPos, Green, 10); + drawWorldSpaceText(getDebugOverlayCanvas2D(), globals.camera.clipFromWorldMatrix, this.pos, `PId: ${this.processId}`, 0, White, { outline: 2 }); + drawWorldSpaceText(getDebugOverlayCanvas2D(), globals.camera.clipFromWorldMatrix, this.pos, `Mode: ${d_a_oship_mode[this.curMode]}`, 14, White, { outline: 2 }); + drawWorldSpaceText(getDebugOverlayCanvas2D(), globals.camera.clipFromWorldMatrix, this.pos, `Aim : ${hexzero0x(this.aimRotX, 4)} ${hexzero0x(this.aimRotY, 4)}`, 14*2, White, { outline: 2 }); + drawWorldSpaceText(getDebugOverlayCanvas2D(), globals.camera.clipFromWorldMatrix, this.pos, `Aim T: ${hexzero0x(this.aimRotXTarget, 4)} ${hexzero0x(this.aimRotYTarget, 4)}`, 14*3, White, { outline: 2 }); + drawWorldSpaceText(getDebugOverlayCanvas2D(), globals.camera.clipFromWorldMatrix, this.pos, `Tgt : ${this.targetPos[0].toFixed(2)} ${this.targetPos[1].toFixed(2)} ${this.targetPos[2].toFixed(2)}`, 14*4, White, { outline: 2 }); + drawWorldSpacePoint(getDebugOverlayCanvas2D(), globals.camera.clipFromWorldMatrix, this.targetPos, Green, 10); */ } private setMtx(globals: dGlobals, deltaTimeFrames: number): void { dLib_waveRot(globals, this.wave, this.pos, this.attackSwayAmount, deltaTimeFrames); - const angleY = this.rot[1] + cLib_targetAngleY(this.pos, globals.cameraPosition); + const angleY = this.rot[1] + cLib_targetAngleY(this.pos, globals.camera.cameraPos); const swayAmount = Math.sin(cM_s2rad(this.attackSwayTimer)) * (this.attackSwayAmount * 10); if (this.curMode !== d_a_oship_mode.delete) { @@ -4245,7 +4245,7 @@ class d_a_obj_flame extends fopAc_ac_c { super.draw(globals, renderInstManager, viewerInput); settingTevStruct(globals, LightType.Actor, this.pos, this.tevStr); - setLightTevColorType(globals, this.model, this.tevStr, viewerInput.camera); + setLightTevColorType(globals, this.model, this.tevStr, globals.camera); this.btkAnm.entry(this.model); if (this.brkAnm !== null) @@ -4575,7 +4575,7 @@ export class d_a_ff extends fopAc_ac_c { const peekZ = globals.dlst.peekZ; const dst = this.peekZResult; - mDoLib_project(scratchVec3a, this.pos, globals.camera); + mDoLib_project(scratchVec3a, this.pos, globals.camera.clipFromWorldMatrix); if (globals.camera.clipSpaceNearZ === GfxClipSpaceNearZ.NegativeOne) scratchVec3a[2] = scratchVec3a[2] * 0.5 + 0.5; @@ -4797,8 +4797,8 @@ class d_a_npc_ls1 extends fopNpc_npc_c { super.draw(globals, renderInstManager, viewerInput); settingTevStruct(globals, LightType.Actor, this.pos, this.tevStr); - setLightTevColorType(globals, this.morf.model, this.tevStr, viewerInput.camera); - setLightTevColorType(globals, this.handModel, this.tevStr, viewerInput.camera); + setLightTevColorType(globals, this.morf.model, this.tevStr, globals.camera); + setLightTevColorType(globals, this.handModel, this.tevStr, globals.camera); // this.btkAnim.entry(this.morf.model, this.btkFrame); // this.btpAnim.entry(this.morf.model, this.btpFrame); @@ -4808,7 +4808,7 @@ class d_a_npc_ls1 extends fopNpc_npc_c { mDoExt_modelEntryDL(globals, this.handModel, renderInstManager, viewerInput); if (this.itemModel) { - setLightTevColorType(globals, this.itemModel, this.tevStr, viewerInput.camera); + setLightTevColorType(globals, this.itemModel, this.tevStr, globals.camera); mDoExt_modelEntryDL(globals, this.itemModel, renderInstManager, viewerInput); } @@ -5031,7 +5031,7 @@ class d_a_npc_zl1 extends fopNpc_npc_c { super.draw(globals, renderInstManager, viewerInput); settingTevStruct(globals, LightType.Actor, this.pos, this.tevStr); - setLightTevColorType(globals, this.morf.model, this.tevStr, viewerInput.camera); + setLightTevColorType(globals, this.morf.model, this.tevStr, globals.camera); if (this.btpAnim.anm) this.btpAnim.entry(this.morf.model); if (this.btkAnim.anm) this.btkAnim.entry(this.morf.model); @@ -5302,15 +5302,15 @@ class d_a_py_lk extends fopAc_ac_c implements ModeFuncExec { this.model.setShapeVisible(LkModelShape.Scabbard, false); this.model.setShapeVisible(LkModelShape.Buckle, false); - setLightTevColorType(globals, this.modelKatsura, this.tevStr, viewerInput.camera); + setLightTevColorType(globals, this.modelKatsura, this.tevStr, globals.camera); mDoExt_modelEntryDL(globals, this.modelKatsura, renderInstManager, viewerInput); } if (this.equippedItem === LkEquipItem.Sword) { - setLightTevColorType(globals, this.equippedItemModel!, this.tevStr, viewerInput.camera); + setLightTevColorType(globals, this.equippedItemModel!, this.tevStr, globals.camera); mDoExt_modelEntryDL(globals, this.equippedItemModel!, renderInstManager, viewerInput); - setLightTevColorType(globals, this.modelSwordHilt, this.tevStr, viewerInput.camera); + setLightTevColorType(globals, this.modelSwordHilt, this.tevStr, globals.camera); mDoExt_modelEntryDL(globals, this.modelSwordHilt, renderInstManager, viewerInput); } @@ -5325,7 +5325,7 @@ class d_a_py_lk extends fopAc_ac_c implements ModeFuncExec { if (this.anmBtp.anm) this.anmBtp.entry(this.model); if (this.anmBtk.anm) this.anmBtk.entry(this.model); - setLightTevColorType(globals, this.model, this.tevStr, viewerInput.camera); + setLightTevColorType(globals, this.model, this.tevStr, globals.camera); mDoExt_modelEntryDL(globals, this.model, renderInstManager, viewerInput); } diff --git a/src/ZeldaWindWaker/d_a_sea.ts b/src/ZeldaWindWaker/d_a_sea.ts index 0db316180..997535509 100644 --- a/src/ZeldaWindWaker/d_a_sea.ts +++ b/src/ZeldaWindWaker/d_a_sea.ts @@ -562,13 +562,13 @@ export class d_a_sea extends fopAc_ac_c { this.texWyurayura.fillTextureMapping(materialParams.m_TextureMapping[1]); this.texSeaBTI.fillTextureMapping(materialParams.m_TextureMapping[2]); materialParams.m_TextureMapping[2].lodBias = 1.0; - dKy_GxFog_sea_set(envLight, materialParams.u_FogBlock, viewerInput.camera); + dKy_GxFog_sea_set(envLight, materialParams.u_FogBlock, globals.camera); const renderInst = this.ddraw.endDrawAndMakeRenderInst(renderInstManager); materialHelper.setOnRenderInst(renderInstManager.gfxRenderCache, renderInst); renderInst.setSamplerBindingsFromTextureMappings(materialParams.m_TextureMapping); materialHelper.allocateMaterialParamsDataOnInst(renderInst, materialParams); - mat4.copy(drawParams.u_PosMtx[0], viewerInput.camera.viewMatrix); + mat4.copy(drawParams.u_PosMtx[0], globals.camera.viewFromWorldMatrix); materialHelper.allocateDrawParamsDataOnInst(renderInst, drawParams); renderInstManager.submitRenderInst(renderInst); } diff --git a/src/ZeldaWindWaker/d_demo.ts b/src/ZeldaWindWaker/d_demo.ts index 12b17bc1a..8631add85 100644 --- a/src/ZeldaWindWaker/d_demo.ts +++ b/src/ZeldaWindWaker/d_demo.ts @@ -99,37 +99,32 @@ class dDemo_camera_c extends TCamera { this.flags |= EDemoCamFlags.HasAspect; } - public override JSGGetViewPosition(dst: vec3) { - vec3.copy(dst, this.globals.cameraPosition); + vec3.copy(dst, this.globals.camera.cameraPos); } - public override JSGSetViewPosition(v: ReadonlyVec3) { vec3.copy(this.viewPosition, v); this.flags |= EDemoCamFlags.HasEyePos; } - public override JSGGetViewUpVector(dst: vec3) { const camera = this.globals.camera; if (!camera) vec3.set(dst, 0, 1, 0); - getMatrixAxisY(dst, camera.viewMatrix); // @TODO: Double check that this is correct + getMatrixAxisY(dst, camera.viewFromWorldMatrix); // @TODO: Double check that this is correct } - public override JSGSetViewUpVector(v: ReadonlyVec3) { vec3.copy(this.upVector, v); this.flags |= EDemoCamFlags.HasUpVec; } - public override JSGGetViewTargetPosition(dst: vec3) { const camera = this.globals.camera; if (!camera) vec3.zero(dst); - vec3.add(dst, this.globals.cameraPosition, this.globals.cameraFwd); + vec3.add(dst, this.globals.camera.cameraPos, this.globals.camera.cameraFwd); } @@ -476,7 +471,7 @@ export class dDemo_manager_c { return false; } - const dtFrames = this.globals.context.viewerInput.deltaTime / 1000.0 * 30; + const dtFrames = this.globals.sceneContext.viewerInput.deltaTime / 1000.0 * 30; // noclip modification: If a demo is suspended (waiting for the user to interact with a message), just resume if (this.control.isSuspended()) { this.control.setSuspend(0); } diff --git a/src/ZeldaWindWaker/d_drawlist.ts b/src/ZeldaWindWaker/d_drawlist.ts index dc749025e..6aabf1530 100644 --- a/src/ZeldaWindWaker/d_drawlist.ts +++ b/src/ZeldaWindWaker/d_drawlist.ts @@ -123,7 +123,7 @@ class dDlst_alphaModel_c { if (this.datas.length === 0) return; - const device = globals.modelCache.device, cache = globals.modelCache.cache; + const cache = globals.modelCache.cache; for (let i = 0; i < this.datas.length; i++) { const data = this.datas[i]; @@ -132,7 +132,7 @@ class dDlst_alphaModel_c { if (data.type === dDlst_alphaModel__Type.Bonbori) { this.bonboriShape.setOnRenderInst(template); - mat4.mul(drawParams.u_PosMtx[0], viewerInput.camera.viewMatrix, data.mtx); + mat4.mul(drawParams.u_PosMtx[0], globals.camera.viewFromWorldMatrix, data.mtx); this.materialHelperBackRevZ.allocateDrawParamsDataOnInst(template, drawParams); materialParams.u_Color[ColorKind.MAT0].a = data.alpha / 0xFF; diff --git a/src/ZeldaWindWaker/d_kankyo.ts b/src/ZeldaWindWaker/d_kankyo.ts index 17f8e149a..c86d8b535 100644 --- a/src/ZeldaWindWaker/d_kankyo.ts +++ b/src/ZeldaWindWaker/d_kankyo.ts @@ -15,7 +15,7 @@ import { cLib_addCalc, cLib_addCalc2, cM_rndF } from "./SComponent.js"; import { ThunderMode, ThunderState, dKankyo__CommonTextures, dKankyo__Windline, dKankyo_housi_Packet, dKankyo_moya_Packet, dKankyo_rain_Packet, dKankyo_star_Packet, dKankyo_sun_Packet, dKankyo_vrkumo_Packet, dKankyo_wave_Packet, dKy_wave_chan_init, dKyr__sun_arrival_check, dKyw_rain_set, dKyw_wether_draw, dKyw_wether_draw2, dKyw_wether_move, dKyw_wether_move_draw, dKyw_wether_move_draw2, dKyw_wind_set } from "./d_kankyo_wether.js"; import { dStage_stagInfo_GetSTType, stage_envr_info_class, stage_palet_info_class, stage_palet_info_class__DifAmb, stage_pselect_info_class, stage_vrbox_info_class } from "./d_stage.js"; import { cPhs__Status, fGlobals, fopKyM_Create, fpcPf__Register, fpc_bs__Constructor, kankyo_class } from "./framework.js"; -import { dGlobals } from "./Main.js"; +import { dCamera_c, dGlobals } from "./Main.js"; import { dProcName_e } from "./d_procname.js"; export const enum LightType { @@ -596,37 +596,37 @@ export function dKy_tevstr_init(tevstr: dKy_tevstr_c, roomNo: number, envrOverri tevstr.envrOverride = envrOverride; } -function GxFogSet_Sub(fog: FogBlock, tevStr: { fogStartZ: number, fogEndZ: number, fogCol: Color }, camera: Camera, fogColor = tevStr.fogCol) { +function GxFogSet_Sub(fog: FogBlock, tevStr: { fogStartZ: number, fogEndZ: number, fogCol: Color }, camera: dCamera_c, fogColor = tevStr.fogCol) { colorCopy(fog.Color, fogColor); // Empirically decided. const fogFarPlane = Number.isFinite(camera.far) ? camera.far : 100000; - const type = camera.isOrthographic ? FogType.ORTHO_LIN : FogType.PERSP_LIN; + const type = camera.clipFromViewMatrix[11] === 0.0 ? FogType.ORTHO_LIN : FogType.PERSP_LIN; fogBlockSet(fog, type, tevStr.fogStartZ, tevStr.fogEndZ, camera.near, fogFarPlane); } -export function dKy_GxFog_set(envLight: dScnKy_env_light_c, fog: FogBlock, camera: Camera): void { +export function dKy_GxFog_set(envLight: dScnKy_env_light_c, fog: FogBlock, camera: dCamera_c): void { GxFogSet_Sub(fog, envLight, camera); } -export function dKy_GxFog_sea_set(envLight: dScnKy_env_light_c, fog: FogBlock, camera: Camera): void { +export function dKy_GxFog_sea_set(envLight: dScnKy_env_light_c, fog: FogBlock, camera: dCamera_c): void { GxFogSet_Sub(fog, envLight, camera, envLight.vrUsoUmiCol); } // This is effectively the global state that dKy_setLight sets up, but since we don't // have global state, we have to do this here. -export function dKy_setLight__OnModelInstance(envLight: dScnKy_env_light_c, modelInstance: J3DModelInstance, camera: Camera): void { +export function dKy_setLight__OnModelInstance(envLight: dScnKy_env_light_c, modelInstance: J3DModelInstance, camera: dCamera_c): void { for (let i = 0; i < 2; i++) - lightSetFromWorldLight(modelInstance.getGXLightReference(i), camera.viewMatrix, envLight.lightStatus[i]); + lightSetFromWorldLight(modelInstance.getGXLightReference(i), camera.viewFromWorldMatrix, envLight.lightStatus[i]); } -export function dKy_setLight__OnMaterialParams(envLight: dScnKy_env_light_c, materialParams: MaterialParams, camera: Camera): void { +export function dKy_setLight__OnMaterialParams(envLight: dScnKy_env_light_c, materialParams: MaterialParams, camera: dCamera_c): void { for (let i = 0; i < 2; i++) - lightSetFromWorldLight(materialParams.u_Lights[i], camera.viewMatrix, envLight.lightStatus[i]); + lightSetFromWorldLight(materialParams.u_Lights[i], camera.viewFromWorldMatrix, envLight.lightStatus[i]); } -export function setLightTevColorType(globals: dGlobals, modelInstance: J3DModelInstance, tevStr: dKy_tevstr_c, camera: Camera): void { +export function setLightTevColorType(globals: dGlobals, modelInstance: J3DModelInstance, tevStr: dKy_tevstr_c, camera: dCamera_c): void { const envLight = globals.g_env_light; if (tevStr.lightMode !== LightMode.BG) { @@ -634,10 +634,10 @@ export function setLightTevColorType(globals: dGlobals, modelInstance: J3DModelI } const light0 = modelInstance.getGXLightReference(0); - lightSetFromWorldLight(light0, camera.viewMatrix, tevStr.lightObj); + lightSetFromWorldLight(light0, camera.viewFromWorldMatrix, tevStr.lightObj); const light1 = modelInstance.getGXLightReference(1); - lightSetFromWorldLight(light1, camera.viewMatrix, envLight.lightStatus[1]); + lightSetFromWorldLight(light1, camera.viewFromWorldMatrix, envLight.lightStatus[1]); // if (toon_proc_check() == 0) @@ -690,7 +690,7 @@ function setSunpos(envLight: dScnKy_env_light_c, cameraPos: vec3): void { function drawKankyo(globals: dGlobals): void { const envLight = globals.g_env_light; - setSunpos(envLight, globals.cameraPosition); + setSunpos(envLight, globals.camera.cameraPos); SetBaseLight(globals); setLight(globals, envLight); } diff --git a/src/ZeldaWindWaker/d_kankyo_wether.ts b/src/ZeldaWindWaker/d_kankyo_wether.ts index d983ce4d6..a1ddf85ff 100644 --- a/src/ZeldaWindWaker/d_kankyo_wether.ts +++ b/src/ZeldaWindWaker/d_kankyo_wether.ts @@ -161,11 +161,11 @@ export function loadRawTexture(globals: dGlobals, data: ArrayBufferSlice, width: const materialParams = new MaterialParams(); const drawParams = new DrawParams(); -function submitScratchRenderInst(renderInstManager: GfxRenderInstManager, materialHelper: GXMaterialHelperGfx, renderInst: GfxRenderInst, viewerInput: ViewerRenderInput, materialParams_ = materialParams, drawParams_ = drawParams): void { +function submitScratchRenderInst(globals: dGlobals, renderInstManager: GfxRenderInstManager, materialHelper: GXMaterialHelperGfx, renderInst: GfxRenderInst, materialParams_ = materialParams, drawParams_ = drawParams): void { materialHelper.setOnRenderInst(renderInstManager.gfxRenderCache, renderInst); renderInst.setSamplerBindingsFromTextureMappings(materialParams_.m_TextureMapping); materialHelper.allocateMaterialParamsDataOnInst(renderInst, materialParams_); - mat4.copy(drawParams_.u_PosMtx[0], viewerInput.camera.viewMatrix); + mat4.copy(drawParams_.u_PosMtx[0], globals.camera.viewFromWorldMatrix); materialHelper.allocateDrawParamsDataOnInst(renderInst, drawParams_); renderInstManager.submitRenderInst(renderInst); } @@ -310,7 +310,7 @@ export class dKankyo_sun_Packet { if (!drawSun && !drawMoon) return; - const camPitch = vecPitch(globals.cameraFwd); + const camPitch = vecPitch(globals.camera.cameraFwd); renderInstManager.setCurrentList(globals.dlst.sky[1]); @@ -324,8 +324,8 @@ export class dKankyo_sun_Packet { vec3.copy(moonPos, this.sunPos); } else { // Mirror the sun position - vec3.sub(moonPos, this.sunPos, globals.cameraPosition); - vec3.scaleAndAdd(moonPos, globals.cameraPosition, moonPos, -1.0); + vec3.sub(moonPos, this.sunPos, globals.camera.cameraPos); + vec3.scaleAndAdd(moonPos, globals.camera.cameraPos, moonPos, -1.0); } const scaleX = dayOfWeek < 4 ? -1 : 1; @@ -338,7 +338,7 @@ export class dKankyo_sun_Packet { if (i === 1) moonSize *= 1.7; - computeMatrixWithoutTranslation(scratchMatrix, viewerInput.camera.worldMatrix); + computeMatrixWithoutTranslation(scratchMatrix, globals.camera.worldFromViewMatrix); mat4.rotateZ(scratchMatrix, scratchMatrix, MathConstants.DEG_TO_RAD * (45 + (360.0 * ((moonPitch - camPitch) / -8.0)))); if (i === 0) { @@ -369,7 +369,7 @@ export class dKankyo_sun_Packet { } const renderInst = ddraw.makeRenderInst(renderInstManager); - submitScratchRenderInst(renderInstManager, this.materialHelperSunMoon, renderInst, viewerInput); + submitScratchRenderInst(globals, renderInstManager, this.materialHelperSunMoon, renderInst); } } @@ -377,7 +377,7 @@ export class dKankyo_sun_Packet { const sunPos = this.sunPos; const sunPitch = vecPitch(sunPos); - computeMatrixWithoutTranslation(scratchMatrix, viewerInput.camera.worldMatrix); + computeMatrixWithoutTranslation(scratchMatrix, globals.camera.worldFromViewMatrix); mat4.rotateZ(scratchMatrix, scratchMatrix, MathConstants.DEG_TO_RAD * (-50 + (360.0 * ((sunPitch - camPitch) / -8.0)))); let sunSizeBase = 575.0; @@ -402,7 +402,7 @@ export class dKankyo_sun_Packet { this.drawSquare(ddraw, scratchMatrix, sunPos, sunSize, 1.0, 1.0); const renderInst = ddraw.makeRenderInst(renderInstManager); - submitScratchRenderInst(renderInstManager, this.materialHelperSunMoon, renderInst, viewerInput); + submitScratchRenderInst(globals, renderInstManager, this.materialHelperSunMoon, renderInst); } } } @@ -428,7 +428,7 @@ export class dKankyo_sun_Packet { const envLight = globals.g_env_light; - computeMatrixWithoutTranslation(scratchMatrix, viewerInput.camera.worldMatrix); + computeMatrixWithoutTranslation(scratchMatrix, globals.camera.worldFromViewMatrix); if (this.drawLenzInSky) renderInstManager.setCurrentList(globals.dlst.sky[1]); @@ -493,7 +493,7 @@ export class dKankyo_sun_Packet { colorCopy(materialParams.u_Color[ColorKind.C0], this.lensflareColor, lensflareAlpha); const renderInst = ddraw.makeRenderInst(renderInstManager); - submitScratchRenderInst(renderInstManager, this.materialHelperLenzflareSolid, renderInst, viewerInput); + submitScratchRenderInst(globals, renderInstManager, this.materialHelperLenzflareSolid, renderInst); mat4.rotateZ(scratchMatrix, scratchMatrix, this.lensflareAngle); @@ -536,7 +536,7 @@ export class dKankyo_sun_Packet { materialParams.u_Color[ColorKind.C0].a *= alpha; colorFromRGBA8(materialParams.u_Color[ColorKind.C1], 0xFF91491E); - submitScratchRenderInst(renderInstManager, this.materialHelperLenzflare, renderInst, viewerInput); + submitScratchRenderInst(globals, renderInstManager, this.materialHelperLenzflare, renderInst); } } @@ -702,7 +702,7 @@ export class dKankyo_vrkumo_Packet { y = Math.sin(polarY0); z = Math.cos(polarY0) * Math.cos(azimuthal + azimuthalOffsY0); vec3.set(scratchVec3, x * domeRadius, y * domeRadius, z * domeRadius); - vec3.add(scratchVec3, scratchVec3, globals.cameraPosition); + vec3.add(scratchVec3, scratchVec3, globals.camera.cameraPos); ddraw.position3vec3(scratchVec3); ddraw.color4color(GX.Attr.CLR0, materialParams.u_Color[ColorKind.C0]); ddraw.texCoord2f32(GX.Attr.TEX0, 0, 0); @@ -711,7 +711,7 @@ export class dKankyo_vrkumo_Packet { y = Math.sin(polarY0); z = Math.cos(polarY0) * Math.cos(azimuthal - azimuthalOffsY0); vec3.set(scratchVec3, x * domeRadius, y * domeRadius, z * domeRadius); - vec3.add(scratchVec3, scratchVec3, globals.cameraPosition); + vec3.add(scratchVec3, scratchVec3, globals.camera.cameraPos); ddraw.position3vec3(scratchVec3); ddraw.color4color(GX.Attr.CLR0, materialParams.u_Color[ColorKind.C0]); ddraw.texCoord2f32(GX.Attr.TEX0, 1, 0); @@ -720,7 +720,7 @@ export class dKankyo_vrkumo_Packet { y = Math.sin(polarY1); z = Math.cos(polarY1) * Math.cos(azimuthal - azimuthalOffsY1); vec3.set(scratchVec3, x * domeRadius, y * domeRadius, z * domeRadius); - vec3.add(scratchVec3, scratchVec3, globals.cameraPosition); + vec3.add(scratchVec3, scratchVec3, globals.camera.cameraPos); ddraw.position3vec3(scratchVec3); ddraw.color4color(GX.Attr.CLR0, materialParams.u_Color[ColorKind.C0]); ddraw.texCoord2f32(GX.Attr.TEX0, 1, 1); @@ -729,7 +729,7 @@ export class dKankyo_vrkumo_Packet { y = Math.sin(polarY1); z = Math.cos(polarY1) * Math.cos(azimuthal + azimuthalOffsY1); vec3.set(scratchVec3, x * domeRadius, y * domeRadius, z * domeRadius); - vec3.add(scratchVec3, scratchVec3, globals.cameraPosition); + vec3.add(scratchVec3, scratchVec3, globals.camera.cameraPos); ddraw.position3vec3(scratchVec3); ddraw.color4color(GX.Attr.CLR0, materialParams.u_Color[ColorKind.C0]); ddraw.texCoord2f32(GX.Attr.TEX0, 0, 1); @@ -739,7 +739,7 @@ export class dKankyo_vrkumo_Packet { if (ddraw.hasIndicesToDraw()) { const renderInst = ddraw.makeRenderInst(renderInstManager); - submitScratchRenderInst(renderInstManager, this.materialHelper, renderInst, viewerInput); + submitScratchRenderInst(globals, renderInstManager, this.materialHelper, renderInst); } } @@ -809,7 +809,7 @@ export class dKankyo_rain_Packet { const envLight = globals.g_env_light; const ddraw = this.ddraw; - computeMatrixWithoutTranslation(scratchMatrix, viewerInput.camera.worldMatrix); + computeMatrixWithoutTranslation(scratchMatrix, globals.camera.worldFromViewMatrix); renderInstManager.setCurrentList(globals.dlst.wetherEffect); @@ -838,7 +838,7 @@ export class dKankyo_rain_Packet { // basePos vec3.add(scratchVec3, rain.basePos, rain.pos); - const dist = vec3.distance(scratchVec3, globals.cameraPosition); + const dist = vec3.distance(scratchVec3, globals.camera.cameraPos); vec3.add(scratchVec3c, scratchVec3c, scratchVec3); vec3.add(scratchVec3d, scratchVec3d, scratchVec3); @@ -881,7 +881,7 @@ export class dKankyo_rain_Packet { if (ddraw.hasIndicesToDraw()) { const renderInst = ddraw.makeRenderInst(renderInstManager); - submitScratchRenderInst(renderInstManager, this.materialHelperRain, renderInst, viewerInput); + submitScratchRenderInst(globals, renderInstManager, this.materialHelperRain, renderInst); } } @@ -897,9 +897,9 @@ export class dKankyo_rain_Packet { this.sibukiAlpha = cLib_addCalc(this.sibukiAlpha, alphaTarget, 0.2, 3.0, 0.001); let additionalAlphaFade: number; - if (globals.cameraFwd[1] > 0.0 && globals.cameraFwd[1] < 0.5) - additionalAlphaFade = 1.0 - (globals.cameraFwd[1] / 0.5); - else if (globals.cameraFwd[1] > 0.0) + if (globals.camera.cameraFwd[1] > 0.0 && globals.camera.cameraFwd[1] < 0.5) + additionalAlphaFade = 1.0 - (globals.camera.cameraFwd[1] / 0.5); + else if (globals.camera.cameraFwd[1] > 0.0) additionalAlphaFade = 0.0; else additionalAlphaFade = 1.0; @@ -949,7 +949,7 @@ export class dKankyo_rain_Packet { ddraw.end(); const renderInst = ddraw.makeRenderInst(renderInstManager); - submitScratchRenderInst(renderInstManager, this.materialHelperSibuki, renderInst, viewerInput); + submitScratchRenderInst(globals, renderInstManager, this.materialHelperSibuki, renderInst); } public draw(globals: dGlobals, renderInstManager: GfxRenderInstManager, viewerInput: ViewerRenderInput): void { @@ -1061,7 +1061,7 @@ export class dKankyo_wave_Packet { return; const ddraw = this.ddraw; - computeMatrixWithoutTranslation(scratchMatrix, viewerInput.camera.worldMatrix); + computeMatrixWithoutTranslation(scratchMatrix, globals.camera.worldFromViewMatrix); renderInstManager.setCurrentList(globals.dlst.wetherEffect); @@ -1071,7 +1071,7 @@ export class dKankyo_wave_Packet { else this.texUsonami.fillTextureMapping(materialParams.m_TextureMapping[0]); - dKy_GxFog_sea_set(envLight, materialParams.u_FogBlock, viewerInput.camera); + dKy_GxFog_sea_set(envLight, materialParams.u_FogBlock, globals.camera); ddraw.beginDraw(globals.modelCache.cache); ddraw.begin(GX.Command.DRAW_QUADS, 4 * envLight.waveCount); @@ -1130,7 +1130,7 @@ export class dKankyo_wave_Packet { if (ddraw.hasIndicesToDraw()) { const renderInst = ddraw.makeRenderInst(renderInstManager); - submitScratchRenderInst(renderInstManager, this.materialHelper, renderInst, viewerInput); + submitScratchRenderInst(globals, renderInstManager, this.materialHelper, renderInst); } } @@ -1211,7 +1211,7 @@ export class dKankyo_star_Packet { else renderInstManager.setCurrentList(globals.dlst.sky[1]); - dKy_GxFog_sea_set(envLight, materialParams.u_FogBlock, viewerInput.camera); + dKy_GxFog_sea_set(envLight, materialParams.u_FogBlock, globals.camera); ddraw.beginDraw(globals.modelCache.cache); ddraw.begin(GX.Command.DRAW_TRIANGLES, 6 * envLight.starCount); @@ -1226,7 +1226,7 @@ export class dKankyo_star_Packet { vec3.set(scratchVec3c, starSize, -0.5 * starSize, 0.0); vec3.set(scratchVec3d, -starSize, -0.5 * starSize, 0.0); - computeMatrixWithoutTranslation(scratchMatrix, viewerInput.camera.worldMatrix); + computeMatrixWithoutTranslation(scratchMatrix, globals.camera.worldFromViewMatrix); mat4.rotateZ(scratchMatrix, scratchMatrix, this.rot * MathConstants.DEG_TO_RAD); vec3.transformMat4(scratchVec3b, scratchVec3b, scratchMatrix); @@ -1234,7 +1234,7 @@ export class dKankyo_star_Packet { vec3.transformMat4(scratchVec3d, scratchVec3d, scratchMatrix); // Projected moon position. - mDoLib_projectFB(scratchVec3e, envLight.moonPos, viewerInput); + mDoLib_projectFB(scratchVec3e, envLight.moonPos, viewerInput, globals.camera.clipFromWorldMatrix); let radius = 0.0, angle = -Math.PI, angleIncr = 0.0; for (let i = 0; i < envLight.starCount; i++) { @@ -1263,9 +1263,9 @@ export class dKankyo_star_Packet { radius = (20.0 * i) / 1000.0; } - vec3.add(scratchVec3a, scratchVec3a, globals.cameraPosition); + vec3.add(scratchVec3a, scratchVec3a, globals.camera.cameraPos); - mDoLib_projectFB(scratchVec3, scratchVec3a, viewerInput); + mDoLib_projectFB(scratchVec3, scratchVec3a, viewerInput, globals.camera.clipFromWorldMatrix); const distToMoon = vec3.dist(scratchVec3, scratchVec3e); if (distToMoon < 80.0) continue; @@ -1313,7 +1313,7 @@ export class dKankyo_star_Packet { if (ddraw.hasIndicesToDraw()) { const renderInst = ddraw.makeRenderInst(renderInstManager); - submitScratchRenderInst(renderInstManager, this.materialHelper, renderInst, viewerInput); + submitScratchRenderInst(globals, renderInstManager, this.materialHelper, renderInst); } } @@ -1371,7 +1371,7 @@ export class dKankyo_housi_Packet { return; const ddraw = this.ddraw; - computeMatrixWithoutTranslation(scratchMatrix, viewerInput.camera.worldMatrix); + computeMatrixWithoutTranslation(scratchMatrix, globals.camera.worldFromViewMatrix); renderInstManager.setCurrentList(globals.dlst.wetherEffect); @@ -1428,7 +1428,7 @@ export class dKankyo_housi_Packet { colorFromRGBA8(materialParams.u_Color[ColorKind.C0], 0xE5FFC8FF); colorFromRGBA8(materialParams.u_Color[ColorKind.C1], 0x43D2CAFF); - submitScratchRenderInst(renderInstManager, this.materialHelper, renderInst, viewerInput); + submitScratchRenderInst(globals, renderInstManager, this.materialHelper, renderInst); } } @@ -1487,7 +1487,7 @@ export class dKankyo_moya_Packet { return; const ddraw = this.ddraw; - computeMatrixWithoutTranslation(scratchMatrix, viewerInput.camera.worldMatrix); + computeMatrixWithoutTranslation(scratchMatrix, globals.camera.worldFromViewMatrix); mat4.rotateZ(scratchMatrix, scratchMatrix, this.rot * MathConstants.DEG_TO_RAD); renderInstManager.setCurrentList(globals.dlst.wetherEffect); @@ -1548,7 +1548,7 @@ export class dKankyo_moya_Packet { else colorCopy(materialParams.u_Color[ColorKind.C0], envLight.bgCol[0].K0, 1.0); - submitScratchRenderInst(renderInstManager, this.materialHelper, renderInst, viewerInput); + submitScratchRenderInst(globals, renderInstManager, this.materialHelper, renderInst); } } @@ -1589,11 +1589,11 @@ function dKyr_sun_move(globals: dGlobals): void { const roomType = dStage_stagInfo_GetSTType(globals.dStage_dt.stag); if (envLight.baseLight.color.r === 0.0 && roomType !== 2) { - dKyr_get_vectle_calc(globals.cameraPosition, envLight.baseLight.pos, scratchVec3); + dKyr_get_vectle_calc(globals.camera.cameraPos, envLight.baseLight.pos, scratchVec3); } else { - dKyr_get_vectle_calc(globals.cameraPosition, envLight.sunPos, scratchVec3); + dKyr_get_vectle_calc(globals.camera.cameraPos, envLight.sunPos, scratchVec3); } - vec3.scaleAndAdd(pkt.sunPos, globals.cameraPosition, scratchVec3, 8000.0); + vec3.scaleAndAdd(pkt.sunPos, globals.camera.cameraPos, scratchVec3, 8000.0); const horizonY = scratchVec3[1]; let sunCanGlare = true; @@ -1618,7 +1618,7 @@ function dKyr_sun_move(globals: dGlobals): void { if (sunCanGlare) { // Original game projects the vector into viewport space, and gets distance to 320, 240. - mDoLib_project(scratchVec3, pkt.sunPos, globals.camera); + mDoLib_project(scratchVec3, pkt.sunPos, globals.camera.clipFromWorldMatrix); const peekZ = globals.dlst.peekZ; @@ -1678,7 +1678,7 @@ function dKyr_sun_move(globals: dGlobals): void { } if (dKyr_moon_arrival_check(envLight)) { - const diffY = (pkt.sunPos[1] - globals.cameraPosition[1]) / -8000.0; + const diffY = (pkt.sunPos[1] - globals.camera.cameraPos[1]) / -8000.0; const target = Math.min(diffY * diffY * 6.0, 1.0); pkt.moonAlpha = cLib_addCalc(pkt.moonAlpha, target, 0.2, 0.01, 0.001); } else { @@ -1687,19 +1687,19 @@ function dKyr_sun_move(globals: dGlobals): void { } function dKy_set_eyevect_calc(globals: dGlobals, dst: vec3, scaleXZ: number, scaleY: number = scaleXZ): void { - dst[0] = globals.cameraPosition[0] + globals.cameraFwd[0] * scaleXZ; - dst[1] = (globals.cameraPosition[1] + globals.cameraFwd[1] * scaleY) - 200.0; - dst[2] = globals.cameraPosition[2] + globals.cameraFwd[2] * scaleXZ; + dst[0] = globals.camera.cameraPos[0] + globals.camera.cameraFwd[0] * scaleXZ; + dst[1] = (globals.camera.cameraPos[1] + globals.camera.cameraFwd[1] * scaleY) - 200.0; + dst[2] = globals.camera.cameraPos[2] + globals.camera.cameraFwd[2] * scaleXZ; } function dKy_set_eyevect_calc2(globals: dGlobals, dst: vec3, scaleXZ: number, scaleY: number = scaleXZ): void { - vec3.copy(dst, globals.cameraFwd); + vec3.copy(dst, globals.camera.cameraFwd); if (scaleY === 0.0) dst[1] = 0.0; vec3.normalize(dst, dst); - dst[0] = globals.cameraPosition[0] + dst[0] * scaleXZ; - dst[1] = globals.cameraPosition[1] + dst[1] * scaleXZ; - dst[2] = globals.cameraPosition[2] + dst[2] * scaleXZ; + dst[0] = globals.camera.cameraPos[0] + dst[0] * scaleXZ; + dst[1] = globals.camera.cameraPos[1] + dst[1] * scaleXZ; + dst[2] = globals.camera.cameraPos[2] + dst[2] * scaleXZ; } function dKyr_lenzflare_move(globals: dGlobals): void { @@ -1709,21 +1709,21 @@ function dKyr_lenzflare_move(globals: dGlobals): void { dKy_set_eyevect_calc(globals, scratchVec3, 7200); dKyr_get_vectle_calc(scratchVec3, pkt.sunPos, scratchVec3); - const dist = vec3.distance(scratchVec3, globals.cameraFwd); + const dist = vec3.distance(scratchVec3, globals.camera.cameraFwd); const intensity = 250.0 + (350.0 * dist); for (let i = 0; i < 6; i++) { const whichLenz = i + 2; vec3.scaleAndAdd(pkt.lensflarePos[i], pkt.sunPos, scratchVec3, -intensity * whichLenz); } - mDoLib_project(scratchVec3, pkt.sunPos, globals.camera); + mDoLib_project(scratchVec3, pkt.sunPos, globals.camera.clipFromWorldMatrix); pkt.lensflareAngle = Math.atan2(scratchVec3[1], scratchVec3[0]) + Math.PI / 2; } function wether_move_thunder(globals: dGlobals): void { const envLight = globals.g_env_light; if (envLight.thunderActive) { - dKyr_thunder_move(globals, envLight, globals.cameraPosition); + dKyr_thunder_move(globals, envLight, globals.camera.cameraPos); } else if (envLight.thunderMode !== ThunderMode.Off) { dKyr_thunder_init(envLight); envLight.thunderActive = true; @@ -1746,9 +1746,9 @@ function dKyr_kamome_move(globals: dGlobals, deltaTimeFrames: number): void { if (eff.timer <= 0.0) { eff.angleY = cM_rndFX(Math.PI); eff.angleX = cM_rndFX(Math.PI); - eff.pos[0] = globals.cameraPosition[0] + Math.sin(eff.angleY) * 7000.0; + eff.pos[0] = globals.camera.cameraPos[0] + Math.sin(eff.angleY) * 7000.0; eff.pos[1] = 4500.0; - eff.pos[2] = globals.cameraPosition[2] + Math.cos(eff.angleY) * 7000.0; + eff.pos[2] = globals.camera.cameraPos[2] + Math.cos(eff.angleY) * 7000.0; eff.angleYSpeed = cM_rndFX(1.0); eff.scale = 0.0; eff.timer = 300.0 + cM_rndF(180.0); @@ -1775,9 +1775,9 @@ function dKyr_kamome_move(globals: dGlobals, deltaTimeFrames: number): void { const newTargetY = Math.abs(Math.sin(eff.angleX) * 3200.0); const newTargetZ = Math.cos(eff.angleY) * 7000.0; - eff.pos[0] = globals.cameraPosition[0] + newTargetX; + eff.pos[0] = globals.camera.cameraPos[0] + newTargetX; eff.pos[1] = newTargetY + 4800; - eff.pos[2] = globals.cameraPosition[2] + newTargetZ; + eff.pos[2] = globals.camera.cameraPos[2] + newTargetZ; eff.emitter.setGlobalTranslation(eff.pos); if (eff.timer > 0 && spawnBirds) { @@ -1964,7 +1964,7 @@ function dKyr_windline_move(globals: dGlobals, deltaTimeFrames: number): void { vec3.scaleAndAdd(eff.animPos, eff.animPos, scratchVec3, swervePosMag * deltaTimeFrames); vec3.add(emitter.globalTranslation, eff.basePos, eff.animPos); - const dist = vec3.distance(emitter.globalTranslation, globals.cameraPosition); + const dist = vec3.distance(emitter.globalTranslation, globals.camera.cameraPos); const distFade = Math.min(dist / 200.0, 1.0); const colorAvg = (envLight.bgCol[0].K0.r + envLight.bgCol[0].K0.g + envLight.bgCol[0].K0.b) / 3; @@ -2093,14 +2093,14 @@ function wether_move_rain(globals: dGlobals, deltaTimeFrames: number): void { } else { vec3.set(rain.pos, cM_rndFX(800), cM_rndFX(800), cM_rndFX(800)); } - rain.minY = -800 + globals.cameraPosition[1]; + rain.minY = -800 + globals.camera.cameraPos[1]; } const posY = rain.basePos[1] + rain.pos[1]; if (posY < 20.0 + rain.minY) { vec3.copy(rain.basePos, scratchVec3); vec3.set(rain.pos, cM_rndFX(800.0), 200.0, cM_rndFX(800.0)); - rain.minY = -800 + globals.cameraPosition[1]; + rain.minY = -800 + globals.camera.cameraPos[1]; rain.timer = 10; } } else { @@ -2111,7 +2111,7 @@ function wether_move_rain(globals: dGlobals, deltaTimeFrames: number): void { vec3.set(rain.pos, cM_rndFX(800.0), cM_rndFX(600.0), cM_rndFX(800.0)); rain.alpha = 1.0; rain.timer = 0; - rain.minY = -800 + globals.cameraPosition[1]; + rain.minY = -800 + globals.camera.cameraPos[1]; rain.initialized = true; } @@ -2335,7 +2335,7 @@ function wether_move_moya(globals: dGlobals, deltaTimeFrames: number): void { eff.sizeTimer += 120 * deltaTimeFrames; - const distanceCam = vec3.distance(globals.cameraPosition, scratchVec3c); + const distanceCam = vec3.distance(globals.camera.cameraPos, scratchVec3c); eff.size = (Math.sin(cM_s2rad(eff.sizeTimer)) * 40.0) + eff.baseSize + (eff.baseSize * 1.5 * (distanceCam - 1000.0) / 2000.0); if (i < envLight.moyaCount) { @@ -2404,7 +2404,7 @@ function wether_move_wave(globals: dGlobals, deltaTimeFrames: number): void { skyboxY = fili.skyboxY; // Camera forward in XZ plane - vec3.copy(scratchVec3a, globals.cameraFwd); + vec3.copy(scratchVec3a, globals.camera.cameraFwd); scratchVec3a[1] = 0; vec3.normalize(scratchVec3a, scratchVec3a); @@ -2472,7 +2472,7 @@ function wether_move_wave(globals: dGlobals, deltaTimeFrames: number): void { // Sea flat fade. if (envLight.waveFlatInter > 0.0) { - const dist = Math.hypot(globals.cameraPosition[0] - scratchVec3d[0], globals.cameraPosition[2] - scratchVec3d[2]); + const dist = Math.hypot(globals.camera.cameraPos[0] - scratchVec3d[0], globals.camera.cameraPos[2] - scratchVec3d[2]); const innerRadius = envLight.waveFlatInter * 1.5 * envLight.waveSpawnRadius; const outerRadius = innerRadius + 1000.0; const fade = invlerpDistance(dist, innerRadius, outerRadius); @@ -2487,7 +2487,7 @@ function wether_move_wave(globals: dGlobals, deltaTimeFrames: number): void { wave.strengthEnv *= fade; } - const windSpeed = Math.max(windPow, vec3.distance(scratchVec3d, globals.cameraPosition)); + const windSpeed = Math.max(windPow, vec3.distance(scratchVec3d, globals.camera.cameraPos)); const alphaTarget = saturate(1.03 * (1.0 - (windSpeed / (2.0 * envLight.waveSpawnDist))) * Math.sin(wave.animCounter)); wave.alpha = cLib_addCalc(wave.alpha, alphaTarget, 0.5, 0.5, 0.001); wave.basePos[1] = skyboxY; @@ -2532,7 +2532,7 @@ function vrkumo_move(globals: dGlobals, deltaTimeFrames: number): void { if (globals.stageName === 'Siren' && globals.mStayNo === 17) skyboxY = -14101.0; // TODO(jstpierre): Re-enable this? - // skyboxOffsY -= 0.09 * (globals.cameraPosition[1] - skyboxY); + // skyboxOffsY -= 0.09 * (globals.camera.cameraPos[1] - skyboxY); } for (let i = 0; i < 100; i++) { @@ -2630,7 +2630,7 @@ function wether_move_vrkumo(globals: dGlobals, deltaTimeFrames: number): void { if (globals.stageName === 'sea' && globals.mStayNo === 9) { vec3.set(scratchVec3, -180000.0, 750.0, -200000.0); - const sqrDist = vec3.squaredDistance(globals.cameraPosition, scratchVec3); + const sqrDist = vec3.squaredDistance(globals.camera.cameraPos, scratchVec3); if (sqrDist < 2500**2) pkt.strength = 1.0; } @@ -2789,7 +2789,7 @@ export class d_thunder extends kankyo_class { this.scale[1] = nearMul * (20.0 + cM_rndF(60.0)); this.scale[2] = 1.0; - const fwd = globals.cameraFwd; + const fwd = globals.camera.cameraFwd; const a = Math.atan2(fwd[0], fwd[2]); const theta = (cM_rndFX(1.0) < 0.0) ? a - Math.PI / 2 : a + Math.PI / 2; const phi = vecPitch(fwd); @@ -2797,9 +2797,9 @@ export class d_thunder extends kankyo_class { const cosP = Math.cos(phi); const rndRot = cM_rndFX(120000.0); - this.pos[0] = globals.cameraPosition[0] + 100000.0 * fwd[0] + ((cosP * sinT) * rndRot); - this.pos[1] = globals.cameraPosition[1] + cM_rndFX(2000.0); - this.pos[2] = globals.cameraPosition[2] + 100000.0 * fwd[2] + ((cosP * cosT) * rndRot); + this.pos[0] = globals.camera.cameraPos[0] + 100000.0 * fwd[0] + ((cosP * sinT) * rndRot); + this.pos[1] = globals.camera.cameraPos[1] + cM_rndFX(2000.0); + this.pos[2] = globals.camera.cameraPos[2] + 100000.0 * fwd[2] + ((cosP * cosT) * rndRot); return cPhs__Status.Next; } diff --git a/src/ZeldaWindWaker/d_particle.ts b/src/ZeldaWindWaker/d_particle.ts index 33a581d7f..b8bd1ec11 100644 --- a/src/ZeldaWindWaker/d_particle.ts +++ b/src/ZeldaWindWaker/d_particle.ts @@ -69,7 +69,7 @@ export class dPa_control_c { this.drawInfo.frustum = frustum; } - public calc(viewerInput: ViewerRenderInput): void { + public calc(globals: dGlobals, viewerInput: ViewerRenderInput): void { const inc = viewerInput.deltaTime / 1000 * 30; // Some hacky distance culling for emitters. diff --git a/src/ZeldaWindWaker/d_place_name.ts b/src/ZeldaWindWaker/d_place_name.ts index b54e05900..a6ad556b4 100644 --- a/src/ZeldaWindWaker/d_place_name.ts +++ b/src/ZeldaWindWaker/d_place_name.ts @@ -100,7 +100,7 @@ export class d_place_name extends msg_class { if (status !== cPhs__Status.Complete) return status; const imgData = globals.modelCache.getFileData(filename); - img = new BTIData(globals.context.device, globals.renderer.renderCache, BTI.parse(imgData, filename).texture); + img = new BTIData(globals.sceneContext.device, globals.renderer.renderCache, BTI.parse(imgData, filename).texture); } this.screen = new J2DScreen(screen, globals.renderer.renderCache); diff --git a/src/ZeldaWindWaker/d_wood.ts b/src/ZeldaWindWaker/d_wood.ts index ae2e2ca44..dba881235 100644 --- a/src/ZeldaWindWaker/d_wood.ts +++ b/src/ZeldaWindWaker/d_wood.ts @@ -737,7 +737,7 @@ export class WoodPacket implements J3DPacket { const shadowRenderInst = renderInstManager.newRenderInst(); this.model.shapeShadow.setOnRenderInst(shadowRenderInst); - mat4.mul(drawParams.u_PosMtx[0], globals.camera.viewMatrix, unit.shadowModelMtx); + mat4.mul(drawParams.u_PosMtx[0], globals.camera.viewFromWorldMatrix, unit.shadowModelMtx); this.model.shadowMaterial.allocateDrawParamsDataOnInst(shadowRenderInst, drawParams); renderInstManager.submitRenderInst(shadowRenderInst); } @@ -763,7 +763,7 @@ export class WoodPacket implements J3DPacket { // Set the room color and fog params colorCopy(materialParams.u_Color[ColorKind.C0], globals.roomCtrl.status[r].tevStr.colorC0); colorCopy(materialParams.u_Color[ColorKind.C1], globals.roomCtrl.status[r].tevStr.colorK0); - dKy_GxFog_set(globals.g_env_light, materialParams.u_FogBlock, viewerInput.camera); + dKy_GxFog_set(globals.g_env_light, materialParams.u_FogBlock, globals.camera); for (let unit of this.unit[r]) { if (unit.flags & UnitState_e.IsFrustumCulled) @@ -783,7 +783,7 @@ export class WoodPacket implements J3DPacket { const renderInst = renderInstManager.newRenderInst(); this.model.shapeMain.setOnRenderInst(renderInst); - mat4.mul(drawParams.u_PosMtx[0], globals.camera.viewMatrix, unit.modelMtx); + mat4.mul(drawParams.u_PosMtx[0], globals.camera.viewFromWorldMatrix, unit.modelMtx); this.model.bushMaterial.allocateDrawParamsDataOnInst(renderInst, drawParams); renderInstManager.submitRenderInst(renderInst); @@ -797,7 +797,7 @@ export class WoodPacket implements J3DPacket { // Always draw the trunk const renderInst = renderInstManager.newRenderInst(); this.model.shapeTrunk.setOnRenderInst(renderInst); - mat4.mul(drawParams.u_PosMtx[0], globals.camera.viewMatrix, unit.trunkModelMtx); + mat4.mul(drawParams.u_PosMtx[0], globals.camera.viewFromWorldMatrix, unit.trunkModelMtx); this.model.bushMaterial.allocateDrawParamsDataOnInst(renderInst, drawParams); renderInstManager.submitRenderInst(renderInst); } diff --git a/src/ZeldaWindWaker/f_op_actor.ts b/src/ZeldaWindWaker/f_op_actor.ts index 8b31ae39e..f7419df56 100644 --- a/src/ZeldaWindWaker/f_op_actor.ts +++ b/src/ZeldaWindWaker/f_op_actor.ts @@ -7,7 +7,7 @@ import { assert } from "../util.js"; import { dKy_tevstr_c, dKy_tevstr_init } from "./d_kankyo.js"; import { dProcName_e } from "./d_procname.js"; import { base_process_class, cPhs__Status, fGlobals, fopDwTg_DrawQTo, fopDwTg_ToDrawQ, fpcDt_Delete, fpcPc__IsVisible, fpcSCtRq_Request, leafdraw_class } from "./framework.js"; -import { dGlobals } from "./Main.js"; +import { dCamera_c, dGlobals } from "./Main.js"; const scratchVec3a = vec3.create(); const scratchAABB = new AABB(); @@ -111,7 +111,7 @@ export class fopAc_ac_c extends leafdraw_class { vec4.set(this.cullSizeSphere, x, y, z, r); } - protected cullingCheck(camera: Camera): boolean { + protected cullingCheck(camera: dCamera_c): boolean { if (!fpcPc__IsVisible(this)) return false; @@ -155,7 +155,7 @@ export class fopAc_ac_c extends leafdraw_class { return false; // Calculate the length of a line R at distance D from the camera. - const r = Math.abs(camera.projectionMatrix[11] * this.cullSizeSphere[2] + camera.projectionMatrix[15]); + const r = Math.abs(camera.clipFromViewMatrix[11] * this.cullSizeSphere[2] + camera.clipFromViewMatrix[15]); const area = MathConstants.TAU * r; if (area <= 0.0002) diff --git a/src/ZeldaWindWaker/m_do_ext.ts b/src/ZeldaWindWaker/m_do_ext.ts index 7391509d9..c6a5ab788 100644 --- a/src/ZeldaWindWaker/m_do_ext.ts +++ b/src/ZeldaWindWaker/m_do_ext.ts @@ -4,8 +4,8 @@ import { TTK1, LoopMode, TRK1, AnimationBase, TPT1, VAF1, ANK1, JointTransformIn import { J3DModelInstance, J3DModelData, JointMatrixCalc, ShapeInstanceState } from "../Common/JSYSTEM/J3D/J3DGraphBase.js"; import { GfxRenderInstManager } from "../gfx/render/GfxRenderInstManager.js"; import { ViewerRenderInput } from "../viewer.js"; -import { dGlobals } from "./Main.js"; -import { mat4, vec3, vec4 } from "gl-matrix"; +import { dCamera_c, dGlobals } from "./Main.js"; +import { mat4, ReadonlyMat4, vec3, vec4 } from "gl-matrix"; import { Camera, divideByW } from "../Camera.js"; import { dDlst_list_Set } from "./d_drawlist.js"; @@ -101,13 +101,13 @@ export function mDoExt_modelEntryDL(globals: dGlobals, modelInstance: J3DModelIn modelInstance.setTexturesEnabled(globals.renderHacks.texturesEnabled); } - const camera = viewerInput.camera; - modelInstance.calcView(camera.viewMatrix, camera.frustum); + const camera = globals.camera; + modelInstance.calcView(camera.viewFromWorldMatrix, camera.frustum); renderInstManager.setCurrentList(drawListSet[0]); - modelInstance.drawOpa(renderInstManager, camera.projectionMatrix); + modelInstance.drawOpa(renderInstManager, camera.clipFromViewMatrix); renderInstManager.setCurrentList(drawListSet[1]); - modelInstance.drawXlu(renderInstManager, camera.projectionMatrix); + modelInstance.drawXlu(renderInstManager, camera.clipFromViewMatrix); } export function mDoExt_modelUpdateDL(globals: dGlobals, modelInstance: J3DModelInstance, renderInstManager: GfxRenderInstManager, viewerInput: ViewerRenderInput, drawListSet: dDlst_list_Set | null = null): void { @@ -234,15 +234,15 @@ export class mDoExt_McaMorf implements JointMatrixCalc { } const scratchVec4 = vec4.create(); -export function mDoLib_project(dst: vec3, v: vec3, camera: Camera, v4 = scratchVec4): void { +export function mDoLib_project(dst: vec3, v: vec3, clipFromWorldMatrix: ReadonlyMat4, v4 = scratchVec4): void { vec4.set(v4, v[0], v[1], v[2], 1.0); - vec4.transformMat4(v4, v4, camera.clipFromWorldMatrix); + vec4.transformMat4(v4, v4, clipFromWorldMatrix); divideByW(v4, v4); vec3.set(dst, v4[0], v4[1], v4[2]); } -export function mDoLib_projectFB(dst: vec3, v: vec3, viewerInput: ViewerRenderInput): void { - mDoLib_project(dst, v, viewerInput.camera); +export function mDoLib_projectFB(dst: vec3, v: vec3, viewerInput: ViewerRenderInput, clipFromWorldMatrix: ReadonlyMat4 = viewerInput.camera.clipFromWorldMatrix): void { + mDoLib_project(dst, v, clipFromWorldMatrix); // Put in viewport framebuffer space. dst[0] = (dst[0] * 0.5 + 0.5) * viewerInput.backbufferWidth; dst[1] = (dst[1] * 0.5 + 0.5) * viewerInput.backbufferHeight; diff --git a/src/gfx/render/GfxRenderDynamicUniformBuffer.ts b/src/gfx/render/GfxRenderDynamicUniformBuffer.ts index 245fa5b7b..aaec1bcb1 100644 --- a/src/gfx/render/GfxRenderDynamicUniformBuffer.ts +++ b/src/gfx/render/GfxRenderDynamicUniformBuffer.ts @@ -41,20 +41,21 @@ export class GfxRenderDynamicUniformBuffer { } private ensureShadowBuffer(wordOffset: number, wordCount: number): void { - if (this.shadowBufferU8 === null || this.shadowBufferF32 === null) { + if (this.shadowBufferU8 === null) { const newWordCount = alignNonPowerOfTwo(this.currentWordOffset, this.uniformBufferMaxPageWordSize); - this.shadowBufferU8 = new Uint8Array(newWordCount * 4); - this.shadowBufferF32 = new Float32Array(this.shadowBufferU8.buffer); - } else if (wordOffset + wordCount >= this.shadowBufferF32.length) { + const buffer = new ArrayBuffer(newWordCount << 2); + this.shadowBufferU8 = new Uint8Array(buffer); + this.shadowBufferF32 = new Float32Array(buffer); + } else if (wordOffset + wordCount >= this.shadowBufferF32!.length) { assert(wordOffset < this.currentWordOffset && wordOffset + wordCount <= this.currentWordOffset); // Grow logarithmically, aligned to page size. - const newWordCount = alignNonPowerOfTwo(Math.max(this.currentWordOffset, this.shadowBufferF32.length * 2), this.uniformBufferMaxPageWordSize); - const newBuffer = new Uint8Array(newWordCount * 4); + const newWordCount = alignNonPowerOfTwo(Math.max(this.currentWordOffset, this.shadowBufferF32!.length * 2), this.uniformBufferMaxPageWordSize); + const buffer = this.shadowBufferU8.buffer as ArrayBuffer; + const newBuffer = buffer.transfer(newWordCount << 2); - newBuffer.set(this.shadowBufferU8, 0); - this.shadowBufferU8 = newBuffer; - this.shadowBufferF32 = new Float32Array(this.shadowBufferU8.buffer); + this.shadowBufferU8 = new Uint8Array(newBuffer); + this.shadowBufferF32 = new Float32Array(newBuffer); if (!(this.currentWordOffset <= newWordCount)) throw new Error(`Assert fail: this.currentWordOffset [${this.currentWordOffset}] <= newWordCount [${newWordCount}]`); diff --git a/src/gfx/render/GfxRenderInstManager.ts b/src/gfx/render/GfxRenderInstManager.ts index a480f3874..b5e20eaea 100644 --- a/src/gfx/render/GfxRenderInstManager.ts +++ b/src/gfx/render/GfxRenderInstManager.ts @@ -334,13 +334,21 @@ export class GfxRenderInst { return this.getUniformBufferOffset(bufferIndex); } + /** + * This is a convenience wrapper for {@param allocateUniformBuffer} and {@param mapUniformBufferF32} + * that returns a pre-sliced {@see Float32Array} for the given offset. + */ + public allocateUniformBufferF32(bufferIndex: number, wordCount: number): Float32Array { + const wordOffset = this.allocateUniformBuffer(bufferIndex, wordCount); + return this._uniformBuffer.mapBufferF32().subarray(wordOffset); + } + /** * Returns the offset into the uniform buffer, in words, that is assigned to the buffer slot * at index {@param bufferIndex}, to be used with e.g. {@see mapUniformBufferF32}. */ public getUniformBufferOffset(bufferIndex: number) { - const wordOffset = this._dynamicUniformBufferByteOffsets[bufferIndex] >>> 2; - return wordOffset; + return this._dynamicUniformBufferByteOffsets[bufferIndex] >>> 2; } /** diff --git a/src/gx/gx_render.ts b/src/gx/gx_render.ts index 3233a68c9..d61b144fa 100644 --- a/src/gx/gx_render.ts +++ b/src/gx/gx_render.ts @@ -152,18 +152,12 @@ function fillDrawParamsDataWithOptimizations(material: GX_Material.GXMaterial, d assert(d.length >= offs); } -export function fillSceneParams(sceneParams: SceneParams, projectionMatrix: ReadonlyMat4, viewportWidth: number, viewportHeight: number, customLODBias: number | null = null): void { - mat4.copy(sceneParams.u_Projection, projectionMatrix); - - if (customLODBias !== null) { - sceneParams.u_SceneTextureLODBias = customLODBias; - } else { - // Mip levels in GX are assumed to be relative to the GameCube's embedded framebuffer (EFB) size, - // which is hardcoded to be 640x528. We need to bias our mipmap LOD selection by this amount to - // make sure textures are sampled correctly... - const textureLODBias = Math.log2(Math.min(viewportWidth / GX_Material.EFB_WIDTH, viewportHeight / GX_Material.EFB_HEIGHT)); - sceneParams.u_SceneTextureLODBias = textureLODBias; - } +export function calcLODBias(viewportWidth: number, viewportHeight: number): number { + // Mip levels in GX are assumed to be relative to the GameCube's embedded framebuffer (EFB) size, + // which is hardcoded to be 640x528. We need to bias our mipmap LOD selection by this amount to + // make sure textures are sampled correctly... + const textureLODBias = Math.log2(Math.min(viewportWidth / GX_Material.EFB_WIDTH, viewportHeight / GX_Material.EFB_HEIGHT)); + return textureLODBias; } export function loadedDataCoalescerComboGfx(device: GfxDevice, loadedVertexDatas: LoadedVertexData[]): GfxBufferCoalescerCombo { @@ -605,10 +599,11 @@ export const gxBindingLayouts: GfxBindingLayoutDescriptor[] = [ const sceneParams = new SceneParams(); export function fillSceneParamsDataOnTemplate(renderInst: GfxRenderInst, viewerInput: Viewer.ViewerRenderInput, customLODBias: number | null = null, sceneParamsScratch = sceneParams): void { - fillSceneParams(sceneParamsScratch, viewerInput.camera.projectionMatrix, viewerInput.backbufferWidth, viewerInput.backbufferHeight, customLODBias); + mat4.copy(sceneParamsScratch.u_Projection, viewerInput.camera.projectionMatrix); + sceneParams.u_SceneTextureLODBias = customLODBias !== null ? customLODBias : calcLODBias(viewerInput.backbufferWidth, viewerInput.backbufferHeight); let offs = renderInst.getUniformBufferOffset(GX_Material.GX_Program.ub_SceneParams); const d = renderInst.mapUniformBufferF32(GX_Material.GX_Program.ub_SceneParams); - fillSceneParamsData(d, offs, sceneParams); + fillSceneParamsData(d, offs, sceneParamsScratch); } export class GXRenderHelperGfx extends GfxRenderHelper { diff --git a/tsconfig.json b/tsconfig.json index 4a731ffe3..34eb5c26d 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -16,10 +16,9 @@ "useDefineForClassFields": false, "resolveJsonModule": true, "lib": [ - "es2017", - "es2019.array", - "es2021.string", - "esnext.BigInt", + "ES2020", + "ES2021.String", + "ES2024.ArrayBuffer", "dom" ], "sourceMap": true,