r3-legacy/src/game-lib-component-vehicle-...

570 lines
18 KiB
JavaScript

/**
*
* @param id
* @param name
* @param physicsWorld
* @constructor
*/
GameLib.D3.ComponentVehicleAIObjectAvoidance = function(
id,
name,
physicsWorld
) {
this.id = id|| GameLib.D3.Tools.RandomId();
if (typeof name == 'undefined') {
name = this.constructor.name;
}
this.name = name;
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");
};
//#ifdef RUNTIME__
/////////////////////////////////////////////////////////////////////////
///////////////////////// 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 = 7.0;
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,
0//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,
0//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,
0//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,
0//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,
0//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,
0//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,
0//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,
0//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) {
// debug
this.debugArrows.avgDirection = this.debugArrows.avgDirection || {};
this.debugArrows.sensors = this.debugArrows.sensors || [];
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();
this.debugArrows.avgDirection.vector = new THREE.Vector3();
for(var s = 0, l = this.sensors.length; s < l; ++s) {
// debug
if(!this.debugArrows.sensors[s]) {
this.debugArrows.sensors[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);
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);
var direction = 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();
/*var reflection = direction.reflect(
new THREE.Vector3(
result.hitNormalWorld.x,
result.hitNormalWorld.y,
result.hitNormalWorld.z
)
).normalize();*/
var reflection = direction.reflect(
new THREE.Vector3(
result.hitPointWorld.x,
result.hitPointWorld.y,
result.hitPointWorld.z
).normalize().cross(direction)
).normalize().negate();
var origin = 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 moveDirection = direction.add(reflection).setY(0).normalize();
this.debugArrows.avgDirection.vector = this.debugArrows.avgDirection.vector.add(moveDirection);
if(this.debugArrows.sensors[s].intersectionArrow && this.debugArrows.sensors[s].mesh) {
this.debugArrows.sensors[s].mesh.remove(this.debugArrows.sensors[s].intersectionArrow);
}
if(this.debugArrows.sensors[s].mesh){
var arrow = new THREE.ArrowHelper(
moveDirection,
origin,
22,
new THREE.Color(1, 1, 0)
);
this.debugArrows.sensors[s].intersectionArrow = arrow;
this.debugArrows.sensors[s].mesh.add(this.debugArrows.sensors[s].intersectionArrow);
}
} else {
sensor.sensorColor = new THREE.Color(0, 0, 1);
if(this.debugArrows.sensors[s].intersectionArrow && this.debugArrows.sensors[s].mesh) {
this.debugArrows.sensors[s].mesh.remove(this.debugArrows.sensors[s].intersectionArrow);
}
}
}
this.debugArrows.avgDirection.vector = this.debugArrows.avgDirection.vector.normalize();
// draw the avg move direction
/*if(!this.debugArrows.avgDirection.mesh) {
this.debugArrows.avgDirection.mesh = new THREE.Mesh(
new THREE.Geometry(),
new THREE.MeshBasicMaterial(
{
color : 0x00ffff,
wireframe : true
}
)
);
sys.game.scenes["MainScene"].instance.add(this.debugArrows.avgDirection.mesh);
}
if(this.debugArrows.avgDirection.arrow && this.debugArrows.avgDirection.mesh) {
this.debugArrows.avgDirection.mesh.remove(this.debugArrows.avgDirection.arrow);
}*/
/*this.debugArrows.avgDirection.arrow = new THREE.ArrowHelper(
this.debugArrows.avgDirection.vector,
new THREE.Vector3(
this.parentEntity.position.x,
this.parentEntity.position.y,
this.parentEntity.position.z
),
12,
this.debugArrows.avgDirection.mesh.material.color
);*/
//this.debugArrows.avgDirection.mesh.add(this.debugArrows.avgDirection.arrow);
// draw sensors
/*{
for(var s = 0, l = this.sensors.length; s < l; ++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,
sensor.sensorColor
);
this.debugArrows.sensors[s].mesh.add(this.debugArrows.sensors[s].arrow);
}
}*/
// . . . . . . . . . . . . correct the path . . . . . . . . . . . . . .
if( this.debugArrows.avgDirection.vector.x != 0
|| this.debugArrows.avgDirection.vector.y != 0
|| this.debugArrows.avgDirection.vector.z != 0
) {
// get forward direction OR better the velocity angle of the car
var avgMoveVector = this.debugArrows.avgDirection.vector;
var forward = new THREE.Vector3(
1,
0,
0
).applyQuaternion(new THREE.Quaternion(
this.parentEntity.quaternion.x,
this.parentEntity.quaternion.y,
this.parentEntity.quaternion.z,
this.parentEntity.quaternion.w
)).setY(0).normalize();
// get angle and steer.
var cos = avgMoveVector.dot(forward);
var angleRadians = Math.acos(cos);
var steerAngleModifier = GameLib.D3.Vector3.AngleDirection(
forward,
avgMoveVector,
new GameLib.D3.Vector3(
0,
1,
0
)
);
var steerAngle = Math.min(angleRadians, 0.5) * steerAngleModifier;
this.raycastVehicleComponent.instance.setSteeringValue(steerAngle, 0);
this.raycastVehicleComponent.instance.setSteeringValue(steerAngle, 1);
}
}
};
//#endif