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