Skip to content

Commit

Permalink
Some more camera cleanups
Browse files Browse the repository at this point in the history
And Zelda LegacyActor cleanups.
  • Loading branch information
magcius committed Dec 24, 2024
1 parent d171961 commit dadee7e
Show file tree
Hide file tree
Showing 14 changed files with 144 additions and 141 deletions.
56 changes: 19 additions & 37 deletions src/Camera.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import { mat4, vec3, vec4, quat, ReadonlyVec3, ReadonlyMat4, ReadonlyVec4 } from 'gl-matrix';
import InputManager from './InputManager.js';
import { Frustum, AABB } from './Geometry.js';
import { clampRange, projectionMatrixForFrustum, computeUnitSphericalCoordinates, projectionMatrixForCuboid, lerpAngle, MathConstants, getMatrixAxisY, transformVec3Mat4w1, Vec3Zero, Vec3UnitY, Vec3UnitX, Vec3UnitZ, transformVec3Mat4w0, getMatrixAxisZ, getMatrixAxisX, computeEulerAngleRotationFromSRTMatrix } from './MathHelpers.js';
import { clampRange, projectionMatrixForFrustum, calcUnitSphericalCoordinates, projectionMatrixForCuboid, lerpAngle, MathConstants, getMatrixAxisY, transformVec3Mat4w1, Vec3Zero, Vec3UnitY, Vec3UnitX, Vec3UnitZ, transformVec3Mat4w0, getMatrixAxisZ, getMatrixAxisX, calcEulerAngleRotationFromSRTMatrix } from './MathHelpers.js';
import { projectionMatrixConvertClipSpaceNearZ } from './gfx/helpers/ProjectionHelpers.js';
import { WebXRContext } from './WebXR.js';
import { assert } from './util.js';
Expand Down Expand Up @@ -137,14 +137,13 @@ const scratchVec3c = vec3.create();
const scratchVec3d = vec3.create();
const scratchVec3e = vec3.create();
const scratchVec3f = vec3.create();
const scratchVec4 = vec4.create();
const scratchMat4 = mat4.create();
const scratchQuat = quat.create();

/**
* Computes a view-space depth given @param viewMatrix and @param aabb in world-space.
* Computes a view-space depth given {@param viewMatrix} and {@param aabb} in world-space.
*
* This is computed by taking the depth of the center of the passed-in @param aabb.
* This is computed by taking the depth of the center of the passed-in {@param aabb}.
*
* The convention of "view-space depth" is that 0 is near plane, +z is further away.
*
Expand All @@ -160,11 +159,11 @@ export function computeViewSpaceDepthFromWorldSpaceAABB(viewMatrix: ReadonlyMat4
}

/**
* Computes a view-space depth given @param viewMatrix and @param v in world-space.
* Computes a view-space depth given {@param viewMatrix} and {@param v} in world-space.
*
* The convention of "view-space depth" is that 0 is near plane, +z is further away.
*
* The returned value is not clamped to the near or far planes -- that is, the depth
* The returned value is not clamped to the near or far planes — that is, the depth
* value is less than zero if the camera is behind the point.
*
* The returned value can be passed directly to {@see GfxRenderInst.setSortKeyDepth},
Expand All @@ -185,10 +184,10 @@ export class ScreenSpaceProjection {
// These values are in "flat clip space" (that is, -1 corresponds to the left frustum plane,
// and +1 corresponds to the right frustum plane). If the projected area extends beyond these
// planes, then these values might go less than -1 or greater than +1. This is normal.
public projectedMinX!: number;
public projectedMinY!: number;
public projectedMaxX!: number;
public projectedMaxY!: number;
public projectedMinX: number;
public projectedMinY: number;
public projectedMaxX: number;
public projectedMaxY: number;

constructor() {
this.reset();
Expand Down Expand Up @@ -221,40 +220,25 @@ export class ScreenSpaceProjection {
}
}

/**
* Transforms the world-space point @param p, viewed by the camera @param Camera into
* normalized clip space and stores the result in @param output. Note that this is normalized
* clip space (between -1 and 1 on all three axes). Conversion into screen or viewport space
* is not done in this function.
*/
export function computeClipSpacePointFromWorldSpacePoint(output: vec3, camera: Camera, p: ReadonlyVec3, v4 = scratchVec4): void {
vec4.set(v4, p[0], p[1], p[2], 1.0);
vec4.transformMat4(v4, v4, camera.clipFromWorldMatrix);
const w = v4[3];
vec3.set(output, v4[0] / w, v4[1] / w, v4[2] / w);
}

