/** * Entity Runtime * @param graphics GameLib.D3.Graphics * @param apiEntity GameLib.D3.API.Entity * @constructor */ GameLib.D3.Entity = function Entity( graphics, apiEntity ) { for (var property in apiEntity) { if (apiEntity.hasOwnProperty(property)) { this[property] = apiEntity[property]; } } this.graphics = graphics; this.graphics.isNotThreeThrow(); this.position = new GameLib.D3.Vector3( this.graphics, this, this.position ); this.quaternion = new GameLib.D3.Quaternion( this.graphics, this, this.quaternion ); this.scale = new GameLib.D3.Vector3( this.graphics, this, this.scale ); }; /** * Converts a GameLib.D3.Entity to GameLib.D3.API.Entity * @returns {GameLib.D3.API.Entity} */ GameLib.D3.Entity.prototype.toApiEntity = function() { return new GameLib.D3.API.Entity( this.id, this.name, this.ids, this.position.toApiVector(), this.quaternion.toApiQuaternion(), this.scale.toApiVector(), GameLib.D3.Utils.IdOrNull(this.parentScene), GameLib.D3.Utils.IdOrNull(this.mesh) ); }; /** * * @param graphics GameLib.D3.Graphics * @param objectEntity Object * @constructor */ GameLib.D3.Entity.FromObjectEntity = function(graphics, objectEntity) { var apiEntity = new GameLib.D3.API.Entity( objectEntity.id, objectEntity.name, objectEntity.ids, new GameLib.D3.API.Vector3( objectEntity.position.x, objectEntity.position.y, objectEntity.position.z ), new GameLib.D3.API.Quaternion( objectEntity.quaternion.x, objectEntity.quaternion.y, objectEntity.quaternion.z, objectEntity.quaternion.w, new GameLib.D3.API.Vector3( objectEntity.quaternion.axis.x, objectEntity.quaternion.axis.y, objectEntity.quaternion.axis.z ) ), new GameLib.D3.API.Vector3( objectEntity.scale.x, objectEntity.scale.y, objectEntity.scale.z ), objectEntity.parentScene, objectEntity.mesh ); return new GameLib.D3.Entity( graphics, apiEntity ); }; /** * Updates the Entity and it's components * @param deltaTime Number */ GameLib.D3.Entity.prototype.update = function( deltaTime ) { for(var c in this.ids) { var id = this.ids[c]; var component = this.parentScene.idToObject[id]; if(component && component.onUpdate) { component.onUpdate(deltaTime, this); } } // todo: maybe we only need to call this AFTER late update this.updateMesh(); this.onUpdate(deltaTime); }; GameLib.D3.Entity.prototype.updateMesh = function() { if (this.mesh) { /** * Normalize to prevent stretching */ this.quaternion.normalize(); this.mesh.position.x = this.position.x; this.mesh.position.y = this.position.y; this.mesh.position.z = this.position.z; this.mesh.scale.x = this.scale.x; this.mesh.scale.y = this.scale.y; this.mesh.scale.z = this.scale.z; this.mesh.quaternion.x = this.quaternion.x; this.mesh.quaternion.y = this.quaternion.y; this.mesh.quaternion.z = this.quaternion.z; this.mesh.quaternion.w = this.quaternion.w; this.mesh.updateInstance(); } }; /** * Late updates the Entity and it's components * @param deltaTime Number */ GameLib.D3.Entity.prototype.lateUpdate = function( deltaTime ) { for(var c in this.ids) { var id = this.ids[c]; var component = this.parentScene.idToObject[id]; if(component && component.onLateUpdate) { component.onLateUpdate(deltaTime, this); } } this.updateMesh(); this.onLateUpdate(deltaTime); }; /** * Gets called when the entity was registered with it's parent scene * @param parentScene GameLib.D3.Scene */ GameLib.D3.Entity.prototype.register = function( parentScene ) { // this.parentScene = parentScene; // // if (this.mesh && this.mesh.id != null && parentScene.meshIdToMesh[this.mesh.id]) { // parentScene.instance.add(parentScene.meshIdToMesh[this.mesh.id]); // this.mesh = parentScene.meshIdToMesh[this.id]; // } this.onRegistered(this.parentScene); }; /** * Add an already registered component to the entity * @param id Number */ GameLib.D3.Entity.prototype.addComponentId = function( id ) { this.ids.push(id); }; /** * Adds a components to the entity and registers it with the entity's parent scene * @param component GameLib.D3.ComponentInterface */ GameLib.D3.Entity.prototype.addComponent = function( component ) { this.parentScene.registerComponent(component); this.ids.push(component.id); if(component.setParentEntity && typeof component.setParentEntity == 'function') { component.setParentEntity(this.parentScene, this); } }; GameLib.D3.Entity.prototype.removeComponent = function(component) { if(component && component.id && this.parentScene.idToObject[component.id]) { this.ids = this.ids.splice(this.ids.indexOf(component), 1); delete this.parentScene.idToObject[component.id]; } }; GameLib.D3.Entity.prototype.getComponent = function( componentType ) { for (var componentId in this.ids) { if (this.ids.hasOwnProperty(componentId)) { var id = this.ids[componentId]; var component = this.parentScene.idToObject[id]; if (component instanceof componentType) { return component; } } } return null; }; ///////////////////////// Methods to override ////////////////////////// GameLib.D3.Entity.prototype.onUpdate = function( deltaTime ) { }; GameLib.D3.Entity.prototype.onLateUpdate = function( deltaTime ) { }; GameLib.D3.Entity.prototype.onRegistered = function( parentScene ) { }; GameLib.D3.Entity.prototype.linkObjects = function(idToObject) { /** * @param scene GameLib.D3.Scene * @param mesh GameLib.D3.Mesh */ GameLib.D3.Utils.Link('parentScene', idToObject, this, this.parentScene); GameLib.D3.Utils.Link('mesh', idToObject, this, this.mesh); };