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  */
26 CMotionTrail ( ) {
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  */
72 ~CMotionTrail ( ) {
73 
74 }
75 
76 /**
77  * Reset the frame sample history.
78  */
80 reset ( ) {
81  _frame_list.clear ( );
82 }
83 
84 /**
85  * Reset the vertex list.
86  */
89  _vertex_list.clear ( );
90 }
91 
92 /**
93  * Enable/disable the motion trail.
94  */
96 enable (bool enable) {
97  _enable = enable;
98 }
99 
100 /**
101  * Set the GeomNode.
102  */
104 set_geom_node (GeomNode *geom_node) {
105  _geom_node = geom_node;
106 }
107 
108 /**
109  * Add a vertex.
110  */
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  */
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  */
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  */
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  */
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  */
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 (motion_trail_frame._transform == UnalignedLMatrix4(*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 }
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void reset()
Reset the frame sample history.
void update_motion_trail(PN_stdfloat current_time, LMatrix4 *transform)
See class header comments.
int check_for_update(PN_stdfloat current_time)
Check if a sample can be submitted.
~CMotionTrail()
Destructor.
void enable(bool enable)
Enable/disable the motion trail.
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.
void reset_vertex_list()
Reset the vertex list.
void set_geom_node(GeomNode *geom_node)
Set the GeomNode.
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 add_vertex(LVector4 *vertex, LVector4 *start_color, LVector4 *end_color, PN_stdfloat v)
Add a vertex.
CMotionTrail()
Constructor.
A node that holds Geom objects, renderable pieces of geometry.
Definition: geomNode.h:34
Defines a series of disconnected triangles.
Definition: geomTriangles.h:23
This defines the actual numeric vertex data stored in a Geom, in the structure defined by a particula...
This class defines the physical layout of the vertex data stored within a Geom.
static const GeomVertexFormat * get_v3c4()
Returns a standard vertex format with a 4-component color and a 3-component vertex position.
static const GeomVertexFormat * get_v3c4t2()
Returns a standard vertex format with a 2-component texture coordinate pair, a 4-component color,...
This object provides a high-level interface for quickly writing a sequence of numeric values from a v...
void clear()
Resets the GeomVertexWriter to the initial state.
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_data2(PN_stdfloat x, PN_stdfloat y)
Sets the write row to a particular 2-component value, and advances the write row.
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.
A container for geometry primitives.
Definition: geom.h:54
This class is an abstraction for evaluating NURBS curves.
The result of a NurbsCurveEvaluator.
This represents a unique collection of RenderAttrib objects that correspond to a particular renderabl...
Definition: renderState.h:47
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:81
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.