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..c999894 --- /dev/null +++ b/src/game-lib-component-trigger-box-box.js @@ -0,0 +1,74 @@ +// +// 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 +) { + 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; + + // 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) { + this.onEnter(parentEntity, entityToCheck); + } + } + + + if(this.onInside) { + this.onInside(parentEntity, entityToCheck); + } + + } else if(this.entitiesInside.indexOf(entityToCheck) > -1) { // entity WAS inside the trigger + this.entitiesInside.splice(this.entitiesInside.indexOf(entityToCheck), 1); + + if(this.onLeave) { + this.onLeave(parentEntity, entityToCheck); + } + } + + } + } +}; \ 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 0a90b65..2f91a2c 100644 --- a/src/game-lib-component-trigger-box-sphere.js +++ b/src/game-lib-component-trigger-box-sphere.js @@ -25,7 +25,6 @@ GameLib.D3.ComponentTriggerBoxSphere = function( }; if(typeof THREE != "undefined") { - ComponentTriggerBoxSphere_BoxInverseTransform = new THREE.Matrix4(); ComponentTriggerBoxSphere_TargetPosition_Vec3 = new THREE.Vector3(); ComponentTriggerBoxSphere_TargetRadius = 0.0; } @@ -39,11 +38,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]; @@ -61,14 +57,23 @@ GameLib.D3.ComponentTriggerBoxSphere.prototype.onUpdate = function( entityToCheck.position.z ); - spherePosition.applyMatrix4(ComponentTriggerBoxSphere_BoxInverseTransform); + 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 : 1 + entityToCheck.mesh + ? entityToCheck.mesh.geometry.boundingSphere.radius * maxScale + : 1 ); - if(parentEntity.mesh.geometry.boundingBox.intersectsSphere(sphere)) { + + 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); diff --git a/src/game-lib-component-trigger-sphere-sphere.js b/src/game-lib-component-trigger-sphere-sphere.js index 2ad9bdb..9cc5b97 100644 --- a/src/game-lib-component-trigger-sphere-sphere.js +++ b/src/game-lib-component-trigger-sphere-sphere.js @@ -1,5 +1,7 @@ // // uses the entity position + mesh bounding sphere to check if intersections +// this is a bit jerky to use. +// so please feel free to use the box-sphere & box-box triggers instead. // GameLib.D3.ComponentTriggerSphereSphere = function( componentId, @@ -54,9 +56,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