motiontrail: Clean up and optimization of C++ implementation

This commit is contained in:
rdb 2022-12-16 16:14:06 +01:00
parent 9cb60ccd93
commit 19186781f3
2 changed files with 240 additions and 292 deletions

View File

@ -15,7 +15,16 @@
#include "cMotionTrail.h" #include "cMotionTrail.h"
#include "renderState.h" #include "renderState.h"
#include "colorAttrib.h" #include "colorAttrib.h"
#include "cmath.h"
static PN_stdfloat one_minus_x(PN_stdfloat x) {
x = 1.0 - x;
if (x < 0.0) {
x = 0.0;
}
return x;
}
TypeHandle CMotionTrail::_type_handle; TypeHandle CMotionTrail::_type_handle;
@ -23,7 +32,7 @@ TypeHandle CMotionTrail::_type_handle;
* Constructor * Constructor
*/ */
CMotionTrail:: CMotionTrail::
CMotionTrail ( ) { CMotionTrail() {
_active = true; _active = true;
_enable = true; _enable = true;
@ -39,8 +48,8 @@ CMotionTrail ( ) {
_last_update_time = 0.0f; _last_update_time = 0.0f;
_vertex_list.clear ( ); _vertex_list.clear();
_frame_list.clear ( ); _frame_list.clear();
// parameters // parameters
_color_scale = 1.0; _color_scale = 1.0;
@ -69,7 +78,7 @@ CMotionTrail ( ) {
* Destructor * Destructor
*/ */
CMotionTrail:: CMotionTrail::
~CMotionTrail ( ) { ~CMotionTrail() {
} }
@ -77,23 +86,23 @@ CMotionTrail::
* Reset the frame sample history. * Reset the frame sample history.
*/ */
void CMotionTrail:: void CMotionTrail::
reset ( ) { reset() {
_frame_list.clear ( ); _frame_list.clear();
} }
/** /**
* Reset the vertex list. * Reset the vertex list.
*/ */
void CMotionTrail:: void CMotionTrail::
reset_vertex_list ( ) { reset_vertex_list() {
_vertex_list.clear ( ); _vertex_list.clear();
} }
/** /**
* Enable/disable the motion trail. * Enable/disable the motion trail.
*/ */
void CMotionTrail:: void CMotionTrail::
enable (bool enable) { enable(bool enable) {
_enable = enable; _enable = enable;
} }
@ -101,7 +110,7 @@ enable (bool enable) {
* Set the GeomNode. * Set the GeomNode.
*/ */
void CMotionTrail:: void CMotionTrail::
set_geom_node (GeomNode *geom_node) { set_geom_node(GeomNode *geom_node) {
_geom_node = geom_node; _geom_node = geom_node;
} }
@ -109,7 +118,7 @@ set_geom_node (GeomNode *geom_node) {
* Add a vertex. * Add a vertex.
*/ */
void CMotionTrail:: void CMotionTrail::
add_vertex (LVector4 *vertex, LVector4 *start_color, LVector4 *end_color, PN_stdfloat v) { add_vertex(LVector4 *vertex, LVector4 *start_color, LVector4 *end_color, PN_stdfloat v) {
CMotionTrailVertex motion_trail_vertex; CMotionTrailVertex motion_trail_vertex;
@ -118,9 +127,9 @@ add_vertex (LVector4 *vertex, LVector4 *start_color, LVector4 *end_color, PN_std
motion_trail_vertex._end_color = *end_color; motion_trail_vertex._end_color = *end_color;
motion_trail_vertex._v = v; motion_trail_vertex._v = v;
motion_trail_vertex._nurbs_curve_evaluator = new NurbsCurveEvaluator ( ); motion_trail_vertex._nurbs_curve_evaluator = new NurbsCurveEvaluator();
_vertex_list.push_back (motion_trail_vertex); _vertex_list.push_back(motion_trail_vertex);
} }
/** /**
@ -143,7 +152,7 @@ add_vertex (LVector4 *vertex, LVector4 *start_color, LVector4 *end_color, PN_std
* only if nurbs is on. * only if nurbs is on.
*/ */
void CMotionTrail:: void CMotionTrail::
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_parameters(PN_stdfloat sampling_time, PN_stdfloat time_window, bool use_texture, bool calculate_relative_matrix, bool use_nurbs, PN_stdfloat resolution_distance) {
_sampling_time = sampling_time; _sampling_time = sampling_time;
_time_window = time_window; _time_window = time_window;
@ -157,7 +166,7 @@ set_parameters (PN_stdfloat sampling_time, PN_stdfloat time_window, bool use_tex
* Check if a sample can be submitted. * Check if a sample can be submitted.
*/ */
int CMotionTrail:: int CMotionTrail::
check_for_update (PN_stdfloat current_time) { check_for_update(PN_stdfloat current_time) {
int state; int state;
@ -173,29 +182,28 @@ check_for_update (PN_stdfloat current_time) {
return state; return state;
} }
PN_stdfloat one_minus_x (PN_stdfloat x) { /**
x = 1.0 - x; *
if (x < 0.0) { */
x = 0.0; void CMotionTrail::
} begin_geometry() {
begin_geometry(0);
return x;
} }
/** /**
* *
*/ */
void CMotionTrail:: void CMotionTrail::
begin_geometry ( ) { begin_geometry(int num_quads) {
const int num_vertices = num_quads * 4;
const GeomVertexFormat *format; const GeomVertexFormat *format;
_vertex_index = 0; _vertex_index = 0;
if (_use_texture) { if (_use_texture) {
format = GeomVertexFormat::get_v3c4t2 ( ); format = GeomVertexFormat::get_v3c4t2();
} }
else { else {
format = GeomVertexFormat::get_v3c4 ( ); format = GeomVertexFormat::get_v3c4();
} }
// Clear the previous writers before we create a new vertex data object-- // Clear the previous writers before we create a new vertex data object--
@ -205,111 +213,124 @@ begin_geometry ( ) {
_color_writer.clear(); _color_writer.clear();
_texture_writer.clear(); _texture_writer.clear();
_vertex_data = new GeomVertexData ("vertices", format, Geom::UH_static); Thread *current_thread = Thread::get_current_thread();
_vertex_writer = GeomVertexWriter (_vertex_data, "vertex");
_color_writer = GeomVertexWriter (_vertex_data, "color"); _vertex_data = new GeomVertexData("vertices", format, Geom::UH_static);
_vertex_data->unclean_set_num_rows(num_vertices);
_vertex_writer = GeomVertexWriter(_vertex_data, "vertex", current_thread);
_color_writer = GeomVertexWriter(_vertex_data, "color", current_thread);
if (_use_texture) { if (_use_texture) {
_texture_writer = GeomVertexWriter (_vertex_data, "texcoord"); _texture_writer = GeomVertexWriter(_vertex_data, "texcoord", current_thread);
} }
_triangles = new GeomTriangles (Geom::UH_static); // We know how many triangles we'll be adding, so add them up front.
_triangles = new GeomTriangles(Geom::UH_static);
if (num_quads * 6 <= 65535) {
_triangles->set_index_type(GeomEnums::NT_uint16);
} else {
_triangles->set_index_type(GeomEnums::NT_uint32);
}
{
PT(GeomVertexArrayDataHandle) idx_handle = _triangles->modify_vertices_handle(current_thread);
idx_handle->unclean_set_num_rows(num_quads * 6);
if (num_quads * 6 <= 65535) {
// 16-bit index case.
uint16_t *idx_ptr = (uint16_t *)idx_handle->get_write_pointer();
for (int i = 0; i < num_vertices; i += 4) {
*(idx_ptr++) = i + 0;
*(idx_ptr++) = i + 1;
*(idx_ptr++) = i + 2;
*(idx_ptr++) = i + 1;
*(idx_ptr++) = i + 3;
*(idx_ptr++) = i + 2;
}
} else {
// 32-bit index case.
uint32_t *idx_ptr = (uint32_t *)idx_handle->get_write_pointer();
for (int i = 0; i < num_vertices; i += 4) {
*(idx_ptr++) = i + 0;
*(idx_ptr++) = i + 1;
*(idx_ptr++) = i + 2;
*(idx_ptr++) = i + 1;
*(idx_ptr++) = i + 3;
*(idx_ptr++) = i + 2;
}
}
}
// We can compute this value much faster than GeomPrimitive can.
_triangles->set_minmax(0, num_vertices - 1, nullptr, nullptr);
} }
/** /**
* LVector3 vertex version. * LVector3 vertex version.
*/ */
void CMotionTrail:: void CMotionTrail::
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) { 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) {
_vertex_writer.set_data3(v0);
_vertex_writer.set_data3(v1);
_vertex_writer.set_data3(v2);
_vertex_writer.set_data3(v3);
_vertex_writer.add_data3 (v0); _color_writer.set_data4(c0);
_vertex_writer.add_data3 (v1); _color_writer.set_data4(c1);
_vertex_writer.add_data3 (v2); _color_writer.set_data4(c2);
_vertex_writer.add_data3 (v3); _color_writer.set_data4(c3);
_color_writer.add_data4 (c0);
_color_writer.add_data4 (c1);
_color_writer.add_data4 (c2);
_color_writer.add_data4 (c3);
if (_use_texture) { if (_use_texture) {
_texture_writer.add_data2 (t0); _texture_writer.set_data2(t0);
_texture_writer.add_data2 (t1); _texture_writer.set_data2(t1);
_texture_writer.add_data2 (t2); _texture_writer.set_data2(t2);
_texture_writer.add_data2 (t3); _texture_writer.set_data2(t3);
} }
int vertex_index;
vertex_index = _vertex_index;
_triangles -> add_vertex (vertex_index + 0);
_triangles -> add_vertex (vertex_index + 1);
_triangles -> add_vertex (vertex_index + 2);
_triangles -> close_primitive ( );
_triangles -> add_vertex (vertex_index + 1);
_triangles -> add_vertex (vertex_index + 3);
_triangles -> add_vertex (vertex_index + 2);
_triangles -> close_primitive ( );
_vertex_index += 4;
} }
/** /**
* LVector4 vertex version. * LVector4 vertex version.
*/ */
void CMotionTrail:: void CMotionTrail::
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) { 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) {
_vertex_writer.set_data3(v0[0], v0[1], v0[2]);
_vertex_writer.set_data3(v1[0], v1[1], v1[2]);
_vertex_writer.set_data3(v2[0], v2[1], v2[2]);
_vertex_writer.set_data3(v3[0], v3[1], v3[2]);
_vertex_writer.add_data3 (v0 [0], v0 [1], v0 [2]); _color_writer.set_data4(c0);
_vertex_writer.add_data3 (v1 [0], v1 [1], v1 [2]); _color_writer.set_data4(c1);
_vertex_writer.add_data3 (v2 [0], v2 [1], v2 [2]); _color_writer.set_data4(c2);
_vertex_writer.add_data3 (v3 [0], v3 [1], v3 [2]); _color_writer.set_data4(c3);
_color_writer.add_data4 (c0);
_color_writer.add_data4 (c1);
_color_writer.add_data4 (c2);
_color_writer.add_data4 (c3);
if (_use_texture) { if (_use_texture) {
_texture_writer.add_data2 (t0); _texture_writer.set_data2(t0);
_texture_writer.add_data2 (t1); _texture_writer.set_data2(t1);
_texture_writer.add_data2 (t2); _texture_writer.set_data2(t2);
_texture_writer.add_data2 (t3); _texture_writer.set_data2(t3);
} }
int vertex_index;
vertex_index = _vertex_index;
_triangles -> add_vertex (vertex_index + 0);
_triangles -> add_vertex (vertex_index + 1);
_triangles -> add_vertex (vertex_index + 2);
_triangles -> close_primitive ( );
_triangles -> add_vertex (vertex_index + 1);
_triangles -> add_vertex (vertex_index + 3);
_triangles -> add_vertex (vertex_index + 2);
_triangles -> close_primitive ( );
_vertex_index += 4;
} }
/** /**
* *
*/ */
void CMotionTrail::end_geometry ( ) { void CMotionTrail::
end_geometry() {
static CPT(RenderState) state; static CPT(RenderState) state;
if (state == nullptr) { if (state == nullptr) {
state = RenderState::make(ColorAttrib::make_vertex()); state = RenderState::make(ColorAttrib::make_vertex());
} }
PT(Geom) geometry; _vertex_writer.clear();
_color_writer.clear();
_texture_writer.clear();
geometry = new Geom (_vertex_data); PT(Geom) geometry = new Geom(_vertex_data);
geometry -> add_primitive (_triangles); geometry->add_primitive(_triangles);
if (_geom_node) { if (_geom_node) {
_geom_node -> remove_all_geoms ( ); _geom_node->remove_all_geoms();
_geom_node -> add_geom (geometry, state); _geom_node->add_geom(geometry, state);
} }
} }
@ -317,33 +338,21 @@ void CMotionTrail::end_geometry ( ) {
* See class header comments. * See class header comments.
*/ */
void CMotionTrail:: void CMotionTrail::
update_motion_trail (PN_stdfloat current_time, LMatrix4 *transform) { update_motion_trail(PN_stdfloat current_time, LMatrix4 *transform) {
int debug = false;
int debug; if (!_frame_list.empty()) {
int total_frames; if (_frame_list.front()._transform == UnalignedLMatrix4(*transform)) {
debug = false;
total_frames = _frame_list.size ( );
if (total_frames >= 1) {
FrameList::iterator frame_iterator;
CMotionTrailFrame motion_trail_frame;
frame_iterator = _frame_list.begin ( );
motion_trail_frame = *frame_iterator;
if (motion_trail_frame._transform == UnalignedLMatrix4(*transform)) {
// duplicate transform // duplicate transform
return; return;
} }
} }
int total_vertices;
PN_stdfloat color_scale; PN_stdfloat color_scale;
LMatrix4 start_transform; LMatrix4 start_transform;
LMatrix4 end_transform; LMatrix4 end_transform;
LMatrix4 inverse_matrix; LMatrix4 inverse_matrix;
total_vertices = _vertex_list.size ( );
color_scale = _color_scale; color_scale = _color_scale;
if (_fade) { if (_fade) {
PN_stdfloat elapsed_time; PN_stdfloat elapsed_time;
@ -364,40 +373,33 @@ update_motion_trail (PN_stdfloat current_time, LMatrix4 *transform) {
_last_update_time = current_time; _last_update_time = current_time;
// remove expired frames // remove expired frames
PN_stdfloat minimum_time; PN_stdfloat minimum_time = current_time - _time_window;
minimum_time = current_time - _time_window;
CMotionTrailFrame motion_trail_frame;
while (!_frame_list.empty()) { while (!_frame_list.empty()) {
motion_trail_frame = _frame_list.back(); if (_frame_list.back()._time >= minimum_time) {
if (motion_trail_frame._time >= minimum_time) {
break; break;
} }
_frame_list.pop_back ( ); _frame_list.pop_back();
} }
// add new frame to beginning of list // add new frame to beginning of list
{ {
CMotionTrailFrame motion_trail_frame; CMotionTrailFrame motion_trail_frame;
motion_trail_frame._time = current_time; motion_trail_frame._time = current_time;
motion_trail_frame._transform = *transform; motion_trail_frame._transform = *transform;
_frame_list.push_front(std::move(motion_trail_frame));
_frame_list.push_front(motion_trail_frame);
} }
// convert frames and vertices to geometry // convert frames and vertices to geometry
total_frames = _frame_list.size ( ); int total_frames = (int)_frame_list.size();
int total_vertices = (int)_vertex_list.size();
if (debug) { if (debug) {
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); 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);
} }
if ((total_frames >= 2) && (total_vertices >= 2)) { if (total_frames >= 2 && total_vertices >= 2) {
int total_segments;
PN_stdfloat minimum_time; PN_stdfloat minimum_time;
PN_stdfloat delta_time; PN_stdfloat delta_time;
CMotionTrailFrame last_motion_trail_frame; CMotionTrailFrame last_motion_trail_frame;
@ -406,16 +408,14 @@ update_motion_trail (PN_stdfloat current_time, LMatrix4 *transform) {
// convert vertex list to vertex array // convert vertex list to vertex array
int index = 0; int index = 0;
_vertex_array = new CMotionTrailVertex [total_vertices]; CMotionTrailVertex *vertex_array = new CMotionTrailVertex[total_vertices];
for (vertex_iterator = _vertex_list.begin ( ); vertex_iterator != _vertex_list.end ( ); vertex_iterator++) { for (vertex_iterator = _vertex_list.begin(); vertex_iterator != _vertex_list.end(); vertex_iterator++) {
_vertex_array [index] = *vertex_iterator; vertex_array[index] = *vertex_iterator;
index++; ++index;
} }
// begin geometry const int total_segments = total_frames - 1;
this -> begin_geometry ( ); const int total_vertex_segments = total_vertices - 1;
total_segments = total_frames - 1;
last_motion_trail_frame = _frame_list.back(); last_motion_trail_frame = _frame_list.back();
minimum_time = last_motion_trail_frame._time; minimum_time = last_motion_trail_frame._time;
@ -423,14 +423,11 @@ update_motion_trail (PN_stdfloat current_time, LMatrix4 *transform) {
if (_calculate_relative_matrix) { if (_calculate_relative_matrix) {
inverse_matrix = *transform; inverse_matrix = *transform;
inverse_matrix.invert_in_place ( ); inverse_matrix.invert_in_place();
} }
if (_use_nurbs && (total_frames >= 5)) { if (_use_nurbs && total_frames >= 5) {
// nurbs version // nurbs version
int total_vertex_segments;
PN_stdfloat total_distance;
LVector3 vector; LVector3 vector;
LVector4 v; LVector4 v;
LVector4 v0; LVector4 v0;
@ -438,8 +435,7 @@ update_motion_trail (PN_stdfloat current_time, LMatrix4 *transform) {
LVector4 v2; LVector4 v2;
LVector4 v3; LVector4 v3;
total_vertex_segments = total_vertices - 1; PN_stdfloat total_distance = 0.0f;
total_distance = 0.0f;
// reset NurbsCurveEvaluators for each vertex (the starting point for // reset NurbsCurveEvaluators for each vertex (the starting point for
// the trail) // the trail)
@ -447,33 +443,28 @@ update_motion_trail (PN_stdfloat current_time, LMatrix4 *transform) {
CMotionTrailVertex *motion_trail_vertex; CMotionTrailVertex *motion_trail_vertex;
PT(NurbsCurveEvaluator) nurbs_curve_evaluator; PT(NurbsCurveEvaluator) nurbs_curve_evaluator;
for (index = 0; index < total_vertices; index++) { for (int index = 0; index < total_vertices; ++index) {
motion_trail_vertex = &_vertex_array [index]; motion_trail_vertex = &vertex_array[index];
nurbs_curve_evaluator = motion_trail_vertex -> _nurbs_curve_evaluator; nurbs_curve_evaluator = motion_trail_vertex->_nurbs_curve_evaluator;
nurbs_curve_evaluator -> set_order (4); nurbs_curve_evaluator->set_order(4);
nurbs_curve_evaluator -> reset (total_segments); nurbs_curve_evaluator->reset(total_segments);
} }
} }
// add vertices to each NurbsCurveEvaluator // add vertices to each NurbsCurveEvaluator
int segment_index;
CMotionTrailFrame motion_trail_frame_start; CMotionTrailFrame motion_trail_frame_start;
CMotionTrailFrame motion_trail_frame_end; CMotionTrailFrame motion_trail_frame_end;
segment_index = 0;
FrameList::iterator frame_iterator; FrameList::iterator frame_iterator;
frame_iterator = _frame_list.begin ( ); frame_iterator = _frame_list.begin();
while (segment_index < total_segments) { for (int segment_index = 0; segment_index < total_segments; ++segment_index) {
int vertex_segement_index;
motion_trail_frame_start = *frame_iterator; motion_trail_frame_start = *frame_iterator;
frame_iterator++; frame_iterator++;
motion_trail_frame_end = *frame_iterator; motion_trail_frame_end = *frame_iterator;
if (_calculate_relative_matrix) { if (_calculate_relative_matrix) {
start_transform.multiply (motion_trail_frame_start._transform, inverse_matrix); start_transform.multiply(motion_trail_frame_start._transform, inverse_matrix);
end_transform.multiply (motion_trail_frame_end._transform, inverse_matrix); end_transform.multiply(motion_trail_frame_end._transform, inverse_matrix);
} }
else { else {
start_transform = motion_trail_frame_start._transform; start_transform = motion_trail_frame_start._transform;
@ -484,26 +475,27 @@ update_motion_trail (PN_stdfloat current_time, LMatrix4 *transform) {
CMotionTrailVertex *motion_trail_vertex_end; CMotionTrailVertex *motion_trail_vertex_end;
PT(NurbsCurveEvaluator) nurbs_curve_evaluator; PT(NurbsCurveEvaluator) nurbs_curve_evaluator;
motion_trail_vertex_start = &_vertex_array [0]; motion_trail_vertex_start = &vertex_array[0];
v0 = start_transform.xform (motion_trail_vertex_start -> _vertex); v0 = start_transform.xform(motion_trail_vertex_start->_vertex);
v2 = end_transform.xform (motion_trail_vertex_start -> _vertex); v2 = end_transform.xform(motion_trail_vertex_start->_vertex);
nurbs_curve_evaluator = motion_trail_vertex_start -> _nurbs_curve_evaluator; nurbs_curve_evaluator = motion_trail_vertex_start->_nurbs_curve_evaluator;
nurbs_curve_evaluator -> set_vertex (segment_index, v0); nurbs_curve_evaluator->set_vertex(segment_index, v0);
vertex_segement_index = 0; for (int vertex_segment_index = 0;
while (vertex_segement_index < total_vertex_segments) { vertex_segment_index < total_vertex_segments;
motion_trail_vertex_start = &_vertex_array [vertex_segement_index]; ++vertex_segment_index) {
motion_trail_vertex_end = &_vertex_array [vertex_segement_index + 1]; motion_trail_vertex_start = &vertex_array[vertex_segment_index];
motion_trail_vertex_end = &vertex_array[vertex_segment_index + 1];
v1 = start_transform.xform (motion_trail_vertex_end -> _vertex); v1 = start_transform.xform(motion_trail_vertex_end->_vertex);
v3 = end_transform.xform (motion_trail_vertex_end -> _vertex); v3 = end_transform.xform(motion_trail_vertex_end->_vertex);
nurbs_curve_evaluator = motion_trail_vertex_end -> _nurbs_curve_evaluator; nurbs_curve_evaluator = motion_trail_vertex_end->_nurbs_curve_evaluator;
nurbs_curve_evaluator -> set_vertex (segment_index, v1); nurbs_curve_evaluator->set_vertex(segment_index, v1);
if (vertex_segement_index == (total_vertex_segments - 1)) { if (vertex_segment_index == (total_vertex_segments - 1)) {
PN_stdfloat distance; PN_stdfloat distance;
v = v1 - v3; v = v1 - v3;
@ -511,72 +503,56 @@ update_motion_trail (PN_stdfloat current_time, LMatrix4 *transform) {
distance = vector.length(); distance = vector.length();
total_distance += distance; total_distance += distance;
} }
vertex_segement_index += 1;
} }
segment_index += 1;
} }
// evaluate NurbsCurveEvaluator for each vertex // evaluate NurbsCurveEvaluator for each vertex
PT(NurbsCurveResult) *nurbs_curve_result_array; PT(NurbsCurveResult) *nurbs_curve_result_array;
nurbs_curve_result_array = new PT(NurbsCurveResult) [total_vertices]; nurbs_curve_result_array = new PT(NurbsCurveResult)[total_vertices];
for (index = 0; index < total_vertices; index++) { for (int index = 0; index < total_vertices; ++index) {
CMotionTrailVertex *motion_trail_vertex; CMotionTrailVertex *motion_trail_vertex;
PT(NurbsCurveEvaluator) nurbs_curve_evaluator; PT(NurbsCurveEvaluator) nurbs_curve_evaluator;
PT(NurbsCurveResult) nurbs_curve_result; PT(NurbsCurveResult) nurbs_curve_result;
motion_trail_vertex = &_vertex_array [index]; motion_trail_vertex = &vertex_array[index];
nurbs_curve_evaluator = motion_trail_vertex -> _nurbs_curve_evaluator; nurbs_curve_evaluator = motion_trail_vertex->_nurbs_curve_evaluator;
nurbs_curve_result = nurbs_curve_evaluator -> evaluate ( ); nurbs_curve_result = nurbs_curve_evaluator->evaluate();
nurbs_curve_result_array [index] = nurbs_curve_result; nurbs_curve_result_array[index] = nurbs_curve_result;
if (debug) { if (debug) {
PN_stdfloat nurbs_start_t; PN_stdfloat nurbs_start_t;
PN_stdfloat nurbs_end_t; PN_stdfloat nurbs_end_t;
nurbs_start_t = nurbs_curve_result -> get_start_t(); nurbs_start_t = nurbs_curve_result->get_start_t();
nurbs_end_t = nurbs_curve_result -> get_end_t(); nurbs_end_t = nurbs_curve_result->get_end_t();
printf ("nurbs_start_t %f, nurbs_end_t %f \n", nurbs_start_t, nurbs_end_t); printf("nurbs_start_t %f, nurbs_end_t %f \n", nurbs_start_t, nurbs_end_t);
} }
} }
// create quads from NurbsCurveResult // create quads from NurbsCurveResult
PN_stdfloat total_curve_segments; PN_stdfloat total_curve_segments = total_distance / _resolution_distance;
total_curve_segments = (total_distance / _resolution_distance);
if (total_curve_segments < total_segments) { if (total_curve_segments < total_segments) {
total_curve_segments = total_segments; total_curve_segments = total_segments;
} }
const int total_curve_segments_int = (int)cceil(total_curve_segments);
begin_geometry(total_curve_segments_int * total_vertex_segments);
{ {
LVector3 v0; LVector3 v0, v1, v2, v3;
LVector3 v1; LVector4 c0, c1, c2, c3;
LVector3 v2; LVector2 t0, t1, t2, t3;
LVector3 v3;
LVector4 c0;
LVector4 c1;
LVector4 c2;
LVector4 c3;
LVector2 t0;
LVector2 t1;
LVector2 t2;
LVector2 t3;
LVector4 vertex_start_color; LVector4 vertex_start_color;
LVector4 vertex_end_color; LVector4 vertex_end_color;
PN_stdfloat curve_segment_index; for (int curve_segment_index = 0;
curve_segment_index < total_curve_segments_int;
curve_segment_index = 0.0; ++curve_segment_index) {
while (curve_segment_index < total_curve_segments) {
PN_stdfloat st; PN_stdfloat st;
PN_stdfloat et; PN_stdfloat et;
PN_stdfloat start_t; PN_stdfloat start_t;
@ -584,17 +560,13 @@ update_motion_trail (PN_stdfloat current_time, LMatrix4 *transform) {
PN_stdfloat color_start_t; PN_stdfloat color_start_t;
PN_stdfloat color_end_t; PN_stdfloat color_end_t;
int vertex_segement_index;
CMotionTrailVertex *motion_trail_vertex_start; CMotionTrailVertex *motion_trail_vertex_start;
CMotionTrailVertex *motion_trail_vertex_end; CMotionTrailVertex *motion_trail_vertex_end;
PT(NurbsCurveResult) start_nurbs_curve_result; PT(NurbsCurveResult) start_nurbs_curve_result;
PT(NurbsCurveResult) end_nurbs_curve_result; PT(NurbsCurveResult) end_nurbs_curve_result;
vertex_segement_index = 0;
st = curve_segment_index / total_curve_segments; st = curve_segment_index / total_curve_segments;
et = (curve_segment_index + 1.0) / total_curve_segments; et = (curve_segment_index + 1) / total_curve_segments;
start_t = st; start_t = st;
end_t = et; end_t = et;
@ -604,36 +576,38 @@ update_motion_trail (PN_stdfloat current_time, LMatrix4 *transform) {
end_t *= end_t; end_t *= end_t;
} }
motion_trail_vertex_start = &_vertex_array [0]; motion_trail_vertex_start = &vertex_array[0];
vertex_start_color = motion_trail_vertex_start -> _end_color + (motion_trail_vertex_start -> _start_color - motion_trail_vertex_start -> _end_color); vertex_start_color = motion_trail_vertex_start->_end_color + (motion_trail_vertex_start->_start_color - motion_trail_vertex_start ->_end_color);
color_start_t = color_scale * start_t; color_start_t = color_scale * start_t;
color_end_t = color_scale * end_t; color_end_t = color_scale * end_t;
c0 = vertex_start_color * one_minus_x (color_start_t); c0 = vertex_start_color * one_minus_x(color_start_t);
c2 = vertex_start_color * one_minus_x (color_end_t); c2 = vertex_start_color * one_minus_x(color_end_t);
t0.set (one_minus_x (st), motion_trail_vertex_start -> _v); t0.set(one_minus_x(st), motion_trail_vertex_start->_v);
t2.set (one_minus_x (et), motion_trail_vertex_start -> _v); t2.set(one_minus_x(et), motion_trail_vertex_start->_v);
while (vertex_segement_index < total_vertex_segments) { for (int vertex_segment_index = 0;
vertex_segment_index < total_vertex_segments;
++vertex_segment_index) {
PN_stdfloat start_nurbs_start_t; PN_stdfloat start_nurbs_start_t;
PN_stdfloat start_nurbs_end_t; PN_stdfloat start_nurbs_end_t;
PN_stdfloat end_nurbs_start_t; PN_stdfloat end_nurbs_start_t;
PN_stdfloat end_nurbs_end_t; PN_stdfloat end_nurbs_end_t;
motion_trail_vertex_start = &_vertex_array [vertex_segement_index]; motion_trail_vertex_start = &vertex_array[vertex_segment_index];
motion_trail_vertex_end = &_vertex_array [vertex_segement_index + 1]; motion_trail_vertex_end = &vertex_array[vertex_segment_index + 1];
start_nurbs_curve_result = nurbs_curve_result_array [vertex_segement_index]; start_nurbs_curve_result = nurbs_curve_result_array[vertex_segment_index];
end_nurbs_curve_result = nurbs_curve_result_array [vertex_segement_index + 1]; end_nurbs_curve_result = nurbs_curve_result_array[vertex_segment_index + 1];
start_nurbs_start_t = start_nurbs_curve_result -> get_start_t(); start_nurbs_start_t = start_nurbs_curve_result->get_start_t();
start_nurbs_end_t = start_nurbs_curve_result -> get_end_t(); start_nurbs_end_t = start_nurbs_curve_result->get_end_t();
end_nurbs_start_t = end_nurbs_curve_result -> get_start_t(); end_nurbs_start_t = end_nurbs_curve_result->get_start_t();
end_nurbs_end_t = end_nurbs_curve_result -> get_end_t(); end_nurbs_end_t = end_nurbs_curve_result->get_end_t();
PN_stdfloat start_delta_t; PN_stdfloat start_delta_t;
PN_stdfloat end_delta_t; PN_stdfloat end_delta_t;
@ -641,23 +615,23 @@ update_motion_trail (PN_stdfloat current_time, LMatrix4 *transform) {
start_delta_t = (start_nurbs_end_t - start_nurbs_start_t); start_delta_t = (start_nurbs_end_t - start_nurbs_start_t);
end_delta_t = (end_nurbs_end_t - end_nurbs_start_t); end_delta_t = (end_nurbs_end_t - end_nurbs_start_t);
start_nurbs_curve_result -> eval_point (start_nurbs_start_t + (start_delta_t * st), v0); start_nurbs_curve_result->eval_point(start_nurbs_start_t + (start_delta_t * st), v0);
end_nurbs_curve_result -> eval_point (end_nurbs_start_t + (end_delta_t * st), v1); end_nurbs_curve_result->eval_point(end_nurbs_start_t + (end_delta_t * st), v1);
start_nurbs_curve_result -> eval_point (start_nurbs_start_t + (start_delta_t * et), v2); start_nurbs_curve_result->eval_point(start_nurbs_start_t + (start_delta_t * et), v2);
end_nurbs_curve_result -> eval_point (end_nurbs_start_t + (end_delta_t * et), v3); end_nurbs_curve_result->eval_point(end_nurbs_start_t + (end_delta_t * et), v3);
// color // color
vertex_end_color = motion_trail_vertex_end -> _end_color + (motion_trail_vertex_end -> _start_color - motion_trail_vertex_end -> _end_color); vertex_end_color = motion_trail_vertex_end->_end_color + (motion_trail_vertex_end->_start_color - motion_trail_vertex_end->_end_color);
c1 = vertex_end_color * one_minus_x (color_start_t); c1 = vertex_end_color * one_minus_x(color_start_t);
c3 = vertex_end_color * one_minus_x (color_end_t); c3 = vertex_end_color * one_minus_x(color_end_t);
// uv // uv
t1.set (one_minus_x (st), motion_trail_vertex_end -> _v); t1.set(one_minus_x(st), motion_trail_vertex_end->_v);
t3.set (one_minus_x (et), motion_trail_vertex_end -> _v); t3.set(one_minus_x(et), motion_trail_vertex_end->_v);
this -> add_geometry_quad (v0, v1, v2, v3, c0, c1, c2, c3, t0, t1, t2, t3); add_geometry_quad(v0, v1, v2, v3, c0, c1, c2, c3, t0, t1, t2, t3);
// reuse calculations // reuse calculations
c0 = c1; c0 = c1;
@ -665,26 +639,21 @@ update_motion_trail (PN_stdfloat current_time, LMatrix4 *transform) {
t0 = t1; t0 = t1;
t2 = t3; t2 = t3;
vertex_segement_index += 1;
} }
curve_segment_index += 1.0;
} }
} }
for (index = 0; index < total_vertices; index++) { for (int index = 0; index < total_vertices; ++index) {
nurbs_curve_result_array [index] = nullptr; nurbs_curve_result_array[index] = nullptr;
} }
delete[] nurbs_curve_result_array; delete[] nurbs_curve_result_array;
} }
else { else {
// non-nurbs version // non-nurbs version
int segment_index; const int total_vertex_segments = total_vertices - 1;
int vertex_segment_index;
int total_vertex_segments; begin_geometry(total_segments * total_vertex_segments);
PN_stdfloat st; PN_stdfloat st;
PN_stdfloat et; PN_stdfloat et;
@ -693,20 +662,9 @@ update_motion_trail (PN_stdfloat current_time, LMatrix4 *transform) {
PN_stdfloat color_start_t; PN_stdfloat color_start_t;
PN_stdfloat color_end_t; PN_stdfloat color_end_t;
LVector4 v0; LVector4 v0, v1, v2, v3;
LVector4 v1; LVector4 c0, c1, c2, c3;
LVector4 v2; LVector2 t0, t1, t2, t3;
LVector4 v3;
LVector4 c0;
LVector4 c1;
LVector4 c2;
LVector4 c3;
LVector2 t0;
LVector2 t1;
LVector2 t2;
LVector2 t3;
LVector4 vertex_start_color; LVector4 vertex_start_color;
LVector4 vertex_end_color; LVector4 vertex_end_color;
@ -714,11 +672,8 @@ update_motion_trail (PN_stdfloat current_time, LMatrix4 *transform) {
CMotionTrailFrame motion_trail_frame_start; CMotionTrailFrame motion_trail_frame_start;
CMotionTrailFrame motion_trail_frame_end; CMotionTrailFrame motion_trail_frame_end;
segment_index = 0; FrameList::iterator frame_iterator = _frame_list.begin();
FrameList::iterator frame_iterator; for (int segment_index = 0; segment_index < total_segments; ++segment_index) {
frame_iterator = _frame_list.begin ( );
while (segment_index < total_segments) {
CMotionTrailVertex *motion_trail_vertex_start; CMotionTrailVertex *motion_trail_vertex_start;
CMotionTrailVertex *motion_trail_vertex_end; CMotionTrailVertex *motion_trail_vertex_end;
@ -737,51 +692,49 @@ update_motion_trail (PN_stdfloat current_time, LMatrix4 *transform) {
end_t *= end_t; end_t *= end_t;
} }
vertex_segment_index = 0;
total_vertex_segments = total_vertices - 1;
if (_calculate_relative_matrix) { if (_calculate_relative_matrix) {
start_transform.multiply (motion_trail_frame_start._transform, inverse_matrix); start_transform.multiply(motion_trail_frame_start._transform, inverse_matrix);
end_transform.multiply (motion_trail_frame_end._transform, inverse_matrix); end_transform.multiply(motion_trail_frame_end._transform, inverse_matrix);
} }
else { else {
start_transform = motion_trail_frame_start._transform; start_transform = motion_trail_frame_start._transform;
end_transform = motion_trail_frame_end._transform; end_transform = motion_trail_frame_end._transform;
} }
motion_trail_vertex_start = &_vertex_array [0]; motion_trail_vertex_start = &vertex_array[0];
v0 = start_transform.xform (motion_trail_vertex_start -> _vertex); v0 = start_transform.xform(motion_trail_vertex_start->_vertex);
v2 = end_transform.xform (motion_trail_vertex_start -> _vertex); v2 = end_transform.xform(motion_trail_vertex_start->_vertex);
vertex_start_color = motion_trail_vertex_start -> _end_color + (motion_trail_vertex_start -> _start_color - motion_trail_vertex_start -> _end_color); vertex_start_color = motion_trail_vertex_start->_end_color + (motion_trail_vertex_start->_start_color - motion_trail_vertex_start->_end_color);
color_start_t = color_scale * start_t; color_start_t = color_scale * start_t;
color_end_t = color_scale * end_t; color_end_t = color_scale * end_t;
c0 = vertex_start_color * color_start_t; c0 = vertex_start_color * color_start_t;
c2 = vertex_start_color * color_end_t; c2 = vertex_start_color * color_end_t;
t0.set (st, motion_trail_vertex_start -> _v); t0.set(st, motion_trail_vertex_start->_v);
t2.set (et, motion_trail_vertex_start -> _v); t2.set(et, motion_trail_vertex_start->_v);
while (vertex_segment_index < total_vertex_segments) { for (int vertex_segment_index = 0;
vertex_segment_index < total_vertex_segments;
++vertex_segment_index) {
motion_trail_vertex_start = &vertex_array[vertex_segment_index];
motion_trail_vertex_end = &vertex_array[vertex_segment_index + 1];
motion_trail_vertex_start = &_vertex_array [vertex_segment_index]; v1 = start_transform.xform(motion_trail_vertex_end->_vertex);
motion_trail_vertex_end = &_vertex_array [vertex_segment_index + 1]; v3 = end_transform.xform(motion_trail_vertex_end->_vertex);
v1 = start_transform.xform (motion_trail_vertex_end -> _vertex);
v3 = end_transform.xform (motion_trail_vertex_end -> _vertex);
// color // color
vertex_end_color = motion_trail_vertex_end -> _end_color + (motion_trail_vertex_end -> _start_color - motion_trail_vertex_end -> _end_color); vertex_end_color = motion_trail_vertex_end->_end_color + (motion_trail_vertex_end->_start_color - motion_trail_vertex_end->_end_color);
c1 = vertex_end_color * color_start_t; c1 = vertex_end_color * color_start_t;
c3 = vertex_end_color * color_end_t; c3 = vertex_end_color * color_end_t;
// uv // uv
t1.set (st, motion_trail_vertex_end -> _v); t1.set(st, motion_trail_vertex_end->_v);
t3.set (et, motion_trail_vertex_end -> _v); t3.set(et, motion_trail_vertex_end->_v);
this -> add_geometry_quad (v0, v1, v2, v3, c0, c1, c2, c3, t0, t1, t2, t3); add_geometry_quad(v0, v1, v2, v3, c0, c1, c2, c3, t0, t1, t2, t3);
// reuse calculations // reuse calculations
v0 = v1; v0 = v1;
@ -792,18 +745,12 @@ update_motion_trail (PN_stdfloat current_time, LMatrix4 *transform) {
t0 = t1; t0 = t1;
t2 = t3; t2 = t3;
vertex_segment_index += 1;
} }
segment_index += 1;
} }
} }
// end geometry end_geometry();
this -> end_geometry ( );
delete[] _vertex_array; delete[] vertex_array;
_vertex_array = nullptr;
} }
} }

View File

@ -90,6 +90,7 @@ PUBLISHED:
public: public:
void begin_geometry(); void begin_geometry();
void begin_geometry(int num_quads);
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); 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);
void 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); void 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);
void end_geometry(); void end_geometry();