From 79392536222fca6fe7da774eac14a5c19d96c872 Mon Sep 17 00:00:00 2001 From: yhh <359807859@qq.com> Date: Mon, 8 Jun 2020 17:18:21 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dtransform=20=E4=B8=8D?= =?UTF-8?q?=E6=9B=B4=E6=96=B0=E9=97=AE=E9=A2=98=20=E4=BC=98=E5=8C=96transf?= =?UTF-8?q?orm=20=E6=80=A7=E8=83=BD=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- demo/libs/framework/framework.d.ts | 14 +++++ demo/libs/framework/framework.js | 58 ++++++++++++++++----- demo/libs/framework/framework.min.js | 2 +- source/bin/framework.d.ts | 14 +++++ source/bin/framework.js | 58 ++++++++++++++++----- source/bin/framework.min.js | 2 +- source/src/ECS/Entity.ts | 1 + source/src/ECS/Transform.ts | 76 ++++++++++++++++++++++------ 8 files changed, 179 insertions(+), 46 deletions(-) diff --git a/demo/libs/framework/framework.d.ts b/demo/libs/framework/framework.d.ts index 951abb1d..3f9d0423 100644 --- a/demo/libs/framework/framework.d.ts +++ b/demo/libs/framework/framework.d.ts @@ -63,6 +63,12 @@ declare class SceneManager { static setActiveScene(scene: Scene): Scene; static getActiveScene(): Scene; } +declare enum DirtyType { + clean = 0, + positionDirty = 1, + scaleDirty = 2, + rotationDirty = 3 +} declare class Transform { readonly entity: Entity; private _children; @@ -80,6 +86,14 @@ declare class Transform { private _position; private _scale; private _localTransform; + private _hierachyDirty; + private _localDirty; + private _localPositionDirty; + private _localScaleDirty; + private _localRotationDirty; + private _positionDirty; + private _worldToLocalDirty; + private _worldInverseDirty; readonly childCount: number; constructor(entity: Entity); getChild(index: number): Transform; diff --git a/demo/libs/framework/framework.js b/demo/libs/framework/framework.js index a7e78b2d..9fb3cb0a 100644 --- a/demo/libs/framework/framework.js +++ b/demo/libs/framework/framework.js @@ -289,6 +289,7 @@ var Entity = (function () { }; Entity.prototype.update = function () { this.components.forEach(function (component) { return component.update(); }); + this.transform.updateTransform(); }; Entity.prototype.destory = function () { this.scene.entities.remove(this); @@ -377,6 +378,13 @@ var SceneManager = (function () { SceneManager._loadedScenes = new Map(); return SceneManager; }()); +var DirtyType; +(function (DirtyType) { + DirtyType[DirtyType["clean"] = 0] = "clean"; + DirtyType[DirtyType["positionDirty"] = 1] = "positionDirty"; + DirtyType[DirtyType["scaleDirty"] = 2] = "scaleDirty"; + DirtyType[DirtyType["rotationDirty"] = 3] = "rotationDirty"; +})(DirtyType || (DirtyType = {})); var Transform = (function () { function Transform(entity) { this._localRotation = 0; @@ -451,6 +459,7 @@ var Transform = (function () { if (localPosition == this._localPosition) return this; this._localPosition = localPosition; + this._localDirty = this._positionDirty = this._localPositionDirty = this._localRotationDirty = this._localScaleDirty = true; return this; }; Transform.prototype.setPosition = function (position) { @@ -473,20 +482,41 @@ var Transform = (function () { return this; }; Transform.prototype.updateTransform = function () { - this._translationMatrix = Matrix2D.createTranslation(this._localPosition.x, this._localPosition.y); - this._rotationMatrix = Matrix2D.createRotation(this._localRotation); - this._scaleMatrix = Matrix2D.createScale(this._localScale.x, this._localScale.y); - this._localTransform = Matrix2D.multiply(this._scaleMatrix, this._rotationMatrix); - this._localTransform = Matrix2D.multiply(this._localTransform, this._translationMatrix); - if (!this.parent) { - this._worldTransform = this._localTransform; - this._rotation = this._localRotation; - this._scale = this._localScale; - } - else { - this._worldTransform = Matrix2D.multiply(this._localTransform, this.parent._worldTransform); - this._rotation = this._localRotation + this.parent._rotation; - this._scale = Vector2.multiply(this.parent._scale, this._localScale); + if (this._hierachyDirty != DirtyType.clean) { + if (this.parent) + this.parent.updateTransform(); + if (this._localDirty) { + if (this._localPositionDirty) { + this._translationMatrix = Matrix2D.createTranslation(this._localPosition.x, this._localPosition.y); + this._localPositionDirty = false; + } + if (this._localRotationDirty) { + this._rotationMatrix = Matrix2D.createRotation(this._localRotation); + this._localRotationDirty = false; + } + if (this._localScaleDirty) { + this._scaleMatrix = Matrix2D.createScale(this._localScale.x, this._localScale.y); + this._localScaleDirty = false; + } + this._localTransform = Matrix2D.multiply(this._scaleMatrix, this._rotationMatrix); + this._localTransform = Matrix2D.multiply(this._localTransform, this._translationMatrix); + if (!this.parent) { + this._worldTransform = this._localTransform; + this._rotation = this._localRotation; + this._scale = this._localScale; + this._worldInverseDirty = true; + } + this._localDirty = false; + } + if (this.parent) { + this._worldTransform = Matrix2D.multiply(this._localTransform, this.parent._worldTransform); + this._rotation = this._localRotation + this.parent._rotation; + this._scale = Vector2.multiply(this.parent._scale, this._localScale); + this._worldInverseDirty = true; + } + this._worldToLocalDirty = true; + this._positionDirty = true; + this._hierachyDirty = DirtyType.clean; } }; return Transform; diff --git a/demo/libs/framework/framework.min.js b/demo/libs/framework/framework.min.js index 608e5e2c..f0173442 100644 --- a/demo/libs/framework/framework.min.js +++ b/demo/libs/framework/framework.min.js @@ -1 +1 @@ -window.framework={},window.__extends=this&&this.__extends||function(){var t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,n){t.__proto__=n}||function(t,n){for(var e in n)n.hasOwnProperty(e)&&(t[e]=n[e])};return function(n,e){function r(){this.constructor=n}t(n,e),n.prototype=null===e?Object.create(e):(r.prototype=e.prototype,new r)}}(),Array.prototype.findIndex=function(t){return function(t,n){for(var e=0,r=t.length;e-1}(this,t)},Array.prototype.firstOrDefault=function(t){return function(t,n){var e=t.findIndex(n);return-1==e?null:t[e]}(this,t)},Array.prototype.find=function(t){return function(t,n){return t.firstOrDefault(n)}(this,t)},Array.prototype.where=function(t){return function(t,n){if("function"==typeof t.reduce)return t.reduce(function(e,r,i){return n.call(arguments[2],r,i,t)&&e.push(r),e},[]);for(var e=[],r=0,i=t.length;r=0&&t.splice(e,1)}while(e>=0)}(this,t)},Array.prototype.remove=function(t){return function(t,n){var e=t.findIndex(function(t){return t===n});return e>=0&&(t.splice(e,1),!0)}(this,t)},Array.prototype.removeAt=function(t){return function(t,n){t.splice(n,1)}(this,t)},Array.prototype.removeRange=function(t,n){return function(t,n,e){t.splice(n,e)}(this,t,n)},Array.prototype.select=function(t){return function(t,n){if("function"==typeof t.reduce)return t.reduce(function(e,r,i){return e.push(n.call(arguments[2],r,i,t)),e},[]);for(var e=[],r=0,i=t.length;ro?1:-1}),t}(this,t,n)},Array.prototype.orderByDescending=function(t,n){return function(t,n,e){return t.sort(function(t,r){var i=n(t),o=n(r);return e?-e(i,o):i=0;t--){this.transform.getChild(t).entity.destory()}},t}(),Scene=function(t){function n(n){var e=t.call(this)||this;return e.entities=[],n.stage.addChild(e),e.camera=e.createEntity("camera").addComponent(new Camera),e._projectionMatrix=new Matrix2D(0,0,0,0,0,0),e.addEventListener(egret.Event.ACTIVATE,e.onActive,e),e.addEventListener(egret.Event.DEACTIVATE,e.onDeactive,e),e.addEventListener(egret.Event.ENTER_FRAME,e.update,e),e}return __extends(n,t),n.prototype.createEntity=function(t){var n=new Entity(t);return n.transform.position=new Vector2(0,0),this.addEntity(n)},n.prototype.addEntity=function(t){return this.entities.push(t),t.scene=this,t},n.prototype.setActive=function(){return SceneManager.setActiveScene(this),this},n.prototype.initialize=function(){},n.prototype.onActive=function(){},n.prototype.onDeactive=function(){},n.prototype.update=function(){this.entities.forEach(function(t){return t.update()})},n.prototype.prepRenderState=function(){this._projectionMatrix.m11=2/this.stage.width,this._projectionMatrix.m22=-2/this.stage.height,this._transformMatrix=this.camera.transformMatrix,this._matrixTransformMatrix=Matrix2D.multiply(this._transformMatrix,this._projectionMatrix)},n.prototype.destory=function(){this.removeEventListener(egret.Event.DEACTIVATE,this.onDeactive,this),this.removeEventListener(egret.Event.ACTIVATE,this.onActive,this),this.camera.destory(),this.camera=null,this.entities.forEach(function(t){return t.destory()}),this.entities.length=0},n}(egret.DisplayObjectContainer),SceneManager=function(){function t(){}return t.createScene=function(t,n){return n.name=t,this._loadedScenes.set(t,n),n},t.setActiveScene=function(t){if(this._activeScene){if(this._activeScene==t)return;this._lastScene=this._activeScene,this._activeScene.destory()}return this._activeScene=t,this._activeScene.initialize(),t},t.getActiveScene=function(){return this._activeScene},t._loadedScenes=new Map,t}(),Transform=function(){function t(t){this._localRotation=0,this._worldTransform=Matrix2D.identity,this._worldToLocalTransform=Matrix2D.identity,this._worldInverseTransform=Matrix2D.identity,this._rotation=0,this.entity=t,this._scale=this._localScale=Vector2.One,this._children=[]}return Object.defineProperty(t.prototype,"childCount",{get:function(){return this._children.length},enumerable:!0,configurable:!0}),t.prototype.getChild=function(t){return this._children[t]},Object.defineProperty(t.prototype,"parent",{get:function(){return this._parent},set:function(t){this.setParent(t)},enumerable:!0,configurable:!0}),t.prototype.setParent=function(t){return this._parent==t?this:(this._parent&&this._parent._children.remove(this),t&&t._children.push(this),this._parent=t,this)},Object.defineProperty(t.prototype,"position",{get:function(){return this.updateTransform(),this.parent?(this.parent.updateTransform(),this._position=Vector2.transform(this._localPosition,this.parent._worldTransform)):this._position=this._localPosition,this._position},set:function(t){this.setPosition(t)},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"localPosition",{get:function(){return this.updateTransform(),this._localPosition},set:function(t){this.setLocalPosition(t)},enumerable:!0,configurable:!0}),t.prototype.setLocalPosition=function(t){return t==this._localPosition?this:(this._localPosition=t,this)},t.prototype.setPosition=function(t){if(t==this._position)return this;this._position=t,this.parent?this.localPosition=Vector2.transform(this._position,this._worldToLocalTransform):this.localPosition=t;for(var n=0;n-1}(this,t)},Array.prototype.firstOrDefault=function(t){return function(t,n){var i=t.findIndex(n);return-1==i?null:t[i]}(this,t)},Array.prototype.find=function(t){return function(t,n){return t.firstOrDefault(n)}(this,t)},Array.prototype.where=function(t){return function(t,n){if("function"==typeof t.reduce)return t.reduce(function(i,e,r){return n.call(arguments[2],e,r,t)&&i.push(e),i},[]);for(var i=[],e=0,r=t.length;e=0&&t.splice(i,1)}while(i>=0)}(this,t)},Array.prototype.remove=function(t){return function(t,n){var i=t.findIndex(function(t){return t===n});return i>=0&&(t.splice(i,1),!0)}(this,t)},Array.prototype.removeAt=function(t){return function(t,n){t.splice(n,1)}(this,t)},Array.prototype.removeRange=function(t,n){return function(t,n,i){t.splice(n,i)}(this,t,n)},Array.prototype.select=function(t){return function(t,n){if("function"==typeof t.reduce)return t.reduce(function(i,e,r){return i.push(n.call(arguments[2],e,r,t)),i},[]);for(var i=[],e=0,r=t.length;eo?1:-1}),t}(this,t,n)},Array.prototype.orderByDescending=function(t,n){return function(t,n,i){return t.sort(function(t,e){var r=n(t),o=n(e);return i?-i(r,o):r=0;t--){this.transform.getChild(t).entity.destory()}},t}(),Scene=function(t){function n(n){var i=t.call(this)||this;return i.entities=[],n.stage.addChild(i),i.camera=i.createEntity("camera").addComponent(new Camera),i._projectionMatrix=new Matrix2D(0,0,0,0,0,0),i.addEventListener(egret.Event.ACTIVATE,i.onActive,i),i.addEventListener(egret.Event.DEACTIVATE,i.onDeactive,i),i.addEventListener(egret.Event.ENTER_FRAME,i.update,i),i}return __extends(n,t),n.prototype.createEntity=function(t){var n=new Entity(t);return n.transform.position=new Vector2(0,0),this.addEntity(n)},n.prototype.addEntity=function(t){return this.entities.push(t),t.scene=this,t},n.prototype.setActive=function(){return SceneManager.setActiveScene(this),this},n.prototype.initialize=function(){},n.prototype.onActive=function(){},n.prototype.onDeactive=function(){},n.prototype.update=function(){this.entities.forEach(function(t){return t.update()})},n.prototype.prepRenderState=function(){this._projectionMatrix.m11=2/this.stage.width,this._projectionMatrix.m22=-2/this.stage.height,this._transformMatrix=this.camera.transformMatrix,this._matrixTransformMatrix=Matrix2D.multiply(this._transformMatrix,this._projectionMatrix)},n.prototype.destory=function(){this.removeEventListener(egret.Event.DEACTIVATE,this.onDeactive,this),this.removeEventListener(egret.Event.ACTIVATE,this.onActive,this),this.camera.destory(),this.camera=null,this.entities.forEach(function(t){return t.destory()}),this.entities.length=0},n}(egret.DisplayObjectContainer),SceneManager=function(){function t(){}return t.createScene=function(t,n){return n.name=t,this._loadedScenes.set(t,n),n},t.setActiveScene=function(t){if(this._activeScene){if(this._activeScene==t)return;this._lastScene=this._activeScene,this._activeScene.destory()}return this._activeScene=t,this._activeScene.initialize(),t},t.getActiveScene=function(){return this._activeScene},t._loadedScenes=new Map,t}();!function(t){t[t.clean=0]="clean",t[t.positionDirty=1]="positionDirty",t[t.scaleDirty=2]="scaleDirty",t[t.rotationDirty=3]="rotationDirty"}(DirtyType||(DirtyType={}));var Transform=function(){function t(t){this._localRotation=0,this._worldTransform=Matrix2D.identity,this._worldToLocalTransform=Matrix2D.identity,this._worldInverseTransform=Matrix2D.identity,this._rotation=0,this.entity=t,this._scale=this._localScale=Vector2.One,this._children=[]}return Object.defineProperty(t.prototype,"childCount",{get:function(){return this._children.length},enumerable:!0,configurable:!0}),t.prototype.getChild=function(t){return this._children[t]},Object.defineProperty(t.prototype,"parent",{get:function(){return this._parent},set:function(t){this.setParent(t)},enumerable:!0,configurable:!0}),t.prototype.setParent=function(t){return this._parent==t?this:(this._parent&&this._parent._children.remove(this),t&&t._children.push(this),this._parent=t,this)},Object.defineProperty(t.prototype,"position",{get:function(){return this.updateTransform(),this.parent?(this.parent.updateTransform(),this._position=Vector2.transform(this._localPosition,this.parent._worldTransform)):this._position=this._localPosition,this._position},set:function(t){this.setPosition(t)},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"localPosition",{get:function(){return this.updateTransform(),this._localPosition},set:function(t){this.setLocalPosition(t)},enumerable:!0,configurable:!0}),t.prototype.setLocalPosition=function(t){return t==this._localPosition?this:(this._localPosition=t,this._localDirty=this._positionDirty=this._localPositionDirty=this._localRotationDirty=this._localScaleDirty=!0,this)},t.prototype.setPosition=function(t){if(t==this._position)return this;this._position=t,this.parent?this.localPosition=Vector2.transform(this._position,this._worldToLocalTransform):this.localPosition=t;for(var n=0;n-1}(this,t)},Array.prototype.firstOrDefault=function(t){return function(t,n){var e=t.findIndex(n);return-1==e?null:t[e]}(this,t)},Array.prototype.find=function(t){return function(t,n){return t.firstOrDefault(n)}(this,t)},Array.prototype.where=function(t){return function(t,n){if("function"==typeof t.reduce)return t.reduce(function(e,r,i){return n.call(arguments[2],r,i,t)&&e.push(r),e},[]);for(var e=[],r=0,i=t.length;r=0&&t.splice(e,1)}while(e>=0)}(this,t)},Array.prototype.remove=function(t){return function(t,n){var e=t.findIndex(function(t){return t===n});return e>=0&&(t.splice(e,1),!0)}(this,t)},Array.prototype.removeAt=function(t){return function(t,n){t.splice(n,1)}(this,t)},Array.prototype.removeRange=function(t,n){return function(t,n,e){t.splice(n,e)}(this,t,n)},Array.prototype.select=function(t){return function(t,n){if("function"==typeof t.reduce)return t.reduce(function(e,r,i){return e.push(n.call(arguments[2],r,i,t)),e},[]);for(var e=[],r=0,i=t.length;ro?1:-1}),t}(this,t,n)},Array.prototype.orderByDescending=function(t,n){return function(t,n,e){return t.sort(function(t,r){var i=n(t),o=n(r);return e?-e(i,o):i=0;t--){this.transform.getChild(t).entity.destory()}},t}(),Scene=function(t){function n(n){var e=t.call(this)||this;return e.entities=[],n.stage.addChild(e),e.camera=e.createEntity("camera").addComponent(new Camera),e._projectionMatrix=new Matrix2D(0,0,0,0,0,0),e.addEventListener(egret.Event.ACTIVATE,e.onActive,e),e.addEventListener(egret.Event.DEACTIVATE,e.onDeactive,e),e.addEventListener(egret.Event.ENTER_FRAME,e.update,e),e}return __extends(n,t),n.prototype.createEntity=function(t){var n=new Entity(t);return n.transform.position=new Vector2(0,0),this.addEntity(n)},n.prototype.addEntity=function(t){return this.entities.push(t),t.scene=this,t},n.prototype.setActive=function(){return SceneManager.setActiveScene(this),this},n.prototype.initialize=function(){},n.prototype.onActive=function(){},n.prototype.onDeactive=function(){},n.prototype.update=function(){this.entities.forEach(function(t){return t.update()})},n.prototype.prepRenderState=function(){this._projectionMatrix.m11=2/this.stage.width,this._projectionMatrix.m22=-2/this.stage.height,this._transformMatrix=this.camera.transformMatrix,this._matrixTransformMatrix=Matrix2D.multiply(this._transformMatrix,this._projectionMatrix)},n.prototype.destory=function(){this.removeEventListener(egret.Event.DEACTIVATE,this.onDeactive,this),this.removeEventListener(egret.Event.ACTIVATE,this.onActive,this),this.camera.destory(),this.camera=null,this.entities.forEach(function(t){return t.destory()}),this.entities.length=0},n}(egret.DisplayObjectContainer),SceneManager=function(){function t(){}return t.createScene=function(t,n){return n.name=t,this._loadedScenes.set(t,n),n},t.setActiveScene=function(t){if(this._activeScene){if(this._activeScene==t)return;this._lastScene=this._activeScene,this._activeScene.destory()}return this._activeScene=t,this._activeScene.initialize(),t},t.getActiveScene=function(){return this._activeScene},t._loadedScenes=new Map,t}(),Transform=function(){function t(t){this._localRotation=0,this._worldTransform=Matrix2D.identity,this._worldToLocalTransform=Matrix2D.identity,this._worldInverseTransform=Matrix2D.identity,this._rotation=0,this.entity=t,this._scale=this._localScale=Vector2.One,this._children=[]}return Object.defineProperty(t.prototype,"childCount",{get:function(){return this._children.length},enumerable:!0,configurable:!0}),t.prototype.getChild=function(t){return this._children[t]},Object.defineProperty(t.prototype,"parent",{get:function(){return this._parent},set:function(t){this.setParent(t)},enumerable:!0,configurable:!0}),t.prototype.setParent=function(t){return this._parent==t?this:(this._parent&&this._parent._children.remove(this),t&&t._children.push(this),this._parent=t,this)},Object.defineProperty(t.prototype,"position",{get:function(){return this.updateTransform(),this.parent?(this.parent.updateTransform(),this._position=Vector2.transform(this._localPosition,this.parent._worldTransform)):this._position=this._localPosition,this._position},set:function(t){this.setPosition(t)},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"localPosition",{get:function(){return this.updateTransform(),this._localPosition},set:function(t){this.setLocalPosition(t)},enumerable:!0,configurable:!0}),t.prototype.setLocalPosition=function(t){return t==this._localPosition?this:(this._localPosition=t,this)},t.prototype.setPosition=function(t){if(t==this._position)return this;this._position=t,this.parent?this.localPosition=Vector2.transform(this._position,this._worldToLocalTransform):this.localPosition=t;for(var n=0;n-1}(this,t)},Array.prototype.firstOrDefault=function(t){return function(t,n){var i=t.findIndex(n);return-1==i?null:t[i]}(this,t)},Array.prototype.find=function(t){return function(t,n){return t.firstOrDefault(n)}(this,t)},Array.prototype.where=function(t){return function(t,n){if("function"==typeof t.reduce)return t.reduce(function(i,e,r){return n.call(arguments[2],e,r,t)&&i.push(e),i},[]);for(var i=[],e=0,r=t.length;e=0&&t.splice(i,1)}while(i>=0)}(this,t)},Array.prototype.remove=function(t){return function(t,n){var i=t.findIndex(function(t){return t===n});return i>=0&&(t.splice(i,1),!0)}(this,t)},Array.prototype.removeAt=function(t){return function(t,n){t.splice(n,1)}(this,t)},Array.prototype.removeRange=function(t,n){return function(t,n,i){t.splice(n,i)}(this,t,n)},Array.prototype.select=function(t){return function(t,n){if("function"==typeof t.reduce)return t.reduce(function(i,e,r){return i.push(n.call(arguments[2],e,r,t)),i},[]);for(var i=[],e=0,r=t.length;eo?1:-1}),t}(this,t,n)},Array.prototype.orderByDescending=function(t,n){return function(t,n,i){return t.sort(function(t,e){var r=n(t),o=n(e);return i?-i(r,o):r=0;t--){this.transform.getChild(t).entity.destory()}},t}(),Scene=function(t){function n(n){var i=t.call(this)||this;return i.entities=[],n.stage.addChild(i),i.camera=i.createEntity("camera").addComponent(new Camera),i._projectionMatrix=new Matrix2D(0,0,0,0,0,0),i.addEventListener(egret.Event.ACTIVATE,i.onActive,i),i.addEventListener(egret.Event.DEACTIVATE,i.onDeactive,i),i.addEventListener(egret.Event.ENTER_FRAME,i.update,i),i}return __extends(n,t),n.prototype.createEntity=function(t){var n=new Entity(t);return n.transform.position=new Vector2(0,0),this.addEntity(n)},n.prototype.addEntity=function(t){return this.entities.push(t),t.scene=this,t},n.prototype.setActive=function(){return SceneManager.setActiveScene(this),this},n.prototype.initialize=function(){},n.prototype.onActive=function(){},n.prototype.onDeactive=function(){},n.prototype.update=function(){this.entities.forEach(function(t){return t.update()})},n.prototype.prepRenderState=function(){this._projectionMatrix.m11=2/this.stage.width,this._projectionMatrix.m22=-2/this.stage.height,this._transformMatrix=this.camera.transformMatrix,this._matrixTransformMatrix=Matrix2D.multiply(this._transformMatrix,this._projectionMatrix)},n.prototype.destory=function(){this.removeEventListener(egret.Event.DEACTIVATE,this.onDeactive,this),this.removeEventListener(egret.Event.ACTIVATE,this.onActive,this),this.camera.destory(),this.camera=null,this.entities.forEach(function(t){return t.destory()}),this.entities.length=0},n}(egret.DisplayObjectContainer),SceneManager=function(){function t(){}return t.createScene=function(t,n){return n.name=t,this._loadedScenes.set(t,n),n},t.setActiveScene=function(t){if(this._activeScene){if(this._activeScene==t)return;this._lastScene=this._activeScene,this._activeScene.destory()}return this._activeScene=t,this._activeScene.initialize(),t},t.getActiveScene=function(){return this._activeScene},t._loadedScenes=new Map,t}();!function(t){t[t.clean=0]="clean",t[t.positionDirty=1]="positionDirty",t[t.scaleDirty=2]="scaleDirty",t[t.rotationDirty=3]="rotationDirty"}(DirtyType||(DirtyType={}));var Transform=function(){function t(t){this._localRotation=0,this._worldTransform=Matrix2D.identity,this._worldToLocalTransform=Matrix2D.identity,this._worldInverseTransform=Matrix2D.identity,this._rotation=0,this.entity=t,this._scale=this._localScale=Vector2.One,this._children=[]}return Object.defineProperty(t.prototype,"childCount",{get:function(){return this._children.length},enumerable:!0,configurable:!0}),t.prototype.getChild=function(t){return this._children[t]},Object.defineProperty(t.prototype,"parent",{get:function(){return this._parent},set:function(t){this.setParent(t)},enumerable:!0,configurable:!0}),t.prototype.setParent=function(t){return this._parent==t?this:(this._parent&&this._parent._children.remove(this),t&&t._children.push(this),this._parent=t,this)},Object.defineProperty(t.prototype,"position",{get:function(){return this.updateTransform(),this.parent?(this.parent.updateTransform(),this._position=Vector2.transform(this._localPosition,this.parent._worldTransform)):this._position=this._localPosition,this._position},set:function(t){this.setPosition(t)},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"localPosition",{get:function(){return this.updateTransform(),this._localPosition},set:function(t){this.setLocalPosition(t)},enumerable:!0,configurable:!0}),t.prototype.setLocalPosition=function(t){return t==this._localPosition?this:(this._localPosition=t,this._localDirty=this._positionDirty=this._localPositionDirty=this._localRotationDirty=this._localScaleDirty=!0,this)},t.prototype.setPosition=function(t){if(t==this._position)return this;this._position=t,this.parent?this.localPosition=Vector2.transform(this._position,this._worldToLocalTransform):this.localPosition=t;for(var n=0;n component.update()); + this.transform.updateTransform(); } public destory(){ diff --git a/source/src/ECS/Transform.ts b/source/src/ECS/Transform.ts index 190e5c4c..9258f56c 100644 --- a/source/src/ECS/Transform.ts +++ b/source/src/ECS/Transform.ts @@ -1,3 +1,10 @@ +enum DirtyType{ + clean, + positionDirty, + scaleDirty, + rotationDirty, +} + class Transform { /** 相关联的实体 */ public readonly entity: Entity; @@ -21,6 +28,14 @@ class Transform { private _scale: Vector2; private _localTransform; + private _hierachyDirty: DirtyType; + private _localDirty: boolean; + private _localPositionDirty: boolean; + private _localScaleDirty: boolean; + private _localRotationDirty: boolean; + private _positionDirty: boolean; + private _worldToLocalDirty: boolean; + private _worldInverseDirty: boolean; public get childCount(){ return this._children.length; @@ -89,7 +104,8 @@ class Transform { return this; this._localPosition = localPosition; - + this._localDirty = this._positionDirty = this._localPositionDirty = this._localRotationDirty = this._localScaleDirty = true; + return this; } @@ -116,25 +132,53 @@ class Transform { } public updateTransform(){ - if (this.parent) - this.parent.updateTransform(); + if (this._hierachyDirty != DirtyType.clean){ + if (this.parent) + this.parent.updateTransform(); - this._translationMatrix = Matrix2D.createTranslation(this._localPosition.x, this._localPosition.y); - this._rotationMatrix = Matrix2D.createRotation(this._localRotation); - this._scaleMatrix = Matrix2D.createScale(this._localScale.x, this._localScale.y); + if (this._localDirty){ + if (this._localPositionDirty){ + this._translationMatrix = Matrix2D.createTranslation(this._localPosition.x, this._localPosition.y); + this._localPositionDirty = false; + } - this._localTransform = Matrix2D.multiply(this._scaleMatrix, this._rotationMatrix); - this._localTransform = Matrix2D.multiply(this._localTransform, this._translationMatrix); + if (this._localRotationDirty){ + this._rotationMatrix = Matrix2D.createRotation(this._localRotation); + this._localRotationDirty = false; + } + - if (!this.parent){ - this._worldTransform = this._localTransform; - this._rotation = this._localRotation; - this._scale = this._localScale; - }else{ - this._worldTransform = Matrix2D.multiply(this._localTransform, this.parent._worldTransform); + if (this._localScaleDirty){ + this._scaleMatrix = Matrix2D.createScale(this._localScale.x, this._localScale.y); + this._localScaleDirty = false; + } + - this._rotation = this._localRotation + this.parent._rotation; - this._scale = Vector2.multiply( this.parent._scale, this._localScale); + this._localTransform = Matrix2D.multiply(this._scaleMatrix, this._rotationMatrix); + this._localTransform = Matrix2D.multiply(this._localTransform, this._translationMatrix); + + if (!this.parent){ + this._worldTransform = this._localTransform; + this._rotation = this._localRotation; + this._scale = this._localScale; + this._worldInverseDirty = true; + } + + this._localDirty = false; + } + + if (this.parent){ + this._worldTransform = Matrix2D.multiply(this._localTransform, this.parent._worldTransform); + + this._rotation = this._localRotation + this.parent._rotation; + this._scale = Vector2.multiply( this.parent._scale, this._localScale); + this._worldInverseDirty = true; + } + + this._worldToLocalDirty = true; + this._positionDirty = true; + this._hierachyDirty = DirtyType.clean; } + } } \ No newline at end of file