257 lines
6.5 KiB
JavaScript
257 lines
6.5 KiB
JavaScript
|
/**
|
||
|
* This component makes the parentEntity (ex. car) follow the path provided by the spline
|
||
|
* @param graphics R3.GraphicsRuntime
|
||
|
* @param apiPathFollowing R3.D3.API.PathFollowing
|
||
|
* @constructor
|
||
|
*/
|
||
|
R3.D3.PathFollowing = function (
|
||
|
graphics,
|
||
|
apiPathFollowing
|
||
|
) {
|
||
|
|
||
|
this.graphics = graphics;
|
||
|
this.graphics.isNotThreeThrow();
|
||
|
|
||
|
if (R3.Utils.UndefinedOrNull(apiPathFollowing)) {
|
||
|
apiPathFollowing = {};
|
||
|
}
|
||
|
|
||
|
if (apiPathFollowing instanceof R3.D3.PathFollowing) {
|
||
|
return apiPathFollowing;
|
||
|
}
|
||
|
|
||
|
R3.D3.API.PathFollowing.call(
|
||
|
this,
|
||
|
apiPathFollowing.id,
|
||
|
apiPathFollowing.name,
|
||
|
apiPathFollowing.spline,
|
||
|
apiPathFollowing.mesh,
|
||
|
apiPathFollowing.raytraceMesh,
|
||
|
apiPathFollowing.accelleration,
|
||
|
apiPathFollowing.maxSpeed,
|
||
|
apiPathFollowing.baseOffset,
|
||
|
apiPathFollowing.maxOffset,
|
||
|
apiPathFollowing.steeringSpeed,
|
||
|
apiPathFollowing.targetOffset,
|
||
|
apiPathFollowing.currentOffset,
|
||
|
apiPathFollowing.currentPathValue,
|
||
|
apiPathFollowing.currentSpeed,
|
||
|
apiPathFollowing.direction,
|
||
|
apiPathFollowing.raycaster,
|
||
|
apiPathFollowing.currentPosition,
|
||
|
apiPathFollowing.futurePosition,
|
||
|
apiPathFollowing.up,
|
||
|
apiPathFollowing.rotationMatrix,
|
||
|
apiPathFollowing.rotationVector,
|
||
|
apiPathFollowing.parentEntity
|
||
|
);
|
||
|
|
||
|
this.baseOffset = new R3.Vector3(
|
||
|
this.graphics,
|
||
|
this.baseOffset,
|
||
|
this
|
||
|
);
|
||
|
|
||
|
this.maxOffset = new R3.Vector3(
|
||
|
this.graphics,
|
||
|
this.maxOffset,
|
||
|
this
|
||
|
);
|
||
|
|
||
|
this.targetOffset = new R3.Vector3(
|
||
|
this.graphics,
|
||
|
this.targetOffset,
|
||
|
this
|
||
|
);
|
||
|
|
||
|
this.currentOffset = new R3.Vector3(
|
||
|
this.graphics,
|
||
|
this.currentOffset,
|
||
|
this
|
||
|
);
|
||
|
|
||
|
this.raycaster = new R3.D3.Raycaster(
|
||
|
this.graphics,
|
||
|
this.raycaster
|
||
|
);
|
||
|
|
||
|
this.currentPosition = new R3.Vector3(
|
||
|
this.graphics,
|
||
|
this.currentPosition,
|
||
|
this
|
||
|
);
|
||
|
|
||
|
this.futurePosition = new R3.Vector3(
|
||
|
this.graphics,
|
||
|
this.futurePosition,
|
||
|
this
|
||
|
);
|
||
|
|
||
|
this.up = new R3.Vector3(
|
||
|
this.graphics,
|
||
|
this.up,
|
||
|
this
|
||
|
);
|
||
|
|
||
|
this.rotationMatrix = new R3.Matrix4(
|
||
|
this.graphics,
|
||
|
this.rotationMatrix,
|
||
|
this
|
||
|
);
|
||
|
|
||
|
this.rotationVector = new R3.Quaternion(
|
||
|
this.graphics,
|
||
|
this.rotationVector,
|
||
|
this
|
||
|
);
|
||
|
|
||
|
this.mx = new R3.Utils.MovingAverage(10);
|
||
|
this.my = new R3.Utils.MovingAverage(10);
|
||
|
this.mz = new R3.Utils.MovingAverage(10);
|
||
|
|
||
|
R3.Component.call(
|
||
|
this,
|
||
|
R3.Component.COMPONENT_PATH_FOLLOWING,
|
||
|
{
|
||
|
'spline': R3.D3.Spline,
|
||
|
'mesh' : R3.D3.Mesh,
|
||
|
'raytraceMesh' : R3.D3.Mesh
|
||
|
}
|
||
|
);
|
||
|
};
|
||
|
|
||
|
R3.D3.PathFollowing.prototype = Object.create(R3.D3.API.PathFollowing.prototype);
|
||
|
R3.D3.PathFollowing.prototype.constructor = R3.D3.PathFollowing;
|
||
|
|
||
|
R3.D3.PathFollowing.prototype.createInstance = function() {
|
||
|
|
||
|
console.log('R3.D3.PathFollowing.prototype.createInstance()');
|
||
|
|
||
|
R3.Component.prototype.createInstance.call(this);
|
||
|
|
||
|
};
|
||
|
|
||
|
R3.D3.PathFollowing.prototype.toApiObject = function() {
|
||
|
|
||
|
var apiPathFollowing = new R3.D3.API.PathFollowing(
|
||
|
this.id,
|
||
|
this.name,
|
||
|
R3.Utils.IdOrNull(this.spline),
|
||
|
R3.Utils.IdOrNull(this.mesh),
|
||
|
R3.Utils.IdOrNull(this.raytraceMesh),
|
||
|
this.accelleration,
|
||
|
this.maxSpeed,
|
||
|
this.baseOffset.toApiObject(),
|
||
|
this.maxOffset.toApiObject(),
|
||
|
this.steeringSpeed,
|
||
|
this.targetOffset.toApiObject(),
|
||
|
this.currentOffset.toApiObject(),
|
||
|
this.currentPathValue,
|
||
|
this.currentSpeed,
|
||
|
this.direction,
|
||
|
this.raycaster.toApiObject(),
|
||
|
this.currentPosition.toApiObject(),
|
||
|
this.futurePosition.toApiObject(),
|
||
|
this.up.toApiObject(),
|
||
|
this.rotationMatrix.toApiObject(),
|
||
|
this.rotationVector.toApiObject(),
|
||
|
R3.Utils.IdOrNull(this.parentEntity)
|
||
|
);
|
||
|
|
||
|
return apiPathFollowing;
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Object path following to R3.D3.PathFollowing
|
||
|
* @param graphics
|
||
|
* @param objectComponent
|
||
|
* @returns {R3.D3.PathFollowing}
|
||
|
* @constructor
|
||
|
*/
|
||
|
R3.D3.PathFollowing.FromObject = function(graphics, objectComponent) {
|
||
|
|
||
|
var apiPathFollowing = R3.D3.API.PathFollowing.FromObject(objectComponent);
|
||
|
|
||
|
return new R3.D3.PathFollowing(
|
||
|
graphics,
|
||
|
apiPathFollowing
|
||
|
);
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Updates the component
|
||
|
* @param deltaTime
|
||
|
*/
|
||
|
R3.D3.PathFollowing.prototype.update = function(deltaTime) {
|
||
|
|
||
|
if (this.spline && this.mesh && this.raytraceMesh) {
|
||
|
|
||
|
this.currentSpeed += this.accelleration * deltaTime * this.direction;
|
||
|
if(this.currentSpeed > this.maxSpeed) {
|
||
|
this.currentSpeed = this.maxSpeed;
|
||
|
}
|
||
|
this.grain = (this.currentSpeed / 100.0);
|
||
|
|
||
|
var currentPosition = this.spline.getPointAt(this.currentPathValue);
|
||
|
|
||
|
this.currentPosition.x = currentPosition.x;
|
||
|
this.currentPosition.y = currentPosition.y;
|
||
|
this.currentPosition.z = currentPosition.z;
|
||
|
|
||
|
this.currentPathValue += this.grain;
|
||
|
|
||
|
if (this.currentPathValue >= 1) {
|
||
|
this.currentPathValue = this.currentPathValue - 1;
|
||
|
}
|
||
|
|
||
|
if (this.currentPathValue < 0) {
|
||
|
this.currentPathValue = 0.0;
|
||
|
}
|
||
|
|
||
|
var futurePosition = this.spline.getPointAt(this.currentPathValue);
|
||
|
|
||
|
this.futurePosition.x = futurePosition.x;
|
||
|
this.futurePosition.y = futurePosition.y;
|
||
|
this.futurePosition.z = futurePosition.z;
|
||
|
|
||
|
this.raycaster.setPosition(
|
||
|
this.currentPosition
|
||
|
);
|
||
|
|
||
|
this.raycaster.setDirection(
|
||
|
{
|
||
|
x : -this.up.x,
|
||
|
y : -this.up.y,
|
||
|
z : -this.up.z
|
||
|
}
|
||
|
);
|
||
|
|
||
|
var normal = this.raycaster.getFaceNormal(this.raytraceMesh);
|
||
|
|
||
|
if (normal) {
|
||
|
this.up.x = this.mx(normal.x);
|
||
|
this.up.y = this.my(normal.y);
|
||
|
this.up.z = this.mz(normal.z);
|
||
|
}
|
||
|
|
||
|
this.rotationMatrix.lookAt(
|
||
|
this.currentPosition,
|
||
|
this.futurePosition,
|
||
|
this.up
|
||
|
);
|
||
|
|
||
|
this.rotationVector.setFromRotationMatrix(this.rotationMatrix);
|
||
|
|
||
|
this.mesh.position.x = this.futurePosition.x;
|
||
|
this.mesh.position.y = this.futurePosition.y;
|
||
|
this.mesh.position.z = this.futurePosition.z;
|
||
|
|
||
|
/**
|
||
|
* Update Rotation
|
||
|
*/
|
||
|
this.mesh.quaternion.x = this.rotationVector.x;
|
||
|
this.mesh.quaternion.y = this.rotationVector.y;
|
||
|
this.mesh.quaternion.z = this.rotationVector.z;
|
||
|
this.mesh.quaternion.w = this.rotationVector.w;
|
||
|
}
|
||
|
};
|