/** * * @param componentId * @param physicsWorld * @constructor */ GameLib.D3.ComponentVehicleAIObjectAvoidance = function( componentId, physicsWorld ) { this.componentId = componentId || GameLib.D3.Tools.RandomId(); this.parentEntity = null; GameLib.D3.Utils.Extend(GameLib.D3.ComponentVehicleAIObjectAvoidance, GameLib.D3.ComponentInterface); this.raycastVehicleComponent = null; this.physicsWorld = physicsWorld || null; this.sensors = []; // debug this.debugArrows = {}; console.log("constructor for : ComponentVehicleAIObjectAvoidance"); }; ///////////////////////////////////////////////////////////////////////// ///////////////////////// Methods to override /////////////////////////// ///////////////////////////////////////////////////////////////////////// GameLib.D3.ComponentVehicleAIObjectAvoidance.prototype.onSetParentEntity = function( parentScene, parentEntity ) { this.parentEntity = parentEntity; this.raycastVehicleComponent = parentEntity.getComponent(GameLib.D3.RaycastVehicle); console.log("onSetParentEntity for : ComponentVehicleAIObjectAvoidance"); if(!this.raycastVehicleComponent) { console.warn("NO RAYCAST VEHICLE FOUND!"); } // create sensors var boundingBox = this.parentEntity.mesh.geometry.boundingBox; // this is taken from the main.js. // this should be configurable inside the editor var carBoxScaleModifier = { x : 3 / 4, y : 1 / 2, z : 0.90 }; var sensorLength = 0.65; var sensorColor = new THREE.Color(0, 0, 1); // . . . . . . . . . . FRONT . . . . . . . . . . // right this.sensors.push( { sensorLength : sensorLength, sensorColor : sensorColor, sensorDirection : new THREE.Vector3( 1, 0, 0 ).normalize(), sensorPositionOffset : new THREE.Vector3( boundingBox.max.x * this.parentEntity.mesh.scale.x * carBoxScaleModifier.x, boundingBox.max.z * this.parentEntity.mesh.scale.z * carBoxScaleModifier.z, boundingBox.max.y * this.parentEntity.mesh.scale.y * carBoxScaleModifier.y // this is still swapped with y, because cannon. ) } ); // left this.sensors.push( { sensorLength : sensorLength, sensorColor : sensorColor, sensorDirection : new THREE.Vector3( 1, 0, 0 ).normalize(), sensorPositionOffset : new THREE.Vector3( boundingBox.max.x * this.parentEntity.mesh.scale.x * carBoxScaleModifier.x, -boundingBox.max.z * this.parentEntity.mesh.scale.z * carBoxScaleModifier.z, boundingBox.max.y * this.parentEntity.mesh.scale.y * carBoxScaleModifier.y // this is still swapped with y, because cannon. ) } ); // center this.sensors.push( { sensorLength : sensorLength, sensorColor : sensorColor, sensorDirection : new THREE.Vector3( 1, 0, 0 ).normalize(), sensorPositionOffset : new THREE.Vector3( boundingBox.max.x * this.parentEntity.mesh.scale.x * carBoxScaleModifier.x, 0, 0 ) } ); // . . . . . . DIAGONAL FRONT . . . . . . . . // right this.sensors.push( { sensorLength : sensorLength, sensorColor : sensorColor, sensorDirection : new THREE.Vector3( 0, 1, 0 ).normalize(), sensorPositionOffset : new THREE.Vector3( boundingBox.max.x * this.parentEntity.mesh.scale.x * carBoxScaleModifier.x, boundingBox.max.z * this.parentEntity.mesh.scale.z * carBoxScaleModifier.z, boundingBox.max.y * this.parentEntity.mesh.scale.y * carBoxScaleModifier.y // this is still swapped with y, because cannon. ) } ); // left this.sensors.push( { sensorLength : sensorLength, sensorColor : sensorColor, sensorDirection : new THREE.Vector3( 0, -1, 0 ).normalize(), sensorPositionOffset : new THREE.Vector3( boundingBox.max.x * this.parentEntity.mesh.scale.x * carBoxScaleModifier.x, -boundingBox.max.z * this.parentEntity.mesh.scale.z * carBoxScaleModifier.z, boundingBox.max.y * this.parentEntity.mesh.scale.y * carBoxScaleModifier.y // this is still swapped with y, because cannon. ) } ); // right this.sensors.push( { sensorLength : sensorLength, sensorColor : sensorColor, sensorDirection : new THREE.Vector3( 0.5, 0.5, 0 ).normalize(), sensorPositionOffset : new THREE.Vector3( boundingBox.max.x * this.parentEntity.mesh.scale.x * carBoxScaleModifier.x, boundingBox.max.z * this.parentEntity.mesh.scale.z * carBoxScaleModifier.z, boundingBox.max.y * this.parentEntity.mesh.scale.y * carBoxScaleModifier.y // this is still swapped with y, because cannon. ) } ); // left this.sensors.push( { sensorLength : sensorLength, sensorColor : sensorColor, sensorDirection : new THREE.Vector3( 0.5, -0.5, 0 ).normalize(), sensorPositionOffset : new THREE.Vector3( boundingBox.max.x * this.parentEntity.mesh.scale.x * carBoxScaleModifier.x, -boundingBox.max.z * this.parentEntity.mesh.scale.z * carBoxScaleModifier.z, boundingBox.max.y * this.parentEntity.mesh.scale.y * carBoxScaleModifier.y // this is still swapped with y, because cannon. ) } ); // right this.sensors.push( { sensorLength : sensorLength, sensorColor : sensorColor, sensorDirection : new THREE.Vector3( 0.75, 0.25, 0 ).normalize(), sensorPositionOffset : new THREE.Vector3( boundingBox.max.x * this.parentEntity.mesh.scale.x * carBoxScaleModifier.x, boundingBox.max.z * this.parentEntity.mesh.scale.z * carBoxScaleModifier.z, boundingBox.max.y * this.parentEntity.mesh.scale.y * carBoxScaleModifier.y // this is still swapped with y, because cannon. ) } ); // left this.sensors.push( { sensorLength : sensorLength, sensorColor : sensorColor, sensorDirection : new THREE.Vector3( 0.75, -0.25, 0 ).normalize(), sensorPositionOffset : new THREE.Vector3( boundingBox.max.x * this.parentEntity.mesh.scale.x * carBoxScaleModifier.x, -boundingBox.max.z * this.parentEntity.mesh.scale.z * carBoxScaleModifier.z, boundingBox.max.y * this.parentEntity.mesh.scale.y * carBoxScaleModifier.y // this is still swapped with y, because cannon. ) } ); console.log("pushed sensors", this.sensors.length); }; GameLib.D3.ComponentVehicleAIObjectAvoidance.prototype.onUpdate = function( deltaTime, parentEntity ) { if(this.raycastVehicleComponent && this.physicsWorld) { var vehicleVelocity = this.parentEntity.getComponent(GameLib.D3.RigidBody).instance.velocity; var vehicleVelocityLength = 12; // shoot rays for each sensor & check collisions. var world = this.physicsWorld.instance; var result = new CANNON.RaycastResult(); for(var s = 0, l = this.sensors.length; s < l; ++s) { var sensor = this.sensors[s]; var from = new THREE.Vector3( this.parentEntity.position.x, this.parentEntity.position.y, this.parentEntity.position.z ).add(new THREE.Vector3( sensor.sensorPositionOffset.x, sensor.sensorPositionOffset.y, sensor.sensorPositionOffset.z ).applyQuaternion(new THREE.Quaternion( this.parentEntity.quaternion.x, this.parentEntity.quaternion.y, this.parentEntity.quaternion.z, this.parentEntity.quaternion.w ))); var fromC = new CANNON.Vec3( from.x, from.y, from.z ); var to = new THREE.Vector3( sensor.sensorDirection.x, sensor.sensorDirection.y, sensor.sensorDirection.z ).applyQuaternion(new THREE.Quaternion( this.parentEntity.quaternion.x, this.parentEntity.quaternion.y, this.parentEntity.quaternion.z, this.parentEntity.quaternion.w )).normalize().multiplyScalar(sensor.sensorLength * vehicleVelocityLength); var toC = new CANNON.Vec3( from.x + to.x, from.y + to.y, from.z + to.z ); world.raycastClosest( fromC, toC, { collisionFilterMask : 2 // check only group 2 (track) }, result ); if(result.hasHit) { sensor.sensorColor = new THREE.Color(1, 0, 0); } else { sensor.sensorColor = new THREE.Color(0, 0, 1); } } // draw sensors { this.debugArrows.sensors = this.debugArrows.sensors || []; for(var s = 0, l = this.sensors.length; s < l; ++s) { if(!this.debugArrows.sensors[s]) { this.debugArrows.sensors[s] = {}; } if(!this.debugArrows.sensors[s].mesh) { var geometry = new THREE.Geometry(); var mesh = new THREE.Mesh( geometry, new THREE.MeshBasicMaterial( { color : 0x000000, wireframe : true } ) ); this.debugArrows.sensors[s].mesh = mesh; sys.game.scenes["MainScene"].instance.add(this.debugArrows.sensors[s].mesh); } // remove old arrow, if we have one if(this.debugArrows.sensors[s].arrow) { this.debugArrows.sensors[s].mesh.remove(this.debugArrows.sensors[s].arrow); } var sensor = this.sensors[s]; var sensorLength = sensor.sensorLength; // should get this from the sensor itself this.debugArrows.sensors[s].arrow = new THREE.ArrowHelper( new THREE.Vector3( sensor.sensorDirection.x, sensor.sensorDirection.y, sensor.sensorDirection.z ).applyQuaternion(new THREE.Quaternion( this.parentEntity.quaternion.x, this.parentEntity.quaternion.y, this.parentEntity.quaternion.z, this.parentEntity.quaternion.w )).normalize(), new THREE.Vector3( this.parentEntity.position.x, this.parentEntity.position.y, this.parentEntity.position.z ).add(new THREE.Vector3( sensor.sensorPositionOffset.x, sensor.sensorPositionOffset.y, sensor.sensorPositionOffset.z ).applyQuaternion(new THREE.Quaternion( this.parentEntity.quaternion.x, this.parentEntity.quaternion.y, this.parentEntity.quaternion.z, this.parentEntity.quaternion.w ))), sensorLength * vehicleVelocityLength, sensor.sensorColor ); this.debugArrows.sensors[s].mesh.add(this.debugArrows.sensors[s].arrow); } } } };