/**
* Computes the screen-space projection @param screenSpaceProjection, that
* a sphere in world-space coordinates with parameters @param center and @param radius
* will take up when viewed by @param camera.
*/
export function computeScreenSpaceProjectionFromWorldSpaceSphere(screenSpaceProjection: ScreenSpaceProjection, camera: Camera, center: ReadonlyVec3, radius: number, v: vec3 = scratchVec3a, v4: vec4 = scratchVec4): void {
export function calcScreenSpaceProjectionFromWorldSpaceSphere(screenSpaceProjection: ScreenSpaceProjection, camera: Camera, center: ReadonlyVec3, radius: number): void {
screenSpaceProjection.reset();

const v = scratchVec3a;
transformVec3Mat4w1(v, camera.viewMatrix, center);

v[2] = -Math.max(Math.abs(v[2] - radius), camera.near);

const viewCenterX = v[0], viewCenterY = v[1], viewCenterZ = v[2];

// Compute the corners of screen-space square that encloses the sphere.
for (let xs = -1; xs <= 1; xs += 2) {
for (let ys = -1; ys <= 1; ys += 2) {
vec4.set(v4, viewCenterX + radius*xs, viewCenterY + radius*ys, viewCenterZ, 1.0);
vec4.transformMat4(v4, v4, camera.projectionMatrix);
divideByW(v4, v4);
screenSpaceProjection.union(v4[0], v4[1]);
vec3.set(v, viewCenterX + radius*xs, viewCenterY + radius*ys, viewCenterZ);
vec3.transformMat4(v, v, camera.projectionMatrix);
screenSpaceProjection.union(v[0], v[1]);
}
}
}
Expand All @@ -263,13 +247,11 @@ export function computeScreenSpaceProjectionFromWorldSpaceSphere(screenSpaceProj
* Computes the screen-space projection @param screenSpaceProjection, that
* world-space AABB @param aabb will take up when viewed by @param camera.
*/
export function computeScreenSpaceProjectionFromWorldSpaceAABB(screenSpaceProjection: ScreenSpaceProjection, camera: Camera, aabb: AABB, v: vec3 = scratchVec3a, v4: vec4 = scratchVec4): void {
export function calcScreenSpaceProjectionFromWorldSpaceAABB(screenSpaceProjection: ScreenSpaceProjection, camera: Camera, aabb: AABB): void {
const radius = aabb.boundingSphereRadius();

// Compute view-space center.
aabb.centerPoint(v);

return computeScreenSpaceProjectionFromWorldSpaceSphere(screenSpaceProjection, camera, v, radius, v, v4);
aabb.centerPoint(scratchVec3a);
return calcScreenSpaceProjectionFromWorldSpaceSphere(screenSpaceProjection, camera, scratchVec3a, radius);
}

export const enum CameraUpdateResult {
Expand Down Expand Up @@ -790,7 +772,7 @@ export class OrbitCameraController implements CameraController {
vec3.scaleAndAdd(this.translation, this.translation, scratchVec3a, this.tyVel);

const eyePos = scratchVec3a;
computeUnitSphericalCoordinates(eyePos, this.x, this.y);
calcUnitSphericalCoordinates(eyePos, this.x, this.y);
vec3.scale(eyePos, eyePos, this.z);
vec3.add(eyePos, eyePos, this.translation);
this.camera.isOrthographic = false;
Expand Down Expand Up @@ -968,7 +950,7 @@ export class OrthoCameraController implements CameraController {

const eyePos = scratchVec3a;

computeUnitSphericalCoordinates(eyePos, this.x, this.y);
calcUnitSphericalCoordinates(eyePos, this.x, this.y);
vec3.scale(eyePos, eyePos, -this.farPlane / 2);
vec3.add(eyePos, eyePos, this.translation);
mat4.targetTo(this.camera.worldMatrix, eyePos, this.translation, Vec3UnitY);
Expand Down
4 changes: 2 additions & 2 deletions src/MathHelpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -385,7 +385,7 @@ export function projectionMatrixForCuboid(m: mat4, left: number, right: number,
m[15] = 1;
}

export function computeEulerAngleRotationFromSRTMatrix(dst: vec3, m: ReadonlyMat4): void {
export function calcEulerAngleRotationFromSRTMatrix(dst: vec3, m: ReadonlyMat4): void {
// "Euler Angle Conversion", Ken Shoemake, Graphics Gems IV. http://www.gregslabaugh.net/publications/euler.pdf

if (compareEpsilon(m[2], 1.0)) {
Expand All @@ -403,7 +403,7 @@ export function computeEulerAngleRotationFromSRTMatrix(dst: vec3, m: ReadonlyMat
}
}

export function computeUnitSphericalCoordinates(dst: vec3, azimuthal: number, polar: number): void {
export function calcUnitSphericalCoordinates(dst: vec3, azimuthal: number, polar: number): void {
// https://en.wikipedia.org/wiki/Spherical_coordinate_system
// https://en.wikipedia.org/wiki/List_of_common_coordinate_transformations#From_spherical_coordinates
// Wikipedia uses the convention of Z-up, we use Y-up here.
Expand Down
8 changes: 4 additions & 4 deletions src/Studio.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { FloatingPanel } from './DebugFloaters.js';
import { drawWorldSpaceLine, drawWorldSpacePoint, getDebugOverlayCanvas2D } from './DebugJunk.js';
import { Blue, Color, Green, Red, Magenta, Cyan } from './Color.js';
import { StudioCameraController } from './Camera.js';
import { clamp, computeEulerAngleRotationFromSRTMatrix, getMatrixAxisZ, lerp, invlerp, Vec3UnitY, Vec3Zero, MathConstants } from './MathHelpers.js';
import { clamp, calcEulerAngleRotationFromSRTMatrix, getMatrixAxisZ, lerp, invlerp, Vec3UnitY, Vec3Zero, MathConstants } from './MathHelpers.js';
import { mat4, ReadonlyMat4, vec3, vec2 } from 'gl-matrix';
import { GlobalSaveManager } from './SaveManager.js';
import { getPointHermite } from './Spline.js';
Expand Down Expand Up @@ -2479,7 +2479,7 @@ export class StudioPanel extends FloatingPanel {
} else {
mat4.rotateZ(this.scratchMat, this.scratchMat, this.animationPreviewSteps[i].bank);
}
computeEulerAngleRotationFromSRTMatrix(this.scratchVec3a, this.scratchMat);
calcEulerAngleRotationFromSRTMatrix(this.scratchVec3a, this.scratchMat);
vec3.copy(this.scratchVec3c, Vec3UnitY);
vec3.rotateZ(this.scratchVec3c, this.scratchVec3c, Vec3Zero, -this.scratchVec3a[2]);
vec3.rotateY(this.scratchVec3c, this.scratchVec3c, Vec3Zero, -this.scratchVec3a[1]);
Expand Down Expand Up @@ -2511,7 +2511,7 @@ export class StudioPanel extends FloatingPanel {
} else {
mat4.rotateZ(this.scratchMat, this.scratchMat, this.animationPreviewSteps[stepIndex].bank);
}
computeEulerAngleRotationFromSRTMatrix(this.scratchVec3a, this.scratchMat);
calcEulerAngleRotationFromSRTMatrix(this.scratchVec3a, this.scratchMat);
vec3.copy(this.scratchVec3c, Vec3UnitY);
vec3.rotateZ(this.scratchVec3c, this.scratchVec3c, Vec3Zero, -this.scratchVec3a[2]);
vec3.rotateY(this.scratchVec3c, this.scratchVec3c, Vec3Zero, -this.scratchVec3a[1]);
Expand Down Expand Up @@ -3603,7 +3603,7 @@ export class StudioPanel extends FloatingPanel {
const lookAtYKf: Keyframe = { time: t, value: this.scratchVecLook[1], tangentIn: 0, tangentOut: 0, interpInType: interpType, interpOutType: interpType, easeInCoeff: 1, easeOutCoeff: 1 };
const lookAtZKf: Keyframe = { time: t, value: this.scratchVecLook[2], tangentIn: 0, tangentOut: 0, interpInType: interpType, interpOutType: interpType, easeInCoeff: 1, easeOutCoeff: 1 };

computeEulerAngleRotationFromSRTMatrix(this.scratchVecPos, mat);
calcEulerAngleRotationFromSRTMatrix(this.scratchVecPos, mat);
vec3.copy(this.scratchVecLook, Vec3UnitY);
vec3.rotateZ(this.scratchVecLook, this.scratchVecLook, Vec3Zero, -this.scratchVecPos[2]);
vec3.rotateY(this.scratchVecLook, this.scratchVecLook, Vec3Zero, -this.scratchVecPos[1]);
Expand Down
8 changes: 4 additions & 4 deletions src/SuperMarioGalaxy/Actors/Enemy.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

import { mat4, quat, ReadonlyMat4, ReadonlyQuat, ReadonlyVec3, vec3 } from 'gl-matrix';
import { GfxRenderInstManager } from '../../gfx/render/GfxRenderInstManager.js';
import { clamp, computeEulerAngleRotationFromSRTMatrix, computeModelMatrixR, computeModelMatrixT, getMatrixAxisX, getMatrixAxisY, getMatrixAxisZ, getMatrixTranslation, invlerp, isNearZero, isNearZeroVec3, lerp, lerpAngle, MathConstants, normToLength, normToLengthAndAdd, quatFromEulerRadians, saturate, scaleMatrix, setMatrixTranslation, transformVec3Mat4w0, transformVec3Mat4w1, vec3SetAll, Vec3UnitX, Vec3UnitY, Vec3UnitZ, Vec3Zero } from '../../MathHelpers.js';
import { clamp, calcEulerAngleRotationFromSRTMatrix, computeModelMatrixR, computeModelMatrixT, getMatrixAxisX, getMatrixAxisY, getMatrixAxisZ, getMatrixTranslation, invlerp, isNearZero, isNearZeroVec3, lerp, lerpAngle, MathConstants, normToLength, normToLengthAndAdd, quatFromEulerRadians, saturate, scaleMatrix, setMatrixTranslation, transformVec3Mat4w0, transformVec3Mat4w1, vec3SetAll, Vec3UnitX, Vec3UnitY, Vec3UnitZ, Vec3Zero } from '../../MathHelpers.js';
import { assert, assertExists, fallback, nArray } from '../../util.js';
import * as Viewer from '../../viewer.js';
import { addVelocityFromPush, addVelocityFromPushHorizon, addVelocityMoveToDirection, addVelocityToGravity, appearStarPiece, attenuateVelocity, blendQuatUpFront, calcDistanceToPlayer, calcFrontVec, calcGravity, calcGravityVector, calcMtxFromGravityAndZAxis, calcNearestRailPos, calcNearestRailDirection, calcPerpendicFootToLine, calcRailPointPos, calcRailStartPos, calcSqDistanceToPlayer, calcUpVec, calcVelocityMoveToDirection, connectToScene, connectToSceneCollisionEnemyNoShadowedMapObjStrongLight, connectToSceneCollisionEnemyStrongLight, connectToSceneEnemy, connectToSceneEnemyMovement, connectToSceneIndirectEnemy, declareStarPiece, excludeCalcShadowToMyCollision, FixedPosition, getBckFrameMax, getBrkFrameMax, getCamYdir, getCamZdir, getCurrentRailPointArg0, getEaseInOutValue, getEaseInValue, getGroupFromArray, getJointMtxByName, getPlayerPos, getRailDirection, getRailPointNum, getRandomInt, getRandomVector, hideModel, initCollisionParts, initDefaultPos, invalidateShadowAll, isActionEnd, isBckOneTimeAndStopped, isBckPlaying, isBckStopped, isBrkStopped, isBtpStopped, isHiddenModel, isInDeath, isNearPlayer, isNearPlayerPose, isOnSwitchA, isSameDirection, isValidSwitchA, isValidSwitchAppear, isValidSwitchB, isValidSwitchDead, joinToGroupArray, listenStageSwitchOnOffA, listenStageSwitchOnOffB, makeMtxFrontUp, makeMtxFrontUpPos, makeMtxTRFromQuatVec, makeMtxUpFront, makeMtxUpFrontPos, makeMtxUpNoSupportPos, makeQuatFromVec, makeQuatUpFront, moveCoordAndFollowTrans, moveCoordAndTransToNearestRailPos, moveCoordAndTransToRailStartPoint, moveCoordToRailPoint, moveCoordToStartPos, moveTransToCurrentRailPos, quatFromMat4, quatGetAxisX, quatGetAxisY, quatGetAxisZ, quatSetRotate, reboundVelocityFromCollision, reboundVelocityFromEachCollision, restrictVelocity, reverseRailDirection, rotateQuatRollBall, sendMsgPushAndKillVelocityToTarget, setBckFrameAndStop, setBckRate, setBrkFrameAndStop, setBvaRate, setRailCoord, setRailCoordSpeed, setRailDirectionToEnd, showModel, startAction, startBck, startBckNoInterpole, startBckWithInterpole, startBpk, startBrk, startBtk, startBtp, startBtpIfExist, startBva, syncStageSwitchAppear, tryStartBck, turnVecToVecCos, turnVecToVecCosOnPlane, useStageSwitchReadAppear, useStageSwitchSleep, useStageSwitchWriteA, useStageSwitchWriteB, useStageSwitchWriteDead, validateShadowAll, vecKillElement, setBtkFrameAndStop, getBckFrame, setBckFrame, isRailReachedGoal, isRailReachedNearGoal, setRailDirectionToStart, moveCoordToNearestPos, moveTransToOtherActorRailPos, moveCoord, calcNearestRailPosAndDirection, isLoopRail, isRailGoingToEnd, getRandomFloat, calcVecToPlayerH, calcVecFromPlayerH, calcDistanceToPlayerH, makeQuatSideUp, turnQuatYDirRad, setMtxQuat, calcRailEndPointDirection, rotateVecDegree, calcSideVec, connectToSceneMapObj, makeMtxSideUp, makeMtxSideFront, appearStarPieceToDirection, isNearPlayerAnyTime, addVelocityMoveToTarget, addVelocityAwayFromTarget, blendMtx, getRailPos, getRailTotalLength, connectToSceneMapObjDecorationStrongLight, connectToSceneMapObjMovement, getRailCoord, calcRailPosAtCoord, calcRailDirectionAtCoord, moveRailRider, getCurrentRailPointNo, getNextRailPointNo, moveCoordAndTransToRailPoint, getBckFrameMaxNamed, clampVecAngleDeg, connectToSceneEnvironment, isBtkExist, isBtkStopped, clampVecAngleRad, connectToSceneEnemyDecorationMovementCalcAnim, isExistRail, getRailPointArg0, getRailPointCoord, calcReboundVelocity, calcReboundVelocitySimple, calcNerveEaseInOutValue } from '../ActorUtil.js';
Expand Down Expand Up @@ -1388,7 +1388,7 @@ export class Unizo extends LiveActor<UnizoNrv> {
getCamZdir(scratchVec3b, sceneObjHolder.viewerInput.camera);
vec3.negate(scratchVec3b, scratchVec3b);
makeMtxFrontUp(scratchMatrix, scratchVec3b, scratchVec3a);
computeEulerAngleRotationFromSRTMatrix(this.breakModel.rotation, scratchMatrix);
calcEulerAngleRotationFromSRTMatrix(this.breakModel.rotation, scratchMatrix);
this.breakModel.makeActorAppeared(sceneObjHolder);

hideModel(this);
Expand Down Expand Up @@ -4508,7 +4508,7 @@ function calcRotate(actor: LiveActor, front: ReadonlyVec3, turnSpeedDegrees: num
vec3.copy(scratchVec3a, scratchVec3b);

makeMtxUpFront(scratchMatrix, scratchVec3a, scratchVec3c);
computeEulerAngleRotationFromSRTMatrix(actor.rotation, scratchMatrix);
calcEulerAngleRotationFromSRTMatrix(actor.rotation, scratchMatrix);
}

function moveAndTurnToTarget(actor: LiveActor, target: ReadonlyVec3, moveSpeed: number, gravitySpeed: number, velocityDamp: number, turnSpeedDegrees: number): void {
Expand Down Expand Up @@ -7109,7 +7109,7 @@ export class Mogucchi extends LiveActor<MogucchiNrv> {
getRailDirection(scratchVec3a, this);
vec3.negate(scratchVec3b, this.gravityStrikeVec);
makeMtxUpFront(scratchMatrix, scratchVec3b, scratchVec3a);
computeEulerAngleRotationFromSRTMatrix(this.rotation, scratchMatrix);
calcEulerAngleRotationFromSRTMatrix(this.rotation, scratchMatrix);
}

public override makeActorAppeared(sceneObjHolder: SceneObjHolder): void {
Expand Down
Loading

0 comments on commit dadee7e

Please sign in to comment.