279 lines
6.3 KiB
JavaScript
279 lines
6.3 KiB
JavaScript
/**
|
|
* Raycaster for GameLib.D3
|
|
* @param graphics GameLib.GraphicsRuntime
|
|
* @param apiRaycaster
|
|
* @constructor
|
|
*/
|
|
GameLib.D3.Raycaster = function(
|
|
graphics,
|
|
apiRaycaster
|
|
) {
|
|
|
|
this.graphics = graphics;
|
|
this.graphics.isNotThreeThrow();
|
|
|
|
if (GameLib.Utils.UndefinedOrNull(apiRaycaster)) {
|
|
apiRaycaster = {};
|
|
}
|
|
|
|
if (apiRaycaster instanceof GameLib.D3.Raycaster) {
|
|
return apiRaycaster;
|
|
}
|
|
|
|
GameLib.D3.API.Raycaster.call(
|
|
this,
|
|
apiRaycaster.id,
|
|
apiRaycaster.name,
|
|
apiRaycaster.position,
|
|
apiRaycaster.direction
|
|
);
|
|
|
|
this.position = new GameLib.Vector3(
|
|
this.graphics,
|
|
this.position,
|
|
this
|
|
);
|
|
|
|
this.direction = new GameLib.Vector3(
|
|
this.graphics,
|
|
this.direction,
|
|
this
|
|
);
|
|
|
|
GameLib.Component.call(this);
|
|
};
|
|
|
|
GameLib.D3.Raycaster.prototype = Object.create(GameLib.D3.API.Raycaster.prototype);
|
|
GameLib.D3.Raycaster.prototype.constructor = GameLib.D3.Raycaster;
|
|
|
|
/**
|
|
* Creates or updates a raycaster instance
|
|
*/
|
|
GameLib.D3.Raycaster.prototype.createInstance = function() {
|
|
this.instance = new THREE.Raycaster();
|
|
this.instance.set(
|
|
this.position.instance,
|
|
this.direction.instance
|
|
);
|
|
|
|
GameLib.Component.prototype.createInstance.call(this);
|
|
};
|
|
|
|
GameLib.D3.Raycaster.prototype.updateInstance = function() {
|
|
|
|
this.position.instance.x = this.position.x;
|
|
this.position.instance.y = this.position.y;
|
|
this.position.instance.z = this.position.z;
|
|
|
|
this.direction.instance.x = this.direction.x;
|
|
this.direction.instance.y = this.direction.y;
|
|
this.direction.instance.z = this.direction.z;
|
|
|
|
this.instance.set(
|
|
this.position.instance,
|
|
this.direction.instance
|
|
);
|
|
};
|
|
|
|
GameLib.D3.Raycaster.prototype.toApiObject = function() {
|
|
return new GameLib.D3.API.Raycaster(
|
|
this.id,
|
|
this.name,
|
|
this.position.toApiObject(),
|
|
this.direction.toApiObject(),
|
|
GameLib.Utils.IdOrNull(this.parentEntity)
|
|
)
|
|
};
|
|
|
|
GameLib.D3.Raycaster.FromObject = function(graphics, objectRaycaster) {
|
|
|
|
var apiRaycaster = GameLib.D3.API.Raycaster.FromObject(objectRaycaster);
|
|
|
|
var raycaster = new GameLib.D3.Raycaster(
|
|
graphics,
|
|
apiRaycaster
|
|
);
|
|
|
|
return raycaster;
|
|
};
|
|
|
|
/**
|
|
* Sets the direction and position of this raycaster
|
|
* @param position GameLib.Vector3
|
|
* @param direction GameLib.Vector3
|
|
*/
|
|
GameLib.D3.Raycaster.prototype.set = function(
|
|
position,
|
|
direction
|
|
) {
|
|
this.position.x = position.x;
|
|
this.position.y = position.y;
|
|
this.position.z = position.z;
|
|
|
|
this.direction.x = direction.x;
|
|
this.direction.y = direction.y;
|
|
this.direction.z = direction.z;
|
|
|
|
this.position.updateInstance();
|
|
this.direction.updateInstance();
|
|
};
|
|
|
|
/**
|
|
* Sets the direction of this raycaster
|
|
* @param direction GameLib.Vector3
|
|
*/
|
|
GameLib.D3.Raycaster.prototype.setDirection = function(
|
|
direction
|
|
) {
|
|
this.direction.x = direction.x;
|
|
this.direction.y = direction.y;
|
|
this.direction.z = direction.z;
|
|
|
|
this.direction.updateInstance();
|
|
};
|
|
|
|
/**
|
|
* Sets the position of this raycaster
|
|
* @param position GameLib.Vector3
|
|
*/
|
|
GameLib.D3.Raycaster.prototype.setPosition = function(
|
|
position
|
|
) {
|
|
this.position.x = position.x;
|
|
this.position.y = position.y;
|
|
this.position.z = position.z;
|
|
|
|
this.position.updateInstance();
|
|
};
|
|
|
|
/**
|
|
* Sets the ray position and direction from the mouse coordinates (in proper x and y (-1 to 1))
|
|
* @param mouse
|
|
* @param camera
|
|
*/
|
|
GameLib.D3.Raycaster.prototype.setFromCamera = function(
|
|
mouse,
|
|
camera
|
|
) {
|
|
this.instance.setFromCamera(
|
|
mouse,
|
|
camera.instance
|
|
);
|
|
|
|
this.position.x = this.instance.ray.origin.x;
|
|
this.position.y = this.instance.ray.origin.y;
|
|
this.position.z = this.instance.ray.origin.z;
|
|
|
|
this.direction.x = this.instance.ray.direction.x;
|
|
this.direction.y = this.instance.ray.direction.y;
|
|
this.direction.z = this.instance.ray.direction.z;
|
|
};
|
|
|
|
/**
|
|
* Gets all interesected GameLib.D3.Mesh objects
|
|
* @param meshes [GameLib.D3.Mesh]
|
|
*/
|
|
GameLib.D3.Raycaster.prototype.getIntersectedObjects = function(meshes) {
|
|
|
|
return meshes.reduce(
|
|
function (result, mesh) {
|
|
|
|
var intersects = this.instance.intersectObject(mesh.instance);
|
|
|
|
if (intersects.length > 0) {
|
|
result.push(
|
|
{
|
|
mesh: mesh,
|
|
distance : intersects[0].distance
|
|
}
|
|
);
|
|
}
|
|
|
|
return result;
|
|
}.bind(this),
|
|
[]
|
|
);
|
|
|
|
// var intersects = this.instance.intersectObjects(meshInstances);
|
|
//
|
|
// return intersects.reduce(
|
|
//
|
|
// function (result, intersect) {
|
|
//
|
|
// meshes.map(
|
|
// function(mesh){
|
|
// if (mesh.instance === intersect.object){
|
|
// result.push(
|
|
// {
|
|
// mesh : mesh,
|
|
// distance : intersect.distance
|
|
// }
|
|
// );
|
|
// }
|
|
// }
|
|
// );
|
|
//
|
|
// return result;
|
|
// },
|
|
// []
|
|
// );
|
|
|
|
};
|
|
|
|
|
|
/**
|
|
* Returns the face normal (if any) of an intersection between current ray position, direction and a provided mesh
|
|
* @param mesh GameLib.D3.Mesh
|
|
* @returns {null | GameLib.Vector3}
|
|
*/
|
|
GameLib.D3.Raycaster.prototype.getFaceNormal = function(mesh) {
|
|
|
|
var normal = null;
|
|
|
|
var intersect = this.instance.intersectObject(
|
|
mesh.instance
|
|
);
|
|
|
|
if (intersect && intersect.length > 0) {
|
|
|
|
normal = new GameLib.Vector3(
|
|
this.graphics,
|
|
new GameLib.API.Vector3(
|
|
intersect[0].face.normal.x,
|
|
intersect[0].face.normal.y,
|
|
intersect[0].face.normal.z
|
|
),
|
|
this
|
|
);
|
|
}
|
|
|
|
return normal;
|
|
};
|
|
|
|
/**
|
|
* Returns the face normal (if any) of an intersection between current ray position, direction and a provided mesh
|
|
* @param mesh GameLib.D3.Mesh
|
|
* @returns {null | GameLib.Vector3}
|
|
*/
|
|
GameLib.D3.Raycaster.prototype.getIntersectPoint = function(mesh) {
|
|
|
|
var point = null;
|
|
|
|
var intersect = this.instance.intersectObject(
|
|
mesh.instance
|
|
);
|
|
|
|
if (intersect && intersect.length > 0) {
|
|
point = new GameLib.Vector3(
|
|
this.graphics,
|
|
new GameLib.API.Vector3(
|
|
intersect[0].point.x,
|
|
intersect[0].point.y,
|
|
intersect[0].point.z
|
|
),
|
|
this
|
|
);
|
|
}
|
|
|
|
return point;
|
|
}; |