From e6273fcc928caec81ec30b38e640e1386b885196 Mon Sep 17 00:00:00 2001 From: James Chen Date: Thu, 6 Feb 2025 19:47:02 +0800 Subject: [PATCH 1/2] Optimize code size once more. (#18267) --- cocos/2d/assets/sprite-frame.ts | 13 +- cocos/asset/asset-manager/builtin-res-mgr.ts | 11 +- cocos/asset/asset-manager/depend-util.ts | 2 +- cocos/asset/assets/material.jsb.ts | 2 +- cocos/asset/assets/material.ts | 6 +- cocos/core/geometry/aabb.ts | 8 +- cocos/core/geometry/obb.ts | 8 +- cocos/core/geometry/spline.ts | 64 +++---- cocos/core/math/mat4.ts | 12 +- cocos/core/math/utils.ts | 32 ++-- cocos/core/math/vec2.ts | 14 +- cocos/core/math/vec3.ts | 22 ++- cocos/core/math/vec4.ts | 18 +- cocos/game/splash-screen.ts | 173 ++++++++++--------- cocos/profiler/profiler.ts | 23 +-- cocos/render-scene/core/pass.ts | 11 +- cocos/rendering/instanced-buffer.ts | 19 +- cocos/ui/view.ts | 25 +-- 18 files changed, 257 insertions(+), 206 deletions(-) diff --git a/cocos/2d/assets/sprite-frame.ts b/cocos/2d/assets/sprite-frame.ts index 4906ff1fa92..c41c490beeb 100644 --- a/cocos/2d/assets/sprite-frame.ts +++ b/cocos/2d/assets/sprite-frame.ts @@ -45,6 +45,9 @@ const INSET_BOTTOM = 3; const temp_vec3 = v3(); const temp_matrix = mat4(); +const vec3TransformMat4 = Vec3.transformMat4; +const vec3ToArray = Vec3.toArray; + enum MeshType { RECT = 0, POLYGON = 1, // Todo: Polygon mode need add @@ -1214,7 +1217,7 @@ export class SpriteFrame extends Asset { const posArray = []; for (let i = 0; i < this.vertices.rawPosition.length; i++) { const pos = this.vertices.rawPosition[i]; - Vec3.toArray(posArray, pos, 3 * i); + vec3ToArray(posArray, pos, 3 * i); } vertices = { rawPosition: posArray, @@ -1532,11 +1535,11 @@ export class SpriteFrame extends Asset { for (let i = 0; i < vertices.rawPosition.length; i++) { const pos = vertices.rawPosition[i]; - Vec3.transformMat4(temp_vec3, pos, temp_matrix); - Vec3.toArray(vertices.positions, temp_vec3, 3 * i); + vec3TransformMat4(temp_vec3, pos, temp_matrix); + vec3ToArray(vertices.positions, temp_vec3, 3 * i); } - Vec3.transformMat4(this._minPos, vertices.minPos, temp_matrix); - Vec3.transformMat4(this._maxPos, vertices.maxPos, temp_matrix); + vec3TransformMat4(this._minPos, vertices.minPos, temp_matrix); + vec3TransformMat4(this._maxPos, vertices.maxPos, temp_matrix); } protected _createMesh (): void { diff --git a/cocos/asset/asset-manager/builtin-res-mgr.ts b/cocos/asset/asset-manager/builtin-res-mgr.ts index dd3e536a81c..d95d869fbfe 100644 --- a/cocos/asset/asset-manager/builtin-res-mgr.ts +++ b/cocos/asset/asset-manager/builtin-res-mgr.ts @@ -47,12 +47,13 @@ export class BuiltinResMgr { const resources = this._resources; const len = 2; const numChannels = 4; + const byteLength = len * len * numChannels; - const blackValueView = new Uint8Array(len * len * numChannels); - const emptyValueView = new Uint8Array(len * len * numChannels); - const greyValueView = new Uint8Array(len * len * numChannels); - const whiteValueView = new Uint8Array(len * len * numChannels); - const normalValueView = new Uint8Array(len * len * numChannels); + const blackValueView = new Uint8Array(byteLength); + const emptyValueView = new Uint8Array(byteLength); + const greyValueView = new Uint8Array(byteLength); + const whiteValueView = new Uint8Array(byteLength); + const normalValueView = new Uint8Array(byteLength); let offset = 0; for (let i = 0; i < len * len; i++) { diff --git a/cocos/asset/asset-manager/depend-util.ts b/cocos/asset/asset-manager/depend-util.ts index 8f826676aea..77117c2b65a 100644 --- a/cocos/asset/asset-manager/depend-util.ts +++ b/cocos/asset/asset-manager/depend-util.ts @@ -141,7 +141,7 @@ export class DependUtil { * */ public getDepsRecursively (uuid: string): string[] { - const exclude = Object.create(null); + const exclude: Record = Object.create(null); const depends = []; this._descend(uuid, exclude, depends); return depends; diff --git a/cocos/asset/assets/material.jsb.ts b/cocos/asset/assets/material.jsb.ts index 5a4c9e89d78..09fbe591bbf 100644 --- a/cocos/asset/assets/material.jsb.ts +++ b/cocos/asset/assets/material.jsb.ts @@ -73,7 +73,7 @@ interface IMaterialInfo { states?: PassOverrides | PassOverrides[]; } -type MaterialPropertyFull = MaterialProperty | TextureBase | Texture | null; +export type MaterialPropertyFull = MaterialProperty | TextureBase | Texture | null; declare const jsb: any; const matProto: any = jsb.Material.prototype; diff --git a/cocos/asset/assets/material.ts b/cocos/asset/assets/material.ts index 833a370254c..aea9148bab7 100644 --- a/cocos/asset/assets/material.ts +++ b/cocos/asset/assets/material.ts @@ -495,9 +495,9 @@ export class Material extends Asset { pass.resetUniform(name); } } else if (Array.isArray(val)) { - for (let i = 0; i < val.length; i++) { - this._bindTexture(pass, handle, val[i], i); - } + val.forEach((v, i) => { + this._bindTexture(pass, handle, v, i); + }); } else if (val) { this._bindTexture(pass, handle, val); } else { diff --git a/cocos/core/geometry/aabb.ts b/cocos/core/geometry/aabb.ts index 0bf5641cea1..f679a2692b8 100644 --- a/cocos/core/geometry/aabb.ts +++ b/cocos/core/geometry/aabb.ts @@ -36,11 +36,13 @@ const _v3_tmp3 = new Vec3(); const _v3_tmp4 = new Vec3(); const _m3_tmp = new Mat3(); +const mathAbs = Math.abs; + // https://zeuxcg.org/2010/10/17/aabb-from-obb-with-component-wise-abs/ const transform_extent_m4 = (out: Vec3, extent: Vec3, m4: Mat4 | Readonly): void => { - _m3_tmp.m00 = Math.abs(m4.m00); _m3_tmp.m01 = Math.abs(m4.m01); _m3_tmp.m02 = Math.abs(m4.m02); - _m3_tmp.m03 = Math.abs(m4.m04); _m3_tmp.m04 = Math.abs(m4.m05); _m3_tmp.m05 = Math.abs(m4.m06); - _m3_tmp.m06 = Math.abs(m4.m08); _m3_tmp.m07 = Math.abs(m4.m09); _m3_tmp.m08 = Math.abs(m4.m10); + _m3_tmp.m00 = mathAbs(m4.m00); _m3_tmp.m01 = mathAbs(m4.m01); _m3_tmp.m02 = mathAbs(m4.m02); + _m3_tmp.m03 = mathAbs(m4.m04); _m3_tmp.m04 = mathAbs(m4.m05); _m3_tmp.m05 = mathAbs(m4.m06); + _m3_tmp.m06 = mathAbs(m4.m08); _m3_tmp.m07 = mathAbs(m4.m09); _m3_tmp.m08 = mathAbs(m4.m10); Vec3.transformMat3(out, extent, _m3_tmp); }; diff --git a/cocos/core/geometry/obb.ts b/cocos/core/geometry/obb.ts index 177fa9c69da..84b3e3a76c8 100644 --- a/cocos/core/geometry/obb.ts +++ b/cocos/core/geometry/obb.ts @@ -29,11 +29,13 @@ const _v3_tmp = new Vec3(); const _v3_tmp2 = new Vec3(); const _m3_tmp = new Mat3(); +const mathAbs = Math.abs; + // https://zeuxcg.org/2010/10/17/aabb-from-obb-with-component-wise-abs/ const transform_extent_m3 = (out: Vec3, extent: Vec3, m3: Mat3): void => { - _m3_tmp.m00 = Math.abs(m3.m00); _m3_tmp.m01 = Math.abs(m3.m01); _m3_tmp.m02 = Math.abs(m3.m02); - _m3_tmp.m03 = Math.abs(m3.m03); _m3_tmp.m04 = Math.abs(m3.m04); _m3_tmp.m05 = Math.abs(m3.m05); - _m3_tmp.m06 = Math.abs(m3.m06); _m3_tmp.m07 = Math.abs(m3.m07); _m3_tmp.m08 = Math.abs(m3.m08); + _m3_tmp.m00 = mathAbs(m3.m00); _m3_tmp.m01 = mathAbs(m3.m01); _m3_tmp.m02 = mathAbs(m3.m02); + _m3_tmp.m03 = mathAbs(m3.m03); _m3_tmp.m04 = mathAbs(m3.m04); _m3_tmp.m05 = mathAbs(m3.m05); + _m3_tmp.m06 = mathAbs(m3.m06); _m3_tmp.m07 = mathAbs(m3.m07); _m3_tmp.m08 = mathAbs(m3.m08); Vec3.transformMat3(out, extent, _m3_tmp); }; diff --git a/cocos/core/geometry/spline.ts b/cocos/core/geometry/spline.ts index e4b928fc5fa..e5f27cd9542 100644 --- a/cocos/core/geometry/spline.ts +++ b/cocos/core/geometry/spline.ts @@ -22,12 +22,14 @@ THE SOFTWARE. */ -import { JSB } from 'internal:constants'; -import { clamp, Vec3 } from '../math'; +import { clamp, v3, Vec3 } from '../math'; import { assertID, warnID } from '../platform/debug'; import { ShapeType } from './enums'; import { assertsArrayIndex } from '../data/utils/asserts'; +const vec3MultiplyScalar = Vec3.multiplyScalar; +const vec3Add = Vec3.add; + export enum SplineMode { /** * @en @@ -77,10 +79,10 @@ export enum SplineMode { const SPLINE_WHOLE_INDEX = 0xffffffff; -const _v0 = new Vec3(); -const _v1 = new Vec3(); -const _v2 = new Vec3(); -const _v3 = new Vec3(); +const _v0 = v3(); +const _v1 = v3(); +const _v2 = v3(); +const _v3 = v3(); /** * @en @@ -99,7 +101,7 @@ export class Spline { this._mode = mode; for (let i = 0; i < knots.length; i++) { - this._knots[i] = new Vec3(knots[i]); + this._knots[i] = v3(knots[i]); } } @@ -144,7 +146,7 @@ export class Spline { const knots = s.knots; const length = knots.length; for (let i = 0; i < length; i++) { - out._knots[i] = new Vec3(knots[i]); + out._knots[i] = v3(knots[i]); } return out; @@ -193,7 +195,7 @@ export class Spline { this._knots.length = 0; for (let i = 0; i < knots.length; i++) { - this._knots[i] = new Vec3(knots[i]); + this._knots[i] = v3(knots[i]); } } @@ -226,7 +228,7 @@ export class Spline { * @param knot @en The knot to add to this Spline instance. @zh 要添加到当前 Spline 实例的结点。 */ public addKnot (knot: Vec3): void { - this._knots.push(new Vec3(knot)); + this._knots.push(v3(knot)); } /** @@ -238,7 +240,7 @@ export class Spline { * @param knot @en The knot to be inserted. @zh 要插入的结点。 */ public insertKnot (index: number, knot: Vec3): void { - const item = new Vec3(knot); + const item = v3(knot); if (index >= this._knots.length) { this._knots.push(item); return; @@ -302,7 +304,7 @@ export class Spline { const segments = this.getSegments(); if (segments === 0) { - return new Vec3(); + return v3(); } if (index === SPLINE_WHOLE_INDEX) { @@ -315,7 +317,7 @@ export class Spline { const knots = this._knots; if (index >= segments) { - return new Vec3(knots[knots.length - 1]); + return v3(knots[knots.length - 1]); } switch (this._mode) { @@ -331,7 +333,7 @@ export class Spline { return Spline.calcCatmullRom(v0, knots[index], knots[index + 1], v3, t); } default: - return new Vec3(); + return v3(); } } @@ -394,9 +396,9 @@ export class Spline { private static calcLinear (v0: Vec3, v1: Vec3, t: number): Vec3 { const result = new Vec3(); - Vec3.multiplyScalar(_v0, v0, (1.0 - t)); - Vec3.multiplyScalar(_v1, v1, t); - Vec3.add(result, _v0, _v1); + vec3MultiplyScalar(_v0, v0, (1.0 - t)); + vec3MultiplyScalar(_v1, v1, t); + vec3Add(result, _v0, _v1); return result; } @@ -404,13 +406,13 @@ export class Spline { private static calcBezier (v0: Vec3, v1: Vec3, v2: Vec3, v3: Vec3, t: number): Vec3 { const result = new Vec3(); const s = 1.0 - t; - Vec3.multiplyScalar(_v0, v0, s * s * s); - Vec3.multiplyScalar(_v1, v1, 3.0 * t * s * s); - Vec3.multiplyScalar(_v2, v2, 3.0 * t * t * s); - Vec3.multiplyScalar(_v3, v3, t * t * t); - Vec3.add(_v0, _v0, _v1); - Vec3.add(_v2, _v2, _v3); - Vec3.add(result, _v0, _v2); + vec3MultiplyScalar(_v0, v0, s * s * s); + vec3MultiplyScalar(_v1, v1, 3.0 * t * s * s); + vec3MultiplyScalar(_v2, v2, 3.0 * t * t * s); + vec3MultiplyScalar(_v3, v3, t * t * t); + vec3Add(_v0, _v0, _v1); + vec3Add(_v2, _v2, _v3); + vec3Add(result, _v0, _v2); return result; } @@ -418,13 +420,13 @@ export class Spline { const result = new Vec3(); const t2 = t * t; const t3 = t2 * t; - Vec3.multiplyScalar(_v0, v0, -0.5 * t3 + t2 - 0.5 * t); - Vec3.multiplyScalar(_v1, v1, 1.5 * t3 - 2.5 * t2 + 1.0); - Vec3.multiplyScalar(_v2, v2, -1.5 * t3 + 2.0 * t2 + 0.5 * t); - Vec3.multiplyScalar(_v3, v3, 0.5 * t3 - 0.5 * t2); - Vec3.add(_v0, _v0, _v1); - Vec3.add(_v2, _v2, _v3); - Vec3.add(result, _v0, _v2); + vec3MultiplyScalar(_v0, v0, -0.5 * t3 + t2 - 0.5 * t); + vec3MultiplyScalar(_v1, v1, 1.5 * t3 - 2.5 * t2 + 1.0); + vec3MultiplyScalar(_v2, v2, -1.5 * t3 + 2.0 * t2 + 0.5 * t); + vec3MultiplyScalar(_v3, v3, 0.5 * t3 - 0.5 * t2); + vec3Add(_v0, _v0, _v1); + vec3Add(_v2, _v2, _v3); + vec3Add(result, _v0, _v2); return result; } diff --git a/cocos/core/math/mat4.ts b/cocos/core/math/mat4.ts index 9e2da778df8..9fe3549f905 100644 --- a/cocos/core/math/mat4.ts +++ b/cocos/core/math/mat4.ts @@ -35,14 +35,16 @@ import { EPSILON } from './utils'; import { Vec3 } from './vec3'; import { legacyCC } from '../global-exports'; +const objectFreeze = Object.freeze; + /** * @engineInternal */ -export const preTransforms = Object.freeze([ - Object.freeze([1, 0, 0, 1]), // SurfaceTransform.IDENTITY - Object.freeze([0, 1, -1, 0]), // SurfaceTransform.ROTATE_90 - Object.freeze([-1, 0, 0, -1]), // SurfaceTransform.ROTATE_180 - Object.freeze([0, -1, 1, 0]), // SurfaceTransform.ROTATE_270 +export const preTransforms = objectFreeze([ + objectFreeze([1, 0, 0, 1]), // SurfaceTransform.IDENTITY + objectFreeze([0, 1, -1, 0]), // SurfaceTransform.ROTATE_90 + objectFreeze([-1, 0, 0, -1]), // SurfaceTransform.ROTATE_180 + objectFreeze([0, -1, 1, 0]), // SurfaceTransform.ROTATE_270 ]); /** diff --git a/cocos/core/math/utils.ts b/cocos/core/math/utils.ts index 9b036367e8e..9a71fe5c5d0 100644 --- a/cocos/core/math/utils.ts +++ b/cocos/core/math/utils.ts @@ -27,14 +27,18 @@ import * as bits from './bits'; import { ValueType } from '../value-types'; import { IVec3Like } from './type-define'; -const _d2r = Math.PI / 180.0; +const mathAbs = Math.abs; +const mathFloor = Math.floor; +const PI = Math.PI; -const _r2d = 180.0 / Math.PI; +const _d2r = PI / 180.0; + +const _r2d = 180.0 / PI; let _random = Math.random; -export const HALF_PI = Math.PI * 0.5; -export const TWO_PI = Math.PI * 2.0; +export const HALF_PI = PI * 0.5; +export const TWO_PI = PI * 2.0; export const EPSILON = 0.000001; @@ -49,7 +53,7 @@ export const EPSILON = 0.000001; * @return True if the numbers are approximately equal, false otherwise. */ export function equals (a: number, b: number): boolean { - return Math.abs(a - b) <= EPSILON * Math.max(1.0, Math.abs(a), Math.abs(b)); + return mathAbs(a - b) <= EPSILON * Math.max(1.0, mathAbs(a), mathAbs(b)); } /** @@ -62,7 +66,7 @@ export function equals (a: number, b: number): boolean { */ export function approx (a: number, b: number, maxDiff?: number): boolean { maxDiff = maxDiff || EPSILON; - return Math.abs(a - b) <= maxDiff; + return mathAbs(a - b) <= maxDiff; } /** @@ -156,7 +160,7 @@ export function randomRange (min: number, max: number): number { * @return The random integer. */ export function randomRangeInt (min: number, max: number): number { - return Math.floor(randomRange(min, max)); + return mathFloor(randomRange(min, max)); } /** @@ -197,7 +201,7 @@ export function pseudoRandomRange (seed: number, min: number, max: number): numb * @return The random integer. */ export function pseudoRandomRangeInt (seed: number, min: number, max: number): number { - return Math.floor(pseudoRandomRange(seed, min, max)); + return mathFloor(pseudoRandomRange(seed, min, max)); } /** @@ -221,7 +225,7 @@ export function nextPow2 (val: number): number { * @return The Time wrapped in the first cycle. */ export function repeat (t: number, length: number): number { - return t - Math.floor(t / length) * length; + return t - mathFloor(t / length) * length; } /** @@ -236,7 +240,7 @@ export function repeat (t: number, length: number): number { */ export function pingPong (t: number, length: number): number { t = repeat(t, length * 2); - t = length - Math.abs(t - length); + t = length - mathAbs(t - length); return t; } @@ -259,13 +263,13 @@ export function inverseLerp (from: number, to: number, value: number): number { * @returns max absolute component */ export function absMaxComponent (v: IVec3Like): number { - if (Math.abs(v.x) > Math.abs(v.y)) { - if (Math.abs(v.x) > Math.abs(v.z)) { + if (mathAbs(v.x) > mathAbs(v.y)) { + if (mathAbs(v.x) > mathAbs(v.z)) { return v.x; } else { return v.z; } - } else if (Math.abs(v.y) > Math.abs(v.z)) { + } else if (mathAbs(v.y) > mathAbs(v.z)) { return v.y; } else { return v.z; @@ -279,7 +283,7 @@ export function absMaxComponent (v: IVec3Like): number { * @param b number */ export function absMax (a: number, b: number): number { - if (Math.abs(a) > Math.abs(b)) { + if (mathAbs(a) > mathAbs(b)) { return a; } else { return b; diff --git a/cocos/core/math/vec2.ts b/cocos/core/math/vec2.ts index ef6a30400d1..9b4314b702e 100644 --- a/cocos/core/math/vec2.ts +++ b/cocos/core/math/vec2.ts @@ -47,16 +47,20 @@ const ceil = Math.ceil; const floor = Math.floor; const round = Math.round; +function freezeVec2 (x: number, y: number): Readonly { + return Object.freeze(new Vec2(x, y)); +} + /** * @en Representation of 2D vectors and points. * @zh 二维向量。 */ export class Vec2 extends ValueType { - public static ZERO = Object.freeze(new Vec2(0, 0)); - public static ONE = Object.freeze(new Vec2(1, 1)); - public static NEG_ONE = Object.freeze(new Vec2(-1, -1)); - public static UNIT_X = Object.freeze(new Vec2(1, 0)); - public static UNIT_Y = Object.freeze(new Vec2(0, 1)); + public static ZERO = freezeVec2(0, 0); + public static ONE = freezeVec2(1, 1); + public static NEG_ONE = freezeVec2(-1, -1); + public static UNIT_X = freezeVec2(1, 0); + public static UNIT_Y = freezeVec2(0, 1); /** * @en Obtains a clone of the given vector object diff --git a/cocos/core/math/vec3.ts b/cocos/core/math/vec3.ts index a3f8d7084ff..bcf75b3853c 100644 --- a/cocos/core/math/vec3.ts +++ b/cocos/core/math/vec3.ts @@ -45,20 +45,24 @@ const ceil = Math.ceil; const floor = Math.floor; const round = Math.round; +function freezeVec3 (x: number, y: number, z: number): Readonly { + return Object.freeze(new Vec3(x, y, z)); +} + /** * @en Representation of 3D vectors and points. * @zh 三维向量。 */ export class Vec3 extends ValueType { - public static UNIT_X = Object.freeze(new Vec3(1, 0, 0)); - public static UNIT_Y = Object.freeze(new Vec3(0, 1, 0)); - public static UNIT_Z = Object.freeze(new Vec3(0, 0, 1)); - public static RIGHT = Object.freeze(new Vec3(1, 0, 0)); - public static UP = Object.freeze(new Vec3(0, 1, 0)); - public static FORWARD = Object.freeze(new Vec3(0, 0, -1)); // we use -z for view-dir - public static ZERO = Object.freeze(new Vec3(0, 0, 0)); - public static ONE = Object.freeze(new Vec3(1, 1, 1)); - public static NEG_ONE = Object.freeze(new Vec3(-1, -1, -1)); + public static UNIT_X = freezeVec3(1, 0, 0); + public static UNIT_Y = freezeVec3(0, 1, 0); + public static UNIT_Z = freezeVec3(0, 0, 1); + public static RIGHT = freezeVec3(1, 0, 0); + public static UP = freezeVec3(0, 1, 0); + public static FORWARD = freezeVec3(0, 0, -1); // we use -z for view-dir + public static ZERO = freezeVec3(0, 0, 0); + public static ONE = freezeVec3(1, 1, 1); + public static NEG_ONE = freezeVec3(-1, -1, -1); /** * @en return a Vec3 object with x = 0, y = 0, z = 0. diff --git a/cocos/core/math/vec4.ts b/cocos/core/math/vec4.ts index eac0c17a95b..02046f774b4 100644 --- a/cocos/core/math/vec4.ts +++ b/cocos/core/math/vec4.ts @@ -43,18 +43,22 @@ const ceil = Math.ceil; const floor = Math.floor; const round = Math.round; +function freezeVec4 (x: number, y: number, z: number, w: number): Readonly { + return Object.freeze(new Vec4(x, y, z, w)); +} + /** * @en Representation of four-dimensional vectors. * @zh 四维向量。 */ export class Vec4 extends ValueType { - public static ZERO = Object.freeze(new Vec4(0, 0, 0, 0)); - public static ONE = Object.freeze(new Vec4(1, 1, 1, 1)); - public static NEG_ONE = Object.freeze(new Vec4(-1, -1, -1, -1)); - public static UNIT_X = Object.freeze(new Vec4(1, 0, 0, 0)); - public static UNIT_Y = Object.freeze(new Vec4(0, 1, 0, 0)); - public static UNIT_Z = Object.freeze(new Vec4(0, 0, 1, 0)); - public static UNIT_W = Object.freeze(new Vec4(0, 0, 0, 1)); + public static ZERO = freezeVec4(0, 0, 0, 0); + public static ONE = freezeVec4(1, 1, 1, 1); + public static NEG_ONE = freezeVec4(-1, -1, -1, -1); + public static UNIT_X = freezeVec4(1, 0, 0, 0); + public static UNIT_Y = freezeVec4(0, 1, 0, 0); + public static UNIT_Z = freezeVec4(0, 0, 1, 0); + public static UNIT_W = freezeVec4(0, 0, 0, 1); /** * @en Obtains a clone of the given vector object diff --git a/cocos/game/splash-screen.ts b/cocos/game/splash-screen.ts index aa9b004f7d0..e5adca9bc29 100644 --- a/cocos/game/splash-screen.ts +++ b/cocos/game/splash-screen.ts @@ -22,15 +22,13 @@ THE SOFTWARE. */ -import { EDITOR, WECHAT } from 'internal:constants'; -import { Material } from '../asset/assets/material'; +import { EDITOR } from 'internal:constants'; +import { Material, MaterialPropertyFull } from '../asset/assets/material'; import { clamp01, Mat4, Vec2, settings, sys, cclegacy, easing, preTransforms, SettingsCategory } from '../core'; import { Sampler, SamplerInfo, Shader, Texture, TextureInfo, Device, InputAssembler, InputAssemblerInfo, Attribute, Buffer, BufferInfo, Rect, Color, BufferTextureCopy, CommandBuffer, BufferUsageBit, Format, MemoryUsageBit, TextureType, TextureUsageBit, Address, Swapchain, Framebuffer, - DescriptorSetInfo, - DescriptorSet, } from '../gfx'; import { PipelineStateManager } from '../rendering'; import { SetIndex } from '../rendering/define'; @@ -44,6 +42,7 @@ type SplashLogoType = 'default' | 'none' | 'custom'; type SplashBackgroundType = 'default' | 'color' | 'custom'; type WatermarkLocationType = 'default' | 'topLeft' | 'topRight' | 'topCenter' | 'bottomLeft' | 'bottomCenter' | 'bottomRight'; +/** @mangle */ interface ISplashSetting { policy?: number; displayRatio: number; @@ -54,6 +53,7 @@ interface ISplashSetting { background?: SplashBackground; } +/** @mangle */ interface SplashBackground { type: SplashBackgroundType; color?: Color; @@ -61,12 +61,17 @@ interface SplashBackground { base64?: string; } +/** @mangle */ interface SplashLogo { type: SplashLogoType; image?: string; base64?: string; } +function setMaterialProperty (mat: Material, key: string, value: MaterialPropertyFull | MaterialPropertyFull[], passIdx?: number): void { + mat.setProperty(key, value, passIdx); +} + export class SplashScreen { private settings!: ISplashSetting; private _curTime = 0; @@ -193,6 +198,7 @@ export class SplashScreen { const clearColor = this.settings.background?.color; this.clearColors = clearColor ? [new Color(clearColor.x, clearColor.y, clearColor.z, clearColor.w)] : [new Color(0, 0, 0, 1)]; const { device, swapchain } = this; + const { capabilities } = device; this.renderArea = new Rect(0, 0, swapchain.width, swapchain.height); this.cmdBuff = device.commandBuffer; @@ -237,8 +243,8 @@ export class SplashScreen { 1, -1, 1, - device.capabilities.clipSpaceMinZ, - device.capabilities.clipSpaceSignY, + capabilities.clipSpaceMinZ, + capabilities.clipSpaceSignY, swapchain.surfaceTransform, ); @@ -275,7 +281,8 @@ export class SplashScreen { } private initScale (): void { - const dw = this.swapchain.width; const dh = this.swapchain.height; + const dw = this.swapchain.width; + const dh = this.swapchain.height; let desiredWidth = this.isMobile ? 375 : 1080; let desiredHeight = this.isMobile ? 812 : 1920; if (dw > dh) { @@ -293,6 +300,7 @@ export class SplashScreen { public update (deltaTime: number): void { const settings = this.settings; const { device, swapchain } = this; + const { capabilities } = device; Mat4.ortho( this.projection, -1, @@ -301,8 +309,8 @@ export class SplashScreen { 1, -1, 1, - device.capabilities.clipSpaceMinZ, - device.capabilities.clipSpaceSignY, + capabilities.clipSpaceMinZ, + capabilities.clipSpaceSignY, swapchain.surfaceTransform, ); const dw = swapchain.width; const dh = swapchain.height; @@ -314,41 +322,43 @@ export class SplashScreen { let scaleX = 1; let scaleY = 1; + const bgImage = this.bgImage; // update bg uniform - if (this.settings.background!.type === 'custom') { - if (this.settings.policy === ResolutionPolicy.FIXED_WIDTH) { + if (settings.background!.type === 'custom') { + if (settings.policy === ResolutionPolicy.FIXED_WIDTH) { scaleX = dw; - scaleY = (dw / this.bgImage.width) * this.bgImage.height; - } else if (this.settings.policy === ResolutionPolicy.FIXED_HEIGHT) { - scaleX = (dh / this.bgImage.height) * this.bgImage.width; + scaleY = (dw / bgImage.width) * bgImage.height; + } else if (settings.policy === ResolutionPolicy.FIXED_HEIGHT) { + scaleX = (dh / bgImage.height) * bgImage.width; scaleY = dh; - } else if (this.settings.policy === ResolutionPolicy.SHOW_ALL) { - if ((this.bgImage.width / this.bgHeight) > (dw / dh)) { + } else if (settings.policy === ResolutionPolicy.SHOW_ALL) { + if ((bgImage.width / this.bgHeight) > (dw / dh)) { scaleX = dw; - scaleY = (dw / this.bgImage.width) * this.bgImage.height; + scaleY = (dw / bgImage.width) * bgImage.height; } else { - scaleX = (dh / this.bgImage.height) * this.bgImage.width; + scaleX = (dh / bgImage.height) * bgImage.width; scaleY = dh; } - } else if (this.settings.policy === ResolutionPolicy.NO_BORDER) { - if ((this.bgImage.width / this.bgImage.height) > (dw / dh)) { - scaleX = (dh / this.bgImage.height) * this.bgImage.width; + } else if (settings.policy === ResolutionPolicy.NO_BORDER) { + if ((bgImage.width / bgImage.height) > (dw / dh)) { + scaleX = (dh / bgImage.height) * bgImage.width; scaleY = dh; } else { scaleX = dw; - scaleY = (dw / this.bgImage.width) * this.bgImage.height; + scaleY = (dw / bgImage.width) * bgImage.height; } } else { scaleX = dw; scaleY = dh; } - this.bgMat.setProperty('resolution', v2_0.set(dw, dh), 0); - this.bgMat.setProperty('scale', v2_0.set(scaleX, scaleY), 0); - this.bgMat.setProperty('translate', v2_0.set(dw * 0.5, dh * 0.5), 0); - this.bgMat.setProperty('percent', 1.0); - this.bgMat.setProperty('u_projection', this.projection); - this.bgMat.passes[0].update(); + const bgMat = this.bgMat; + setMaterialProperty(bgMat, 'resolution', v2_0.set(dw, dh), 0); + setMaterialProperty(bgMat, 'scale', v2_0.set(scaleX, scaleY), 0); + setMaterialProperty(bgMat, 'translate', v2_0.set(dw * 0.5, dh * 0.5), 0); + setMaterialProperty(bgMat, 'percent', 1.0); + setMaterialProperty(bgMat, 'u_projection', this.projection); + bgMat.passes[0].update(); } // update logo uniform const logoYTrans = dh * this.logoYTrans; @@ -356,12 +366,13 @@ export class SplashScreen { // Product design is 0.185 of the height of the screen resolution as the display height of the logo. scaleY = dh * 0.185 * settings.displayRatio; scaleX = this.logoWidth * (dh * 0.185 / this.logoHeight) * settings.displayRatio; - this.logoMat.setProperty('resolution', v2_0.set(dw, dh), 0); - this.logoMat.setProperty('scale', v2_0.set(scaleX, scaleY), 0); - this.logoMat.setProperty('translate', v2_0.set(dw * this.logoXTrans, logoYTrans), 0); - this.logoMat.setProperty('percent', u_p); - this.logoMat.setProperty('u_projection', this.projection); - this.logoMat.passes[0].update(); + const logoMat = this.logoMat; + setMaterialProperty(logoMat, 'resolution', v2_0.set(dw, dh), 0); + setMaterialProperty(logoMat, 'scale', v2_0.set(scaleX, scaleY), 0); + setMaterialProperty(logoMat, 'translate', v2_0.set(dw * this.logoXTrans, logoYTrans), 0); + setMaterialProperty(logoMat, 'percent', u_p); + setMaterialProperty(logoMat, 'u_projection', this.projection); + logoMat.passes[0].update(); } // update watermark uniform @@ -371,12 +382,13 @@ export class SplashScreen { scaleY = watermarkTH; const textYTrans = logoYTrans - (this.logoHeight * 0.5 * settings.displayRatio + this.textYExtraTrans) * this.scaleSize - watermarkTH * 0.5; - this.watermarkMat.setProperty('resolution', v2_0.set(dw, dh), 0); - this.watermarkMat.setProperty('scale', v2_0.set(scaleX, scaleY), 0); - this.watermarkMat.setProperty('translate', v2_0.set(dw * this.textXTrans, textYTrans), 0); - this.watermarkMat.setProperty('percent', u_p); - this.watermarkMat.setProperty('u_projection', this.projection); - this.watermarkMat.passes[0].update(); + const watermarkMat = this.watermarkMat; + setMaterialProperty(watermarkMat, 'resolution', v2_0.set(dw, dh), 0); + setMaterialProperty(watermarkMat, 'scale', v2_0.set(scaleX, scaleY), 0); + setMaterialProperty(watermarkMat, 'translate', v2_0.set(dw * this.textXTrans, textYTrans), 0); + setMaterialProperty(watermarkMat, 'percent', u_p); + setMaterialProperty(watermarkMat, 'u_projection', this.projection); + watermarkMat.passes[0].update(); } this.frame(); } @@ -409,9 +421,10 @@ export class SplashScreen { descriptorSet.bindSampler(binding, this.sampler); descriptorSet.update(); const region = new BufferTextureCopy(); - region.texExtent.width = this.bgImage.width; - region.texExtent.height = this.bgImage.height; - region.texExtent.depth = 1; + const regionTexExtent = region.texExtent; + regionTexExtent.width = this.bgImage.width; + regionTexExtent.height = this.bgImage.height; + regionTexExtent.depth = 1; device.copyTexImagesToTexture([this.bgImage], this.bgTexture, [region]); } @@ -443,9 +456,10 @@ export class SplashScreen { descriptorSet.bindSampler(binding, this.sampler); descriptorSet.update(); const region = new BufferTextureCopy(); - region.texExtent.width = this.logoImage.width; - region.texExtent.height = this.logoImage.height; - region.texExtent.depth = 1; + const regionTexExtent = region.texExtent; + regionTexExtent.width = this.logoImage.width; + regionTexExtent.height = this.logoImage.height; + regionTexExtent.depth = 1; device.copyTexImagesToTexture([this.logoImage], this.logoTexture, [region]); const logoRatio = this.logoImage.width / this.logoImage.height; @@ -473,9 +487,10 @@ export class SplashScreen { ctx.font = `${this.textSize * this.scaleSize}px Arial`; ctx.textBaseline = 'top'; ctx.textAlign = 'center'; ctx.fillStyle = '#707070'; ctx.fillText(text, watermarkImg.width / 2, 0); const region = new BufferTextureCopy(); - region.texExtent.width = watermarkImg.width; - region.texExtent.height = watermarkImg.height; - region.texExtent.depth = 1; + const regionTexExtent = region.texExtent; + regionTexExtent.width = watermarkImg.width; + regionTexExtent.height = watermarkImg.height; + regionTexExtent.depth = 1; this.watermarkTexture = this.device.createTexture(new TextureInfo( TextureType.TEX2D, TextureUsageBit.SAMPLED | TextureUsageBit.TRANSFER_DST, @@ -494,7 +509,8 @@ export class SplashScreen { } private frame (): void { - const { device, swapchain } = this; + const { device, swapchain, projection, bgMat, logoMat, watermarkMat, settings, quadAssmebler } = this; + const { capabilities } = device; if (!sys.isXR || xr.entry.isRenderAllowable()) { const renderSize = sys.isXR ? 2 : 1; @@ -510,32 +526,33 @@ export class SplashScreen { } else if (xrEye === XREye.RIGHT as number) { radioRight = Math.abs(Math.tan(xrFov[1] as number)) / Math.abs(Math.tan(xrFov[0] as number)); } + Mat4.ortho( - this.projection, + projection, -radioLeft, radioRight, -1, 1, -1, 1, - device.capabilities.clipSpaceMinZ, - device.capabilities.clipSpaceSignY, + capabilities.clipSpaceMinZ, + capabilities.clipSpaceSignY, swapchain.surfaceTransform, ); // keep scale to [-1, 1] only use offset - this.projection.m00 = preTransforms[swapchain.surfaceTransform][0]; - this.projection.m05 = preTransforms[swapchain.surfaceTransform][3] * device.capabilities.clipSpaceSignY; - if (this.settings.background!.type === 'custom') { - this.bgMat.setProperty('u_projection', this.projection); - this.bgMat.passes[0].update(); + projection.m00 = preTransforms[swapchain.surfaceTransform][0]; + projection.m05 = preTransforms[swapchain.surfaceTransform][3] * capabilities.clipSpaceSignY; + if (settings.background!.type === 'custom') { + setMaterialProperty(bgMat, 'u_projection', projection); + bgMat.passes[0].update(); } - if (this.settings.logo!.type !== 'none') { - this.logoMat.setProperty('u_projection', this.projection); - this.logoMat.passes[0].update(); + if (settings.logo!.type !== 'none') { + setMaterialProperty(logoMat, 'u_projection', projection); + logoMat.passes[0].update(); } - if (this.settings.logo!.type === 'default' && this.watermarkMat) { - this.watermarkMat.setProperty('u_projection', this.projection); - this.watermarkMat.passes[0].update(); + if (settings.logo!.type === 'default' && watermarkMat) { + setMaterialProperty(watermarkMat, 'u_projection', projection); + watermarkMat.passes[0].update(); } } @@ -554,55 +571,55 @@ export class SplashScreen { cmdBuff.begin(); cmdBuff.beginRenderPass(framebuffer.renderPass, framebuffer, renderArea, this.clearColors, 1.0, 0); const pipeline = cclegacy.director.root.pipeline as PipelineRuntime; - if (this.settings.background!.type === 'custom') { - const bgPass = this.bgMat.passes[0]; + if (settings.background!.type === 'custom') { + const bgPass = bgMat.passes[0]; const bgPso = PipelineStateManager.getOrCreatePipelineState( device, bgPass, this.shader, framebuffer.renderPass, - this.quadAssmebler, + quadAssmebler, ); cmdBuff.bindPipelineState(bgPso); cmdBuff.bindDescriptorSet(SetIndex.GLOBAL, pipeline.descriptorSet); cmdBuff.bindDescriptorSet(SetIndex.MATERIAL, bgPass.descriptorSet); - cmdBuff.bindInputAssembler(this.quadAssmebler); - cmdBuff.draw(this.quadAssmebler); + cmdBuff.bindInputAssembler(quadAssmebler); + cmdBuff.draw(quadAssmebler); } - if (this.settings.logo!.type !== 'none') { - const logoPass = this.logoMat.passes[0]; + if (settings.logo!.type !== 'none') { + const logoPass = logoMat.passes[0]; const logoPso = PipelineStateManager.getOrCreatePipelineState( device, logoPass, this.shader, framebuffer.renderPass, - this.quadAssmebler, + quadAssmebler, ); cmdBuff.bindPipelineState(logoPso); cmdBuff.bindDescriptorSet(SetIndex.GLOBAL, pipeline.descriptorSet); cmdBuff.bindDescriptorSet(SetIndex.MATERIAL, logoPass.descriptorSet); - cmdBuff.bindInputAssembler(this.quadAssmebler); - cmdBuff.draw(this.quadAssmebler); + cmdBuff.bindInputAssembler(quadAssmebler); + cmdBuff.draw(quadAssmebler); } - if (this.settings.logo!.type === 'default' && this.watermarkMat) { + if (settings.logo!.type === 'default' && watermarkMat) { const wartermarkPass = this.watermarkMat.passes[0]; const watermarkPso = PipelineStateManager.getOrCreatePipelineState( device, wartermarkPass, this.shader, framebuffer.renderPass, - this.quadAssmebler, + quadAssmebler, ); cmdBuff.bindPipelineState(watermarkPso); cmdBuff.bindDescriptorSet(SetIndex.GLOBAL, pipeline.descriptorSet); cmdBuff.bindDescriptorSet(SetIndex.MATERIAL, wartermarkPass.descriptorSet); - cmdBuff.bindInputAssembler(this.quadAssmebler); - cmdBuff.draw(this.quadAssmebler); + cmdBuff.bindInputAssembler(quadAssmebler); + cmdBuff.draw(quadAssmebler); } cmdBuff.endRenderPass(); diff --git a/cocos/profiler/profiler.ts b/cocos/profiler/profiler.ts index 1359a908bf2..815e31b3c81 100644 --- a/cocos/profiler/profiler.ts +++ b/cocos/profiler/profiler.ts @@ -216,19 +216,21 @@ export class Profiler extends System { } const { textureWidth, textureHeight } = _constants; + const canvas = this._canvas; + const ctx = this._ctx; - if (!this._ctx || !this._canvas) { + if (!ctx || !canvas) { return; } - this._canvas.width = textureWidth; - this._canvas.height = textureHeight; - this._canvas.style.width = `${this._canvas.width}`; - this._canvas.style.height = `${this._canvas.height}`; + canvas.width = textureWidth; + canvas.height = textureHeight; + canvas.style.width = `${canvas.width}`; + canvas.style.height = `${canvas.height}`; - this._ctx.font = `${_constants.fontSize}px Arial`; - this._ctx.textBaseline = 'top'; - this._ctx.fillStyle = '#fff'; + ctx.font = `${_constants.fontSize}px Arial`; + ctx.textBaseline = 'top'; + ctx.fillStyle = '#fff'; this._texture = this._device!.createTexture(new TextureInfo( TextureType.TEX2D, @@ -238,8 +240,9 @@ export class Profiler extends System { textureHeight, )); - this._region.texExtent.width = textureWidth; - this._region.texExtent.height = textureHeight; + const texExtent = this._region.texExtent; + texExtent.width = textureWidth; + texExtent.height = textureHeight; } public generateStats (): void { diff --git a/cocos/render-scene/core/pass.ts b/cocos/render-scene/core/pass.ts index 07e03999f8e..950e69ade1c 100644 --- a/cocos/render-scene/core/pass.ts +++ b/cocos/render-scene/core/pass.ts @@ -601,7 +601,8 @@ export class Pass { protected _doInit (info: IPassInfoFull, copyDefines = false): void { this._priority = RenderPriority.DEFAULT; this._stage = RenderPassStage.DEFAULT; - if (cclegacy.rendering && cclegacy.rendering.enableEffectImport) { + const enableEffectImport: boolean = cclegacy.rendering?.enableEffectImport; + if (enableEffectImport) { const r = cclegacy.rendering; if (typeof info.phase === 'number') { this._passID = (info as Pass)._passID; @@ -647,7 +648,7 @@ export class Pass { this._propertyIndex = info.propertyIndex !== undefined ? info.propertyIndex : info.passIndex; this._programName = info.program; this._defines = copyDefines ? ({ ...info.defines }) : info.defines; - if (cclegacy.rendering && cclegacy.rendering.enableEffectImport) { + if (enableEffectImport) { this._shaderInfo = (cclegacy.rendering.programLib as ProgramLibrary) .getProgramInfo(this._phaseID, this._programName); } else { @@ -661,7 +662,7 @@ export class Pass { if (info.stateOverrides) { Pass.fillPipelineInfo(this, info.stateOverrides); } // init descriptor set - if (cclegacy.rendering && cclegacy.rendering.enableEffectImport) { + if (enableEffectImport) { _dsInfo.layout = (cclegacy.rendering.programLib as ProgramLibrary) .getMaterialDescriptorSetLayout(this._device, this._phaseID, info.program); } else { @@ -673,7 +674,7 @@ export class Pass { const blocks = this._shaderInfo.blocks; let blockSizes: number[]; let handleMap: Record; - if (cclegacy.rendering && cclegacy.rendering.enableEffectImport) { + if (enableEffectImport) { const programLib = (cclegacy.rendering.programLib as ProgramLibrary); blockSizes = programLib.getBlockSizes(this._phaseID, this._programName); handleMap = programLib.getHandleMap(this._phaseID, this._programName); @@ -684,7 +685,7 @@ export class Pass { } // build uniform blocks - if (cclegacy.rendering && cclegacy.rendering.enableEffectImport) { + if (enableEffectImport) { const programLib = (cclegacy.rendering.programLib as ProgramLibrary); const shaderInfo = programLib.getShaderInfo(this._phaseID, this.program); this._buildMaterialUniformBlocks(device, shaderInfo.blocks, blockSizes); diff --git a/cocos/rendering/instanced-buffer.ts b/cocos/rendering/instanced-buffer.ts index 78ab3bcc626..5ea76ec2dc6 100644 --- a/cocos/rendering/instanced-buffer.ts +++ b/cocos/rendering/instanced-buffer.ts @@ -61,11 +61,10 @@ export class InstancedBuffer { } public destroy (): void { - for (let i = 0; i < this.instances.length; ++i) { - const instance = this.instances[i]; + this.instances.forEach((instance) => { instance.vb.destroy(); instance.ia.destroy(); - } + }); this.instances.length = 0; } @@ -74,10 +73,11 @@ export class InstancedBuffer { const stride = attrs.buffer.length; if (!stride) { return; } // we assume per-instance attributes are always present const sourceIA = subModel.inputAssembler; - const lightingMap = subModel.descriptorSet.getTexture(UNIFORM_LIGHTMAP_TEXTURE_BINDING); - const reflectionProbeCubemap = subModel.descriptorSet.getTexture(UNIFORM_REFLECTION_PROBE_CUBEMAP_BINDING); - const reflectionProbePlanarMap = subModel.descriptorSet.getTexture(UNIFORM_REFLECTION_PROBE_TEXTURE_BINDING); - const reflectionProbeBlendCubemap = subModel.descriptorSet.getTexture(UNIFORM_REFLECTION_PROBE_BLEND_CUBEMAP_BINDING); + const subModelDescriptorSet = subModel.descriptorSet; + const lightingMap = subModelDescriptorSet.getTexture(UNIFORM_LIGHTMAP_TEXTURE_BINDING); + const reflectionProbeCubemap = subModelDescriptorSet.getTexture(UNIFORM_REFLECTION_PROBE_CUBEMAP_BINDING); + const reflectionProbePlanarMap = subModelDescriptorSet.getTexture(UNIFORM_REFLECTION_PROBE_TEXTURE_BINDING); + const reflectionProbeBlendCubemap = subModelDescriptorSet.getTexture(UNIFORM_REFLECTION_PROBE_BLEND_CUBEMAP_BINDING); const useReflectionProbeType = subModel.useReflectionProbeType; let shader = shaderImplant; if (!shader) { @@ -163,10 +163,9 @@ export class InstancedBuffer { } public clear (): void { - for (let i = 0; i < this.instances.length; ++i) { - const instance = this.instances[i]; + this.instances.forEach((instance) => { instance.count = 0; - } + }); this.hasPendingModels = false; } } diff --git a/cocos/ui/view.ts b/cocos/ui/view.ts index ad919546c87..bef71c75989 100644 --- a/cocos/ui/view.ts +++ b/cocos/ui/view.ts @@ -35,6 +35,7 @@ import { Orientation } from '../../pal/screen-adapter/enum-type'; import { director } from '../game/director'; import { settings, SettingsCategory } from '../core/settings'; import type { Root } from '../root'; +import type { Game } from '../game'; /** * @en View represents the game window.
@@ -591,9 +592,10 @@ export class View extends Eventify(System) { private _updateAdaptResult (width: number, height: number, windowId?: number): void { // The default invalid windowId is 0 (cclegacy.director.root as Root).resize(width, height, (windowId === undefined || windowId === 0) ? 1 : windowId); + const designResolutionSize = this._designResolutionSize; // Frame size changed, do resize works - const w = this._designResolutionSize.width; - const h = this._designResolutionSize.height; + const w = designResolutionSize.width; + const h = designResolutionSize.height; if (width > 0 && height > 0) { this.setDesignResolutionSize(w, h, this._resolutionPolicy); @@ -602,7 +604,7 @@ export class View extends Eventify(System) { } this.emit('canvas-resize'); - this._resizeCallback?.(); + if (this._resizeCallback) this._resizeCallback(); } } @@ -660,7 +662,7 @@ class ContainerStrategy { protected _setupCanvas (): void { // TODO: need to figure out why set width and height of canvas - const locCanvas = cclegacy.game.canvas; + const locCanvas = (cclegacy.game as Game).canvas; if (locCanvas) { const windowSize = screen.windowSize; if (locCanvas.width !== windowSize.width) { @@ -757,9 +759,10 @@ class ContentStrategy { contentH, ); - this._result.scale = [scaleX, scaleY]; - this._result.viewport = viewport; - return this._result; + const result = this._result; + result.scale = [scaleX, scaleY]; + result.viewport = viewport; + return result; } } @@ -792,7 +795,7 @@ class ProportionalToFrame extends ContainerStrategy { super(); } - public apply (_view, designedResolution): void { + public apply (_view: View, designedResolution: Size): void { screenAdapter.isProportionalToFrame = true; this._setupCanvas(); } @@ -831,7 +834,7 @@ class ShowAll extends ContentStrategy { this._strategy = ResolutionPolicy.SHOW_ALL; } - public apply (_view, designedResolution): AdaptResult { + public apply (_view: View, designedResolution: Size): AdaptResult { const windowSize = screen.windowSize; const containerW = windowSize.width; const containerH = windowSize.height; @@ -899,7 +902,7 @@ class FixedHeight extends ContentStrategy { this._strategy = ResolutionPolicy.FIXED_HEIGHT; } - public apply (_view, designedResolution): AdaptResult { + public apply (_view: View, designedResolution: Size): AdaptResult { const windowSize = screen.windowSize; const containerW = windowSize.width; const containerH = windowSize.height; @@ -920,7 +923,7 @@ class FixedWidth extends ContentStrategy { this._strategy = ResolutionPolicy.FIXED_WIDTH; } - public apply (_view, designedResolution): AdaptResult { + public apply (_view: View, designedResolution: Size): AdaptResult { const windowSize = screen.windowSize; const containerW = windowSize.width; const containerH = windowSize.height; From f93780265fd5c12a4ebc569c34478ccd1be03019 Mon Sep 17 00:00:00 2001 From: James Chen Date: Fri, 7 Feb 2025 09:38:12 +0800 Subject: [PATCH 2/2] Sync node.ts changes from PR #18280 for native platforms. (#18285) --- native/cocos/core/scene-graph/Node.cpp | 42 +++++++++++++++++--------- native/cocos/core/scene-graph/Node.h | 8 ++++- 2 files changed, 34 insertions(+), 16 deletions(-) diff --git a/native/cocos/core/scene-graph/Node.cpp b/native/cocos/core/scene-graph/Node.cpp index 62899579cfc..8f9edbc01ad 100644 --- a/native/cocos/core/scene-graph/Node.cpp +++ b/native/cocos/core/scene-graph/Node.cpp @@ -495,6 +495,7 @@ void Node::updateWorldTransformRecursive(uint32_t &dirtyBits) { // NOLINT(misc-n dirtyBits |= currDirtyBits; bool positionDirty = dirtyBits & static_cast(TransformBit::POSITION); bool rotationScaleSkewDirty = dirtyBits & static_cast(TransformBit::RSS); + bool foundSkewInAncestor = false; if (parent) { if (positionDirty && !rotationScaleSkewDirty) { _worldPosition.transformMat4(_localPosition, parent->_worldMatrix); @@ -507,19 +508,27 @@ void Node::updateWorldTransformRecursive(uint32_t &dirtyBits) { // NOLINT(misc-n static Mat4 localMatrix; Mat4 *originalWorldMatrix = &_worldMatrix; Mat4::fromRTS(_localRotation, _localPosition, _localScale, &localMatrix); - if (_hasSkewComp) { - // Save the original world matrix without skew side effect. - Mat4::multiply(_parent->_worldMatrix, localMatrix, &tempMat4); - originalWorldMatrix = &tempMat4; - // - // If skew is dirty, rotation and scale must be also dirty. - // See _updateNodeTransformFlags in ui-skew.ts. - updateLocalMatrixBySkew(&localMatrix); + if (skewCompCount > 0) { + foundSkewInAncestor = findSkewAndGetOriginalWorldMatrix(_parent, &tempMat4); + if (_hasSkewComp || foundSkewInAncestor) { + // Save the original world matrix without skew side effect. + Mat4::multiply(tempMat4, localMatrix, &tempMat4); + originalWorldMatrix = &tempMat4; + + if (_hasSkewComp) { + updateLocalMatrixBySkew(&localMatrix); + } + } } Mat4::multiply(parent->_worldMatrix, localMatrix, &_worldMatrix); const bool rotChanged = dirtyBits & static_cast(TransformBit::ROTATION); Quaternion *rotTmp = rotChanged ? &_worldRotation : nullptr; Mat4::toRTS(*originalWorldMatrix, rotTmp, &_worldPosition, &_worldScale); + if (skewCompCount > 0 && foundSkewInAncestor) { + // NOTE: world position from Mat4.toSRT(originalWorldMatrix, ...) will not consider the skew factor. + // So we need to update the world position manually here. + Vec3::transformMat4(_localPosition, parent->_worldMatrix, &_worldPosition); + } } } else { if (dirtyBits & static_cast(TransformBit::POSITION)) { @@ -747,15 +756,16 @@ void Node::setAngle(float val) { notifyLocalRotationUpdated(); } -bool Node::getParentWorldMatrixNoSkew(Node *parent, Mat4 *out) { - if (!parent) { +/* static */ +bool Node::findSkewAndGetOriginalWorldMatrix(Node *node, Mat4 *out) { + if (!node) { return false; } static ccstd::vector tempNodes; tempNodes.resize(0); auto &ancestors = tempNodes; Node *startNode = nullptr; - for (auto *cur = parent; cur; cur = cur->_parent) { + for (auto *cur = node; cur; cur = cur->_parent) { ancestors.emplace_back(cur); if (cur->_hasSkewComp) { startNode = cur; @@ -769,11 +779,13 @@ bool Node::getParentWorldMatrixNoSkew(Node *parent, Mat4 *out) { auto iter = std::find(ancestors.begin(), ancestors.end(), startNode); long start = static_cast(iter - ancestors.begin()); for (long i = start; i >= 0; --i) { - const auto *node = ancestors[i]; - Mat4::fromRTS(node->_localRotation, node->_localPosition, node->_localScale, &curMat4); + const auto *cur = ancestors[i]; + Mat4::fromRTS(cur->_localRotation, cur->_localPosition, cur->_localScale, &curMat4); Mat4::multiply(*out, curMat4, out); } ret = true; + } else { + out->set(node->_worldMatrix); } tempNodes.resize(0); @@ -803,7 +815,7 @@ void Node::onSetParent(Node *oldParent, bool keepWorldTransform) { if (hasSkew) { if (oldParent) { // Calculate old parent's world matrix without skew side effect. - const bool foundSkewInOldParent = Node::getParentWorldMatrixNoSkew(oldParent, &tempMatrix); + const bool foundSkewInOldParent = Node::findSkewAndGetOriginalWorldMatrix(oldParent, &tempMatrix); Mat4::fromRTS(_localRotation, _localPosition, _localScale, &localMatrix); const Mat4 &oldParentMatrix = foundSkewInOldParent ? tempMatrix : oldParent->_worldMatrix; // Calculate current node's world matrix without skew side effect. @@ -811,7 +823,7 @@ void Node::onSetParent(Node *oldParent, bool keepWorldTransform) { } // Calculate new parent's world matrix without skew side effect. - const bool foundSkewInNewParent = Node::getParentWorldMatrixNoSkew(_parent, &tempMatrix); + const bool foundSkewInNewParent = Node::findSkewAndGetOriginalWorldMatrix(_parent, &tempMatrix); if (foundSkewInNewParent) { newParentMatrix = &tempMatrix; } diff --git a/native/cocos/core/scene-graph/Node.h b/native/cocos/core/scene-graph/Node.h index cdaa2510253..b90fa90222a 100644 --- a/native/cocos/core/scene-graph/Node.h +++ b/native/cocos/core/scene-graph/Node.h @@ -610,7 +610,13 @@ class Node : public CCObject { virtual void onBatchCreated(bool dontChildPrefab); virtual void updateScene(); - bool getParentWorldMatrixNoSkew(Node *parent, Mat4 *out); + /** + * Check whether the node or its parent has skew components and return the original world matrix without skew to `out` parameter. + * @param node The node and its parent for finding skew. + * @param out The node's original world matrix without skew. + * @return true if the node or its parent has skew components, otherwise returns false. + */ + static bool findSkewAndGetOriginalWorldMatrix(Node *node, Mat4 *out); void onSetParent(Node *oldParent, bool keepWorldTransform); void onHierarchyChanged(Node *); void onHierarchyChangedBase(Node *oldParent);