diff --git a/packages-user/client-modules/src/render/fx/image3d.ts b/packages-user/client-modules/src/render/fx/image3d.ts index 65a9caf..4c847c5 100644 --- a/packages-user/client-modules/src/render/fx/image3d.ts +++ b/packages-user/client-modules/src/render/fx/image3d.ts @@ -7,7 +7,7 @@ import { EffectBase } from './base'; export class Image3DEffect extends EffectBase - implements ITransformUpdatable + implements ITransformUpdatable { /** 图片的模型变换 */ private model: Transform3D = new Transform3D(); @@ -65,7 +65,7 @@ export class Image3DEffect * @param model 模型变换 */ setModel(model: Transform3D) { - this.model.bind(); + this.model.unbind(this); this.model = model; model.bind(this); } @@ -75,7 +75,7 @@ export class Image3DEffect * @param model 视角变换 */ setView(view: Transform3D) { - this.view.bind(); + this.view.unbind(this); this.view = view; view.bind(this); } @@ -85,7 +85,7 @@ export class Image3DEffect * @param model 投影变换 */ setProj(proj: Transform3D) { - this.proj.bind(); + this.proj.unbind(this); this.proj = proj; proj.bind(this); } diff --git a/packages-user/client-modules/src/render/map/element.ts b/packages-user/client-modules/src/render/map/element.ts index ce4e7bf..91f1145 100644 --- a/packages-user/client-modules/src/render/map/element.ts +++ b/packages-user/client-modules/src/render/map/element.ts @@ -1,8 +1,4 @@ -import { - MotaOffscreenCanvas2D, - RenderItem, - Transform -} from '@motajs/render-core'; +import { MotaOffscreenCanvas2D, RenderItem } from '@motajs/render-core'; import { ILayerState, state } from '@user/data-state'; import { IMapRenderer } from './types'; import { MapRenderer } from './renderer'; @@ -51,10 +47,6 @@ export class MapRender extends RenderItem { this.sizeGL(width, height); } - updateTransform(transform: Transform): void { - super.updateTransform(transform); - } - protected render(canvas: MotaOffscreenCanvas2D): void { this.renderer.clear(true, true); const map = this.renderer.render(); diff --git a/packages-user/client-modules/src/render/map/renderer.ts b/packages-user/client-modules/src/render/map/renderer.ts index 9f9efad..efea1b3 100644 --- a/packages-user/client-modules/src/render/map/renderer.ts +++ b/packages-user/client-modules/src/render/map/renderer.ts @@ -42,7 +42,7 @@ import { DYNAMIC_RESERVE, MOVING_TOLERANCE } from '../shared'; -import { ITransformUpdatable, Transform } from '@motajs/render-core'; +import { Transform } from '@motajs/render-core'; import { MapViewport } from './viewport'; import { INSTANCED_COUNT } from './constant'; import { StaticBlockStatus } from './status'; @@ -54,11 +54,7 @@ const enum BackgroundType { } export class MapRenderer - implements - IMapRenderer, - IMovingRenderer, - ITransformUpdatable, - IMapDataGetter + implements IMapRenderer, IMovingRenderer, IMapDataGetter { //#region 实例属性 @@ -296,7 +292,7 @@ export class MapRenderer //#region 状态控制 setTransform(transform: Transform): void { - this.transform.bind(); + this.transform.unbind(this); this.transform = transform; transform.bind(this); this.viewport.bindTransform(transform); diff --git a/packages/render-core/src/item.ts b/packages/render-core/src/item.ts index ad6fb82..79d041e 100644 --- a/packages/render-core/src/item.ts +++ b/packages/render-core/src/item.ts @@ -301,7 +301,7 @@ export abstract class RenderItem /** 该元素的变换矩阵 */ private _transform: Transform = new Transform(); set transform(value: Transform) { - this._transform.bind(); + this._transform.unbind(this); this._transform = value; value.bind(this); } @@ -798,7 +798,7 @@ export abstract class RenderItem this._parent = void 0; parent.requestSort(); parent.update(); - this._transform.bind(); + this._transform.unbind(this); if (!success) return false; this._root?.disconnect(this); this._root = void 0; diff --git a/packages/render-core/src/transform.ts b/packages/render-core/src/transform.ts index d7d13e7..c3f38c5 100644 --- a/packages/render-core/src/transform.ts +++ b/packages/render-core/src/transform.ts @@ -1,7 +1,11 @@ import { mat3, mat4, ReadonlyMat3, ReadonlyVec3, vec2, vec3 } from 'gl-matrix'; export interface ITransformUpdatable { - updateTransform?(transform: T): void; + /** + * 当变换矩阵更新时触发 + * @param transform 触发更新的变换矩阵 + */ + updateTransform(transform: T): void; } export class Transform { @@ -17,14 +21,26 @@ export class Transform { private modified: boolean = false; /** 绑定的可更新元素 */ - bindedObject?: ITransformUpdatable; + bindedObject: Set> = new Set(); /** * 对这个变换实例添加绑定对象,当矩阵变换时,自动调用其 update 函数 * @param obj 要绑定的对象 */ - bind(obj?: ITransformUpdatable) { - this.bindedObject = obj; + bind(obj: ITransformUpdatable) { + this.bindedObject.add(obj); + } + + /** + * 取消对象的绑定 + * @param obj 要取消绑定的对象 + */ + unbind(obj: ITransformUpdatable) { + this.bindedObject.delete(obj); + } + + private emitUpdate() { + this.bindedObject.forEach(v => v.updateTransform(this)); } /** @@ -38,7 +54,7 @@ export class Transform { this.scaleY = 1; this.rad = 0; this.modified = false; - this.bindedObject?.updateTransform?.(this); + this.emitUpdate(); } /** @@ -49,7 +65,7 @@ export class Transform { this.scaleX *= x; this.scaleY *= y; this.modified = true; - this.bindedObject?.updateTransform?.(this); + this.emitUpdate(); return this; } @@ -61,7 +77,7 @@ export class Transform { this.x += x; this.y += y; this.modified = true; - this.bindedObject?.updateTransform?.(this); + this.emitUpdate(); return this; } @@ -76,7 +92,7 @@ export class Transform { this.rad -= n * Math.PI * 2; } this.modified = true; - this.bindedObject?.updateTransform?.(this); + this.emitUpdate(); return this; } @@ -88,7 +104,7 @@ export class Transform { this.scaleX = x; this.scaleY = y; this.modified = true; - this.bindedObject?.updateTransform?.(this); + this.emitUpdate(); return this; } @@ -100,7 +116,7 @@ export class Transform { this.x = x; this.y = y; this.modified = true; - this.bindedObject?.updateTransform?.(this); + this.emitUpdate(); return this; } @@ -111,7 +127,7 @@ export class Transform { mat3.rotate(this.mat, this.mat, rad - this.rad); this.rad = rad; this.modified = true; - this.bindedObject?.updateTransform?.(this); + this.emitUpdate(); return this; } @@ -138,7 +154,7 @@ export class Transform { mat3.fromValues(a, b, 0, c, d, 0, e, f, 1) ); this.calAttributes(); - this.bindedObject?.updateTransform?.(this); + this.emitUpdate(); return this; } @@ -161,7 +177,7 @@ export class Transform { ): this { mat3.set(this.mat, a, b, 0, c, d, 0, e, f, 1); this.calAttributes(); - this.bindedObject?.updateTransform?.(this); + this.emitUpdate(); return this; } @@ -285,14 +301,26 @@ export class Transform3D { mat: mat4 = mat4.create(); /** 绑定的可更新元素 */ - bindedObject?: ITransformUpdatable; + bindedObject: Set> = new Set(); /** - * 绑定可更新对象 + * 对这个变换实例添加绑定对象,当矩阵变换时,自动调用其 update 函数 * @param obj 要绑定的对象 */ - bind(obj?: ITransformUpdatable) { - this.bindedObject = obj; + bind(obj: ITransformUpdatable) { + this.bindedObject.add(obj); + } + + /** + * 取消对象的绑定 + * @param obj 要取消绑定的对象 + */ + unbind(obj: ITransformUpdatable) { + this.bindedObject.delete(obj); + } + + private emitUpdate() { + this.bindedObject.forEach(v => v.updateTransform(this)); } /** @@ -300,7 +328,7 @@ export class Transform3D { */ reset(): this { mat4.identity(this.mat); - this.bindedObject?.updateTransform?.(this); + this.emitUpdate(); return this; } @@ -312,7 +340,7 @@ export class Transform3D { */ scale(x: number, y: number, z: number): this { mat4.scale(this.mat, this.mat, [x, y, z]); - this.bindedObject?.updateTransform?.(this); + this.emitUpdate(); return this; } @@ -324,7 +352,7 @@ export class Transform3D { */ translate(x: number, y: number, z: number): this { mat4.translate(this.mat, this.mat, [x, y, z]); - this.bindedObject?.updateTransform?.(this); + this.emitUpdate(); return this; } @@ -335,7 +363,7 @@ export class Transform3D { */ rotate(rad: number, axis: vec3): this { mat4.rotate(this.mat, this.mat, rad, axis); - this.bindedObject?.updateTransform?.(this); + this.emitUpdate(); return this; } @@ -371,7 +399,7 @@ export class Transform3D { */ lookAt(eye: vec3, center: vec3, up: vec3): this { mat4.lookAt(this.mat, eye, center, up); - this.bindedObject?.updateTransform?.(this); + this.emitUpdate(); return this; } @@ -384,7 +412,7 @@ export class Transform3D { */ perspective(fovy: number, aspect: number, near: number, far: number): this { mat4.perspective(this.mat, fovy, aspect, near, far); - this.bindedObject?.updateTransform?.(this); + this.emitUpdate(); return this; } @@ -406,7 +434,7 @@ export class Transform3D { far: number ): this { mat4.ortho(this.mat, left, right, bottom, top, near, far); - this.bindedObject?.updateTransform?.(this); + this.emitUpdate(); return this; }