r3-legacy/src/r3-d3-raycaster.js

251 lines
5.8 KiB
JavaScript

/**
* Raycaster for R3.D3
* @param graphics R3.Runtime.Graphics
* @param apiRaycaster
* @constructor
*/
R3.D3.Raycaster = function(
graphics,
apiRaycaster
) {
this.graphics = graphics;
this.graphics.isNotThreeThrow();
if (R3.Utils.UndefinedOrNull(apiRaycaster)) {
apiRaycaster = {};
}
R3.D3.API.Raycaster.call(
this,
apiRaycaster.id,
apiRaycaster.name,
apiRaycaster.parent,
apiRaycaster.position,
apiRaycaster.direction
);
this.position = new R3.Vector3(
this.graphics,
this.position,
this
);
this.direction = new R3.Vector3(
this.graphics,
this.direction,
this
);
R3.Component.call(this);
};
R3.D3.Raycaster.prototype = Object.create(R3.Component.prototype);
R3.D3.Raycaster.prototype.constructor = R3.D3.Raycaster;
/**
* Creates or updates a raycaster instance
*/
R3.D3.Raycaster.prototype.createInstance = function() {
this.instance = new THREE.Raycaster();
this.instance.set(
this.position.instance,
this.direction.instance
);
R3.Component.prototype.createInstance.call(this);
};
R3.D3.Raycaster.prototype.updateInstance = function(property) {
if (property === 'position') {
this.position.instance.x = this.position.x;
this.position.instance.y = this.position.y;
this.position.instance.z = this.position.z;
this.instance.setPosition(this.position.instance);
return;
}
if (property === 'direction') {
this.direction.instance.x = this.direction.x;
this.direction.instance.y = this.direction.y;
this.direction.instance.z = this.direction.z;
this.instance.setDirection(this.direction.instance);
return;
}
R3.Component.prototype.updateInstance.call(this, property);
};
R3.D3.Raycaster.prototype.toApiObject = function() {
return new R3.D3.API.Raycaster(
this.id,
this.name,
R3.Utils.IdOrNull(this.parent),
this.position.toApiObject(),
this.direction.toApiObject()
)
};
/**
* Sets the direction and position of this raycaster
* @param position R3.Vector3
* @param direction R3.Vector3
*/
R3.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 R3.Vector3
*/
R3.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 R3.Vector3
*/
R3.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
*/
R3.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 R3.D3.Mesh objects
* @param meshes [R3.D3.Mesh]
*/
R3.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,
face: mesh.geometry.faces[intersects[0].faceIndex],
faceIndex: intersects[0].faceIndex,
uv : {
x : intersects[0].uv.x,
y : intersects[0].uv.y
}
}
);
}
return result;
}.bind(this),
[]
);
};
/**
* Returns the face normal (if any) of an intersection between current ray position, direction and a provided mesh
* @param mesh R3.D3.Mesh
* @returns {null | R3.Vector3}
*/
R3.D3.Raycaster.prototype.getFaceNormal = function(mesh) {
var normal = null;
var intersect = this.instance.intersectObject(
mesh.instance
);
if (intersect && intersect.length > 0) {
normal = new R3.Vector3(
this.graphics,
new R3.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 R3.D3.Mesh
* @returns {null | R3.Vector3}
*/
R3.D3.Raycaster.prototype.getIntersectPoint = function(mesh) {
var point = null;
var intersect = this.instance.intersectObject(
mesh.instance
);
if (intersect && intersect.length > 0) {
point = new R3.Vector3(
this.graphics,
new R3.API.Vector3(
intersect[0].point.x,
intersect[0].point.y,
intersect[0].point.z
),
this
);
}
return point;
};