15 #include "directbase.h" 16 #include "cMotionTrail.h" 17 #include "renderState.h" 18 #include "colorAttrib.h" 40 _fade_start_time = 0.0f;
41 _fade_color_scale = 1.0f;
43 _last_update_time = 0.0f;
45 _vertex_list.clear ( );
46 _frame_list.clear ( );
54 _calculate_relative_matrix =
false;
58 _resolution_distance = 0.5f;
88 _frame_list.clear ( );
98 _vertex_list.clear ( );
118 _geom_node = geom_node;
131 motion_trail_vertex._vertex = *vertex;
132 motion_trail_vertex._start_color = *start_color;
133 motion_trail_vertex._end_color = *end_color;
134 motion_trail_vertex._v = v;
138 _vertex_list.push_back (motion_trail_vertex);
167 set_parameters (PN_stdfloat sampling_time, PN_stdfloat time_window,
bool use_texture,
bool calculate_relative_matrix,
bool use_nurbs, PN_stdfloat resolution_distance) {
169 _sampling_time = sampling_time;
170 _time_window = time_window;
171 _use_texture = use_texture;
172 _calculate_relative_matrix = calculate_relative_matrix;
173 _use_nurbs = use_nurbs;
174 _resolution_distance = resolution_distance;
188 if ((current_time - _last_update_time) >= _sampling_time) {
194 state = state && _enable;
199 PN_stdfloat one_minus_x (PN_stdfloat x) {
216 const GeomVertexFormat *format;
220 format = GeomVertexFormat::get_v3c4t2 ( );
223 format = GeomVertexFormat::get_v3c4 ( );
229 _vertex_writer.
clear();
230 _color_writer.
clear();
231 _texture_writer.
clear();
233 _vertex_data =
new GeomVertexData (
"vertices", format, Geom::UH_static);
249 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) {
269 vertex_index = _vertex_index;
274 _triangles -> close_primitive ( );
279 _triangles -> close_primitive ( );
290 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) {
292 _vertex_writer.
add_data3 (v0 [0], v0 [1], v0 [2]);
293 _vertex_writer.
add_data3 (v1 [0], v1 [1], v1 [2]);
294 _vertex_writer.
add_data3 (v2 [0], v2 [1], v2 [2]);
295 _vertex_writer.
add_data3 (v3 [0], v3 [1], v3 [2]);
310 vertex_index = _vertex_index;
315 _triangles -> close_primitive ( );
320 _triangles -> close_primitive ( );
330 void CMotionTrail::end_geometry ( ) {
333 state = RenderState::make(ColorAttrib::make_vertex());
338 geometry =
new Geom (_vertex_data);
339 geometry -> add_primitive (_triangles);
342 _geom_node -> remove_all_geoms ( );
343 _geom_node -> add_geom (geometry, state);
360 total_frames = _frame_list.size ( );
361 if (total_frames >= 1) {
362 FrameList::iterator frame_iterator;
365 frame_iterator = _frame_list.begin ( );
366 motion_trail_frame = *frame_iterator;
367 if (*transform == motion_trail_frame._transform) {
374 PN_stdfloat color_scale;
379 total_vertices = _vertex_list.size ( );
380 color_scale = _color_scale;
382 PN_stdfloat elapsed_time;
384 elapsed_time = current_time - _fade_start_time;
385 if (elapsed_time < 0.0) {
388 if (elapsed_time < _fade_time) {
389 color_scale = (1.0f - (elapsed_time / _fade_time)) * color_scale;
397 _last_update_time = current_time;
400 PN_stdfloat minimum_time;
402 minimum_time = current_time - _time_window;
406 while (!_frame_list.empty()) {
407 motion_trail_frame = _frame_list.back();
408 if (motion_trail_frame._time >= minimum_time) {
412 _frame_list.pop_back ( );
419 motion_trail_frame._time = current_time;
420 motion_trail_frame._transform = *transform;
422 _frame_list.push_front(motion_trail_frame);
426 total_frames = _frame_list.size ( );
429 printf (
"update_motion_trail, total_frames = %d, total_vertices = %d, nurbs = %d, _calculate_relative_matrix = %d \n", total_frames, total_vertices, _use_nurbs, _calculate_relative_matrix);
432 if ((total_frames >= 2) && (total_vertices >= 2)) {
434 PN_stdfloat minimum_time;
435 PN_stdfloat delta_time;
438 VertexList::iterator vertex_iterator;
443 for (vertex_iterator = _vertex_list.begin ( ); vertex_iterator != _vertex_list.end ( ); vertex_iterator++) {
444 _vertex_array [index] = *vertex_iterator;
449 this -> begin_geometry ( );
451 total_segments = total_frames - 1;
453 last_motion_trail_frame = _frame_list.back();
454 minimum_time = last_motion_trail_frame._time;
455 delta_time = current_time - minimum_time;
457 if (_calculate_relative_matrix) {
458 inverse_matrix = *transform;
462 if (_use_nurbs && (total_frames >= 5)) {
465 int total_vertex_segments;
466 PN_stdfloat total_distance;
474 total_vertex_segments = total_vertices - 1;
475 total_distance = 0.0f;
482 for (index = 0; index < total_vertices; index++) {
483 motion_trail_vertex = &_vertex_array [index];
484 nurbs_curve_evaluator = motion_trail_vertex -> _nurbs_curve_evaluator;
485 nurbs_curve_evaluator -> set_order (4);
486 nurbs_curve_evaluator ->
reset (total_segments);
497 FrameList::iterator frame_iterator;
498 frame_iterator = _frame_list.begin ( );
499 while (segment_index < total_segments) {
500 int vertex_segement_index;
502 motion_trail_frame_start = *frame_iterator;
504 motion_trail_frame_end = *frame_iterator;
506 if (_calculate_relative_matrix) {
507 start_transform.multiply (motion_trail_frame_start._transform, inverse_matrix);
508 end_transform.multiply (motion_trail_frame_end._transform, inverse_matrix);
511 start_transform = motion_trail_frame_start._transform;
512 end_transform = motion_trail_frame_end._transform;
519 motion_trail_vertex_start = &_vertex_array [0];
521 v0 = start_transform.
xform (motion_trail_vertex_start -> _vertex);
522 v2 = end_transform.
xform (motion_trail_vertex_start -> _vertex);
524 nurbs_curve_evaluator = motion_trail_vertex_start -> _nurbs_curve_evaluator;
525 nurbs_curve_evaluator -> set_vertex (segment_index, v0);
527 vertex_segement_index = 0;
528 while (vertex_segement_index < total_vertex_segments) {
529 motion_trail_vertex_start = &_vertex_array [vertex_segement_index];
530 motion_trail_vertex_end = &_vertex_array [vertex_segement_index + 1];
532 v1 = start_transform.
xform (motion_trail_vertex_end -> _vertex);
533 v3 = end_transform.
xform (motion_trail_vertex_end -> _vertex);
535 nurbs_curve_evaluator = motion_trail_vertex_end -> _nurbs_curve_evaluator;
537 nurbs_curve_evaluator -> set_vertex (segment_index, v1);
538 if (vertex_segement_index == (total_vertex_segments - 1)) {
539 PN_stdfloat distance;
542 vector.set (v[0], v[1], v[2]);
543 distance = vector.
length();
544 total_distance += distance;
547 vertex_segement_index += 1;
557 for (index = 0; index < total_vertices; index++) {
563 motion_trail_vertex = &_vertex_array [index];
565 nurbs_curve_evaluator = motion_trail_vertex -> _nurbs_curve_evaluator;
566 nurbs_curve_result = nurbs_curve_evaluator -> evaluate ( );
567 nurbs_curve_result_array [index] = nurbs_curve_result;
570 PN_stdfloat nurbs_start_t;
571 PN_stdfloat nurbs_end_t;
573 nurbs_start_t = nurbs_curve_result -> get_start_t();
574 nurbs_end_t = nurbs_curve_result -> get_end_t();
576 printf (
"nurbs_start_t %f, nurbs_end_t %f \n", nurbs_start_t, nurbs_end_t);
581 PN_stdfloat total_curve_segments;
583 total_curve_segments = (total_distance / _resolution_distance);
584 if (total_curve_segments < total_segments) {
585 total_curve_segments = total_segments;
607 PN_stdfloat curve_segment_index;
609 curve_segment_index = 0.0;
610 while (curve_segment_index < total_curve_segments) {
616 PN_stdfloat color_start_t;
617 PN_stdfloat color_end_t;
619 int vertex_segement_index;
626 vertex_segement_index = 0;
628 st = curve_segment_index / total_curve_segments;
629 et = (curve_segment_index + 1.0) / total_curve_segments;
639 motion_trail_vertex_start = &_vertex_array [0];
641 vertex_start_color = motion_trail_vertex_start -> _end_color + (motion_trail_vertex_start -> _start_color - motion_trail_vertex_start -> _end_color);
643 color_start_t = color_scale * start_t;
644 color_end_t = color_scale * end_t;
646 c0 = vertex_start_color * one_minus_x (color_start_t);
647 c2 = vertex_start_color * one_minus_x (color_end_t);
649 t0.set (one_minus_x (st), motion_trail_vertex_start -> _v);
650 t2.set (one_minus_x (et), motion_trail_vertex_start -> _v);
652 while (vertex_segement_index < total_vertex_segments) {
654 PN_stdfloat start_nurbs_start_t;
655 PN_stdfloat start_nurbs_end_t;
656 PN_stdfloat end_nurbs_start_t;
657 PN_stdfloat end_nurbs_end_t;
659 motion_trail_vertex_start = &_vertex_array [vertex_segement_index];
660 motion_trail_vertex_end = &_vertex_array [vertex_segement_index + 1];
662 start_nurbs_curve_result = nurbs_curve_result_array [vertex_segement_index];
663 end_nurbs_curve_result = nurbs_curve_result_array [vertex_segement_index + 1];
665 start_nurbs_start_t = start_nurbs_curve_result -> get_start_t();
666 start_nurbs_end_t = start_nurbs_curve_result -> get_end_t();
667 end_nurbs_start_t = end_nurbs_curve_result -> get_start_t();
668 end_nurbs_end_t = end_nurbs_curve_result -> get_end_t();
670 PN_stdfloat start_delta_t;
671 PN_stdfloat end_delta_t;
673 start_delta_t = (start_nurbs_end_t - start_nurbs_start_t);
674 end_delta_t = (end_nurbs_end_t - end_nurbs_start_t);
676 start_nurbs_curve_result -> eval_point (start_nurbs_start_t + (start_delta_t * st), v0);
677 end_nurbs_curve_result -> eval_point (end_nurbs_start_t + (end_delta_t * st), v1);
679 start_nurbs_curve_result -> eval_point (start_nurbs_start_t + (start_delta_t * et), v2);
680 end_nurbs_curve_result -> eval_point (end_nurbs_start_t + (end_delta_t * et), v3);
683 vertex_end_color = motion_trail_vertex_end -> _end_color + (motion_trail_vertex_end -> _start_color - motion_trail_vertex_end -> _end_color);
685 c1 = vertex_end_color * one_minus_x (color_start_t);
686 c3 = vertex_end_color * one_minus_x (color_end_t);
689 t1.set (one_minus_x (st), motion_trail_vertex_end -> _v);
690 t3.set (one_minus_x (et), motion_trail_vertex_end -> _v);
692 this ->
add_geometry_quad (v0, v1, v2, v3, c0, c1, c2, c3, t0, t1, t2, t3);
701 vertex_segement_index += 1;
704 curve_segment_index += 1.0;
708 for (index = 0; index < total_vertices; index++) {
709 nurbs_curve_result_array [index] = 0;
712 delete[] nurbs_curve_result_array;
718 int vertex_segment_index;
719 int total_vertex_segments;
725 PN_stdfloat color_start_t;
726 PN_stdfloat color_end_t;
750 FrameList::iterator frame_iterator;
751 frame_iterator = _frame_list.begin ( );
752 while (segment_index < total_segments) {
757 motion_trail_frame_start = *frame_iterator;
759 motion_trail_frame_end = *frame_iterator;
761 start_t = (motion_trail_frame_start._time - minimum_time) / delta_time;
762 end_t = (motion_trail_frame_end._time - minimum_time) / delta_time;
772 vertex_segment_index = 0;
773 total_vertex_segments = total_vertices - 1;
775 if (_calculate_relative_matrix) {
776 start_transform.multiply (motion_trail_frame_start._transform, inverse_matrix);
777 end_transform.multiply (motion_trail_frame_end._transform, inverse_matrix);
780 start_transform = motion_trail_frame_start._transform;
781 end_transform = motion_trail_frame_end._transform;
784 motion_trail_vertex_start = &_vertex_array [0];
786 v0 = start_transform.
xform (motion_trail_vertex_start -> _vertex);
787 v2 = end_transform.
xform (motion_trail_vertex_start -> _vertex);
789 vertex_start_color = motion_trail_vertex_start -> _end_color + (motion_trail_vertex_start -> _start_color - motion_trail_vertex_start -> _end_color);
790 color_start_t = color_scale * start_t;
791 color_end_t = color_scale * end_t;
792 c0 = vertex_start_color * color_start_t;
793 c2 = vertex_start_color * color_end_t;
795 t0.set (st, motion_trail_vertex_start -> _v);
796 t2.set (et, motion_trail_vertex_start -> _v);
798 while (vertex_segment_index < total_vertex_segments) {
800 motion_trail_vertex_start = &_vertex_array [vertex_segment_index];
801 motion_trail_vertex_end = &_vertex_array [vertex_segment_index + 1];
803 v1 = start_transform.
xform (motion_trail_vertex_end -> _vertex);
804 v3 = end_transform.
xform (motion_trail_vertex_end -> _vertex);
807 vertex_end_color = motion_trail_vertex_end -> _end_color + (motion_trail_vertex_end -> _start_color - motion_trail_vertex_end -> _end_color);
809 c1 = vertex_end_color * color_start_t;
810 c3 = vertex_end_color * color_end_t;
813 t1.set (st, motion_trail_vertex_end -> _v);
814 t3.set (et, motion_trail_vertex_end -> _v);
816 this ->
add_geometry_quad (v0, v1, v2, v3, c0, c1, c2, c3, t0, t1, t2, t3);
828 vertex_segment_index += 1;
836 this -> end_geometry ( );
838 delete[] _vertex_array;
void enable(bool enable)
Enable/disable the motion trail.
This object provides a high-level interface for quickly writing a sequence of numeric values from a v...
void reset_vertex_list()
Reset the vertex list.
void clear()
Resets the GeomVertexWriter to the initial state.
This class is an abstraction for evaluating NURBS curves.
void add_data2(PN_stdfloat x, PN_stdfloat y)
Sets the write row to a particular 2-component value, and advances the write row. ...
This is a three-component vector distance (as opposed to a three-component point, which represents a ...
void add_data4(PN_stdfloat x, PN_stdfloat y, PN_stdfloat z, PN_stdfloat w)
Sets the write row to a particular 4-component value, and advances the write row. ...
void add_geometry_quad(LVector3 &v0, LVector3 &v1, LVector3 &v2, LVector3 &v3, LVector4 &c0, LVector4 &c1, LVector4 &c2, LVector4 &c3, LVector2 &t0, LVector2 &t1, LVector2 &t2, LVector2 &t3)
LVector3 vertex version.
void reset()
Reset the frame sample history.
This is a 4-by-4 transform matrix.
This defines the actual numeric vertex data stored in a Geom, in the structure defined by a particula...
CMotionTrail()
Constructor.
A container for geometry primitives.
void add_data3(PN_stdfloat x, PN_stdfloat y, PN_stdfloat z)
Sets the write row to a particular 3-component value, and advances the write row. ...
This is a four-component vector distance.
~CMotionTrail()
Destructor.
LVecBase4f xform(const LVecBase4f &v) const
4-component vector or point times matrix.
This represents a unique collection of RenderAttrib objects that correspond to a particular renderabl...
void set_parameters(PN_stdfloat sampling_time, PN_stdfloat time_window, bool use_texture, bool calculate_relative_matrix, bool use_nurbs, PN_stdfloat resolution_distance)
Set motion trail parameters.
float length() const
Returns the length of the vector, by the Pythagorean theorem.
This is a two-component vector offset.
bool invert_in_place()
Inverts the current matrix.
int check_for_update(PN_stdfloat current_time)
Check if a sample can be submitted.
Defines a series of disconnected triangles.
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.
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.
void set_geom_node(GeomNode *geom_node)
Set the GeomNode.