API Docs for:
Show:

File: ../src/components/poser.js

  1. ///@INFO: UNCOMMON
  2. /**
  3. * Transitions between different poses
  4. * @class Poser
  5. * @namespace LS.Components
  6. * @constructor
  7. * @param {String} object to configure from
  8. */
  9.  
  10.  
  11. function Poser(o)
  12. {
  13. this.enabled = true;
  14.  
  15. this.only_internal_nodes = true;
  16. this.base_nodes = []; //uids and original transform of the nodes affected by the poser
  17. this.poses = {};
  18.  
  19. if(o)
  20. this.configure(o);
  21. }
  22.  
  23. /*
  24. Poser.prototype.configure = function(o)
  25. {
  26. }
  27. */
  28.  
  29. Poser.icon = "mini-icon-clock.png";
  30.  
  31. Poser.prototype.onAddedToScene = function( scene )
  32. {
  33. //LEvent.bind(scene,"update",this.onUpdate, this);
  34. }
  35.  
  36. Poser.prototype.onRemovedFromScene = function(scene)
  37. {
  38. //LEvent.unbind(scene,"update",this.onUpdate, this);
  39. }
  40.  
  41. /*
  42. Poser.prototype.onUpdate = function(e, dt)
  43. {
  44. this.applyPose();
  45.  
  46. var scene = this._root.scene;
  47. if(!scene)
  48. scene.requestFrame();
  49. }
  50. */
  51.  
  52. Poser.prototype.addBaseNode = function( node )
  53. {
  54. var node_data = null;
  55. var uid = node.uid;
  56.  
  57. //check if it is already in this.base_nodes
  58. for(var i = 0; i < this.base_nodes.length; ++i)
  59. {
  60. var v = this.base_nodes[i];
  61. if( v.node_uid != uid )
  62. continue;
  63. node_data = v;
  64. break;
  65. }
  66.  
  67. //add new base node
  68. if(!node_data)
  69. {
  70. node_data = {
  71. node_uid: uid,
  72. data: Array(10)
  73. };
  74. this.base_nodes.push( node_data );
  75. }
  76. if(node.transform)
  77. node_data.data = node.transform.data;
  78. }
  79.  
  80. Poser.prototype.removeBaseNode = function( node )
  81. {
  82. if(!node)
  83. return;
  84.  
  85. if(node.constructor === String)
  86. node = this._root.scene.getNode( node );
  87.  
  88. if(!node)
  89. {
  90. console.warn("Node not found");
  91. return;
  92. }
  93.  
  94. //check if it is already in this.base_nodes
  95. for(var i = 0; i < this.base_nodes.length; ++i)
  96. {
  97. var v = this.base_nodes[i];
  98. if( v.node_uid != node.uid )
  99. continue;
  100.  
  101. this.base_nodes.splice(i,1);
  102. this.purgePoses();
  103. break;
  104. }
  105. }
  106.  
  107. Poser.prototype.setChildrenAsBaseNodes = function( include_root )
  108. {
  109. this.base_nodes.length = 0;
  110. if(include_root)
  111. this.addBaseNode( this._root );
  112. var descendants = this._root.getDescendants();
  113. for(var i = 0; i < descendants.length; ++i)
  114. this.addBaseNode( descendants[i] );
  115. }
  116.  
  117. Poser.prototype.addPose = function( name )
  118. {
  119. var pose = {
  120. name: name,
  121. nodes: []
  122. };
  123. this.poses[ name ] = pose;
  124. this.updatePose( name );
  125. }
  126.  
  127. Poser.prototype.removePose = function( name )
  128. {
  129. delete this.poses[ name ];
  130. }
  131.  
  132. //call to update the value of a pose using the current nodes transform
  133. Poser.prototype.updatePose = function( name )
  134. {
  135. if(!this._root || !this._root.scene) //could happen
  136. return;
  137.  
  138. var pose = this.poses[ name ];
  139. if(!pose)
  140. return null;
  141.  
  142. var scene = this._root.scene;
  143. pose.nodes.length = 0;
  144.  
  145. for(var i = 0; i < this.base_nodes.length; ++i)
  146. {
  147. var base_node_info = this.base_nodes[i];
  148. var node = scene.getNode( base_node_info.node_uid );
  149. if(!node)
  150. {
  151. console.warn("addPose error, node not found in scene");
  152. continue;
  153. }
  154.  
  155. var pose_info = {
  156. node_uid: node.uid,
  157. data: toArray( node.transform.data )
  158. };
  159.  
  160. pose.nodes.push( pose_info );
  161. }
  162.  
  163. this.poses[ name ] = pose;
  164. return pose;
  165. }
  166.  
  167. //call to apply one pose to the nodes
  168. Poser.prototype.applyPose = function( name, weight )
  169. {
  170. if(!name || !this._root || !this._root.scene)
  171. return;
  172.  
  173. if(weight === undefined)
  174. weight = 1;
  175. if(weight <= 0)
  176. return;
  177.  
  178. var pose = this.poses[ name ];
  179. if(!pose)
  180. return null;
  181.  
  182. var scene = this._root.scene;
  183. if(!scene)
  184. return;
  185.  
  186. for(var i = 0; i < pose.nodes.length; ++i)
  187. {
  188. var info = pose.nodes[i];
  189. var node = scene.getNode( info.node_uid );
  190. if(!node || !node.transform)
  191. continue; //maybe the node was removed from the scene
  192.  
  193. //overwrite
  194. if(weight >= 1)
  195. {
  196. node.transform.data = info.data;
  197. continue;
  198. }
  199.  
  200. var a = node.transform;
  201. var b = info.data;
  202.  
  203. //interpolate
  204. vec3.lerp( a._position, a._position, b, weight ); //position
  205. vec3.lerp( a._scaling, a._scaling, b.subarray(7,10), weight ); //scale
  206. quat.slerp( a._rotation, a._rotation, b.subarray(3,7), weight ); //rotation
  207. node.transform._must_update = true;
  208. }
  209.  
  210. this.poses[ name ] = pose;
  211. return pose;
  212. }
  213.  
  214. //remove nodes from poses if they are not used
  215. Poser.prototype.purgePoses = function()
  216. {
  217. //mark which nodes in the pose exist in the scene
  218. var valid_nodes = {};
  219. var scene = this._root.scene;
  220. if(!scene)
  221. return;
  222.  
  223. for(var i = 0; i < this.base_nodes.length; ++i)
  224. {
  225. var info = this.base_nodes[i];
  226. var node = scene.getNode( info.node_uid );
  227. if(node)
  228. valid_nodes[ node.uid ] = true;
  229. }
  230.  
  231. //now check all the poses, if they use a node that doesnt exist in the scene, remove it from the pose
  232. for(var i in this.poses)
  233. {
  234. var pose = this.poses[i];
  235. var pose_nodes = pose.nodes;
  236.  
  237. for( var j = 0; j < pose_nodes.length; ++j )
  238. {
  239. var uid = pose_nodes[j].node_uid;
  240. if(valid_nodes[uid])
  241. continue;
  242. pose_nodes.splice(j,1);
  243. j--;
  244. }
  245. }
  246. }
  247.  
  248.  
  249.  
  250. LS.registerComponent( Poser );