API Docs for:
Show:

File: ../src/components/interactiveController.js

///@INFO: UNCOMMON
/**
* Allows to easily test interaction between the user and the scene, attach the InteractiveController to the root and the mouse down,move and up events will
* be processed using a raycast and trigger events.
* @namespace LS
* @class InteractiveController
* @constructor
* @param {Object} last serialized data [optional]
*/
function InteractiveController(o)
{
	this.enabled = true;
	this.mode = InteractiveController.PICKING;
	this.layers = 3;

	this._last_collision = null;

	if(o)
		this.configure(o);
}

InteractiveController.icon = "mini-icon-cursor.png";

InteractiveController.PICKING = 1;
InteractiveController.BOUNDING = 2;
InteractiveController.COLLIDERS = 3;
InteractiveController.RENDER_INSTANCES = 4;

InteractiveController["@mode"] = { type: "enum", values: { "Picking": InteractiveController.PICKING, "Bounding": InteractiveController.BOUNDING, "Colliders": InteractiveController.COLLIDERS }};
InteractiveController["@layers"] = { type: "layers" };

InteractiveController.prototype.onAddedToScene = function(scene)
{
	LEvent.bind( scene, "mousedown", this._onMouse, this );
	LEvent.bind( scene, "mousemove", this._onMouse, this );
	LEvent.bind( scene, "mouseup", this._onMouse, this );
}

InteractiveController.prototype.onRemovedFromScene = function(scene)
{
	LEvent.unbindAll( scene, this );
}

InteractiveController.prototype.getNodeUnderMouse = function( e )
{
	var layers = this.layers;

	if(this.mode == InteractiveController.PICKING)
		return LS.Picking.getNodeAtCanvasPosition( e.canvasx, e.canvasy, null, layers );

	var camera = LS.Renderer.getCameraAtPosition( e.canvasx, e.canvasy );
	if(!camera)
		return null;
	var ray = camera.getRayInPixel( e.canvasx, e.canvasy );

	if(this.mode == InteractiveController.BOUNDING)
	{
		var collisions = LS.Physics.raycastRenderInstances( ray.origin, ray.direction, { layers: layers } );
		if(!collisions || !collisions.length)
			return null;
		this._last_collision = collisions[0];
		return collisions[0].node;
	}

	if(this.mode == InteractiveController.RENDER_INSTANCES)
	{
		var collisions = LS.Physics.raycastRenderInstances( ray.origin, ray.direction, { layers: layers, triangle_collision: true } );
		if(!collisions || !collisions.length)
			return null;
		this._last_collision = collisions[0];
		return collisions[0].node;
	}

	if(this.mode == InteractiveController.COLLIDERS)
	{
		var collisions = LS.Physics.raycast( ray.origin, ray.direction, { layers: layers } );
		if(!collisions || !collisions.length)
			return null;
		this._last_collision = collisions[0];
		return collisions[0].node;
	}

	return null;

}

InteractiveController.prototype._onMouse = function(type, e)
{
	if(!this.enabled)
		return;

	//Intereactive: check which node was clicked (this is a mode that helps clicking stuff)
	if(e.eventType == "mousedown" || e.eventType == "mousewheel" )
	{
		var node = this.getNodeUnderMouse(e);
		this._clicked_node = node;
		if(this._clicked_node && e.eventType == "mousedown" && e.button == 0 )
		{
			console.log("Node clicked: " + this._clicked_node.name );
			LEvent.trigger( this._clicked_node, "clicked", this._clicked_node ); //event in node clicked
			LEvent.trigger( this._root, "node_clicked", this._clicked_node ); //event in this node
			LEvent.trigger( this._root.scene, "node_clicked", this._clicked_node ); //event in scene
			if(this.onNodeClicked) //extra method, if you inject a new method in this component
				this.onNodeClicked( this._clicked_node );
		}
	}

	var levent = null; //levent dispatched

	//send event to clicked node
	if(this._clicked_node) // && this._clicked_node.flags.interactive)
	{
		e.scene_node = this._clicked_node;
		levent = LEvent.trigger( this._clicked_node, e.eventType, e );
	}

	if(e.eventType == "mouseup")
		this._clicked_node = null;

	if(this._clicked_node)
		return true;
}


LS.registerComponent( InteractiveController );