Skip to content

Commit

Permalink
Camera: Start on some cleanups
Browse files Browse the repository at this point in the history
Don't rely on the Camera class in J3D as much
  • Loading branch information
magcius committed Dec 24, 2024
1 parent 6011094 commit 61da0ab
Show file tree
Hide file tree
Showing 32 changed files with 253 additions and 315 deletions.
8 changes: 4 additions & 4 deletions src/Camera.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1021,8 +1021,8 @@ export function deserializeCamera(camera: Camera, view: DataView, byteOffs: numb
return 0x04*4*3;
}

function texProjCamera(dst: mat4, camera: Camera, scaleS: number, scaleT: number, transS: number, transT: number): void {
const projMtx = camera.projectionMatrix;
function texProjCamera(dst: mat4, clipFromViewMatrix: ReadonlyMat4, scaleS: number, scaleT: number, transS: number, transT: number): void {
const projMtx = clipFromViewMatrix;

// Avoid multiplications where we know the result will be 0.
dst[0] = projMtx[0] * scaleS;
Expand All @@ -1049,8 +1049,8 @@ function texProjCamera(dst: mat4, camera: Camera, scaleS: number, scaleT: number
dst[15] = 9999.0;
}

export function texProjCameraSceneTex(dst: mat4, camera: Camera, flipYScale: number): void {
export function texProjCameraSceneTex(dst: mat4, clipFromViewMatrix: ReadonlyMat4, flipYScale: number): void {
// Map from -1 to 1 to 0 to 1.
let scaleS = 0.5, scaleT = -0.5 * flipYScale, transS = 0.5, transT = 0.5;
texProjCamera(dst, camera, scaleS, scaleT, transS, transT);
texProjCamera(dst, clipFromViewMatrix, scaleS, scaleT, transS, transT);
}
267 changes: 121 additions & 146 deletions src/Common/JSYSTEM/J3D/J3DGraphBase.ts

Large diffs are not rendered by default.

10 changes: 6 additions & 4 deletions src/Common/JSYSTEM/J3D/J3DGraphSimple.ts
Original file line number Diff line number Diff line change
Expand Up @@ -284,18 +284,20 @@ export class J3DModelInstanceSimple extends J3DModelInstance {
if (!this.visible)
return;

const camera = viewerInput.camera;

this.animationController.setTimeInMilliseconds(viewerInput.time);
this.calcSkybox(viewerInput.camera);
this.calcSkybox(camera);
this.calcAnim();
this.calcView(viewerInput.camera, viewerInput.camera.viewMatrix);
this.calcView(camera.viewMatrix, camera.frustum);

// If entire model is culled away, then we don't need to render anything.
if (!this.isAnyShapeVisible())
return;

const depth = this.computeDepth(viewerInput.camera);
const viewDepth = this.computeDepth();
for (let i = 0; i < this.materialInstances.length; i++)
this.materialInstances[i].prepareToRenderShapes(device, renderInstManager, depth, viewerInput.camera, this.modelData, this.materialInstanceState, this.shapeInstanceState);
this.materialInstances[i].prepareToRenderShapes(renderInstManager, viewDepth, camera.projectionMatrix, this.modelData, this.materialInstanceState, this.shapeInstanceState);
}

public override destroy(device: GfxDevice): void {
Expand Down
3 changes: 2 additions & 1 deletion src/Common/JSYSTEM/J3D/J3DLoader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -549,8 +549,9 @@ export const enum TexMtxMapMode {
ProjmapBasic = 0x02,
ViewProjmapBasic = 0x03,
// Unknown: 0x04, 0x05. No known uses.
Unk0x04 = 0x04,
Unk0x05 = 0x05,
// Uses "Old" conventions, remaps translation in fourth component
// TODO(jstpierre): Figure out the geometric interpretation of old vs. new
EnvmapOld = 0x06,
// Uses "New" conventions, remaps translation in third component
Envmap = 0x07,
Expand Down
2 changes: 1 addition & 1 deletion src/InteractiveExamples/JPAExplorer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -463,7 +463,7 @@ export class Explorer implements SceneGfx {
{
renderInstManager.setCurrentList(this.indirectList);
const texPrjMtx = scratchMatrix;
texProjCameraSceneTex(texPrjMtx, viewerInput.camera, 1);
texProjCameraSceneTex(texPrjMtx, viewerInput.camera.projectionMatrix, 1);
this.effectSystem.setDrawInfo(viewerInput.camera.viewMatrix, viewerInput.camera.projectionMatrix, texPrjMtx);
this.effectSystem.draw(device, this.renderHelper.renderInstManager, EfGroup.Indirect);
}
Expand Down
5 changes: 3 additions & 2 deletions src/InteractiveExamples/SlimySpringWater.ts
Original file line number Diff line number Diff line change
Expand Up @@ -235,9 +235,10 @@ class FakeWaterModelInstance {
if (!this.visible)
return;

const camera = viewerInput.camera;
this.modelInstance.animationController.setTimeInMilliseconds(viewerInput.time);
this.modelInstance.calcAnim();
this.modelInstance.calcView(viewerInput.camera, viewerInput.camera.viewMatrix);
this.modelInstance.calcView(camera.viewMatrix, camera.frustum);

const template = renderInstManager.pushTemplate();

Expand All @@ -247,7 +248,7 @@ class FakeWaterModelInstance {

// Push our material instance.
this.materialInstance.setOnRenderInst(renderInstManager.gfxRenderCache, template);
this.materialInstance.fillMaterialParams(template, this.modelInstance.materialInstanceState, this.modelInstance.shapeInstanceState.worldToViewMatrix, this.modelInstance.modelMatrix, viewerInput.camera, drawParams);
this.materialInstance.fillMaterialParams(template, this.modelInstance.materialInstanceState, this.modelInstance.shapeInstanceState.viewFromWorldMatrix, this.modelInstance.modelMatrix, viewerInput.camera.projectionMatrix, drawParams);
this.plane.prepareToRender(renderInstManager);

renderInstManager.popTemplate();
Expand Down
8 changes: 4 additions & 4 deletions src/InteractiveExamples/SunshineWater.ts
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ class SunshineWaterModel {
bindTTK1MaterialInstance(this.seaMaterialInstance, this.animationController, btk);
this.plane = new PlaneShape(device, cache);

this.shapeInstanceState.worldToViewMatrix = scratchViewMatrix;
this.shapeInstanceState.viewFromWorldMatrix = scratchViewMatrix;
}

public mangleMaterial(material: MaterialEntry, configName: string): void {
Expand Down Expand Up @@ -192,11 +192,11 @@ class SunshineWaterModel {
fillSceneParamsDataOnTemplate(template, viewerInput);
this.seaMaterialInstance.setOnRenderInst(renderHelper.renderInstManager.gfxRenderCache, template);

computeViewMatrix(this.shapeInstanceState.worldToViewMatrix, viewerInput.camera);
mat4.mul(drawParams.u_PosMtx[0], this.shapeInstanceState.worldToViewMatrix, this.modelMatrix);
computeViewMatrix(this.shapeInstanceState.viewFromWorldMatrix, viewerInput.camera);
mat4.mul(drawParams.u_PosMtx[0], this.shapeInstanceState.viewFromWorldMatrix, this.modelMatrix);
this.seaMaterialInstance.materialHelper.allocateDrawParamsDataOnInst(template, drawParams);

this.seaMaterialInstance.fillMaterialParams(template, this.materialInstanceState, this.shapeInstanceState.worldToViewMatrix, this.modelMatrix, viewerInput.camera, drawParams);
this.seaMaterialInstance.fillMaterialParams(template, this.materialInstanceState, this.shapeInstanceState.viewFromWorldMatrix, viewerInput.camera.projectionMatrix, this.modelMatrix, drawParams);

this.plane.prepareToRender(renderHelper);

Expand Down
6 changes: 3 additions & 3 deletions src/MetroidPrime/render.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import { GfxRendererLayer, GfxRenderInst, makeSortKey, setSortKeyBias, setSortKe
import { computeViewMatrix, computeViewMatrixSkybox } from '../Camera.js';
import { LoadedVertexData, LoadedVertexDraw, LoadedVertexLayout } from '../gx/gx_displaylist.js';
import * as GX_Material from '../gx/gx_material.js';
import { GX_Program, GXMaterialHacks, lightSetWorldDirectionNormalMatrix, lightSetWorldPositionViewMatrix } from '../gx/gx_material.js';
import { GX_Program, GXMaterialHacks, lightSetWorldDirection, lightSetWorldPosition } from '../gx/gx_material.js';
import { AreaAttributes, Effect, Entity, LightParameters, MP1EntityType, WorldLightingOptions } from './script.js';
import { Color, colorAdd, colorCopy, colorMult, colorNewCopy, OpaqueBlack, TransparentBlack, White } from '../Color.js';
import { computeNormalMatrix, getMatrixTranslation, setMatrixTranslation, texEnvMtx, transformVec3Mat4w0, transformVec3Mat4w1, Vec3One } from '../MathHelpers.js';
Expand Down Expand Up @@ -290,8 +290,8 @@ class MaterialGroupInstance {
if (actorLights !== null && i < actorLights.lights.length) {
const light = actorLights.lights[i].gxLight;
materialParams.u_Lights[i].copy(light);
lightSetWorldPositionViewMatrix(materialParams.u_Lights[i], viewMatrix, light.Position);
lightSetWorldDirectionNormalMatrix(materialParams.u_Lights[i], viewMatrix, light.Direction);
lightSetWorldPosition(materialParams.u_Lights[i], viewMatrix, light.Position);
lightSetWorldDirection(materialParams.u_Lights[i], viewMatrix, light.Direction);
} else {
materialParams.u_Lights[i].reset();
}
Expand Down
5 changes: 2 additions & 3 deletions src/NeedForSpeedMostWanted/render.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@

import { mat4, vec3 } from "gl-matrix";
import { CameraController, computeViewMatrix, computeViewSpaceDepthFromWorldSpacePoint } from "../Camera.js";
import { CameraController, computeViewSpaceDepthFromWorldSpacePoint } from "../Camera.js";
import { GfxShaderLibrary } from "../gfx/helpers/GfxShaderLibrary.js";
import { makeBackbufferDescSimple, standardFullClearRenderPassDescriptor } from "../gfx/helpers/RenderGraphHelpers.js";
import { fillMatrix4x3, fillMatrix4x4, fillVec4v } from "../gfx/helpers/UniformBufferHelpers.js";
Expand Down Expand Up @@ -91,8 +91,7 @@ export class NfsRenderer implements SceneGfx {
let offs = template.allocateUniformBuffer(NfsProgram.ub_SceneParams, 24);
const sceneParamsMapped = template.mapUniformBufferF32(NfsProgram.ub_SceneParams);
const worldProjMatrix = mat4.create();
computeViewMatrix(worldProjMatrix, viewerInput.camera);
mat4.mul(worldProjMatrix, viewerInput.camera.projectionMatrix, worldProjMatrix);
mat4.mul(worldProjMatrix, viewerInput.camera.projectionMatrix, viewerInput.camera.viewMatrix);
offs += fillMatrix4x4(sceneParamsMapped, offs, worldProjMatrix);
offs += fillVec4v(sceneParamsMapped, offs, [cameraPos[0], cameraPos[1], cameraPos[2], 0]);
offs += fillVec4v(sceneParamsMapped, offs, [viewerInput.backbufferWidth, viewerInput.backbufferHeight, 0, 0]);
Expand Down
17 changes: 8 additions & 9 deletions src/PokemonSnap/particles.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@

import * as RDP from "../Common/N64/RDP.js";

import { mat4, vec3, vec4 } from "gl-matrix";
import ArrayBufferSlice from "../ArrayBufferSlice.js";
import { TexCM } from "../Common/N64/Image.js";
import { makeStaticDataBuffer } from "../gfx/helpers/BufferHelpers.js";
import { GfxBuffer, GfxBufferUsage, GfxDevice, GfxFormat, GfxInputLayout, GfxInputLayoutBufferDescriptor, GfxSampler, GfxTexture, GfxVertexAttributeDescriptor, GfxVertexBufferFrequency, GfxBindingLayoutDescriptor, GfxProgram, GfxMegaStateDescriptor, GfxCompareMode, GfxBlendMode, GfxBlendFactor, GfxCullMode, GfxVertexBufferDescriptor, GfxIndexBufferDescriptor } from "../gfx/platform/GfxPlatform.js";
import { setAttachmentStateSimple } from "../gfx/helpers/GfxMegaStateDescriptorHelpers.js";
import { fillMatrix4x3, fillMatrix4x4, fillVec4v } from "../gfx/helpers/UniformBufferHelpers.js";
import { GfxBindingLayoutDescriptor, GfxBlendFactor, GfxBlendMode, GfxBuffer, GfxBufferUsage, GfxCompareMode, GfxCullMode, GfxDevice, GfxFormat, GfxIndexBufferDescriptor, GfxInputLayout, GfxMegaStateDescriptor, GfxProgram, GfxSampler, GfxTexture, GfxVertexAttributeDescriptor, GfxVertexBufferDescriptor, GfxVertexBufferFrequency } from "../gfx/platform/GfxPlatform.js";
import { GfxRenderCache } from "../gfx/render/GfxRenderCache.js";
import { GfxRenderInstManager, makeSortKey, GfxRendererLayer } from "../gfx/render/GfxRenderInstManager.js";
import { clamp, lerp, MathConstants, normToLength, normToLengthAndAdd, transformVec3Mat4w0, Vec3Zero, Vec3UnitX, calcBillboardMatrix, CalcBillboardFlags } from "../MathHelpers.js";
import { GfxRendererLayer, GfxRenderInstManager, makeSortKey } from "../gfx/render/GfxRenderInstManager.js";
import { CalcBillboardFlags, calcBillboardMatrix, clamp, lerp, MathConstants, normToLength, normToLengthAndAdd, transformVec3Mat4w0, Vec3UnitX, Vec3Zero } from "../MathHelpers.js";
import { DeviceProgram } from "../Program.js";
import { TextureMapping } from "../TextureHolder.js";
import { align, assert, hexzero, nArray } from "../util.js";
import { ViewerRenderInput } from "../viewer.js";
import { getColor, getVec3 } from "./room.js";
import { fillMatrix4x4, fillMatrix4x3, fillVec4v } from "../gfx/helpers/UniformBufferHelpers.js";
import { TextureMapping } from "../TextureHolder.js";
import { computeViewMatrix } from "../Camera.js";
import { setAttachmentStateSimple } from "../gfx/helpers/GfxMegaStateDescriptorHelpers.js";

export interface EmitterData {
isCommon: boolean;
Expand Down Expand Up @@ -968,8 +968,7 @@ class Particle {
let offs = renderInst.allocateUniformBuffer(ParticleProgram.ub_DrawParams, 12 + 4 * 2);
const draw = renderInst.mapUniformBufferF32(ParticleProgram.ub_DrawParams);

computeViewMatrix(particleMtx, viewerInput.camera);
mat4.mul(particleMtx, particleMtx, this.modelMatrix);
mat4.mul(particleMtx, viewerInput.camera.viewMatrix, this.modelMatrix);
calcBillboardMatrix(particleMtx, particleMtx, CalcBillboardFlags.UseRollLocal | CalcBillboardFlags.PriorityZ | CalcBillboardFlags.UseZPlane);
offs += fillMatrix4x3(draw, offs, particleMtx);

Expand Down
16 changes: 5 additions & 11 deletions src/StarFoxAdventures/SphereMaps.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import { mat4, vec3 } from 'gl-matrix';
import { computeViewMatrix } from '../Camera.js';
import { Blue, Color, colorCopy, colorNewFromRGBA, Red, TransparentBlack, White } from '../Color.js';
import { projectionMatrixConvertClipSpaceNearZ } from '../gfx/helpers/ProjectionHelpers.js';
import { GfxClipSpaceNearZ, GfxDevice, GfxFormat, GfxMipFilterMode, GfxSampler, GfxTexFilterMode, GfxWrapMode } from '../gfx/platform/GfxPlatform.js';
import { GfxRenderCache } from '../gfx/render/GfxRenderCache.js';
import { GfxrAttachmentSlot, GfxrGraphBuilder, GfxrPass, GfxrPassScope, GfxrRenderTargetDescription, GfxrRenderTargetID, GfxrResolveTextureID } from '../gfx/render/GfxRenderGraph.js';
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, fillSceneParams, fillSceneParamsData, GXRenderHelperGfx, MaterialParams, DrawParams, SceneParams } from '../gx/gx_render.js';
import { ColorKind, DrawParams, fillSceneParams, fillSceneParamsData, gxBindingLayouts, GXRenderHelperGfx, MaterialParams, SceneParams, ub_SceneParamsBufferSize } from '../gx/gx_render.js';
import { projectionMatrixForCuboid } from '../MathHelpers.js';
import { TDDraw, TSDraw } from "../SuperMarioGalaxy/DDraw.js";
import { TSDraw } from "../SuperMarioGalaxy/DDraw.js";
import { TextureMapping } from '../TextureHolder.js';
import { nArray } from '../util.js';
import { SFAMaterialBuilder } from './MaterialBuilder.js';
Expand All @@ -19,15 +19,11 @@ import { TextureFetcher } from './textures.js';
import { mat4SetTranslation } from './util.js';
import { World } from './world.js';
import { LightType } from './WorldLights.js';
import { ub_SceneParamsBufferSize } from '../gx/gx_render.js';
import { gxBindingLayouts } from '../gx/gx_render.js';
import { projectionMatrixConvertClipSpaceNearZ } from '../gfx/helpers/ProjectionHelpers.js';

const scratchMaterialParams = new MaterialParams();
const scratchDrawParams = new DrawParams();
const scratchSceneParams = new SceneParams();
const scratchMtx0 = mat4.create();
const scratchMtx1 = mat4.create();
const scratchVec0 = vec3.create();
const scratchVec1 = vec3.create();

Expand Down Expand Up @@ -231,10 +227,8 @@ export class SphereMapManager {
const skyLight = this.world.envfxMan.skyLight;
const groundLight = this.world.envfxMan.groundLight;

const worldView = scratchMtx0;
computeViewMatrix(worldView, sceneCtx.viewerInput.camera);
const worldViewSR = scratchMtx1;
mat4.copy(worldViewSR, worldView);
const worldViewSR = scratchMtx0;
mat4.copy(worldViewSR, sceneCtx.viewToWorldMtx);
mat4SetTranslation(worldViewSR, 0, 0, 0);

const skyLightVec = scratchVec0;
Expand Down
29 changes: 7 additions & 22 deletions src/StarFoxAdventures/envfx.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,15 @@
import { mat4, vec3 } from 'gl-matrix';
import { Color, colorCopy, colorNewFromRGBA, colorScale, White } from '../Color.js';
import { DataFetcher } from '../DataFetcher.js';
import { Color, colorNewFromRGBA, colorCopy, colorNewCopy, colorFromRGBA, White, colorScale } from '../Color.js';
import { nArray } from '../util.js';

import { GfxDevice } from '../gfx/platform/GfxPlatform.js';
import { ObjectInstance } from './objects.js';
import { SceneUpdateContext } from './render.js';
import { SFATexture } from './textures.js';
import { dataSubarray, readUint16 } from './util.js';
import { ObjectInstance } from './objects.js';
import { World } from './world.js';
import { GfxDevice } from '../gfx/platform/GfxPlatform.js';
import { createDirectionalLight, Light } from './WorldLights.js';
import { SceneUpdateContext } from './render.js';
import { computeViewMatrix } from '../Camera.js';
import { GfxRenderCache } from '../gfx/render/GfxRenderCache.js';

enum EnvfxType {
Atmosphere = 5,
Expand Down Expand Up @@ -75,22 +73,9 @@ export class EnvfxManager {

public update(device: GfxDevice, sceneCtx: SceneUpdateContext) {
this.updateAmbience();

const viewToWorldMtx = scratchMtx0;
computeViewMatrix(viewToWorldMtx, sceneCtx.viewerInput.camera);
mat4.invert(viewToWorldMtx, viewToWorldMtx);

const viewToWorldTY = viewToWorldMtx[4*3+1];

// XXX: This code causes the mist to "overwhelm" the camera when the camera is immersed.
// This doesn't work well with noclip, so I have disabled it.
// let mistParam;
// if (viewToWorldTY >= this.mistTop)
// mistParam = 0;
// else if (viewToWorldTY <= this.mistBottom)
// mistParam = 64;
// else
// mistParam = 64 * (this.mistTop - viewToWorldTY) / (this.mistTop - this.mistBottom);
// const viewToWorldTY = sceneCtx.viewerInput.camera.worldMatrix[13];
// const mistPercent = 1.0 - saturate(invlerp(this.mistBottom, this.mistTop, viewToWorldTY));
// let mistParam = mistPercent * 64.0;
let mistParam = 0; // Behave as if the camera is always above the mist
this.updateMistTexture(device, mistParam);
}
Expand Down
7 changes: 4 additions & 3 deletions src/StarFoxAdventures/materials.ts
Original file line number Diff line number Diff line change
Expand Up @@ -793,8 +793,9 @@ export class StandardMapMaterial extends StandardMaterial {
this.aprevIsValid = false;

this.mb.setTexMtx(2, (dst: mat4, matCtx: MaterialRenderContext) => {

// Flipped
texProjCameraSceneTex(dst, matCtx.sceneCtx.viewerInput.camera, -matCtx.sceneCtx.flipYScale);
texProjCameraSceneTex(dst, matCtx.sceneCtx.viewerInput.camera.projectionMatrix, -matCtx.sceneCtx.flipYScale);
mat4.mul(dst, dst, matCtx.modelToViewMtx);
return dst;
});
Expand Down Expand Up @@ -1381,13 +1382,13 @@ class WaterMaterial extends MaterialBase {
protected rebuildInternal() {
this.mb.setTexMtx(0, (dst: mat4, ctx: MaterialRenderContext) => {
// Flipped
texProjCameraSceneTex(dst, ctx.sceneCtx.viewerInput.camera, -ctx.sceneCtx.flipYScale);
texProjCameraSceneTex(dst, ctx.sceneCtx.viewerInput.camera.projectionMatrix, -ctx.sceneCtx.flipYScale);
mat4.mul(dst, dst, ctx.modelToViewMtx);
});

this.mb.setTexMtx(1, (dst: mat4, ctx: MaterialRenderContext) => {
// Unflipped
texProjCameraSceneTex(dst, ctx.sceneCtx.viewerInput.camera, ctx.sceneCtx.flipYScale);
texProjCameraSceneTex(dst, ctx.sceneCtx.viewerInput.camera.projectionMatrix, ctx.sceneCtx.flipYScale);
mat4.mul(dst, dst, ctx.modelToViewMtx);
});

Expand Down
Loading

0 comments on commit 61da0ab

Please sign in to comment.