diff --git a/packages/core/src/Camera.ts b/packages/core/src/Camera.ts index cb26b35e42..b82ae00e4a 100644 --- a/packages/core/src/Camera.ts +++ b/packages/core/src/Camera.ts @@ -436,9 +436,9 @@ export class Camera extends Component { const transform = this.entity.transform; Matrix.multiply(this.projectionMatrix, this.viewMatrix, virtualCamera.viewProjectionMatrix); - virtualCamera.forward.copyFrom(transform.worldPosition); + virtualCamera.position.copyFrom(transform.worldPosition); if (virtualCamera.isOrthographic) { - transform.getWorldForward(virtualCamera.forward); + virtualCamera.forward.copyFrom(transform.worldForward); } context.camera = this; diff --git a/packages/core/src/Transform.ts b/packages/core/src/Transform.ts index 2426853c8d..867f3e8204 100644 --- a/packages/core/src/Transform.ts +++ b/packages/core/src/Transform.ts @@ -1,6 +1,6 @@ import { MathUtil, Matrix, Matrix3x3, Quaternion, Vector3 } from "@oasis-engine/math"; import { BoolUpdateFlag } from "./BoolUpdateFlag"; -import { assignmentClone, deepClone, ignoreClone } from "./clone/CloneManager"; +import { deepClone, ignoreClone } from "./clone/CloneManager"; import { Component } from "./Component"; import { Entity } from "./Entity"; import { UpdateFlagManager } from "./UpdateFlagManager"; @@ -39,6 +39,13 @@ export class Transform extends Component { private _localMatrix: Matrix = new Matrix(); @deepClone private _worldMatrix: Matrix = new Matrix(); + @ignoreClone + private _worldForward: Vector3 = null; + @ignoreClone + private _worldRight: Vector3 = null; + @ignoreClone + private _worldUp: Vector3 = null; + @ignoreClone private _isParentDirty: boolean = true; @ignoreClone @@ -403,36 +410,33 @@ export class Transform extends Component { } /** - * Get the forward direction in world space. - * @param forward - Forward vector - * @returns Forward vector + * The forward direction in world space. */ - getWorldForward(forward: Vector3): Vector3 { + get worldForward(): Vector3 { + const worldForward = (this._worldForward ||= new Vector3()); const e = this.worldMatrix.elements; - forward.set(-e[8], -e[9], -e[10]); - return forward.normalize(); + worldForward.set(-e[8], -e[9], -e[10]); + return worldForward.normalize(); } /** - * Get the right direction in world space. - * @param right - Right vector - * @returns Right vector + * The right direction in world space. */ - getWorldRight(right: Vector3): Vector3 { + get worldRight(): Vector3 { + const worldRight = (this._worldRight ||= new Vector3()); const e = this.worldMatrix.elements; - right.set(e[0], e[1], e[2]); - return right.normalize(); + worldRight.set(e[0], e[1], e[2]); + return worldRight.normalize(); } /** - * Get the up direction in world space. - * @param up - Up vector - * @returns Up vector + * The up direction in world space. */ - getWorldUp(up: Vector3): Vector3 { + get worldUp(): Vector3 { + const worldUp = (this._worldUp ||= new Vector3()); const e = this.worldMatrix.elements; - up.set(e[4], e[5], e[6]); - return up.normalize(); + worldUp.set(e[4], e[5], e[6]); + return worldUp.normalize(); } /** diff --git a/packages/core/src/lighting/DirectLight.ts b/packages/core/src/lighting/DirectLight.ts index 5623f08a2f..4ad99bdb04 100644 --- a/packages/core/src/lighting/DirectLight.ts +++ b/packages/core/src/lighting/DirectLight.ts @@ -25,16 +25,13 @@ export class DirectLight extends Light { shaderData.setFloatArray(DirectLight._directionProperty, data.direction); } - private _forward: Vector3 = new Vector3(); - private _reverseDirection: Vector3 = new Vector3(); /** * Get direction. */ get direction(): Vector3 { - this.entity.transform.getWorldForward(this._forward); - return this._forward; + return this.entity.transform.worldForward; } /** diff --git a/packages/core/src/lighting/SpotLight.ts b/packages/core/src/lighting/SpotLight.ts index f35c1d6eec..0aee9ea1e8 100644 --- a/packages/core/src/lighting/SpotLight.ts +++ b/packages/core/src/lighting/SpotLight.ts @@ -44,7 +44,6 @@ export class SpotLight extends Light { /** Angle, in radians, from falloff begins to ends. */ penumbra: number = Math.PI / 12; - private _forward: Vector3 = new Vector3(); private _inverseDirection: Vector3 = new Vector3(); private _projectMatrix: Matrix = new Matrix(); @@ -59,8 +58,7 @@ export class SpotLight extends Light { * Get light direction. */ get direction(): Vector3 { - this.entity.transform.getWorldForward(this._forward); - return this._forward; + return this.entity.transform.worldForward; } /** diff --git a/packages/core/src/shadow/CascadedShadowCasterPass.ts b/packages/core/src/shadow/CascadedShadowCasterPass.ts index 218e2f8ebb..9a4845b78d 100644 --- a/packages/core/src/shadow/CascadedShadowCasterPass.ts +++ b/packages/core/src/shadow/CascadedShadowCasterPass.ts @@ -135,7 +135,8 @@ export class CascadedShadowCasterPass { lightSide.set(lightWorldE[0], lightWorldE[1], lightWorldE[2]); lightUp.set(lightWorldE[4], lightWorldE[5], lightWorldE[6]); lightForward.set(-lightWorldE[8], -lightWorldE[9], -lightWorldE[10]); - camera.entity.transform.getWorldForward(CascadedShadowCasterPass._tempVector); + const cameraForward = CascadedShadowCasterPass._tempVector; + cameraForward.copyFrom(camera.entity.transform.worldForward); const shadowTileResolution = this._shadowTileResolution; @@ -144,7 +145,7 @@ export class CascadedShadowCasterPass { splitDistance[j], splitDistance[j + 1], camera, - CascadedShadowCasterPass._tempVector.normalize(), + cameraForward, shadowSliceData ); ShadowUtils.getDirectionLightShadowCullPlanes( @@ -202,7 +203,7 @@ export class CascadedShadowCasterPass { const { x, y } = viewports[j]; rhi.setGlobalDepthBias(1.0, 1.0); - + rhi.viewport(x, y, shadowTileResolution, shadowTileResolution); // for no cascade is for the edge,for cascade is for the beyond maxCascade pixel can use (0,0,0) trick sample the shadowMap rhi.scissor(x + 1, y + 1, shadowTileResolution - 2, shadowTileResolution - 2); diff --git a/tests/src/core/Transform.test.ts b/tests/src/core/Transform.test.ts new file mode 100644 index 0000000000..60f3c97b0d --- /dev/null +++ b/tests/src/core/Transform.test.ts @@ -0,0 +1,26 @@ +import { MathUtil, Matrix, Ray, Vector2, Vector3, Vector4 } from "@oasis-engine/math"; +import { WebGLEngine } from "@oasis-engine/rhi-webgl"; +import { Camera, Entity } from "@oasis-engine/core"; +import { expect } from "chai"; + +const canvasDOM = document.createElement("canvas"); +canvasDOM.width = 1024; +canvasDOM.height = 1024; + +describe("Transform test", function () { + let entity: Entity; + before(() => { + const engine = new WebGLEngine(canvasDOM); + entity = engine.sceneManager.activeScene.createRootEntity(); + }); + + it("World direction", () => { + const transform = entity.transform; + transform.position.set(1, -2, 3); + transform.rotate(0, 45, 0); + + expect(transform.worldForward).to.deep.equal(new Vector3(-0.7071067811865476, -0, -0.7071067811865476)); + expect(transform.worldRight).to.deep.equal(new Vector3(0.7071067811865476, 0, -0.7071067811865476)); + expect(transform.worldUp).to.deep.equal(new Vector3(0, 1, 0)); + }); +});