diff --git a/src/game-lib-component-trigger-box-box.js b/src/game-lib-component-trigger-box-box.js new file mode 100644 index 0000000..6d92be7 --- /dev/null +++ b/src/game-lib-component-trigger-box-box.js @@ -0,0 +1,91 @@ +// +// this component operates on it's parent entity's bounding box. +// so, you can't use this component with a null-mesh. +// +GameLib.D3.ComponentTriggerBoxBox = function( + componentId, + entitiesToCheck, + onInside, + onEnter, + onLeave, + onSetParent +) { + this.componentId = componentId || GameLib.D3.Tools.RandomId(); + this.parentEntity = null; + + // Todo: this should be executed somewhere in game-lib-z, so that we don't execute it on every construction of an object. + GameLib.D3.Utils.Extend(GameLib.D3.ComponentTriggerBoxBox, GameLib.D3.ComponentInterface); + + this.entitiesToCheck = entitiesToCheck || []; + this.onInside = onInside || null; + this.onEnter = onEnter || null; + this.onLeave = onLeave || null; + this.onSetParent = onSetParent || null; + + // runtime code + this.entitiesInside = []; +}; + +if(typeof THREE != "undefined") { + ComponentTriggerBoxBox_BB = new THREE.Box3(); + ComponentTriggerBoxBox_BBEntity = new THREE.Box3(); +} + + +///////////////////////// Methods to override ////////////////////////// +GameLib.D3.ComponentTriggerBoxBox.prototype.onUpdate = function( + deltaTime, + parentEntity +) { + + if(parentEntity.mesh) { + // Calculate the current transform here, using the position, orientation and scale of the entity. + + ComponentTriggerBoxBox_BB.setFromObject(parentEntity.mesh); + + for(var e in this.entitiesToCheck) { + var entityToCheck = this.entitiesToCheck[e]; + + ComponentTriggerBoxBox_BBEntity.setFromObject(entityToCheck.mesh); + + if(ComponentTriggerBoxBox_BB.intersectsBox(ComponentTriggerBoxBox_BBEntity)) { + + if(this.entitiesInside.indexOf(entityToCheck) <= -1) { // check if this is the first time the entity enters the trigger + this.entitiesInside.push(entityToCheck); + + if(this.onEnter) { + if(this.onEnter(parentEntity, entityToCheck)) { + break; + } + } + } + + + if(this.onInside) { + if(this.onInside(parentEntity, entityToCheck)) { + break; + } + } + + } else if(this.entitiesInside.indexOf(entityToCheck) > -1) { // entity WAS inside the trigger + this.entitiesInside.splice(this.entitiesInside.indexOf(entityToCheck), 1); + + if(this.onLeave) { + if(this.onLeave(parentEntity, entityToCheck)) { + break; + } + } + } + + } + } +}; + +GameLib.D3.ComponentTriggerBoxBox.prototype.onSetParentEntity = function( + parentScene, + parentEntity +) { + if(this.onSetParent) { + this.onSetParent(parentScene, parentEntity); + } +}; \ No newline at end of file diff --git a/src/game-lib-component-trigger-box-sphere.js b/src/game-lib-component-trigger-box-sphere.js index e74c4a0..ad76876 100644 --- a/src/game-lib-component-trigger-box-sphere.js +++ b/src/game-lib-component-trigger-box-sphere.js @@ -6,7 +6,10 @@ GameLib.D3.ComponentTriggerBoxSphere = function ComponentTriggerBoxSphere( id, name, entitiesToCheck, - callback + onInside, + onEnter, + onLeave, + onSetParent ) { this.id = id || GameLib.D3.Tools.RandomId(); @@ -21,11 +24,16 @@ GameLib.D3.ComponentTriggerBoxSphere = function ComponentTriggerBoxSphere( GameLib.D3.Utils.Extend(GameLib.D3.ComponentTriggerBoxSphere, GameLib.D3.ComponentInterface); this.entitiesToCheck = entitiesToCheck || []; - this.callback = callback || null; + this.onInside = onInside || null; + this.onEnter = onEnter || null; + this.onLeave = onLeave || null; + this.onSetParent = onSetParent || null; + + // runtime code + this.entitiesInside = []; }; if(typeof THREE != "undefined") { - ComponentTriggerBoxSphere_BoxInverseTransform = new THREE.Matrix4(); ComponentTriggerBoxSphere_TargetPosition_Vec3 = new THREE.Vector3(); ComponentTriggerBoxSphere_TargetRadius = 0.0; } @@ -39,11 +47,8 @@ GameLib.D3.ComponentTriggerBoxSphere.prototype.onUpdate = function( if(parentEntity.mesh) { // Calculate the current transform here, using the position, orientation and scale of the entity. - if(!parentEntity.mesh.geometry.boundingBox) { - parentEntity.mesh.geometry.computeBoundingBox(); - } - - ComponentTriggerBoxSphere_BoxInverseTransform.getInverse(parentEntity.mesh.matrix); + var bb = new THREE.Box3(); + bb.setFromObject(parentEntity.mesh); for(var e in this.entitiesToCheck) { var entityToCheck = this.entitiesToCheck[e]; @@ -53,44 +58,68 @@ GameLib.D3.ComponentTriggerBoxSphere.prototype.onUpdate = function( if (!entityToCheck.mesh.geometry.boundingSphere) { entityToCheck.mesh.geometry.computeBoundingSphere(); } - - var spherePosition = new THREE.Vector3( - entityToCheck.position.x, - entityToCheck.position.y, - entityToCheck.position.z - ); - - spherePosition.applyMatrix4(ComponentTriggerBoxSphere_BoxInverseTransform); - - var sphere = new THREE.Sphere( - spherePosition, - entityToCheck.mesh.geometry.boundingSphere.radius - ); - - if(this.callback && parentEntity.mesh.geometry.boundingBox.intersectsSphere(sphere)) { - this.callback(parentEntity, entityToCheck); - } - - } else { // no target mesh geometry. - - var spherePosition = new THREE.Vector3( - entityToCheck.position.x, - entityToCheck.position.y, - entityToCheck.position.z - ); - - spherePosition.applyMatrix4(ComponentTriggerBoxSphere_BoxInverseTransform); - - var sphere = new THREE.Sphere( - spherePosition, - 1 - ); - - if(this.callback && parentEntity.mesh.geometry.boundingBox.intersectsSphere(sphere)) { - this.callback(parentEntity, entityToCheck); - } - } + + var spherePosition = new THREE.Vector3( + entityToCheck.position.x, + entityToCheck.position.y, + entityToCheck.position.z + ); + + var maxScale = Math.max( + entityToCheck.scale.x, + Math.max( + entityToCheck.scale.y, + entityToCheck.scale.z + ) + ); + + var sphere = new THREE.Sphere( + spherePosition, + entityToCheck.mesh + ? entityToCheck.mesh.geometry.boundingSphere.radius * maxScale + : 1 + ); + + + if(bb.intersectsSphere(sphere)) { + + if(this.entitiesInside.indexOf(entityToCheck) <= -1) { // check if this is the first time the entity enters the trigger + this.entitiesInside.push(entityToCheck); + + if(this.onEnter) { + if(this.onEnter(parentEntity, entityToCheck)) { + break; + } + } + } + + + if(this.onInside) { + if(this.onInside(parentEntity, entityToCheck)) { + break; + } + } + + } else if(this.entitiesInside.indexOf(entityToCheck) > -1) { // entity WAS inside the trigger + this.entitiesInside.splice(this.entitiesInside.indexOf(entityToCheck), 1); + + if(this.onLeave) { + if(this.onLeave(parentEntity, entityToCheck)) { + break; + } + } + } + } } +}; + +GameLib.D3.ComponentTriggerBoxSphere.prototype.onSetParentEntity = function( + parentScene, + parentEntity +) { + if(this.onSetParent) { + this.onSetParent(parentScene, parentEntity); + } }; \ No newline at end of file diff --git a/src/game-lib-component-trigger-sphere-sphere.js b/src/game-lib-component-trigger-sphere-sphere.js index 8902f2a..8d6dfac 100644 --- a/src/game-lib-component-trigger-sphere-sphere.js +++ b/src/game-lib-component-trigger-sphere-sphere.js @@ -13,9 +13,12 @@ GameLib.D3.ComponentTriggerSphereSphere = function ComponentTriggerSphereSphere( name, sphereRadius, entitiesToCheck, - callback + onInside, + onEnter, + onLeave, + onSetParent ) { - this.id = id || GameLib.D3.Tools.RandomId(); + this.id = id || GameLib.D3.Tools.RandomId(); if (typeof name == 'undefined') { name = this.constructor.name; @@ -29,7 +32,13 @@ GameLib.D3.ComponentTriggerSphereSphere = function ComponentTriggerSphereSphere( this.entitiesToCheck = entitiesToCheck || []; this.sphereRadius = sphereRadius || 1.0; - this.callback = callback || null; + this.onInside = onInside || null; + this.onEnter = onEnter || null; + this.onLeave = onLeave || null; + this.onSetParent = onSetParent || null; + + // runtime code + this.entitiesInside = []; }; if(typeof THREE != "undefined") { @@ -61,9 +70,16 @@ GameLib.D3.ComponentTriggerSphereSphere.prototype.onUpdate = function( ); if(entityToCheck.mesh && entityToCheck.mesh.geometry.boundingSphere) { - ComponentTriggerSphereSphere_targetBoundingSphereRadius = entityToCheck.mesh.geometry.boundingSphere.radius; + var maxScale = Math.max( + entityToCheck.scale.x, + Math.max( + entityToCheck.scale.y, + entityToCheck.scale.z + ) + ); + ComponentTriggerSphereSphere_targetBoundingSphereRadius = entityToCheck.mesh.geometry.boundingSphere.radius * maxScale; } else { - ComponentTriggerSphereSphere_targetBoundingSphereRadius = 0.0; + ComponentTriggerSphereSphere_targetBoundingSphereRadius = 1.0; } // do sphere sphere collision @@ -77,9 +93,40 @@ GameLib.D3.ComponentTriggerSphereSphere.prototype.onUpdate = function( var length = ComponentTriggerSphereSphere_sphereToSphere_Vector3.length(); if((length - (ComponentTriggerSphereSphere_targetBoundingSphereRadius + this.sphereRadius)) < 0) { - if(this.callback) { - this.callback(parentEntity, entityToCheck); + + if(this.entitiesInside.indexOf(entityToCheck) <= -1) { // check if this is the first time the entity enters the trigger + this.entitiesInside.push(entityToCheck); + + if(this.onEnter) { + if(this.onEnter(parentEntity, entityToCheck)) { + break; + } + } + } + + if(this.onInside) { + if(this.onInside(parentEntity, entityToCheck)) { + break; + } + } + + } else if(this.entitiesInside.indexOf(entityToCheck) > -1) { // entity WAS inside the trigger + this.entitiesInside.splice(this.entitiesInside.indexOf(entityToCheck), 1); + + if(this.onLeave) { + if(this.onLeave(parentEntity, entityToCheck)) { + break; + } } } } +}; + +GameLib.D3.ComponentTriggerSphereSphere.prototype.onSetParentEntity = function( + parentScene, + parentEntity +) { + if(this.onSetParent) { + this.onSetParent(parentScene, parentEntity); + } }; \ No newline at end of file diff --git a/src/game-lib-game.js b/src/game-lib-game.js index 70cdadd..8f70283 100644 --- a/src/game-lib-game.js +++ b/src/game-lib-game.js @@ -31,7 +31,7 @@ GameLib.D3.Game.prototype.render = function( ) { for(var s in this.scenes) { var scene = this.scenes[s]; - scene.render(dt, renderer, camera); + scene.render(dt, renderer, scene.camera); } }; diff --git a/src/game-lib-scene.js b/src/game-lib-scene.js index a2cb4f0..ff96ff8 100644 --- a/src/game-lib-scene.js +++ b/src/game-lib-scene.js @@ -224,10 +224,10 @@ GameLib.D3.Scene.prototype.loadTextures = function(urls, onLoadedCallback) { gameLibTexture.wrapS, gameLibTexture.wrapT, gameLibTexture.magFilter, - gameLibTexture.minFilter, - gameLibTexture.format, - gameLibTexture.textureType, - gameLibTexture.anisotropy + gameLibTexture.minFilter + //gameLibTexture.format, + //gameLibTexture.textureType, + //gameLibTexture.anisotropy ); instanceMaterial[instanceMapId].name = gameLibTexture.name; @@ -743,6 +743,13 @@ GameLib.D3.Scene.FromAPIScene = function( ) }; +/** + * Set on runtime. + */ +GameLib.D3.Scene.prototype.setCamera = function(camera) { + this.sceneCamera = camera; +}; + /** * Updates the scene * @param deltaTime @@ -775,10 +782,11 @@ GameLib.D3.Scene.prototype.lateUpdate = function( */ GameLib.D3.Scene.prototype.render = function( deltaTime, - renderer, - camera + renderer ) { - renderer.render(this.instance, camera); + if(this.sceneCamera) { + renderer.render(this.instance, this.sceneCamera); + } }; /**