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
20TypeHandle CMotionTrail::_type_handle;
21
22/**
23 * Constructor
24 */
26CMotionTrail ( ) {
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 */
80reset ( ) {
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 */
96enable (bool enable) {
97 _enable = enable;
98}
99
100/**
101 * Set the GeomNode.
102 */
104set_geom_node (GeomNode *geom_node) {
105 _geom_node = geom_node;
106}
107
108/**
109 * Add a vertex.
110 */
112add_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 */
146set_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 */
160check_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
176PN_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 */
188void CMotionTrail::
189begin_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 */
222add_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 */
261add_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 */
299void 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 */
320update_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.