Panda3D
cMotionTrail.cxx
1 // Filename: cMotionTrail.h
2 // Created by: aignacio (29Jan07)
3 //
4 ////////////////////////////////////////////////////////////////////
5 //
6 // PANDA 3D SOFTWARE
7 // Copyright (c) Carnegie Mellon University. All rights reserved.
8 //
9 // All use of this software is subject to the terms of the revised BSD
10 // license. You should have received a copy of this license along
11 // with this source code in a file named "LICENSE."
12 //
13 ////////////////////////////////////////////////////////////////////
14 
15 #include "directbase.h"
16 #include "cMotionTrail.h"
17 #include "renderState.h"
18 #include "colorAttrib.h"
19 
20 
21 TypeHandle CMotionTrail::_type_handle;
22 
23 ////////////////////////////////////////////////////////////////////
24 // Function: CMotionTrail::Constructor
25 // Access: Published
26 // Description: Constructor
27 ////////////////////////////////////////////////////////////////////
30 
31  _active = true;
32  _enable = true;
33 
34  _pause = false;
35  _pause_time = 0.0f;
36 
37  _fade = false;
38  _fade_end = false;
39  _fade_time = 0.0f;
40  _fade_start_time = 0.0f;
41  _fade_color_scale = 1.0f;
42 
43  _last_update_time = 0.0f;
44 
45  _vertex_list.clear ( );
46  _frame_list.clear ( );
47 
48  // parameters
49  _color_scale = 1.0;
50  _sampling_time = 0.0;
51  _time_window = 1.0;
52  _square_t = true;
53  _use_texture = false;
54  _calculate_relative_matrix = false;
55 
56  // nurbs parameters
57  _use_nurbs = false;
58  _resolution_distance = 0.5f;
59 
60  // node path states
61  _geom_node = 0;
62 
63  // real-time data
64  _vertex_index = 0;
65  _vertex_data = 0;
66  _triangles = 0;
67 
68  _vertex_array = 0;
69 }
70 
71 ////////////////////////////////////////////////////////////////////
72 // Function: CMotionTrail::Destructor
73 // Access: Published
74 // Description: Destructor
75 ////////////////////////////////////////////////////////////////////
78 
79 }
80 
81 ////////////////////////////////////////////////////////////////////
82 // Function: CMotionTrail::reset
83 // Access: Published
84 // Description: Reset the frame sample history.
85 ////////////////////////////////////////////////////////////////////
86 void CMotionTrail::
87 reset ( ) {
88  _frame_list.clear ( );
89 }
90 
91 ////////////////////////////////////////////////////////////////////
92 // Function: CMotionTrail::reset_vertex_list
93 // Access: Published
94 // Description: Reset the vertex list.
95 ////////////////////////////////////////////////////////////////////
96 void CMotionTrail::
98  _vertex_list.clear ( );
99 }
100 
101 ////////////////////////////////////////////////////////////////////
102 // Function: CMotionTrail::enable
103 // Access: Published
104 // Description: Enable/disable the motion trail.
105 ////////////////////////////////////////////////////////////////////
106 void CMotionTrail::
107 enable (bool enable) {
108  _enable = enable;
109 }
110 
111 ////////////////////////////////////////////////////////////////////
112 // Function: CMotionTrail::set_geom_node
113 // Access: Published
114 // Description: Set the GeomNode.
115 ////////////////////////////////////////////////////////////////////
116 void CMotionTrail::
117 set_geom_node (GeomNode *geom_node) {
118  _geom_node = geom_node;
119 }
120 
121 ////////////////////////////////////////////////////////////////////
122 // Function: CMotionTrail::add_vertex
123 // Access: Published
124 // Description: Add a vertex.
125 ////////////////////////////////////////////////////////////////////
126 void CMotionTrail::
127 add_vertex (LVector4 *vertex, LVector4 *start_color, LVector4 *end_color, PN_stdfloat v) {
128 
129  CMotionTrailVertex motion_trail_vertex;
130 
131  motion_trail_vertex._vertex = *vertex;
132  motion_trail_vertex._start_color = *start_color;
133  motion_trail_vertex._end_color = *end_color;
134  motion_trail_vertex._v = v;
135 
136  motion_trail_vertex._nurbs_curve_evaluator = new NurbsCurveEvaluator ( );
137 
138  _vertex_list.push_back (motion_trail_vertex);
139 }
140 
141 ////////////////////////////////////////////////////////////////////
142 // Function: CMotionTrail::set_parameters
143 // Access: Published
144 // Description: Set motion trail parameters.
145 //
146 // sampling_time = Can be used to specify a lower
147 // sampling rate than the frame rate. Use 0.0 with
148 // nurbs.
149 //
150 // time_window = a component for the "length" of the
151 // motion trail. The motion trail length =
152 // time_window * velocity of the object.
153 //
154 // use_texture = texture option on/off.
155 //
156 // calculate_relative_matrix = calculate relative
157 // matrix on/off.
158 //
159 // use_nurbs = nurbs option on/off
160 //
161 // resolution_distance = the distance used to
162 // determine the number of geometry samples.
163 // samples = motion trail length / resolution_distance.
164 // Applicable only if nurbs is on.
165 ////////////////////////////////////////////////////////////////////
166 void CMotionTrail::
167 set_parameters (PN_stdfloat sampling_time, PN_stdfloat time_window, bool use_texture, bool calculate_relative_matrix, bool use_nurbs, PN_stdfloat resolution_distance) {
168 
169  _sampling_time = sampling_time;
170  _time_window = time_window;
171  _use_texture = use_texture;
172  _calculate_relative_matrix = calculate_relative_matrix;
173  _use_nurbs = use_nurbs;
174  _resolution_distance = resolution_distance;
175 }
176 
177 ////////////////////////////////////////////////////////////////////
178 // Function: CMotionTrail::check_for_update
179 // Access: Published
180 // Description: Check if a sample can be submitted.
181 ////////////////////////////////////////////////////////////////////
182 int CMotionTrail::
183 check_for_update (PN_stdfloat current_time) {
184 
185  int state;
186 
187  state = false;
188  if ((current_time - _last_update_time) >= _sampling_time) {
189  state = true;
190  }
191  if (_pause) {
192  state = false;
193  }
194  state = state && _enable;
195 
196  return state;
197 }
198 
199 PN_stdfloat one_minus_x (PN_stdfloat x) {
200  x = 1.0 - x;
201  if (x < 0.0) {
202  x = 0.0;
203  }
204 
205  return x;
206 }
207 
208 ////////////////////////////////////////////////////////////////////
209 // Function: CMotionTrail::begin_geometry
210 // Access: Public
211 // Description:
212 ////////////////////////////////////////////////////////////////////
213 void CMotionTrail::
214 begin_geometry ( ) {
215 
216  const GeomVertexFormat *format;
217 
218  _vertex_index = 0;
219  if (_use_texture) {
220  format = GeomVertexFormat::get_v3c4t2 ( );
221  }
222  else {
223  format = GeomVertexFormat::get_v3c4 ( );
224  }
225 
226  // Clear the previous writers before we create a new vertex data
227  // object--this seems to work around an ordering problem in the
228  // low-level vertex data destructors.
229  _vertex_writer.clear();
230  _color_writer.clear();
231  _texture_writer.clear();
232 
233  _vertex_data = new GeomVertexData ("vertices", format, Geom::UH_static);
234  _vertex_writer = GeomVertexWriter (_vertex_data, "vertex");
235  _color_writer = GeomVertexWriter (_vertex_data, "color");
236  if (_use_texture) {
237  _texture_writer = GeomVertexWriter (_vertex_data, "texcoord");
238  }
239 
240  _triangles = new GeomTriangles (Geom::UH_static);
241 }
242 
243 ////////////////////////////////////////////////////////////////////
244 // Function: CMotionTrail::add_geometry_quad
245 // Access: Public
246 // Description: LVector3 vertex version.
247 ////////////////////////////////////////////////////////////////////
248 void CMotionTrail::
250 
251  _vertex_writer.add_data3 (v0);
252  _vertex_writer.add_data3 (v1);
253  _vertex_writer.add_data3 (v2);
254  _vertex_writer.add_data3 (v3);
255 
256  _color_writer.add_data4 (c0);
257  _color_writer.add_data4 (c1);
258  _color_writer.add_data4 (c2);
259  _color_writer.add_data4 (c3);
260 
261  if (_use_texture) {
262  _texture_writer.add_data2 (t0);
263  _texture_writer.add_data2 (t1);
264  _texture_writer.add_data2 (t2);
265  _texture_writer.add_data2 (t3);
266  }
267 
268  int vertex_index;
269  vertex_index = _vertex_index;
270 
271  _triangles -> add_vertex (vertex_index + 0);
272  _triangles -> add_vertex (vertex_index + 1);
273  _triangles -> add_vertex (vertex_index + 2);
274  _triangles -> close_primitive ( );
275 
276  _triangles -> add_vertex (vertex_index + 1);
277  _triangles -> add_vertex (vertex_index + 3);
278  _triangles -> add_vertex (vertex_index + 2);
279  _triangles -> close_primitive ( );
280 
281  _vertex_index += 4;
282 }
283 
284 ////////////////////////////////////////////////////////////////////
285 // Function: CMotionTrail::add_geometry_quad
286 // Access: Public
287 // Description: LVector4 vertex version.
288 ////////////////////////////////////////////////////////////////////
289 void CMotionTrail::
291 
292  _vertex_writer.add_data3 (v0 [0], v0 [1], v0 [2]);
293  _vertex_writer.add_data3 (v1 [0], v1 [1], v1 [2]);
294  _vertex_writer.add_data3 (v2 [0], v2 [1], v2 [2]);
295  _vertex_writer.add_data3 (v3 [0], v3 [1], v3 [2]);
296 
297  _color_writer.add_data4 (c0);
298  _color_writer.add_data4 (c1);
299  _color_writer.add_data4 (c2);
300  _color_writer.add_data4 (c3);
301 
302  if (_use_texture) {
303  _texture_writer.add_data2 (t0);
304  _texture_writer.add_data2 (t1);
305  _texture_writer.add_data2 (t2);
306  _texture_writer.add_data2 (t3);
307  }
308 
309  int vertex_index;
310  vertex_index = _vertex_index;
311 
312  _triangles -> add_vertex (vertex_index + 0);
313  _triangles -> add_vertex (vertex_index + 1);
314  _triangles -> add_vertex (vertex_index + 2);
315  _triangles -> close_primitive ( );
316 
317  _triangles -> add_vertex (vertex_index + 1);
318  _triangles -> add_vertex (vertex_index + 3);
319  _triangles -> add_vertex (vertex_index + 2);
320  _triangles -> close_primitive ( );
321 
322  _vertex_index += 4;
323 }
324 
325 ////////////////////////////////////////////////////////////////////
326 // Function: CMotionTrail::end_geometry
327 // Access: Public
328 // Description:
329 ////////////////////////////////////////////////////////////////////
330 void CMotionTrail::end_geometry ( ) {
331  static CPT(RenderState) state;
332  if (state == (RenderState *)NULL) {
333  state = RenderState::make(ColorAttrib::make_vertex());
334  }
335 
336  PT(Geom) geometry;
337 
338  geometry = new Geom (_vertex_data);
339  geometry -> add_primitive (_triangles);
340 
341  if (_geom_node) {
342  _geom_node -> remove_all_geoms ( );
343  _geom_node -> add_geom (geometry, state);
344  }
345 }
346 
347 ////////////////////////////////////////////////////////////////////
348 // Function: CMotionTrail::update_motion_trail
349 // Access: Published
350 // Description: See class header comments.
351 ////////////////////////////////////////////////////////////////////
352 void CMotionTrail::
353 update_motion_trail (PN_stdfloat current_time, LMatrix4 *transform) {
354 
355  int debug;
356  int total_frames;
357 
358  debug = false;
359 
360  total_frames = _frame_list.size ( );
361  if (total_frames >= 1) {
362  FrameList::iterator frame_iterator;
363  CMotionTrailFrame motion_trail_frame;
364 
365  frame_iterator = _frame_list.begin ( );
366  motion_trail_frame = *frame_iterator;
367  if (*transform == motion_trail_frame._transform) {
368  // duplicate transform
369  return;
370  }
371  }
372 
373  int total_vertices;
374  PN_stdfloat color_scale;
375  LMatrix4 start_transform;
376  LMatrix4 end_transform;
377  LMatrix4 inverse_matrix;
378 
379  total_vertices = _vertex_list.size ( );
380  color_scale = _color_scale;
381  if (_fade) {
382  PN_stdfloat elapsed_time;
383 
384  elapsed_time = current_time - _fade_start_time;
385  if (elapsed_time < 0.0) {
386  elapsed_time = 0.0;
387  }
388  if (elapsed_time < _fade_time) {
389  color_scale = (1.0f - (elapsed_time / _fade_time)) * color_scale;
390  }
391  else {
392  color_scale = 0.0;
393  _fade_end = true;
394  }
395  }
396 
397  _last_update_time = current_time;
398 
399  // remove expired frames
400  PN_stdfloat minimum_time;
401 
402  minimum_time = current_time - _time_window;
403 
404  CMotionTrailFrame motion_trail_frame;
405 
406  while (!_frame_list.empty()) {
407  motion_trail_frame = _frame_list.back();
408  if (motion_trail_frame._time >= minimum_time) {
409  break;
410  }
411 
412  _frame_list.pop_back ( );
413  }
414 
415  // add new frame to beginning of list
416  {
417  CMotionTrailFrame motion_trail_frame;
418 
419  motion_trail_frame._time = current_time;
420  motion_trail_frame._transform = *transform;
421 
422  _frame_list.push_front(motion_trail_frame);
423  }
424 
425  // convert frames and vertices to geometry
426  total_frames = _frame_list.size ( );
427 
428  if (debug) {
429  printf ("update_motion_trail, total_frames = %d, total_vertices = %d, nurbs = %d, _calculate_relative_matrix = %d \n", total_frames, total_vertices, _use_nurbs, _calculate_relative_matrix);
430  }
431 
432  if ((total_frames >= 2) && (total_vertices >= 2)) {
433  int total_segments;
434  PN_stdfloat minimum_time;
435  PN_stdfloat delta_time;
436  CMotionTrailFrame last_motion_trail_frame;
437 
438  VertexList::iterator vertex_iterator;
439 
440  // convert vertex list to vertex array
441  int index = 0;
442  _vertex_array = new CMotionTrailVertex [total_vertices];
443  for (vertex_iterator = _vertex_list.begin ( ); vertex_iterator != _vertex_list.end ( ); vertex_iterator++) {
444  _vertex_array [index] = *vertex_iterator;
445  index++;
446  }
447 
448  // begin geometry
449  this -> begin_geometry ( );
450 
451  total_segments = total_frames - 1;
452 
453  last_motion_trail_frame = _frame_list.back();
454  minimum_time = last_motion_trail_frame._time;
455  delta_time = current_time - minimum_time;
456 
457  if (_calculate_relative_matrix) {
458  inverse_matrix = *transform;
459  inverse_matrix.invert_in_place ( );
460  }
461 
462  if (_use_nurbs && (total_frames >= 5)) {
463 
464  // nurbs version
465  int total_vertex_segments;
466  PN_stdfloat total_distance;
467  LVector3 vector;
468  LVector4 v;
469  LVector4 v0;
470  LVector4 v1;
471  LVector4 v2;
472  LVector4 v3;
473 
474  total_vertex_segments = total_vertices - 1;
475  total_distance = 0.0f;
476 
477  // reset NurbsCurveEvaluators for each vertex (the starting point for the trail)
478  {
479  CMotionTrailVertex *motion_trail_vertex;
480  PT(NurbsCurveEvaluator) nurbs_curve_evaluator;
481 
482  for (index = 0; index < total_vertices; index++) {
483  motion_trail_vertex = &_vertex_array [index];
484  nurbs_curve_evaluator = motion_trail_vertex -> _nurbs_curve_evaluator;
485  nurbs_curve_evaluator -> set_order (4);
486  nurbs_curve_evaluator -> reset (total_segments);
487  }
488  }
489 
490  // add vertices to each NurbsCurveEvaluator
491  int segment_index;
492  CMotionTrailFrame motion_trail_frame_start;
493  CMotionTrailFrame motion_trail_frame_end;
494 
495  segment_index = 0;
496 
497  FrameList::iterator frame_iterator;
498  frame_iterator = _frame_list.begin ( );
499  while (segment_index < total_segments) {
500  int vertex_segement_index;
501 
502  motion_trail_frame_start = *frame_iterator;
503  frame_iterator++;
504  motion_trail_frame_end = *frame_iterator;
505 
506  if (_calculate_relative_matrix) {
507  start_transform.multiply (motion_trail_frame_start._transform, inverse_matrix);
508  end_transform.multiply (motion_trail_frame_end._transform, inverse_matrix);
509  }
510  else {
511  start_transform = motion_trail_frame_start._transform;
512  end_transform = motion_trail_frame_end._transform;
513  }
514 
515  CMotionTrailVertex *motion_trail_vertex_start;
516  CMotionTrailVertex *motion_trail_vertex_end;
517  PT(NurbsCurveEvaluator) nurbs_curve_evaluator;
518 
519  motion_trail_vertex_start = &_vertex_array [0];
520 
521  v0 = start_transform.xform (motion_trail_vertex_start -> _vertex);
522  v2 = end_transform.xform (motion_trail_vertex_start -> _vertex);
523 
524  nurbs_curve_evaluator = motion_trail_vertex_start -> _nurbs_curve_evaluator;
525  nurbs_curve_evaluator -> set_vertex (segment_index, v0);
526 
527  vertex_segement_index = 0;
528  while (vertex_segement_index < total_vertex_segments) {
529  motion_trail_vertex_start = &_vertex_array [vertex_segement_index];
530  motion_trail_vertex_end = &_vertex_array [vertex_segement_index + 1];
531 
532  v1 = start_transform.xform (motion_trail_vertex_end -> _vertex);
533  v3 = end_transform.xform (motion_trail_vertex_end -> _vertex);
534 
535  nurbs_curve_evaluator = motion_trail_vertex_end -> _nurbs_curve_evaluator;
536 
537  nurbs_curve_evaluator -> set_vertex (segment_index, v1);
538  if (vertex_segement_index == (total_vertex_segments - 1)) {
539  PN_stdfloat distance;
540 
541  v = v1 - v3;
542  vector.set (v[0], v[1], v[2]);
543  distance = vector.length();
544  total_distance += distance;
545  }
546 
547  vertex_segement_index += 1;
548  }
549 
550  segment_index += 1;
551  }
552 
553  // evaluate NurbsCurveEvaluator for each vertex
554  PT(NurbsCurveResult) *nurbs_curve_result_array;
555 
556  nurbs_curve_result_array = new PT(NurbsCurveResult) [total_vertices];
557  for (index = 0; index < total_vertices; index++) {
558 
559  CMotionTrailVertex *motion_trail_vertex;
560  PT(NurbsCurveEvaluator) nurbs_curve_evaluator;
561  PT(NurbsCurveResult) nurbs_curve_result;
562 
563  motion_trail_vertex = &_vertex_array [index];
564 
565  nurbs_curve_evaluator = motion_trail_vertex -> _nurbs_curve_evaluator;
566  nurbs_curve_result = nurbs_curve_evaluator -> evaluate ( );
567  nurbs_curve_result_array [index] = nurbs_curve_result;
568 
569  if (debug) {
570  PN_stdfloat nurbs_start_t;
571  PN_stdfloat nurbs_end_t;
572 
573  nurbs_start_t = nurbs_curve_result -> get_start_t();
574  nurbs_end_t = nurbs_curve_result -> get_end_t();
575 
576  printf ("nurbs_start_t %f, nurbs_end_t %f \n", nurbs_start_t, nurbs_end_t);
577  }
578  }
579 
580  // create quads from NurbsCurveResult
581  PN_stdfloat total_curve_segments;
582 
583  total_curve_segments = (total_distance / _resolution_distance);
584  if (total_curve_segments < total_segments) {
585  total_curve_segments = total_segments;
586  }
587 
588  {
589  LVector3 v0;
590  LVector3 v1;
591  LVector3 v2;
592  LVector3 v3;
593 
594  LVector4 c0;
595  LVector4 c1;
596  LVector4 c2;
597  LVector4 c3;
598 
599  LVector2 t0;
600  LVector2 t1;
601  LVector2 t2;
602  LVector2 t3;
603 
604  LVector4 vertex_start_color;
605  LVector4 vertex_end_color;
606 
607  PN_stdfloat curve_segment_index;
608 
609  curve_segment_index = 0.0;
610  while (curve_segment_index < total_curve_segments) {
611 
612  PN_stdfloat st;
613  PN_stdfloat et;
614  PN_stdfloat start_t;
615  PN_stdfloat end_t;
616  PN_stdfloat color_start_t;
617  PN_stdfloat color_end_t;
618 
619  int vertex_segement_index;
620 
621  CMotionTrailVertex *motion_trail_vertex_start;
622  CMotionTrailVertex *motion_trail_vertex_end;
623  PT(NurbsCurveResult) start_nurbs_curve_result;
624  PT(NurbsCurveResult) end_nurbs_curve_result;
625 
626  vertex_segement_index = 0;
627 
628  st = curve_segment_index / total_curve_segments;
629  et = (curve_segment_index + 1.0) / total_curve_segments;
630 
631  start_t = st;
632  end_t = et;
633 
634  if (_square_t) {
635  start_t *= start_t;
636  end_t *= end_t;
637  }
638 
639  motion_trail_vertex_start = &_vertex_array [0];
640 
641  vertex_start_color = motion_trail_vertex_start -> _end_color + (motion_trail_vertex_start -> _start_color - motion_trail_vertex_start -> _end_color);
642 
643  color_start_t = color_scale * start_t;
644  color_end_t = color_scale * end_t;
645 
646  c0 = vertex_start_color * one_minus_x (color_start_t);
647  c2 = vertex_start_color * one_minus_x (color_end_t);
648 
649  t0.set (one_minus_x (st), motion_trail_vertex_start -> _v);
650  t2.set (one_minus_x (et), motion_trail_vertex_start -> _v);
651 
652  while (vertex_segement_index < total_vertex_segments) {
653 
654  PN_stdfloat start_nurbs_start_t;
655  PN_stdfloat start_nurbs_end_t;
656  PN_stdfloat end_nurbs_start_t;
657  PN_stdfloat end_nurbs_end_t;
658 
659  motion_trail_vertex_start = &_vertex_array [vertex_segement_index];
660  motion_trail_vertex_end = &_vertex_array [vertex_segement_index + 1];
661 
662  start_nurbs_curve_result = nurbs_curve_result_array [vertex_segement_index];
663  end_nurbs_curve_result = nurbs_curve_result_array [vertex_segement_index + 1];
664 
665  start_nurbs_start_t = start_nurbs_curve_result -> get_start_t();
666  start_nurbs_end_t = start_nurbs_curve_result -> get_end_t();
667  end_nurbs_start_t = end_nurbs_curve_result -> get_start_t();
668  end_nurbs_end_t = end_nurbs_curve_result -> get_end_t();
669 
670  PN_stdfloat start_delta_t;
671  PN_stdfloat end_delta_t;
672 
673  start_delta_t = (start_nurbs_end_t - start_nurbs_start_t);
674  end_delta_t = (end_nurbs_end_t - end_nurbs_start_t);
675 
676  start_nurbs_curve_result -> eval_point (start_nurbs_start_t + (start_delta_t * st), v0);
677  end_nurbs_curve_result -> eval_point (end_nurbs_start_t + (end_delta_t * st), v1);
678 
679  start_nurbs_curve_result -> eval_point (start_nurbs_start_t + (start_delta_t * et), v2);
680  end_nurbs_curve_result -> eval_point (end_nurbs_start_t + (end_delta_t * et), v3);
681 
682  // color
683  vertex_end_color = motion_trail_vertex_end -> _end_color + (motion_trail_vertex_end -> _start_color - motion_trail_vertex_end -> _end_color);
684 
685  c1 = vertex_end_color * one_minus_x (color_start_t);
686  c3 = vertex_end_color * one_minus_x (color_end_t);
687 
688  // uv
689  t1.set (one_minus_x (st), motion_trail_vertex_end -> _v);
690  t3.set (one_minus_x (et), motion_trail_vertex_end -> _v);
691 
692  this -> add_geometry_quad (v0, v1, v2, v3, c0, c1, c2, c3, t0, t1, t2, t3);
693 
694  // reuse calculations
695  c0 = c1;
696  c2 = c3;
697 
698  t0 = t1;
699  t2 = t3;
700 
701  vertex_segement_index += 1;
702  }
703 
704  curve_segment_index += 1.0;
705  }
706  }
707 
708  for (index = 0; index < total_vertices; index++) {
709  nurbs_curve_result_array [index] = 0;
710  }
711 
712  delete[] nurbs_curve_result_array;
713  }
714  else {
715 
716  // non-nurbs version
717  int segment_index;
718  int vertex_segment_index;
719  int total_vertex_segments;
720 
721  PN_stdfloat st;
722  PN_stdfloat et;
723  PN_stdfloat start_t;
724  PN_stdfloat end_t;
725  PN_stdfloat color_start_t;
726  PN_stdfloat color_end_t;
727 
728  LVector4 v0;
729  LVector4 v1;
730  LVector4 v2;
731  LVector4 v3;
732 
733  LVector4 c0;
734  LVector4 c1;
735  LVector4 c2;
736  LVector4 c3;
737 
738  LVector2 t0;
739  LVector2 t1;
740  LVector2 t2;
741  LVector2 t3;
742 
743  LVector4 vertex_start_color;
744  LVector4 vertex_end_color;
745 
746  CMotionTrailFrame motion_trail_frame_start;
747  CMotionTrailFrame motion_trail_frame_end;
748 
749  segment_index = 0;
750  FrameList::iterator frame_iterator;
751  frame_iterator = _frame_list.begin ( );
752  while (segment_index < total_segments) {
753 
754  CMotionTrailVertex *motion_trail_vertex_start;
755  CMotionTrailVertex *motion_trail_vertex_end;
756 
757  motion_trail_frame_start = *frame_iterator;
758  frame_iterator++;
759  motion_trail_frame_end = *frame_iterator;
760 
761  start_t = (motion_trail_frame_start._time - minimum_time) / delta_time;
762  end_t = (motion_trail_frame_end._time - minimum_time) / delta_time;
763 
764  st = start_t;
765  et = end_t;
766 
767  if (_square_t) {
768  start_t *= start_t;
769  end_t *= end_t;
770  }
771 
772  vertex_segment_index = 0;
773  total_vertex_segments = total_vertices - 1;
774 
775  if (_calculate_relative_matrix) {
776  start_transform.multiply (motion_trail_frame_start._transform, inverse_matrix);
777  end_transform.multiply (motion_trail_frame_end._transform, inverse_matrix);
778  }
779  else {
780  start_transform = motion_trail_frame_start._transform;
781  end_transform = motion_trail_frame_end._transform;
782  }
783 
784  motion_trail_vertex_start = &_vertex_array [0];
785 
786  v0 = start_transform.xform (motion_trail_vertex_start -> _vertex);
787  v2 = end_transform.xform (motion_trail_vertex_start -> _vertex);
788 
789  vertex_start_color = motion_trail_vertex_start -> _end_color + (motion_trail_vertex_start -> _start_color - motion_trail_vertex_start -> _end_color);
790  color_start_t = color_scale * start_t;
791  color_end_t = color_scale * end_t;
792  c0 = vertex_start_color * color_start_t;
793  c2 = vertex_start_color * color_end_t;
794 
795  t0.set (st, motion_trail_vertex_start -> _v);
796  t2.set (et, motion_trail_vertex_start -> _v);
797 
798  while (vertex_segment_index < total_vertex_segments) {
799 
800  motion_trail_vertex_start = &_vertex_array [vertex_segment_index];
801  motion_trail_vertex_end = &_vertex_array [vertex_segment_index + 1];
802 
803  v1 = start_transform.xform (motion_trail_vertex_end -> _vertex);
804  v3 = end_transform.xform (motion_trail_vertex_end -> _vertex);
805 
806  // color
807  vertex_end_color = motion_trail_vertex_end -> _end_color + (motion_trail_vertex_end -> _start_color - motion_trail_vertex_end -> _end_color);
808 
809  c1 = vertex_end_color * color_start_t;
810  c3 = vertex_end_color * color_end_t;
811 
812  // uv
813  t1.set (st, motion_trail_vertex_end -> _v);
814  t3.set (et, motion_trail_vertex_end -> _v);
815 
816  this -> add_geometry_quad (v0, v1, v2, v3, c0, c1, c2, c3, t0, t1, t2, t3);
817 
818  // reuse calculations
819  v0 = v1;
820  v2 = v3;
821 
822  c0 = c1;
823  c2 = c3;
824 
825  t0 = t1;
826  t2 = t3;
827 
828  vertex_segment_index += 1;
829  }
830 
831  segment_index += 1;
832  }
833  }
834 
835  // end geometry
836  this -> end_geometry ( );
837 
838  delete[] _vertex_array;
839  _vertex_array = 0;
840  }
841 }
void enable(bool enable)
Enable/disable the motion trail.
This object provides a high-level interface for quickly writing a sequence of numeric values from a v...
void reset_vertex_list()
Reset the vertex list.
void clear()
Resets the GeomVertexWriter to the initial state.
This class is an abstraction for evaluating NURBS curves.
void add_data2(PN_stdfloat x, PN_stdfloat y)
Sets the write row to a particular 2-component value, and advances the write row. ...
This is a three-component vector distance (as opposed to a three-component point, which represents a ...
Definition: lvector3.h:100
void add_data4(PN_stdfloat x, PN_stdfloat y, PN_stdfloat z, PN_stdfloat w)
Sets the write row to a particular 4-component value, and advances the write row. ...
void add_geometry_quad(LVector3 &v0, LVector3 &v1, LVector3 &v2, LVector3 &v3, LVector4 &c0, LVector4 &c1, LVector4 &c2, LVector4 &c3, LVector2 &t0, LVector2 &t1, LVector2 &t2, LVector2 &t3)
LVector3 vertex version.
void reset()
Reset the frame sample history.
This is a 4-by-4 transform matrix.
Definition: lmatrix.h:451
This defines the actual numeric vertex data stored in a Geom, in the structure defined by a particula...
CMotionTrail()
Constructor.
A container for geometry primitives.
Definition: geom.h:58
void add_data3(PN_stdfloat x, PN_stdfloat y, PN_stdfloat z)
Sets the write row to a particular 3-component value, and advances the write row. ...
This is a four-component vector distance.
Definition: lvector4.h:91
~CMotionTrail()
Destructor.
LVecBase4f xform(const LVecBase4f &v) const
4-component vector or point times matrix.
Definition: lmatrix.h:1647
This represents a unique collection of RenderAttrib objects that correspond to a particular renderabl...
Definition: renderState.h:53
void set_parameters(PN_stdfloat sampling_time, PN_stdfloat time_window, bool use_texture, bool calculate_relative_matrix, bool use_nurbs, PN_stdfloat resolution_distance)
Set motion trail parameters.
float length() const
Returns the length of the vector, by the Pythagorean theorem.
Definition: lvecBase3.h:766
This is a two-component vector offset.
Definition: lvector2.h:91
bool invert_in_place()
Inverts the current matrix.
Definition: lmatrix.h:2288
int check_for_update(PN_stdfloat current_time)
Check if a sample can be submitted.
Defines a series of disconnected triangles.
Definition: geomTriangles.h:25
void add_vertex(LVector4 *vertex, LVector4 *start_color, LVector4 *end_color, PN_stdfloat v)
Add a vertex.
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:85
The result of a NurbsCurveEvaluator.
void update_motion_trail(PN_stdfloat current_time, LMatrix4 *transform)
See class header comments.
A node that holds Geom objects, renderable pieces of geometry.
Definition: geomNode.h:37
void set_geom_node(GeomNode *geom_node)
Set the GeomNode.