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