File: ../src/components/poser.js
- ///@INFO: UNCOMMON
- /**
- * Transitions between different poses
- * @class Poser
- * @namespace LS.Components
- * @constructor
- * @param {String} object to configure from
- */
-
-
- function Poser(o)
- {
- this.enabled = true;
-
- this.only_internal_nodes = true;
- this.base_nodes = []; //uids and original transform of the nodes affected by the poser
- this.poses = {};
-
- if(o)
- this.configure(o);
- }
-
- /*
- Poser.prototype.configure = function(o)
- {
-
- }
- */
-
- Poser.icon = "mini-icon-clock.png";
-
- Poser.prototype.onAddedToScene = function( scene )
- {
- //LEvent.bind(scene,"update",this.onUpdate, this);
- }
-
- Poser.prototype.onRemovedFromScene = function(scene)
- {
- //LEvent.unbind(scene,"update",this.onUpdate, this);
- }
-
- /*
- Poser.prototype.onUpdate = function(e, dt)
- {
- this.applyPose();
-
- var scene = this._root.scene;
- if(!scene)
- scene.requestFrame();
- }
- */
-
- Poser.prototype.addBaseNode = function( node )
- {
- var node_data = null;
- var uid = node.uid;
-
- //check if it is already in this.base_nodes
- for(var i = 0; i < this.base_nodes.length; ++i)
- {
- var v = this.base_nodes[i];
- if( v.node_uid != uid )
- continue;
- node_data = v;
- break;
- }
-
- //add new base node
- if(!node_data)
- {
- node_data = {
- node_uid: uid,
- data: Array(10)
- };
- this.base_nodes.push( node_data );
- }
-
- if(node.transform)
- node_data.data = node.transform.data;
- }
-
- Poser.prototype.removeBaseNode = function( node )
- {
- if(!node)
- return;
-
- if(node.constructor === String)
- node = this._root.scene.getNode( node );
-
- if(!node)
- {
- console.warn("Node not found");
- return;
- }
-
- //check if it is already in this.base_nodes
- for(var i = 0; i < this.base_nodes.length; ++i)
- {
- var v = this.base_nodes[i];
- if( v.node_uid != node.uid )
- continue;
-
- this.base_nodes.splice(i,1);
- this.purgePoses();
- break;
- }
- }
-
- Poser.prototype.setChildrenAsBaseNodes = function( include_root )
- {
- this.base_nodes.length = 0;
- if(include_root)
- this.addBaseNode( this._root );
- var descendants = this._root.getDescendants();
- for(var i = 0; i < descendants.length; ++i)
- this.addBaseNode( descendants[i] );
- }
-
- Poser.prototype.addPose = function( name )
- {
- var pose = {
- name: name,
- nodes: []
- };
- this.poses[ name ] = pose;
- this.updatePose( name );
- }
-
- Poser.prototype.removePose = function( name )
- {
- delete this.poses[ name ];
- }
-
- //call to update the value of a pose using the current nodes transform
- Poser.prototype.updatePose = function( name )
- {
- if(!this._root || !this._root.scene) //could happen
- return;
-
- var pose = this.poses[ name ];
- if(!pose)
- return null;
-
- var scene = this._root.scene;
- pose.nodes.length = 0;
-
- for(var i = 0; i < this.base_nodes.length; ++i)
- {
- var base_node_info = this.base_nodes[i];
- var node = scene.getNode( base_node_info.node_uid );
- if(!node)
- {
- console.warn("addPose error, node not found in scene");
- continue;
- }
-
- var pose_info = {
- node_uid: node.uid,
- data: toArray( node.transform.data )
- };
-
- pose.nodes.push( pose_info );
- }
-
- this.poses[ name ] = pose;
- return pose;
- }
-
- //call to apply one pose to the nodes
- Poser.prototype.applyPose = function( name, weight )
- {
- if(!name || !this._root || !this._root.scene)
- return;
-
- if(weight === undefined)
- weight = 1;
- if(weight <= 0)
- return;
-
- var pose = this.poses[ name ];
- if(!pose)
- return null;
-
- var scene = this._root.scene;
- if(!scene)
- return;
-
- for(var i = 0; i < pose.nodes.length; ++i)
- {
- var info = pose.nodes[i];
- var node = scene.getNode( info.node_uid );
- if(!node || !node.transform)
- continue; //maybe the node was removed from the scene
-
- //overwrite
- if(weight >= 1)
- {
- node.transform.data = info.data;
- continue;
- }
-
- var a = node.transform;
- var b = info.data;
-
- //interpolate
- vec3.lerp( a._position, a._position, b, weight ); //position
- vec3.lerp( a._scaling, a._scaling, b.subarray(7,10), weight ); //scale
- quat.slerp( a._rotation, a._rotation, b.subarray(3,7), weight ); //rotation
- node.transform._must_update = true;
- }
-
- this.poses[ name ] = pose;
- return pose;
- }
-
- //remove nodes from poses if they are not used
- Poser.prototype.purgePoses = function()
- {
- //mark which nodes in the pose exist in the scene
- var valid_nodes = {};
- var scene = this._root.scene;
- if(!scene)
- return;
-
- for(var i = 0; i < this.base_nodes.length; ++i)
- {
- var info = this.base_nodes[i];
- var node = scene.getNode( info.node_uid );
- if(node)
- valid_nodes[ node.uid ] = true;
- }
-
- //now check all the poses, if they use a node that doesnt exist in the scene, remove it from the pose
- for(var i in this.poses)
- {
- var pose = this.poses[i];
- var pose_nodes = pose.nodes;
-
- for( var j = 0; j < pose_nodes.length; ++j )
- {
- var uid = pose_nodes[j].node_uid;
- if(valid_nodes[uid])
- continue;
- pose_nodes.splice(j,1);
- j--;
- }
- }
- }
-
-
-
- LS.registerComponent( Poser );
-