PageRenderTime 65ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/Src/lib/math/CSpline.hx

http://game4web.googlecode.com/
Haxe | 671 lines | 371 code | 80 blank | 220 comment | 25 complexity | a9b11ff243844363a9dd607de0efe10e MD5 | raw file
  1. package math;
  2. /**
  3. * ...
  4. * @author bdubois
  5. */
  6. import driver.as.renderer.C2DQuadAS;
  7. import flash.display.Shape;
  8. import flash.display.Sprite;
  9. import math.Constants;
  10. import math.CV3D;
  11. import math.Utils;
  12. import CTypes;
  13. // ***************************************
  14. // *** Bezier SplineNode declaration : ***
  15. // ***************************************
  16. typedef SplineNode =
  17. {
  18. var Point : CV3D;
  19. var In : CV3D;
  20. var Out : CV3D;
  21. }
  22. typedef PrecalcSplineNode =
  23. {
  24. var Ratio : Array<Float>;// F32 Ratio[CSpline.SPLINE_NB_SAMPLE];
  25. }
  26. // *******************************
  27. // *** Segment length tags : ***
  28. // *******************************
  29. typedef Segment =
  30. {
  31. var Start : Float;
  32. var End : Float;
  33. }
  34. // ***************************************
  35. // *** Game System base bezier path : ***
  36. // ***************************************
  37. class CSpline
  38. {
  39. public static var g_SplineDefaultResolution : Float = 0.05;
  40. public static var LIGHTWEIGHT_SPLINE_SAMPLING : Bool = true;
  41. public static var SPLINE_NB_SAMPLE : Int = 256;
  42. // *******************************
  43. // *** Internal attributes : ***
  44. // *******************************
  45. var m_Nodes : Array<SplineNode>;
  46. var m_PrecalcNode : Array<PrecalcSplineNode>;
  47. var m_NbNodes : Int;
  48. var m_Length : Float;
  49. var m_Resolution : Float;
  50. var m_Closed : Bool;
  51. var m_CumulLength : Array<Segment>;
  52. public function new()
  53. {
  54. m_Length = 0;
  55. m_Resolution = CSpline.g_SplineDefaultResolution;
  56. m_Nodes = null;
  57. m_CumulLength = null;
  58. m_NbNodes = 0;
  59. m_PrecalcNode = null;
  60. m_Closed = false;
  61. }
  62. /*inline */public function Interpolate ( _SegmentIndex : Int, _Progression : Float, _TgtPoint : CV3D, ?_TgtTan : CV3D = null ) : Void
  63. {
  64. //ASSERTC ( m_Nodes, "[CResource_Spline::Interpolate] Empty spline !" );
  65. //ASSERTC ( ( _SegmentIndex < ( m_NbNodes - 1 ) ),
  66. //"[CResource_Spline::Interpolate] _SegmentIndex out of range !"
  67. //);
  68. //ASSERTC ( ( ( _Progression >= -Constants.EPSILON )
  69. //&& ( _Progression <= ( 1 + Constants.EPSILON ) ) ),
  70. //"[CResource_Spline::Interpolate] _Progression out of range"
  71. //);
  72. //ASSERTC ( _TgtPoint, "[CResource_Spline::Interpolate] _TgtPoint must point to an instanciated V3D !" );
  73. if ( _TgtPoint != null )
  74. {
  75. var l_Knot0 : SplineNode = m_Nodes [ _SegmentIndex + 0 ]; //<
  76. var l_Knot1 : SplineNode = m_Nodes [ _SegmentIndex + 1 ]; //<
  77. var l_Pt0 : CV3D = CV3D.NewCopy( l_Knot0.Point );
  78. var l_Pt1 : CV3D = CV3D.NewCopy( l_Knot0.Out ); //+l_Knot0.Point;
  79. var l_Pt2 : CV3D = CV3D.NewCopy( l_Knot1.In ); //+l_Knot1.Point;
  80. var l_Pt3 : CV3D = CV3D.NewCopy( l_Knot1.Point );
  81. var l_3_Pt0 : CV3D = CV3D.NewCopy( l_Pt0 );
  82. var l_3_Pt1 : CV3D = CV3D.NewCopy( l_Pt1 );
  83. var l_6_Pt1 : CV3D = CV3D.NewCopy( l_Pt1 );
  84. var l_3_Pt2 : CV3D = CV3D.NewCopy( l_Pt2 );
  85. l_3_Pt0 = CV3D.OperatorScale( 3, l_3_Pt0 );
  86. l_3_Pt1 = CV3D.OperatorScale( 3, l_3_Pt1 );
  87. l_6_Pt1 = CV3D.OperatorScale( 6, l_6_Pt1 );
  88. l_3_Pt2 = CV3D.OperatorScale( 3, l_3_Pt2 );
  89. var l_a : CV3D = CV3D.NewCopy( l_3_Pt1 ); l_a = CV3D.OperatorMinus( l_a, l_3_Pt2 ); l_a = CV3D.OperatorPlus( l_a, l_Pt3 ); l_a = CV3D.OperatorMinus( l_a, l_Pt0 );
  90. var l_b : CV3D = CV3D.NewCopy( l_3_Pt0 ); l_b = CV3D.OperatorMinus( l_b, l_6_Pt1 ); l_b = CV3D.OperatorPlus( l_b, l_3_Pt2 );
  91. var l_c : CV3D = CV3D.NewCopy( l_3_Pt1 ); l_c = CV3D.OperatorMinus( l_c, l_3_Pt0 );
  92. var l_d : CV3D = CV3D.NewCopy( l_Pt0 );
  93. var l_Out : CV3D;
  94. l_Out = CV3D.OperatorPlus( CV3D.OperatorScale( _Progression, l_a ), l_b );
  95. l_Out = CV3D.OperatorPlus( CV3D.OperatorScale( _Progression, l_Out ), l_c );
  96. l_Out = CV3D.OperatorPlus( CV3D.OperatorScale( _Progression, l_Out ), l_d );
  97. _TgtPoint.Copy( l_Out );
  98. if ( _TgtTan != null )
  99. {
  100. //l_a *= (3.f*_Progression);
  101. //l_b *= (2.f*_Progression);
  102. //l_a += l_b;
  103. //l_a += l_c;
  104. /*
  105. * l_Out = l_c + _Progression * ( ( 2.f * l_b ) + _Progression * ( 3.f * l_a ) );
  106. */
  107. l_Out = CV3D.OperatorPlus(
  108. l_c,
  109. CV3D.OperatorScale(
  110. _Progression,
  111. CV3D.OperatorPlus(
  112. CV3D.OperatorScale( 2, l_b ),
  113. CV3D.OperatorScale(
  114. _Progression,
  115. CV3D.OperatorScale( 3, l_a )
  116. )
  117. )
  118. )
  119. );
  120. CV3D.Normalize( l_Out );
  121. _TgtTan.Copy( l_Out ); // Dérivée
  122. }
  123. }
  124. }
  125. // ***********************
  126. // *** Path Methods : ***
  127. // ***********************
  128. public function GetLength () : Float
  129. {
  130. return m_Length;
  131. }
  132. // ***************************
  133. // *** Bezier methods : ***
  134. // ***************************
  135. public function SetNodes ( _Nodes : Array<SplineNode>, _NbNodes : Int ) : Void
  136. {
  137. m_Nodes = _Nodes;
  138. m_NbNodes = _NbNodes;
  139. Precalcs (); //<
  140. }
  141. private function NodeCopy( _SrcNode : SplineNode ) : SplineNode
  142. {
  143. var l_TgtNode : SplineNode =
  144. {
  145. Point : CV3D.NewCopy( _SrcNode.Point ),
  146. In : CV3D.NewCopy( _SrcNode.In ),
  147. Out : CV3D.NewCopy( _SrcNode.Out )
  148. }
  149. return l_TgtNode;
  150. }
  151. // 310 : !!! Not use if spline is close on export !!!
  152. public function SetClosed ( _Closed : Bool ) : Void
  153. {
  154. if( m_Closed != _Closed )
  155. {
  156. m_Closed = _Closed;
  157. var l_NbNodes : Int = m_NbNodes;
  158. var l_Nodes : Array<SplineNode> = null;
  159. if( m_Closed )
  160. {
  161. // 310 : If close spline, add last point
  162. l_NbNodes++;
  163. l_Nodes = new Array<SplineNode>();
  164. for ( i in 0 ... m_NbNodes ) //memcpy(l_Nodes,m_Nodes,m_NbNodes*sizeof(SplineNode));
  165. {
  166. l_Nodes[i] = NodeCopy( m_Nodes[i] );
  167. }
  168. l_Nodes[m_NbNodes] = NodeCopy( l_Nodes[0] );
  169. }
  170. else
  171. {
  172. // 310 : If open spline, remove last point
  173. l_NbNodes--;
  174. l_Nodes = new Array<SplineNode>();
  175. for ( i in 0 ... m_NbNodes ) //memcpy(l_Nodes,m_Nodes,l_NbNodes*sizeof(SplineNode));
  176. {
  177. l_Nodes[i] = NodeCopy( m_Nodes[i] );
  178. }
  179. }
  180. SetNodes(l_Nodes, l_NbNodes);
  181. // 310 : In "setNode"
  182. Precalcs ();
  183. }
  184. }
  185. inline public function GetResolution () : Float
  186. {
  187. return m_Resolution;
  188. }
  189. function SetResolution ( _Resolution : Float ) : Void
  190. {
  191. m_Resolution = _Resolution;
  192. Precalcs ();
  193. }
  194. inline function GetNodes() : Array<SplineNode>
  195. {
  196. return m_Nodes;
  197. }
  198. inline function GetNbNodes() : Int
  199. {
  200. return m_NbNodes;
  201. }
  202. inline function IsClosed() : Bool
  203. {
  204. return m_Closed;
  205. }
  206. // ***********************
  207. // *** Interpolate : ***
  208. // ***********************
  209. function FindForwardSegmentFromDistance ( _Distance : Float , ?_StartSegment : Int = 0 ) : Int
  210. {
  211. var l_Ret : Int = Constants.INT_MAX;
  212. var l_NSegment : Int = m_NbNodes;
  213. if ( l_NSegment != 0 )
  214. {
  215. --l_NSegment;
  216. //ASSERT ( _StartSegment < l_NSegment );
  217. for ( i_EachSegment in _StartSegment ... l_NSegment )
  218. {
  219. var l_CurSeg : Segment = m_CumulLength [ i_EachSegment ];
  220. // *** In this segment ?
  221. if ( ( _Distance >= l_CurSeg.Start ) && ( _Distance <= l_CurSeg.End ) )
  222. {
  223. l_Ret = i_EachSegment;
  224. break;
  225. }
  226. }
  227. /*
  228. for ( var l_EachSegment : Int = _StartSegment; ( l_EachSegment < l_NSegment ); l_EachSegment++ )
  229. {
  230. const Segment& l_CurSeg = m_CumulLength [ l_EachSegment ];
  231. // *** In this segment ?
  232. if ( ( _Distance >= l_CurSeg.Start ) && ( _Distance <= l_CurSeg.End ) )
  233. {
  234. l_Ret = l_EachSegment;
  235. break;
  236. }
  237. }
  238. */
  239. }
  240. return l_Ret;
  241. }
  242. function FindSegmentRatioFromDistance ( _Distance : Float, _Segment : Int ) : Float
  243. {
  244. var l_CurSegLen : Segment = m_CumulLength[ _Segment ];
  245. //ASSERT ( ( _Distance >= l_CurSegLen.Start )
  246. // && ( _Distance <= m_Length ) );
  247. // *******************************************
  248. // *** Distance to go in this segment : ***
  249. // *******************************************
  250. var l_DistanceInSegment : Float = ( _Distance - l_CurSegLen.Start );
  251. // ***********************
  252. // *** Scan segment : ***
  253. // ***********************
  254. var l_CurSeg : SplineNode = m_Nodes [ _Segment ];
  255. var l_CurrentPosition : CV3D = CV3D.NewCopy( l_CurSeg.Point );
  256. var l_DiffPos : CV3D;
  257. var l_SegLength : Float = 0;
  258. var l_Ratio : Float = 0;
  259. var l_RatioFound : Float = 1;
  260. var l_NextPosition : CV3D = new CV3D( 0, 0, 0 );
  261. //var l_NextTangent : CV3D;
  262. var l_NormDPosition : Float; // Norm(CurrentPosition - NextPosition)
  263. var l_NumPart : Int = Utils.RoundNearest( 1 / m_Resolution );
  264. for ( i_EachPart in 0 ... l_NumPart )
  265. {
  266. // *** Getting new point :
  267. Interpolate ( _Segment, ( l_Ratio + m_Resolution ), l_NextPosition );
  268. // *** Distance to next point :
  269. l_DiffPos = CV3D.OperatorMinus( l_CurrentPosition, l_NextPosition );
  270. l_NormDPosition = l_DiffPos.Norm();
  271. // *** Still not enough ? :
  272. if ( l_DistanceInSegment < ( l_SegLength + l_NormDPosition ) )
  273. {
  274. // *******************************************
  275. // *** We've reach our point so leave : ***
  276. // *******************************************
  277. l_RatioFound = ( l_Ratio + ( ( l_DistanceInSegment - l_SegLength ) / l_NormDPosition ) * m_Resolution );
  278. break;
  279. }
  280. l_SegLength += l_NormDPosition;
  281. l_Ratio += m_Resolution;
  282. l_CurrentPosition.Copy( l_NextPosition );
  283. }
  284. //ASSERT ( ( ( l_RatioFound >= -Constants.EPSILON ) && ( l_RatioFound <= ( 1 + Constants.EPSILON ) ) ) );
  285. return l_RatioFound;
  286. }
  287. public function GetPositionFromDistance( _Distance : Float, _TgtPoint : CV3D, ?_TgtTan : CV3D = null ) : Void
  288. {
  289. FastGetPositionFromDistance( _Distance, _TgtPoint, _TgtTan );
  290. return;
  291. }
  292. public function FastGetPositionFromDistance( _Distance : Float, _TgtPoint : CV3D, ?_TgtTan : CV3D = null ) : Void
  293. {
  294. _Distance = Utils.Clamp( _Distance, 0, m_Length );
  295. // *** Get the segment
  296. var l_Segment : Int = FindForwardSegmentFromDistance( _Distance );
  297. if ( l_Segment == Constants.INT_MAX )
  298. {
  299. //ASSERT(0);
  300. return;
  301. }
  302. var l_CurSegLen : Segment = m_CumulLength [ l_Segment ];
  303. // *** Find ratio
  304. var l_RatioFound : Float = 1;
  305. var l_BaseRatioIdxF : Float = ( ( ( _Distance - l_CurSegLen.Start ) / ( l_CurSegLen.End - l_CurSegLen.Start ) ) * ( CSpline.SPLINE_NB_SAMPLE - 1 ) );
  306. var l_BaseRatioIdx : Float = Math.floor( l_BaseRatioIdxF );
  307. var l_LerpFactor : Float = l_BaseRatioIdxF - l_BaseRatioIdx;
  308. if( l_BaseRatioIdx < ( CSpline.SPLINE_NB_SAMPLE - 1 ) )
  309. {
  310. l_RatioFound = m_PrecalcNode[ l_Segment ].Ratio[ cast( l_BaseRatioIdx, Int ) ] * ( 1 - l_LerpFactor )
  311. + m_PrecalcNode[ l_Segment ].Ratio[ cast( l_BaseRatioIdx, Int ) + 1 ] * ( l_LerpFactor );
  312. }
  313. // *** Catmul ratio
  314. Interpolate ( l_Segment, l_RatioFound, _TgtPoint, _TgtTan );
  315. }
  316. public function GetDistanceFromPosition( _Pos : CV3D ) : Float
  317. {
  318. var l_NbSamples : Int = CSpline.SPLINE_NB_SAMPLE;
  319. var l_Step : Float = m_Length / l_NbSamples;
  320. var l_P : CV3D = new CV3D(0, 0, 0);
  321. var l_Closest : CV3D = CV3D.NewCopy( CV3D.ZERO );
  322. var l_iClosest : Int = 0;
  323. var l_Dist2Closest : Float = Math.POSITIVE_INFINITY;
  324. for ( i in 0 ... l_NbSamples )
  325. {
  326. GetPositionFromDistance( l_Step * i, l_P );
  327. var l_Dist2 : Float = CV3D.OperatorMinus( l_P, _Pos ).Norm2();
  328. if ( l_Dist2 < l_Dist2Closest )
  329. {
  330. l_Dist2Closest = l_Dist2;
  331. l_Closest.Copy( l_P );
  332. l_iClosest = i;
  333. }
  334. }
  335. var l_P2 : CV3D = new CV3D(0, 0, 0);
  336. var l_iClosest2 : Int = 0;
  337. // *** Get second best
  338. if( l_iClosest == 0 )
  339. {
  340. l_iClosest2 = l_iClosest + 1;
  341. GetPositionFromDistance( l_iClosest2 * l_Step, l_P2 );
  342. }
  343. else
  344. {
  345. if( l_iClosest == l_NbSamples )
  346. {
  347. l_iClosest2 = l_iClosest - 1;
  348. GetPositionFromDistance( l_iClosest2 * l_Step, l_P2 );
  349. }
  350. else
  351. {
  352. var l_PPrev : CV3D = new CV3D(0, 0, 0);
  353. var l_PNext : CV3D = new CV3D(0, 0, 0);
  354. GetPositionFromDistance( ( l_iClosest - 1 ) * l_Step, l_PPrev );
  355. GetPositionFromDistance( ( l_iClosest + 1 ) * l_Step, l_PNext );
  356. if ( CV3D.OperatorMinus( l_PPrev, _Pos ).Norm2() < CV3D.OperatorMinus( l_PNext, _Pos ).Norm2() )
  357. {
  358. l_P2.Copy( l_PPrev );
  359. l_iClosest2 = l_iClosest - 1;
  360. }
  361. else
  362. {
  363. l_P2.Copy( l_PNext );
  364. l_iClosest2 = l_iClosest + 1;
  365. }
  366. }
  367. }
  368. // *** Project _Pos on P-P2
  369. var l_VProj : CV3D = CV3D.OperatorMinus( l_P2, l_Closest );
  370. var l_Dist : Float = l_VProj.Norm();
  371. l_VProj = CV3D.OperatorScale( 1 / l_Dist, l_VProj );
  372. var l_V : CV3D = CV3D.OperatorMinus( _Pos, l_Closest );
  373. var l_Dot : Float = CV3D.DotProduct( l_V, l_VProj );
  374. var l_Ratio : Float = l_Dot / l_Dist;
  375. var l_iFloat : Float = l_iClosest * ( 1 - l_Ratio ) + l_iClosest2 * l_Ratio;
  376. return l_iFloat * l_Step;
  377. }
  378. public function Precalcs () : Void
  379. {
  380. // ***********************
  381. // *** Update infos : ***
  382. // ***********************
  383. var l_NPoints : Int = m_NbNodes;
  384. //SAFEFREE(m_CumulLength);
  385. //SAFEFREE(m_PrecalcNode);
  386. /* m_CumulLength = (Segment*)MALLOC(l_NPoints*sizeof(Segment)); */
  387. m_CumulLength = new Array<Segment>();
  388. m_Length = 0;
  389. if ( l_NPoints != 0 )
  390. {
  391. // ***************************
  392. // *** Computing length : ***
  393. // ***************************
  394. var l_PrevPosition : CV3D = CV3D.NewCopy( m_Nodes[ 0 ].Point );
  395. var l_Position : CV3D = new CV3D(0, 0, 0);
  396. var l_DPosition : CV3D = new CV3D(0, 0, 0);
  397. var l_Progression : Float;
  398. var l_NumPart : Int = Utils.RoundNearest( 1 / m_Resolution );
  399. //for ( i_EachPoint = 0; ( i_EachPoint < ( l_NPoints - 1 ) ); i_EachPoint++ )
  400. for ( i_EachPoint in 0 ... l_NPoints - 1 )
  401. {
  402. var l_CurCumul : Segment=
  403. {
  404. Start : m_Length,
  405. End : 0.0
  406. }
  407. l_Progression = m_Resolution;
  408. //for ( i_EachPart=0; ( i_EachPart < l_NumPart ); i_EachPart++ )
  409. for ( i_EachPart in 0 ... l_NumPart )
  410. {
  411. Interpolate ( i_EachPoint, l_Progression, l_Position );
  412. l_DPosition.Copy ( l_PrevPosition ); // *** Delta pos (derivate).
  413. l_DPosition = CV3D.OperatorMinus( l_DPosition, l_Position );
  414. m_Length += l_DPosition.Norm(); // *** Update length.
  415. l_Progression += m_Resolution; // *** Update progression.
  416. l_PrevPosition.Copy( l_Position ); // *** Backup position to calc delta.
  417. }
  418. l_CurCumul.End = m_Length;
  419. m_CumulLength[ i_EachPoint ] = l_CurCumul;
  420. }
  421. var l_LastCumul : Segment =
  422. {
  423. Start : m_Length,
  424. End : m_Length
  425. }
  426. m_CumulLength[ l_NPoints ] = l_LastCumul;
  427. // *** Compute Ratio From Distance
  428. m_PrecalcNode = new Array<PrecalcSplineNode>();
  429. for ( i_EachPoint in 0 ... l_NPoints - 1 )
  430. {
  431. m_PrecalcNode[ i_EachPoint ] = { Ratio : new Array<Float>() }
  432. var l_Cumul : Segment = m_CumulLength[ i_EachPoint ];
  433. //for ( i_RatioIdx = 0; i_RatioIdx < CSpline.SPLINE_NB_SAMPLE; i_RatioIdx++)
  434. for ( i_RatioIdx in 0 ... CSpline.SPLINE_NB_SAMPLE )
  435. {
  436. var l_Distance : Float = l_Cumul.Start +
  437. i_RatioIdx * ( l_Cumul.End - l_Cumul.Start ) /
  438. ( CSpline.SPLINE_NB_SAMPLE - 1 );
  439. m_PrecalcNode[ i_EachPoint ].Ratio[ i_RatioIdx ] = FindSegmentRatioFromDistance( l_Distance, i_EachPoint );
  440. }
  441. }
  442. }
  443. }
  444. public function ReverseNodes() : Void
  445. {
  446. // *** Reverse the spline
  447. var l_NewNodes : Array<SplineNode> = new Array<SplineNode>();
  448. // *** Build new node array
  449. for ( i in 0 ... m_NbNodes )
  450. {
  451. l_NewNodes[m_NbNodes - i - 1].Point = m_Nodes[i].Point;
  452. l_NewNodes[m_NbNodes - i - 1].In = m_Nodes[i].Out;
  453. l_NewNodes[m_NbNodes - i - 1].Out = m_Nodes[i].In;
  454. }
  455. SetNodes( l_NewNodes, m_NbNodes );
  456. }
  457. public function Translate( _Vec : CV3D ) : Void
  458. {
  459. for ( i in 0 ... m_NbNodes )
  460. {
  461. m_Nodes[i].Point = CV3D.OperatorPlus( m_Nodes[i].Point, _Vec );
  462. m_Nodes[i].In = CV3D.OperatorPlus( m_Nodes[i].In, _Vec );
  463. m_Nodes[i].Out = CV3D.OperatorPlus( m_Nodes[i].Out, _Vec );
  464. }
  465. Precalcs ();
  466. }
  467. /*
  468. public function Debug( ?_Resolution : Int = 20, ?_Scale : Float = 20, ?_Distance : Float ) : Void
  469. {
  470. #if flash
  471. if ( m_DebugSprite == null )
  472. {
  473. m_DebugSprite = new Sprite();
  474. Glb.GetRendererAS().AddToSceneAS( m_DebugSprite );
  475. var l_Pos : CV3D = new CV3D( 0, 0, 0 );
  476. var l_Tan : CV3D = new CV3D( 0, 0, 0 );
  477. if ( m_DebugSpline == null )
  478. {
  479. m_DebugSpline = new Shape();
  480. m_DebugSprite.addChild( m_DebugSpline );
  481. m_DebugSpline.graphics.lineStyle( 1, 0xFF0000 );
  482. // First point
  483. GetPositionFromDistance( 0, l_Pos, l_Tan );
  484. m_DebugSpline.graphics.moveTo( l_Pos.x * _Scale, l_Pos.z * _Scale );
  485. var l_FirstTanHandle = new Shape();
  486. m_DebugSprite.addChild( l_FirstTanHandle );
  487. l_FirstTanHandle.graphics.lineStyle( 1, 0x0000FF );
  488. l_FirstTanHandle.graphics.moveTo( l_Pos.x * _Scale, l_Pos.z * _Scale );
  489. l_FirstTanHandle.graphics.lineTo( ( l_Tan.x * _Scale + l_Pos.x ) * _Scale, ( l_Tan.z * _Scale + l_Pos.z ) * _Scale );
  490. // Next ones
  491. for ( i in 1 ... _Resolution +1)
  492. {
  493. // trace point
  494. GetPositionFromDistance( m_Length * i / _Resolution, l_Pos, l_Tan );
  495. m_DebugSpline.graphics.lineTo( l_Pos.x * _Scale, l_Pos.z * _Scale );
  496. // trace tangente
  497. var l_TanHandle = new Shape();
  498. m_DebugSprite.addChild( l_TanHandle );
  499. l_TanHandle.graphics.lineStyle( 1, 0x0000FF );
  500. l_TanHandle.graphics.moveTo( l_Pos.x * _Scale, l_Pos.z * _Scale );
  501. l_TanHandle.graphics.lineTo( ( l_Tan.x * _Scale + l_Pos.x ) * _Scale, ( l_Tan.z * _Scale + l_Pos.z ) * _Scale );
  502. }
  503. var l_FileSpline = new Shape();
  504. m_DebugSprite.addChild( l_FileSpline );
  505. l_FileSpline.graphics.lineStyle( 1, 0xFF8844 );
  506. // First point
  507. l_Pos.Copy( m_Nodes[0].Point );
  508. l_FileSpline.graphics.moveTo( l_Pos.x * _Scale, l_Pos.z * _Scale );
  509. var l_FirstPoint = new Shape();
  510. l_FirstPoint.graphics.lineStyle( 1, 0xFAFAD2 );
  511. m_DebugSprite.addChild( l_FirstPoint );
  512. l_FirstPoint.graphics.drawCircle( l_Pos.x * _Scale, l_Pos.z * _Scale, _Scale );
  513. // First tangente
  514. l_Tan = CV3D.OperatorMinus( m_Nodes[0].Out, m_Nodes[0].In );
  515. CV3D.Normalize( l_Tan );
  516. var l_FirstDbgTanHandle = new Shape();
  517. m_DebugSprite.addChild( l_FirstDbgTanHandle );
  518. l_FirstDbgTanHandle.graphics.lineStyle( 1, 0x00FF00 );
  519. l_FirstDbgTanHandle.graphics.moveTo( l_Pos.x * _Scale, l_Pos.z * _Scale );
  520. l_FirstDbgTanHandle.graphics.lineTo( ( l_Tan.x * _Scale + l_Pos.x ) * _Scale, ( l_Tan.z * _Scale + l_Pos.z ) * _Scale );
  521. // Next ones
  522. for ( i in 1 ... m_NbNodes )
  523. {
  524. // trace point
  525. l_Pos.Copy( m_Nodes[i].Point );
  526. l_FileSpline.graphics.lineTo( l_Pos.x * _Scale, l_Pos.z * _Scale );
  527. var l_Point = new Shape();
  528. l_Point.graphics.lineStyle( 1, 0xFAFAD2 );
  529. m_DebugSprite.addChild( l_Point );
  530. l_Point.graphics.drawCircle( l_Pos.x * _Scale, l_Pos.z * _Scale, _Scale );
  531. // trace tangente
  532. l_Tan = CV3D.OperatorMinus( m_Nodes[i].Out, m_Nodes[i].In );
  533. CV3D.Normalize( l_Tan );
  534. var l_TanHandle = new Shape();
  535. m_DebugSprite.addChild( l_TanHandle );
  536. l_TanHandle.graphics.lineStyle( 1, 0x00FF00 );
  537. l_TanHandle.graphics.moveTo( l_Pos.x * _Scale, l_Pos.z * _Scale );
  538. l_TanHandle.graphics.lineTo( ( l_Tan.x * _Scale + l_Pos.x ) * _Scale, ( l_Tan.z * _Scale + l_Pos.z ) * _Scale );
  539. }
  540. if ( _Distance != null )
  541. {
  542. GetPositionFromDistance( _Distance, l_Pos, l_Tan );
  543. var l_Point = new Shape();
  544. l_Point.graphics.lineStyle( 1, 0x000000 );
  545. l_Point.graphics.beginFill( 0xFF0000 );
  546. m_DebugSprite.addChild( l_Point );
  547. l_Point.graphics.drawCircle( l_Pos.x * _Scale, l_Pos.z * _Scale, _Scale * 0.2 );
  548. }
  549. m_DebugSprite.x = 300;
  550. m_DebugSprite.y = 300;
  551. }
  552. }
  553. #end
  554. }
  555. public function ClearDebug() : Void
  556. {
  557. #if flash
  558. if ( m_DebugSprite != null )
  559. {
  560. Glb.GetRendererAS().RemoveFromSceneAS( m_DebugSprite );
  561. m_DebugSprite = null;
  562. }
  563. if ( m_DebugSpline != null )
  564. {
  565. //Glb.GetRendererAS().RemoveFromSceneAS( m_DebugSpline );
  566. m_DebugSpline = null;
  567. }
  568. #end
  569. }
  570. #if flash
  571. var m_DebugSprite : Sprite;
  572. var m_DebugSpline : Shape;
  573. #end
  574. */
  575. }