mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-04 10:54:24 -04:00
collect_vertex_data
This commit is contained in:
parent
62305f25bd
commit
d36604ab05
@ -2494,6 +2494,10 @@ draw_tristrips(const qpGeomTristrips *primitive) {
|
|||||||
const unsigned short *client_pointer = setup_primitive(primitive);
|
const unsigned short *client_pointer = setup_primitive(primitive);
|
||||||
|
|
||||||
if (connect_triangle_strips && _render_mode != RenderModeAttrib::M_wireframe) {
|
if (connect_triangle_strips && _render_mode != RenderModeAttrib::M_wireframe) {
|
||||||
|
GLCAT.debug()
|
||||||
|
<< "Connected triangle strips\n";
|
||||||
|
primitive->write(GLCAT.debug(), 2);
|
||||||
|
|
||||||
// One long triangle strip, connected by the degenerate vertices
|
// One long triangle strip, connected by the degenerate vertices
|
||||||
// that have already been set up within the primitive.
|
// that have already been set up within the primitive.
|
||||||
_vertices_tristrip_pcollector.add_level(primitive->get_num_vertices());
|
_vertices_tristrip_pcollector.add_level(primitive->get_num_vertices());
|
||||||
@ -2504,6 +2508,10 @@ draw_tristrips(const qpGeomTristrips *primitive) {
|
|||||||
GL_UNSIGNED_SHORT, client_pointer);
|
GL_UNSIGNED_SHORT, client_pointer);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
GLCAT.debug()
|
||||||
|
<< "Separate triangle strips\n";
|
||||||
|
primitive->write(GLCAT.debug(), 2);
|
||||||
|
|
||||||
// Send the individual triangle strips, stepping over the
|
// Send the individual triangle strips, stepping over the
|
||||||
// degenerate vertices.
|
// degenerate vertices.
|
||||||
CPTA_int ends = primitive->get_ends();
|
CPTA_int ends = primitive->get_ends();
|
||||||
|
@ -141,6 +141,45 @@ set_vertex_data(const qpGeomVertexData *data) {
|
|||||||
reset_point_rendering(cdata);
|
reset_point_rendering(cdata);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: qpGeom::offset_vertices
|
||||||
|
// Access: Published
|
||||||
|
// Description: Replaces a Geom's vertex table with a new table, and
|
||||||
|
// simultaneously adds the indicated offset to all
|
||||||
|
// vertex references within the Geom's primitives. This
|
||||||
|
// is intended to be used to combine multiple
|
||||||
|
// GeomVertexDatas from different Geoms into a single
|
||||||
|
// big buffer, with each Geom referencing a subset of
|
||||||
|
// the vertices in the buffer.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void qpGeom::
|
||||||
|
offset_vertices(const qpGeomVertexData *data, int offset) {
|
||||||
|
clear_cache();
|
||||||
|
CDWriter cdata(_cycler);
|
||||||
|
cdata->_data = (qpGeomVertexData *)data;
|
||||||
|
|
||||||
|
#ifndef NDEBUG
|
||||||
|
bool all_is_valid = true;
|
||||||
|
#endif
|
||||||
|
Primitives::iterator pi;
|
||||||
|
for (pi = cdata->_primitives.begin(); pi != cdata->_primitives.end(); ++pi) {
|
||||||
|
(*pi)->offset_vertices(offset);
|
||||||
|
|
||||||
|
#ifndef NDEBUG
|
||||||
|
if (!(*pi)->check_valid(data)) {
|
||||||
|
all_is_valid = false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
cdata->_got_usage_hint = false;
|
||||||
|
cdata->_modified = qpGeom::get_next_modified();
|
||||||
|
mark_bound_stale();
|
||||||
|
reset_point_rendering(cdata);
|
||||||
|
|
||||||
|
nassertv(all_is_valid);
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: qpGeom::set_primitive
|
// Function: qpGeom::set_primitive
|
||||||
// Access: Published
|
// Access: Published
|
||||||
|
@ -98,6 +98,7 @@ PUBLISHED:
|
|||||||
INLINE CPT(qpGeomVertexData) get_vertex_data() const;
|
INLINE CPT(qpGeomVertexData) get_vertex_data() const;
|
||||||
PT(qpGeomVertexData) modify_vertex_data();
|
PT(qpGeomVertexData) modify_vertex_data();
|
||||||
void set_vertex_data(const qpGeomVertexData *data);
|
void set_vertex_data(const qpGeomVertexData *data);
|
||||||
|
void offset_vertices(const qpGeomVertexData *data, int offset);
|
||||||
|
|
||||||
INLINE int get_num_primitives() const;
|
INLINE int get_num_primitives() const;
|
||||||
INLINE const qpGeomPrimitive *get_primitive(int i) const;
|
INLINE const qpGeomPrimitive *get_primitive(int i) const;
|
||||||
|
@ -274,6 +274,28 @@ clear_vertices() {
|
|||||||
cdata->_got_minmax = false;
|
cdata->_got_minmax = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: qpGeomPrimitive::offset_vertices
|
||||||
|
// Access: Published
|
||||||
|
// Description: Adds the indicated offset to all vertices used by the
|
||||||
|
// primitive.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void qpGeomPrimitive::
|
||||||
|
offset_vertices(int offset) {
|
||||||
|
clear_cache();
|
||||||
|
CDWriter cdata(_cycler);
|
||||||
|
|
||||||
|
cdata->_rotated_vertices.clear();
|
||||||
|
cdata->_mins.clear();
|
||||||
|
cdata->_maxs.clear();
|
||||||
|
cdata->_got_minmax = false;
|
||||||
|
|
||||||
|
PTA_ushort::iterator vi;
|
||||||
|
for (vi = cdata->_vertices.begin(); vi != cdata->_vertices.end(); ++vi) {
|
||||||
|
(*vi) += offset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: qpGeomPrimitive::get_num_primitives
|
// Function: qpGeomPrimitive::get_num_primitives
|
||||||
// Access: Published
|
// Access: Published
|
||||||
|
@ -119,6 +119,7 @@ PUBLISHED:
|
|||||||
void add_next_vertices(int num_vertices);
|
void add_next_vertices(int num_vertices);
|
||||||
bool close_primitive();
|
bool close_primitive();
|
||||||
void clear_vertices();
|
void clear_vertices();
|
||||||
|
void offset_vertices(int offset);
|
||||||
|
|
||||||
int get_num_primitives() const;
|
int get_num_primitives() const;
|
||||||
int get_primitive_start(int n) const;
|
int get_primitive_start(int n) const;
|
||||||
|
@ -197,6 +197,37 @@ get_vector(int n) const {
|
|||||||
return _vectors[n];
|
return _vectors[n];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: qpGeomVertexFormat::get_num_texcoords
|
||||||
|
// Access: Published
|
||||||
|
// Description: Returns the number of columns within the format
|
||||||
|
// that represent texture coordinates.
|
||||||
|
//
|
||||||
|
// This may only be called after the format has been
|
||||||
|
// registered.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE int qpGeomVertexFormat::
|
||||||
|
get_num_texcoords() const {
|
||||||
|
nassertr(_is_registered, 0);
|
||||||
|
return _texcoords.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: qpGeomVertexFormat::get_texcoord
|
||||||
|
// Access: Published
|
||||||
|
// Description: Returns the name of the nth texcoord column. This
|
||||||
|
// represents a texture coordinate.
|
||||||
|
//
|
||||||
|
// This may only be called after the format has been
|
||||||
|
// registered.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE const InternalName *qpGeomVertexFormat::
|
||||||
|
get_texcoord(int n) const {
|
||||||
|
nassertr(_is_registered, NULL);
|
||||||
|
nassertr(n >= 0 && n < (int)_texcoords.size(), NULL);
|
||||||
|
return _texcoords[n];
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: qpGeomVertexFormat::get_num_morphs
|
// Function: qpGeomVertexFormat::get_num_morphs
|
||||||
// Access: Published
|
// Access: Published
|
||||||
|
@ -546,6 +546,11 @@ do_register() {
|
|||||||
_vectors.push_back(column->get_name());
|
_vectors.push_back(column->get_name());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case qpGeomVertexColumn::C_texcoord:
|
||||||
|
// It's a texcoord.
|
||||||
|
_texcoords.push_back(column->get_name());
|
||||||
|
break;
|
||||||
|
|
||||||
case qpGeomVertexColumn::C_morph_delta:
|
case qpGeomVertexColumn::C_morph_delta:
|
||||||
{
|
{
|
||||||
// It's a morph description.
|
// It's a morph description.
|
||||||
@ -604,6 +609,7 @@ do_unregister() {
|
|||||||
_columns_by_name.clear();
|
_columns_by_name.clear();
|
||||||
_points.clear();
|
_points.clear();
|
||||||
_vectors.clear();
|
_vectors.clear();
|
||||||
|
_texcoords.clear();
|
||||||
_morphs.clear();
|
_morphs.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -104,6 +104,9 @@ PUBLISHED:
|
|||||||
INLINE int get_num_vectors() const;
|
INLINE int get_num_vectors() const;
|
||||||
INLINE const InternalName *get_vector(int n) const;
|
INLINE const InternalName *get_vector(int n) const;
|
||||||
|
|
||||||
|
INLINE int get_num_texcoords() const;
|
||||||
|
INLINE const InternalName *get_texcoord(int n) const;
|
||||||
|
|
||||||
INLINE int get_num_morphs() const;
|
INLINE int get_num_morphs() const;
|
||||||
INLINE const InternalName *get_morph_slider(int n) const;
|
INLINE const InternalName *get_morph_slider(int n) const;
|
||||||
INLINE const InternalName *get_morph_base(int n) const;
|
INLINE const InternalName *get_morph_base(int n) const;
|
||||||
@ -190,6 +193,7 @@ private:
|
|||||||
typedef pvector< CPT(InternalName) > Columns;
|
typedef pvector< CPT(InternalName) > Columns;
|
||||||
Columns _points;
|
Columns _points;
|
||||||
Columns _vectors;
|
Columns _vectors;
|
||||||
|
Columns _texcoords;
|
||||||
|
|
||||||
class MorphRecord {
|
class MorphRecord {
|
||||||
public:
|
public:
|
||||||
|
@ -159,7 +159,7 @@ set_column(const InternalName *name) {
|
|||||||
// The return value is true if the data type is valid,
|
// The return value is true if the data type is valid,
|
||||||
// false otherwise.
|
// false otherwise.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
bool qpGeomVertexRewriter::
|
INLINE bool qpGeomVertexRewriter::
|
||||||
set_column(int array, const qpGeomVertexColumn *column) {
|
set_column(int array, const qpGeomVertexColumn *column) {
|
||||||
// It's important to invoke the writer first, then the reader. See
|
// It's important to invoke the writer first, then the reader. See
|
||||||
// set_vertex().
|
// set_vertex().
|
||||||
|
@ -154,6 +154,14 @@ ConfigVariableBool auto_break_cycles
|
|||||||
"is false, you must explicitly call TransformState.clear_cache() "
|
"is false, you must explicitly call TransformState.clear_cache() "
|
||||||
"from time to time to prevent gradual memory bloat."));
|
"from time to time to prevent gradual memory bloat."));
|
||||||
|
|
||||||
|
ConfigVariableInt max_collect_vertices
|
||||||
|
("max-collect-vertices", 4096,
|
||||||
|
PRC_DESC("Specifies the maximum number of vertices that are allowed to be "
|
||||||
|
"accumulated into any one GeomVertexData structure as a result "
|
||||||
|
"of collecting objects together during a flatten operation. This "
|
||||||
|
"does not impose a limit on the original size of any one "
|
||||||
|
"GeomVertexData structure."));
|
||||||
|
|
||||||
ConfigVariableBool polylight_info
|
ConfigVariableBool polylight_info
|
||||||
("polylight-info", false,
|
("polylight-info", false,
|
||||||
PRC_DESC("Set this true to view some info statements regarding the polylight. "
|
PRC_DESC("Set this true to view some info statements regarding the polylight. "
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
#include "notifyCategoryProxy.h"
|
#include "notifyCategoryProxy.h"
|
||||||
#include "dconfig.h"
|
#include "dconfig.h"
|
||||||
#include "configVariableBool.h"
|
#include "configVariableBool.h"
|
||||||
|
#include "configVariableInt.h"
|
||||||
#include "configVariableDouble.h"
|
#include "configVariableDouble.h"
|
||||||
#include "configVariableList.h"
|
#include "configVariableList.h"
|
||||||
|
|
||||||
@ -40,6 +41,7 @@ extern ConfigVariableBool paranoid_compose;
|
|||||||
extern ConfigVariableBool compose_componentwise;
|
extern ConfigVariableBool compose_componentwise;
|
||||||
extern ConfigVariableBool paranoid_const;
|
extern ConfigVariableBool paranoid_const;
|
||||||
extern ConfigVariableBool auto_break_cycles;
|
extern ConfigVariableBool auto_break_cycles;
|
||||||
|
extern ConfigVariableInt max_collect_vertices;
|
||||||
|
|
||||||
extern ConfigVariableBool polylight_info;
|
extern ConfigVariableBool polylight_info;
|
||||||
extern ConfigVariableDouble lod_fade_time;
|
extern ConfigVariableDouble lod_fade_time;
|
||||||
|
@ -17,6 +17,30 @@
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: GeomTransformer::get_max_collect_vertices
|
||||||
|
// Access: Public
|
||||||
|
// Description: Returns the maximum number of vertices that may be
|
||||||
|
// put into a single GeomVertexData as a result of
|
||||||
|
// collecting multiple objects in collect_vertex_data().
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE int GeomTransformer::
|
||||||
|
get_max_collect_vertices() const {
|
||||||
|
return _max_collect_vertices;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: GeomTransformer::set_max_collect_vertices
|
||||||
|
// Access: Public
|
||||||
|
// Description: Specifies the maximum number of vertices that may be
|
||||||
|
// put into a single GeomVertexData as a result of
|
||||||
|
// collecting multiple objects in collect_vertex_data().
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE void GeomTransformer::
|
||||||
|
set_max_collect_vertices(int max_collect_vertices) {
|
||||||
|
_max_collect_vertices = max_collect_vertices;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: GeomTransformer::qpSourceVertices::Ordering Operator
|
// Function: GeomTransformer::qpSourceVertices::Ordering Operator
|
||||||
// Access: Public
|
// Access: Public
|
||||||
@ -113,3 +137,19 @@ operator < (const GeomTransformer::SourceColors &other) const {
|
|||||||
}
|
}
|
||||||
return (_scale.compare_to(other._scale) < 0);
|
return (_scale.compare_to(other._scale) < 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: GeomTransformer::NewCollectedKey::Ordering Operator
|
||||||
|
// Access: Public
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE bool GeomTransformer::NewCollectedKey::
|
||||||
|
operator < (const GeomTransformer::NewCollectedKey &other) const {
|
||||||
|
if (_format != other._format) {
|
||||||
|
return _format < other._format;
|
||||||
|
}
|
||||||
|
if (_usage_hint != other._usage_hint) {
|
||||||
|
return (int)_usage_hint < (int)other._usage_hint;
|
||||||
|
}
|
||||||
|
return _name < other._name;
|
||||||
|
}
|
||||||
|
@ -28,7 +28,21 @@
|
|||||||
// Description:
|
// Description:
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
GeomTransformer::
|
GeomTransformer::
|
||||||
GeomTransformer() {
|
GeomTransformer() :
|
||||||
|
// The default value here comes from the Config file.
|
||||||
|
_max_collect_vertices(max_collect_vertices)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: GeomTransformer::Copy Constructor
|
||||||
|
// Access: Public
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
GeomTransformer::
|
||||||
|
GeomTransformer(const GeomTransformer ©) :
|
||||||
|
_max_collect_vertices(copy._max_collect_vertices)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -510,3 +524,117 @@ apply_state(GeomNode *node, const RenderState *state) {
|
|||||||
|
|
||||||
return any_changed;
|
return any_changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: GeomTransformer::collect_vertex_data
|
||||||
|
// Access: Public
|
||||||
|
// Description: Transforms the vertices and the normals in the
|
||||||
|
// indicated Geom by the indicated matrix. Returns true
|
||||||
|
// if the Geom was changed, false otherwise.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool GeomTransformer::
|
||||||
|
collect_vertex_data(Geom *geom, bool keep_names) {
|
||||||
|
if (!geom->is_of_type(qpGeom::get_class_type())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
qpGeom *qpgeom = DCAST(qpGeom, geom);
|
||||||
|
|
||||||
|
const qpGeomVertexData *vdata = qpgeom->get_vertex_data();
|
||||||
|
|
||||||
|
if (vdata->get_num_vertices() > _max_collect_vertices) {
|
||||||
|
// Don't even bother.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const qpGeomVertexFormat *format = vdata->get_format();
|
||||||
|
|
||||||
|
NewCollectedKey key;
|
||||||
|
if (keep_names) {
|
||||||
|
key._name = vdata->get_name();
|
||||||
|
}
|
||||||
|
key._format = format;
|
||||||
|
key._usage_hint = vdata->get_usage_hint();
|
||||||
|
|
||||||
|
AlreadyCollected::const_iterator ai;
|
||||||
|
ai = _already_collected.find(vdata);
|
||||||
|
if (ai != _already_collected.end()) {
|
||||||
|
// We've previously collected this vertex data; reuse it.
|
||||||
|
const AlreadyCollectedData &acd = (*ai).second;
|
||||||
|
qpgeom->offset_vertices(acd._data, acd._offset);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We haven't collected this vertex data yet; append the vertices
|
||||||
|
// onto the new data.
|
||||||
|
|
||||||
|
NewCollectedData::iterator ni = _new_collected_data.find(key);
|
||||||
|
PT(qpGeomVertexData) new_data;
|
||||||
|
if (ni != _new_collected_data.end()) {
|
||||||
|
new_data = (*ni).second;
|
||||||
|
} else {
|
||||||
|
new_data = new qpGeomVertexData(vdata->get_name(), format,
|
||||||
|
vdata->get_usage_hint());
|
||||||
|
_new_collected_data[key] = new_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
int offset = new_data->get_num_vertices();
|
||||||
|
int new_num_vertices = offset + vdata->get_num_vertices();
|
||||||
|
if (new_num_vertices > _max_collect_vertices) {
|
||||||
|
// Whoa, hold the phone! Too many vertices going into this one
|
||||||
|
// GeomVertexData object; we'd better start over.
|
||||||
|
new_data = new qpGeomVertexData(vdata->get_name(), format,
|
||||||
|
vdata->get_usage_hint());
|
||||||
|
_new_collected_data[key] = new_data;
|
||||||
|
offset = 0;
|
||||||
|
new_num_vertices = vdata->get_num_vertices();
|
||||||
|
}
|
||||||
|
|
||||||
|
new_data->set_num_vertices(new_num_vertices);
|
||||||
|
|
||||||
|
for (int i = 0; i < vdata->get_num_arrays(); ++i) {
|
||||||
|
qpGeomVertexArrayData *new_array = new_data->modify_array(i);
|
||||||
|
const qpGeomVertexArrayData *old_array = vdata->get_array(i);
|
||||||
|
int stride = format->get_array(i)->get_stride();
|
||||||
|
int start_byte = offset * stride;
|
||||||
|
int copy_bytes = old_array->get_data_size_bytes();
|
||||||
|
nassertr(start_byte + copy_bytes == new_array->get_data_size_bytes(), false);
|
||||||
|
|
||||||
|
memcpy(new_array->modify_data() + start_byte,
|
||||||
|
old_array->get_data(), copy_bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
qpgeom->offset_vertices(new_data, offset);
|
||||||
|
AlreadyCollectedData &acd = _already_collected[vdata];
|
||||||
|
acd._data = new_data;
|
||||||
|
acd._offset = offset;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: GeomTransformer::collect_vertex_data
|
||||||
|
// Access: Public
|
||||||
|
// Description: Collects together individual GeomVertexData
|
||||||
|
// structures that share the same format into one big
|
||||||
|
// GeomVertexData structure. This is designed to
|
||||||
|
// minimize context switches on the graphics card.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool GeomTransformer::
|
||||||
|
collect_vertex_data(GeomNode *node, bool keep_names) {
|
||||||
|
bool any_changed = false;
|
||||||
|
|
||||||
|
GeomNode::CDWriter cdata(node->_cycler);
|
||||||
|
GeomNode::Geoms::iterator gi;
|
||||||
|
for (gi = cdata->_geoms.begin(); gi != cdata->_geoms.end(); ++gi) {
|
||||||
|
GeomNode::GeomEntry &entry = (*gi);
|
||||||
|
PT(Geom) new_geom = entry._geom->make_copy();
|
||||||
|
if (collect_vertex_data(new_geom, keep_names)) {
|
||||||
|
entry._geom = new_geom;
|
||||||
|
any_changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return any_changed;
|
||||||
|
}
|
||||||
|
@ -48,8 +48,12 @@ class InternalName;
|
|||||||
class EXPCL_PANDA GeomTransformer {
|
class EXPCL_PANDA GeomTransformer {
|
||||||
public:
|
public:
|
||||||
GeomTransformer();
|
GeomTransformer();
|
||||||
|
GeomTransformer(const GeomTransformer ©);
|
||||||
~GeomTransformer();
|
~GeomTransformer();
|
||||||
|
|
||||||
|
INLINE int get_max_collect_vertices() const;
|
||||||
|
INLINE void set_max_collect_vertices(int max_collect_vertices);
|
||||||
|
|
||||||
bool transform_vertices(Geom *geom, const LMatrix4f &mat);
|
bool transform_vertices(Geom *geom, const LMatrix4f &mat);
|
||||||
bool transform_vertices(GeomNode *node, const LMatrix4f &mat);
|
bool transform_vertices(GeomNode *node, const LMatrix4f &mat);
|
||||||
|
|
||||||
@ -68,7 +72,12 @@ public:
|
|||||||
|
|
||||||
bool apply_state(GeomNode *node, const RenderState *state);
|
bool apply_state(GeomNode *node, const RenderState *state);
|
||||||
|
|
||||||
|
bool collect_vertex_data(Geom *geom, bool keep_names);
|
||||||
|
bool collect_vertex_data(GeomNode *node, bool keep_names);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
int _max_collect_vertices;
|
||||||
|
|
||||||
class qpSourceVertices {
|
class qpSourceVertices {
|
||||||
public:
|
public:
|
||||||
INLINE bool operator < (const qpSourceVertices &other) const;
|
INLINE bool operator < (const qpSourceVertices &other) const;
|
||||||
@ -153,6 +162,25 @@ private:
|
|||||||
};
|
};
|
||||||
typedef pmap<SourceColors, PTA_Colorf> TColors;
|
typedef pmap<SourceColors, PTA_Colorf> TColors;
|
||||||
TColors _tcolors;
|
TColors _tcolors;
|
||||||
|
|
||||||
|
class AlreadyCollectedData {
|
||||||
|
public:
|
||||||
|
CPT(qpGeomVertexData) _data;
|
||||||
|
int _offset;
|
||||||
|
};
|
||||||
|
typedef pmap< CPT(qpGeomVertexData), AlreadyCollectedData> AlreadyCollected;
|
||||||
|
AlreadyCollected _already_collected;
|
||||||
|
|
||||||
|
class NewCollectedKey {
|
||||||
|
public:
|
||||||
|
INLINE bool operator < (const NewCollectedKey &other) const;
|
||||||
|
|
||||||
|
string _name;
|
||||||
|
CPT(qpGeomVertexFormat) _format;
|
||||||
|
qpGeomUsageHint::UsageHint _usage_hint;
|
||||||
|
};
|
||||||
|
typedef pmap< NewCollectedKey, PT(qpGeomVertexData) > NewCollectedData;
|
||||||
|
NewCollectedData _new_collected_data;
|
||||||
};
|
};
|
||||||
|
|
||||||
#include "geomTransformer.I"
|
#include "geomTransformer.I"
|
||||||
|
@ -73,3 +73,22 @@ apply_attribs(PandaNode *node, const AccumulatedAttribs &attribs,
|
|||||||
int attrib_types, GeomTransformer &transformer) {
|
int attrib_types, GeomTransformer &transformer) {
|
||||||
r_apply_attribs(node, attribs, attrib_types, transformer);
|
r_apply_attribs(node, attribs, attrib_types, transformer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: SceneGraphReducer::collect_vertex_data
|
||||||
|
// Access: Published
|
||||||
|
// Description: Collects all different GeomVertexData blocks that
|
||||||
|
// have compatible formats at this node and below into a
|
||||||
|
// single, unified block (or at least multiple larger
|
||||||
|
// blocks). This is intended to reduce rendering
|
||||||
|
// overhead incurred by switching vertex buffers.
|
||||||
|
//
|
||||||
|
// The set of bits passed in collect_bits indicates
|
||||||
|
// which properties are used to differentiate
|
||||||
|
// GeomVertexData blocks. If it is 0, then more blocks
|
||||||
|
// will be combined together than if it is nonzero.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE int SceneGraphReducer::
|
||||||
|
collect_vertex_data(PandaNode *root, int collect_bits) {
|
||||||
|
return r_collect_vertex_data(root, collect_bits, _transformer);
|
||||||
|
}
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
#include "sceneGraphReducer.h"
|
#include "sceneGraphReducer.h"
|
||||||
#include "config_pgraph.h"
|
#include "config_pgraph.h"
|
||||||
#include "accumulatedAttribs.h"
|
#include "accumulatedAttribs.h"
|
||||||
|
#include "modelNode.h"
|
||||||
#include "pointerTo.h"
|
#include "pointerTo.h"
|
||||||
#include "plist.h"
|
#include "plist.h"
|
||||||
#include "pmap.h"
|
#include "pmap.h"
|
||||||
@ -564,3 +564,47 @@ choose_name(PandaNode *preserve, PandaNode *source1, PandaNode *source2) {
|
|||||||
preserve->set_name(name);
|
preserve->set_name(name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: SceneGraphReducer::r_collect_vertex_data
|
||||||
|
// Access: Private
|
||||||
|
// Description: The recursive implementation of
|
||||||
|
// collect_vertex_data().
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
int SceneGraphReducer::
|
||||||
|
r_collect_vertex_data(PandaNode *node, int collect_bits,
|
||||||
|
GeomTransformer &transformer) {
|
||||||
|
int num_collected = 0;
|
||||||
|
|
||||||
|
if ((collect_bits & CVD_model) != 0 &&
|
||||||
|
node->is_of_type(ModelNode::get_class_type())) {
|
||||||
|
// When we come to a model node, start a new collection.
|
||||||
|
GeomTransformer new_transformer(transformer);
|
||||||
|
|
||||||
|
PandaNode::Children children = node->get_children();
|
||||||
|
int num_children = children.get_num_children();
|
||||||
|
for (int i = 0; i < num_children; ++i) {
|
||||||
|
num_collected +=
|
||||||
|
r_collect_vertex_data(children.get_child(i), collect_bits, new_transformer);
|
||||||
|
}
|
||||||
|
return num_collected;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (node->is_geom_node()) {
|
||||||
|
// When we come to geom node, collect.
|
||||||
|
bool keep_names = ((collect_bits & SceneGraphReducer::CVD_name) != 0);
|
||||||
|
if (transformer.collect_vertex_data(DCAST(GeomNode, node), keep_names)) {
|
||||||
|
++num_collected;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Then recurse.
|
||||||
|
PandaNode::Children children = node->get_children();
|
||||||
|
int num_children = children.get_num_children();
|
||||||
|
for (int i = 0; i < num_children; ++i) {
|
||||||
|
num_collected +=
|
||||||
|
r_collect_vertex_data(children.get_child(i), collect_bits, transformer);
|
||||||
|
}
|
||||||
|
|
||||||
|
return num_collected;
|
||||||
|
}
|
||||||
|
@ -61,12 +61,19 @@ PUBLISHED:
|
|||||||
CS_recurse = 0x004,
|
CS_recurse = 0x004,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum CollectVertexData {
|
||||||
|
CVD_name = 0x001,
|
||||||
|
CVD_model = 0x002,
|
||||||
|
};
|
||||||
|
|
||||||
INLINE void apply_attribs(PandaNode *node, int attrib_types = ~0);
|
INLINE void apply_attribs(PandaNode *node, int attrib_types = ~0);
|
||||||
INLINE void apply_attribs(PandaNode *node, const AccumulatedAttribs &attribs,
|
INLINE void apply_attribs(PandaNode *node, const AccumulatedAttribs &attribs,
|
||||||
int attrib_types, GeomTransformer &transformer);
|
int attrib_types, GeomTransformer &transformer);
|
||||||
|
|
||||||
int flatten(PandaNode *root, int combine_siblings_bits);
|
int flatten(PandaNode *root, int combine_siblings_bits);
|
||||||
|
|
||||||
|
INLINE int collect_vertex_data(PandaNode *root, int collect_bits = ~0);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void r_apply_attribs(PandaNode *node, const AccumulatedAttribs &attribs,
|
void r_apply_attribs(PandaNode *node, const AccumulatedAttribs &attribs,
|
||||||
int attrib_types, GeomTransformer &transformer);
|
int attrib_types, GeomTransformer &transformer);
|
||||||
@ -92,6 +99,9 @@ protected:
|
|||||||
void choose_name(PandaNode *preserve, PandaNode *source1,
|
void choose_name(PandaNode *preserve, PandaNode *source1,
|
||||||
PandaNode *source2);
|
PandaNode *source2);
|
||||||
|
|
||||||
|
int r_collect_vertex_data(PandaNode *node, int collect_bits,
|
||||||
|
GeomTransformer &transformer);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
GeomTransformer _transformer;
|
GeomTransformer _transformer;
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user