|
@@ -1339,9 +1339,10 @@ update_animated_vertices(GeomVertexData::CData *cdata, Thread *current_thread) {
|
|
|
PStatTimer timer(_char_pcollector, current_thread);
|
|
PStatTimer timer(_char_pcollector, current_thread);
|
|
|
|
|
|
|
|
const GeomVertexFormat *orig_format = cdata->_format;
|
|
const GeomVertexFormat *orig_format = cdata->_format;
|
|
|
|
|
+ CPT(GeomVertexFormat) new_format = orig_format;
|
|
|
|
|
|
|
|
if (cdata->_animated_vertices == (GeomVertexData *)NULL) {
|
|
if (cdata->_animated_vertices == (GeomVertexData *)NULL) {
|
|
|
- CPT(GeomVertexFormat) new_format = orig_format->get_post_animated_format();
|
|
|
|
|
|
|
+ new_format = orig_format->get_post_animated_format();
|
|
|
cdata->_animated_vertices =
|
|
cdata->_animated_vertices =
|
|
|
new GeomVertexData(get_name(), new_format,
|
|
new GeomVertexData(get_name(), new_format,
|
|
|
min(get_usage_hint(), UH_dynamic));
|
|
min(get_usage_hint(), UH_dynamic));
|
|
@@ -1452,64 +1453,182 @@ update_animated_vertices(GeomVertexData::CData *cdata, Thread *current_thread) {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// Now go through and apply the transforms.
|
|
// Now go through and apply the transforms.
|
|
|
- GeomVertexReader blendi(this, InternalName::get_transform_blend());
|
|
|
|
|
- if (!blendi.has_column()) {
|
|
|
|
|
|
|
+
|
|
|
|
|
+ const SparseArray &rows = tb_table->get_rows();
|
|
|
|
|
+ int num_subranges = rows.get_num_subranges();
|
|
|
|
|
+
|
|
|
|
|
+ int blend_array_index = orig_format->get_array_with(InternalName::get_transform_blend());
|
|
|
|
|
+ if (blend_array_index < 0) {
|
|
|
gobj_cat.warning()
|
|
gobj_cat.warning()
|
|
|
<< "Vertex data " << get_name()
|
|
<< "Vertex data " << get_name()
|
|
|
<< " has a transform_blend_table, but no transform_blend data.\n";
|
|
<< " has a transform_blend_table, but no transform_blend data.\n";
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- const SparseArray &rows = tb_table->get_rows();
|
|
|
|
|
- int num_subranges = rows.get_num_subranges();
|
|
|
|
|
|
|
+ CPT(GeomVertexArrayFormat) blend_array_format = orig_format->get_array(blend_array_index);
|
|
|
|
|
+
|
|
|
|
|
+ if (blend_array_format->get_num_columns() == 1 &&
|
|
|
|
|
+ blend_array_format->get_stride() == 2 &&
|
|
|
|
|
+ blend_array_format->get_column(0)->get_component_bytes() == 2) {
|
|
|
|
|
+ // The blend indices are a table of ushorts. Optimize this
|
|
|
|
|
+ // common case.
|
|
|
|
|
+ CPT(GeomVertexArrayDataHandle) blend_array_handle = cdata->_arrays[blend_array_index].get_read_pointer()->get_handle(current_thread);
|
|
|
|
|
+ const unsigned short *blendt = (const unsigned short *)blend_array_handle->get_read_pointer(true);
|
|
|
|
|
+
|
|
|
|
|
+ int ci;
|
|
|
|
|
+ for (ci = 0; ci < new_format->get_num_points(); ci++) {
|
|
|
|
|
+ GeomVertexRewriter data(new_data, new_format->get_point(ci));
|
|
|
|
|
+ const GeomVertexColumn *data_column = data.get_column();
|
|
|
|
|
+ if (data_column->get_num_values() == 3 &&
|
|
|
|
|
+ data_column->get_numeric_type() == NT_float32) {
|
|
|
|
|
+ // Table of points is a table of LPoint3f's. Optimize this
|
|
|
|
|
+ // common case.
|
|
|
|
|
+ int data_index = new_format->get_array_with(new_format->get_point(ci));
|
|
|
|
|
+ PT(GeomVertexArrayData) data_array = new_data->modify_array(data_index);
|
|
|
|
|
+ PT(GeomVertexArrayDataHandle) data_handle = data_array->modify_handle();
|
|
|
|
|
+ unsigned char *datat = data_handle->get_write_pointer();
|
|
|
|
|
+ datat += data_column->get_start();
|
|
|
|
|
+ size_t stride = data_array->get_array_format()->get_stride();
|
|
|
|
|
+
|
|
|
|
|
+ for (int i = 0; i < num_subranges; ++i) {
|
|
|
|
|
+ int begin = rows.get_subrange_begin(i);
|
|
|
|
|
+ int end = rows.get_subrange_end(i);
|
|
|
|
|
+ for (int j = begin; j < end; ++j) {
|
|
|
|
|
+ LPoint3f &vertex = *(LPoint3f *)(&datat[j * stride]);
|
|
|
|
|
+ int bi = blendt[j];
|
|
|
|
|
+ tb_table->get_blend(bi).transform_point(vertex, current_thread);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- int ci;
|
|
|
|
|
- for (ci = 0; ci < orig_format->get_num_points(); ci++) {
|
|
|
|
|
- GeomVertexRewriter data(new_data, orig_format->get_point(ci));
|
|
|
|
|
-
|
|
|
|
|
- if (data.get_column()->get_num_values() == 4) {
|
|
|
|
|
- for (int i = 0; i < num_subranges; ++i) {
|
|
|
|
|
- int begin = rows.get_subrange_begin(i);
|
|
|
|
|
- int end = rows.get_subrange_end(i);
|
|
|
|
|
- data.set_row(begin);
|
|
|
|
|
- blendi.set_row(begin);
|
|
|
|
|
- for (int j = begin; j < end; ++j) {
|
|
|
|
|
- LPoint4f vertex = data.get_data4f();
|
|
|
|
|
- int bi = blendi.get_data1i();
|
|
|
|
|
- tb_table->get_blend(bi).transform_point(vertex, current_thread);
|
|
|
|
|
- data.set_data4f(vertex);
|
|
|
|
|
|
|
+ } else if (data_column->get_num_values() == 4) {
|
|
|
|
|
+ // Use the GeomVertexRewriter to adjust the 4-component
|
|
|
|
|
+ // points.
|
|
|
|
|
+ for (int i = 0; i < num_subranges; ++i) {
|
|
|
|
|
+ int begin = rows.get_subrange_begin(i);
|
|
|
|
|
+ int end = rows.get_subrange_end(i);
|
|
|
|
|
+ data.set_row(begin);
|
|
|
|
|
+ for (int j = begin; j < end; ++j) {
|
|
|
|
|
+ LPoint4f vertex = data.get_data4f();
|
|
|
|
|
+ int bi = blendt[j];
|
|
|
|
|
+ tb_table->get_blend(bi).transform_point(vertex, current_thread);
|
|
|
|
|
+ data.set_data4f(vertex);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ } else {
|
|
|
|
|
+ // Use the GeomVertexRewriter to adjust the 3-component
|
|
|
|
|
+ // points.
|
|
|
|
|
+ for (int i = 0; i < num_subranges; ++i) {
|
|
|
|
|
+ int begin = rows.get_subrange_begin(i);
|
|
|
|
|
+ int end = rows.get_subrange_end(i);
|
|
|
|
|
+ data.set_row(begin);
|
|
|
|
|
+ for (int j = begin; j < end; ++j) {
|
|
|
|
|
+ LPoint3f vertex = data.get_data3f();
|
|
|
|
|
+ int bi = blendt[j];
|
|
|
|
|
+ tb_table->get_blend(bi).transform_point(vertex, current_thread);
|
|
|
|
|
+ data.set_data3f(vertex);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // Also process vectors: normals, etc.
|
|
|
|
|
+ for (ci = 0; ci < new_format->get_num_vectors(); ci++) {
|
|
|
|
|
+ GeomVertexRewriter data(new_data, new_format->get_vector(ci));
|
|
|
|
|
+ const GeomVertexColumn *data_column = data.get_column();
|
|
|
|
|
+ if (data_column->get_num_values() == 3 &&
|
|
|
|
|
+ data_column->get_numeric_type() == NT_float32) {
|
|
|
|
|
+ // Table of vectors is a table of LVector3f's. Optimize this
|
|
|
|
|
+ // common case.
|
|
|
|
|
+ int data_index = new_format->get_array_with(new_format->get_point(ci));
|
|
|
|
|
+ PT(GeomVertexArrayData) data_array = new_data->modify_array(data_index);
|
|
|
|
|
+ PT(GeomVertexArrayDataHandle) data_handle = data_array->modify_handle();
|
|
|
|
|
+ unsigned char *datat = data_handle->get_write_pointer();
|
|
|
|
|
+ datat += data_column->get_start();
|
|
|
|
|
+ size_t stride = data_array->get_array_format()->get_stride();
|
|
|
|
|
+
|
|
|
|
|
+ for (int i = 0; i < num_subranges; ++i) {
|
|
|
|
|
+ int begin = rows.get_subrange_begin(i);
|
|
|
|
|
+ int end = rows.get_subrange_end(i);
|
|
|
|
|
+ for (int j = begin; j < end; ++j) {
|
|
|
|
|
+ LVector3f &vertex = *(LVector3f *)(&datat[j * stride]);
|
|
|
|
|
+ int bi = blendt[j];
|
|
|
|
|
+ tb_table->get_blend(bi).transform_vector(vertex, current_thread);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ } else {
|
|
|
|
|
+ // Use the GeomVertexRewriter to adjust the vectors.
|
|
|
|
|
+
|
|
|
|
|
+ for (int i = 0; i < num_subranges; ++i) {
|
|
|
|
|
+ int begin = rows.get_subrange_begin(i);
|
|
|
|
|
+ int end = rows.get_subrange_end(i);
|
|
|
|
|
+ data.set_row(begin);
|
|
|
|
|
+ for (int j = begin; j < end; ++j) {
|
|
|
|
|
+ LVector3f vertex = data.get_data3f();
|
|
|
|
|
+ int bi = blendt[j];
|
|
|
|
|
+ tb_table->get_blend(bi).transform_vector(vertex, current_thread);
|
|
|
|
|
+ data.set_data3f(vertex);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ } else {
|
|
|
|
|
+ // The blend indices are anything else. Use the
|
|
|
|
|
+ // GeomVertexReader to iterate through them.
|
|
|
|
|
+ GeomVertexReader blendi(this, InternalName::get_transform_blend());
|
|
|
|
|
+ nassertv(blendi.has_column());
|
|
|
|
|
+
|
|
|
|
|
+ int ci;
|
|
|
|
|
+ for (ci = 0; ci < new_format->get_num_points(); ci++) {
|
|
|
|
|
+ GeomVertexRewriter data(new_data, new_format->get_point(ci));
|
|
|
|
|
+ const GeomVertexColumn *data_column = data.get_column();
|
|
|
|
|
+
|
|
|
|
|
+ if (data_column->get_num_values() == 4) {
|
|
|
|
|
+ for (int i = 0; i < num_subranges; ++i) {
|
|
|
|
|
+ int begin = rows.get_subrange_begin(i);
|
|
|
|
|
+ int end = rows.get_subrange_end(i);
|
|
|
|
|
+ data.set_row(begin);
|
|
|
|
|
+ blendi.set_row(begin);
|
|
|
|
|
+ for (int j = begin; j < end; ++j) {
|
|
|
|
|
+ LPoint4f vertex = data.get_data4f();
|
|
|
|
|
+ int bi = blendi.get_data1i();
|
|
|
|
|
+ tb_table->get_blend(bi).transform_point(vertex, current_thread);
|
|
|
|
|
+ data.set_data4f(vertex);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ } else {
|
|
|
|
|
+ for (int i = 0; i < num_subranges; ++i) {
|
|
|
|
|
+ int begin = rows.get_subrange_begin(i);
|
|
|
|
|
+ int end = rows.get_subrange_end(i);
|
|
|
|
|
+ data.set_row(begin);
|
|
|
|
|
+ blendi.set_row(begin);
|
|
|
|
|
+ for (int j = begin; j < end; ++j) {
|
|
|
|
|
+ LPoint3f vertex = data.get_data3f();
|
|
|
|
|
+ int bi = blendi.get_data1i();
|
|
|
|
|
+ tb_table->get_blend(bi).transform_point(vertex, current_thread);
|
|
|
|
|
+ data.set_data3f(vertex);
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
- } else {
|
|
|
|
|
|
|
+ }
|
|
|
|
|
+ for (ci = 0; ci < new_format->get_num_vectors(); ci++) {
|
|
|
|
|
+ GeomVertexRewriter data(new_data, new_format->get_vector(ci));
|
|
|
for (int i = 0; i < num_subranges; ++i) {
|
|
for (int i = 0; i < num_subranges; ++i) {
|
|
|
int begin = rows.get_subrange_begin(i);
|
|
int begin = rows.get_subrange_begin(i);
|
|
|
int end = rows.get_subrange_end(i);
|
|
int end = rows.get_subrange_end(i);
|
|
|
data.set_row(begin);
|
|
data.set_row(begin);
|
|
|
blendi.set_row(begin);
|
|
blendi.set_row(begin);
|
|
|
for (int j = begin; j < end; ++j) {
|
|
for (int j = begin; j < end; ++j) {
|
|
|
- LPoint3f vertex = data.get_data3f();
|
|
|
|
|
|
|
+ LVector3f vertex = data.get_data3f();
|
|
|
int bi = blendi.get_data1i();
|
|
int bi = blendi.get_data1i();
|
|
|
- tb_table->get_blend(bi).transform_point(vertex, current_thread);
|
|
|
|
|
|
|
+ tb_table->get_blend(bi).transform_vector(vertex, current_thread);
|
|
|
data.set_data3f(vertex);
|
|
data.set_data3f(vertex);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
- for (ci = 0; ci < orig_format->get_num_vectors(); ci++) {
|
|
|
|
|
- GeomVertexRewriter data(new_data, orig_format->get_vector(ci));
|
|
|
|
|
- for (int i = 0; i < num_subranges; ++i) {
|
|
|
|
|
- int begin = rows.get_subrange_begin(i);
|
|
|
|
|
- int end = rows.get_subrange_end(i);
|
|
|
|
|
- data.set_row(begin);
|
|
|
|
|
- blendi.set_row(begin);
|
|
|
|
|
- for (int j = begin; j < end; ++j) {
|
|
|
|
|
- LVector3f vertex = data.get_data3f();
|
|
|
|
|
- int bi = blendi.get_data1i();
|
|
|
|
|
- tb_table->get_blend(bi).transform_vector(vertex, current_thread);
|
|
|
|
|
- data.set_data3f(vertex);
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|