/** * Raycaster for GameLib.D3 * @param graphics GameLib.D3.Graphics * @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 ); this.instance = this.createInstance(); }; 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 * @param update */ GameLib.D3.Raycaster.prototype.createInstance = function(update) { var instance = null; if (update) { instance = this.instance; } else { instance = new THREE.Raycaster(); } instance.set( this.position.instance, this.direction.instance ); return instance; }; GameLib.D3.Raycaster.prototype.updateInstance = function() { this.instance = this.createInstance(true); }; GameLib.D3.Raycaster.prototype.toApiObject = function() { return new GameLib.D3.API.Raycaster( this.id, this.name, this.position.toApiObject(), this.direction.toApiObject() ) }; GameLib.D3.Raycaster.FromObjectRaycaster = function(graphics, parentObject, objectRaycaster) { var apiRaycaster = GameLib.D3.API.Raycaster.FromObjectRaycaster(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(); }; /** * Gets all interesected GameLib.D3.Mesh objects * @param meshes [GameLib.D3.Mesh] */ GameLib.D3.Raycaster.prototype.getIntersectedObjects = function(meshes) { var meshInstances = meshes.map( function (mesh) { return mesh.instance; } ); 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; };