/src/away3d/extrusions/utils/Path.as

http://github.com/away3d/away3d-core-fp11 · ActionScript · 304 lines · 159 code · 46 blank · 99 comment · 27 complexity · 3ab3f6c61800e83b2fe54e4dc7545ff3 MD5 · raw file

  1. package away3d.extrusions.utils
  2. {
  3. import flash.geom.Vector3D;
  4. //import away3d.containers.Scene3D;
  5. //import away3d.extrusions.utils.PathDebug;
  6. /**
  7. * Holds information about a single Path definition.
  8. * DEBUG OPTION OUT AT THIS TIME OF DEV
  9. */
  10. public class Path
  11. {
  12. /**
  13. * Creates a new <code>Path</code> object.
  14. *
  15. * @param aVectors [optional] An array of a series of Vector3D's organized in the following fashion. [a,b,c,a,b,c etc...] a = pEnd, b=pControl (control point), c = v2
  16. */
  17. public function Path(aVectors:Vector.<Vector3D> = null)
  18. {
  19. if(aVectors!= null && aVectors.length < 3)
  20. throw new Error("Path Vector.<Vector3D> must contain at least 3 Vector3D's");
  21. _segments = new Vector.<PathSegment>();
  22. if(aVectors != null)
  23. for(var i:int = 0; i<aVectors.length; i+=3)
  24. _segments.push( new PathSegment(aVectors[i], aVectors[i+1], aVectors[i+2]));
  25. }
  26. //private var _pathDebug:PathDebug;
  27. private var _segments:Vector.<PathSegment>;
  28. /**
  29. * The worldAxis of reference
  30. */
  31. public var worldAxis:Vector3D = new Vector3D(0,1,0);
  32. private var _smoothed:Boolean;
  33. /**
  34. * returns true if the smoothPath handler is being used.
  35. */
  36. public function get smoothed():Boolean
  37. {
  38. return _smoothed;
  39. }
  40. private var _averaged:Boolean;
  41. /**
  42. * returns true if the averagePath handler is being used.
  43. */
  44. public function get averaged():Boolean
  45. {
  46. return _averaged;
  47. }
  48. /**
  49. * display the path in scene
  50. */
  51. /*public function debugPath(scene:Scene3D):void
  52. {
  53. _pathDebug = new PathDebug(scene, this);
  54. }*/
  55. /**
  56. * Defines if the anchors must be displayed if debugPath has been called. if false, only curves are displayed
  57. */
  58. /*public function get showAnchors():Boolean
  59. {
  60. if(!_pathDebug)
  61. throw new Error("Patheditor not set yet! Use Path.debugPath() method first");
  62. return _pathDebug.showAnchors;
  63. }
  64. public function set showAnchors(b:Boolean):void
  65. {
  66. if(!_pathDebug)
  67. throw new Error("Patheditor not set yet! Use Path.debugPath() method first");
  68. _pathDebug.showAnchors = b;
  69. }
  70. */
  71. /**
  72. * Defines if the path data must be visible or not if debugPath has been called
  73. */
  74. /*
  75. public function get display():Boolean
  76. {
  77. return _pathDebug.display;
  78. }
  79. public function set display(b:Boolean):void
  80. {
  81. if(!_pathDebug)
  82. throw new Error("Patheditor not set yet! Use Path.debugPath() method first");
  83. _pathDebug.display = b;
  84. }*/
  85. /**
  86. * adds a PathSegment to the path
  87. * @see PathSegment:
  88. */
  89. public function add(ps:PathSegment):void
  90. {
  91. _segments.push(ps);
  92. }
  93. /**
  94. * returns the length of the Path elements array
  95. *
  96. * @return an integer: the length of the Path elements array
  97. */
  98. public function get length():int
  99. {
  100. return _segments.length;
  101. }
  102. /**
  103. * returns the Vector.&lt;PathSegment&gt; holding the elements (PathSegment) of the path
  104. *
  105. * @return a Vector.&lt;PathSegment&gt;: holding the elements (PathSegment) of the path
  106. */
  107. public function get segments():Vector.<PathSegment>
  108. {
  109. return _segments;
  110. }
  111. /**
  112. * returns a given PathSegment from the path (PathSegment holds 3 Vector3D's)
  113. *
  114. * @param indice uint. the indice of a given PathSegment
  115. * @return given PathSegment from the path
  116. */
  117. public function getSegmentAt(indice:uint):PathSegment
  118. {
  119. return _segments[indice];
  120. }
  121. /**
  122. * removes a segment in the path according to id.
  123. *
  124. * @param index int. The index in path of the to be removed curvesegment
  125. * @param join Boolean. If true previous and next segments coordinates are reconnected
  126. */
  127. public function removeSegment(index:int, join:Boolean = false):void
  128. {
  129. if(_segments.length == 0 || _segments[index ] == null )
  130. return;
  131. if(join && index < _segments.length-1 && index>0){
  132. var seg:PathSegment = _segments[index];
  133. var prevSeg:PathSegment = _segments[index-1];
  134. var nextSeg:PathSegment = _segments[index+1];
  135. prevSeg.pControl.x = (prevSeg.pControl.x+seg.pControl.x)*.5;
  136. prevSeg.pControl.y = (prevSeg.pControl.y+seg.pControl.y)*.5;
  137. prevSeg.pControl.z = (prevSeg.pControl.z+seg.pControl.z)*.5;
  138. nextSeg.pControl.x = (nextSeg.pControl.x+seg.pControl.x)*.5;
  139. nextSeg.pControl.y = (nextSeg.pControl.y+seg.pControl.y)*.5;
  140. nextSeg.pControl.z = (nextSeg.pControl.z+seg.pControl.z)*.5;
  141. prevSeg.pEnd.x = (seg.pStart.x + seg.pEnd.x)*.5;
  142. prevSeg.pEnd.y = (seg.pStart.y + seg.pEnd.y)*.5;
  143. prevSeg.pEnd.z = (seg.pStart.z + seg.pEnd.z)*.5;
  144. nextSeg.pStart.x = prevSeg.pEnd.x;
  145. nextSeg.pStart.y = prevSeg.pEnd.y;
  146. nextSeg.pStart.z = prevSeg.pEnd.z;
  147. /*if(_pathDebug != null)
  148. _pathDebug.updateAnchorAt(index-1);
  149. _pathDebug.updateAnchorAt(index+1);*/
  150. }
  151. if(_segments.length > 1){
  152. _segments.splice(index, 1);
  153. } else{
  154. _segments = new Vector.<PathSegment>();
  155. }
  156. }
  157. /**
  158. * handler will smooth the path using anchors as control vector of the PathSegments
  159. * note that this is not dynamic, the PathSegments values are overwrited
  160. */
  161. public function smoothPath():void
  162. {
  163. if(_segments.length <= 2)
  164. return;
  165. _smoothed = true;
  166. _averaged = false;
  167. var x:Number;
  168. var y:Number;
  169. var z:Number;
  170. var seg0:Vector3D;
  171. var seg1:Vector3D;
  172. var tmp:Vector.<Vector3D> = new Vector.<Vector3D>();
  173. var i:uint;
  174. var startseg:Vector3D = new Vector3D(_segments[0].pStart.x, _segments[0].pStart.y, _segments[0].pStart.z);
  175. var endseg:Vector3D = new Vector3D(_segments[_segments.length-1].pEnd.x,
  176. _segments[_segments.length-1].pEnd.y,
  177. _segments[_segments.length-1].pEnd.z);
  178. for(i = 0; i< length-1; ++i)
  179. {
  180. if(_segments[i].pControl == null)
  181. _segments[i].pControl = _segments[i].pEnd;
  182. if(_segments[i+1].pControl == null)
  183. _segments[i+1].pControl = _segments[i+1].pEnd;
  184. seg0 = _segments[i].pControl;
  185. seg1 = _segments[i+1].pControl;
  186. x = (seg0.x + seg1.x) * .5;
  187. y = (seg0.y + seg1.y) * .5;
  188. z = (seg0.z + seg1.z) * .5;
  189. tmp.push( startseg, new Vector3D(seg0.x, seg0.y, seg0.z), new Vector3D(x, y, z));
  190. startseg = new Vector3D(x, y, z);
  191. _segments[i] = null;
  192. }
  193. seg0 = _segments[_segments.length-1].pControl;
  194. tmp.push( startseg, new Vector3D((seg0.x+seg1.x)*.5, (seg0.y+seg1.y)*.5, (seg0.z+seg1.z)*.5), endseg);
  195. _segments = new Vector.<PathSegment>();
  196. for(i = 0; i<tmp.length; i+=3)
  197. _segments.push( new PathSegment(tmp[i], tmp[i+1], tmp[i+2]) );
  198. tmp[i] = tmp[i+1] = tmp[i+2] = null;
  199. tmp = null;
  200. }
  201. /**
  202. * handler will average the path using averages of the PathSegments
  203. * note that this is not dynamic, the path values are overwrited
  204. */
  205. public function averagePath():void
  206. {
  207. _averaged = true;
  208. _smoothed = false;
  209. for(var i:uint = 0; i<_segments.length; ++i){
  210. _segments[i].pControl.x = (_segments[i].pStart.x+_segments[i].pEnd.x)*.5;
  211. _segments[i].pControl.y = (_segments[i].pStart.y+_segments[i].pEnd.y)*.5;
  212. _segments[i].pControl.z = (_segments[i].pStart.z+_segments[i].pEnd.z)*.5;
  213. }
  214. }
  215. public function continuousCurve(points:Vector.<Vector3D>, closed:Boolean = false):void
  216. {
  217. var aVectors:Vector.<Vector3D> = new Vector.<Vector3D>();
  218. var i:uint;
  219. var X:Number;
  220. var Y:Number;
  221. var Z:Number;
  222. var midPoint:Vector3D;
  223. // Find the mid points and inject them into the array.
  224. for(i = 0; i < points.length - 1; i++)
  225. {
  226. var currentPoint:Vector3D = points[i];
  227. var nextPoint:Vector3D = points[i+1];
  228. X = (currentPoint.x + nextPoint.x)/2;
  229. Y = (currentPoint.y + nextPoint.y)/2;
  230. Z = (currentPoint.z + nextPoint.z)/2;
  231. midPoint = new Vector3D(X, Y, Z);
  232. if (i) aVectors.push(midPoint);
  233. if (i < points.length - 2 || closed) {
  234. aVectors.push(midPoint);
  235. aVectors.push(nextPoint);
  236. }
  237. }
  238. if(closed) {
  239. currentPoint = points[points.length-1];
  240. nextPoint = points[0];
  241. X = (currentPoint.x + nextPoint.x)/2;
  242. Y = (currentPoint.y + nextPoint.y)/2;
  243. Z = (currentPoint.z + nextPoint.z)/2;
  244. midPoint = new Vector3D(X, Y, Z);
  245. aVectors.push(midPoint);
  246. aVectors.push(midPoint);
  247. aVectors.push(points[0]);
  248. aVectors.push(aVectors[0]);
  249. }
  250. _segments = new Vector.<PathSegment>();
  251. for(i = 0; i< aVectors.length; i+=3)
  252. _segments.push( new PathSegment(aVectors[i], aVectors[i+1], aVectors[i+2]));
  253. }
  254. }
  255. }