mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-02 09:52:27 -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);
|
||||
|
||||
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
|
||||
// that have already been set up within the primitive.
|
||||
_vertices_tristrip_pcollector.add_level(primitive->get_num_vertices());
|
||||
@ -2504,6 +2508,10 @@ draw_tristrips(const qpGeomTristrips *primitive) {
|
||||
GL_UNSIGNED_SHORT, client_pointer);
|
||||
|
||||
} else {
|
||||
GLCAT.debug()
|
||||
<< "Separate triangle strips\n";
|
||||
primitive->write(GLCAT.debug(), 2);
|
||||
|
||||
// Send the individual triangle strips, stepping over the
|
||||
// degenerate vertices.
|
||||
CPTA_int ends = primitive->get_ends();
|
||||
|
@ -141,6 +141,45 @@ set_vertex_data(const qpGeomVertexData *data) {
|
||||
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
|
||||
// Access: Published
|
||||
|
@ -98,6 +98,7 @@ PUBLISHED:
|
||||
INLINE CPT(qpGeomVertexData) get_vertex_data() const;
|
||||
PT(qpGeomVertexData) modify_vertex_data();
|
||||
void set_vertex_data(const qpGeomVertexData *data);
|
||||
void offset_vertices(const qpGeomVertexData *data, int offset);
|
||||
|
||||
INLINE int get_num_primitives() const;
|
||||
INLINE const qpGeomPrimitive *get_primitive(int i) const;
|
||||
|
@ -274,6 +274,28 @@ clear_vertices() {
|
||||
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
|
||||
// Access: Published
|
||||
|
@ -119,6 +119,7 @@ PUBLISHED:
|
||||
void add_next_vertices(int num_vertices);
|
||||
bool close_primitive();
|
||||
void clear_vertices();
|
||||
void offset_vertices(int offset);
|
||||
|
||||
int get_num_primitives() const;
|
||||
int get_primitive_start(int n) const;
|
||||
|
@ -197,6 +197,37 @@ get_vector(int n) const {
|
||||
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
|
||||
// Access: Published
|
||||
|
@ -546,6 +546,11 @@ do_register() {
|
||||
_vectors.push_back(column->get_name());
|
||||
break;
|
||||
|
||||
case qpGeomVertexColumn::C_texcoord:
|
||||
// It's a texcoord.
|
||||
_texcoords.push_back(column->get_name());
|
||||
break;
|
||||
|
||||
case qpGeomVertexColumn::C_morph_delta:
|
||||
{
|
||||
// It's a morph description.
|
||||
@ -604,6 +609,7 @@ do_unregister() {
|
||||
_columns_by_name.clear();
|
||||
_points.clear();
|
||||
_vectors.clear();
|
||||
_texcoords.clear();
|
||||
_morphs.clear();
|
||||
}
|
||||
|
||||
|
@ -104,6 +104,9 @@ PUBLISHED:
|
||||
INLINE int get_num_vectors() 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 const InternalName *get_morph_slider(int n) const;
|
||||
INLINE const InternalName *get_morph_base(int n) const;
|
||||
@ -190,6 +193,7 @@ private:
|
||||
typedef pvector< CPT(InternalName) > Columns;
|
||||
Columns _points;
|
||||
Columns _vectors;
|
||||
Columns _texcoords;
|
||||
|
||||
class MorphRecord {
|
||||
public:
|
||||
|
@ -159,7 +159,7 @@ set_column(const InternalName *name) {
|
||||
// The return value is true if the data type is valid,
|
||||
// false otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool qpGeomVertexRewriter::
|
||||
INLINE bool qpGeomVertexRewriter::
|
||||
set_column(int array, const qpGeomVertexColumn *column) {
|
||||
// It's important to invoke the writer first, then the reader. See
|
||||
// set_vertex().
|
||||
|
@ -154,6 +154,14 @@ ConfigVariableBool auto_break_cycles
|
||||
"is false, you must explicitly call TransformState.clear_cache() "
|
||||
"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
|
||||
("polylight-info", false,
|
||||
PRC_DESC("Set this true to view some info statements regarding the polylight. "
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include "notifyCategoryProxy.h"
|
||||
#include "dconfig.h"
|
||||
#include "configVariableBool.h"
|
||||
#include "configVariableInt.h"
|
||||
#include "configVariableDouble.h"
|
||||
#include "configVariableList.h"
|
||||
|
||||
@ -40,6 +41,7 @@ extern ConfigVariableBool paranoid_compose;
|
||||
extern ConfigVariableBool compose_componentwise;
|
||||
extern ConfigVariableBool paranoid_const;
|
||||
extern ConfigVariableBool auto_break_cycles;
|
||||
extern ConfigVariableInt max_collect_vertices;
|
||||
|
||||
extern ConfigVariableBool polylight_info;
|
||||
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
|
||||
// Access: Public
|
||||
@ -113,3 +137,19 @@ operator < (const GeomTransformer::SourceColors &other) const {
|
||||
}
|
||||
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:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
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;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// 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 {
|
||||
public:
|
||||
GeomTransformer();
|
||||
GeomTransformer(const 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(GeomNode *node, const LMatrix4f &mat);
|
||||
|
||||
@ -68,7 +72,12 @@ public:
|
||||
|
||||
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:
|
||||
int _max_collect_vertices;
|
||||
|
||||
class qpSourceVertices {
|
||||
public:
|
||||
INLINE bool operator < (const qpSourceVertices &other) const;
|
||||
@ -153,6 +162,25 @@ private:
|
||||
};
|
||||
typedef pmap<SourceColors, PTA_Colorf> 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"
|
||||
|
@ -73,3 +73,22 @@ apply_attribs(PandaNode *node, const AccumulatedAttribs &attribs,
|
||||
int attrib_types, GeomTransformer &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 "config_pgraph.h"
|
||||
#include "accumulatedAttribs.h"
|
||||
|
||||
#include "modelNode.h"
|
||||
#include "pointerTo.h"
|
||||
#include "plist.h"
|
||||
#include "pmap.h"
|
||||
@ -564,3 +564,47 @@ choose_name(PandaNode *preserve, PandaNode *source1, PandaNode *source2) {
|
||||
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,
|
||||
};
|
||||
|
||||
enum CollectVertexData {
|
||||
CVD_name = 0x001,
|
||||
CVD_model = 0x002,
|
||||
};
|
||||
|
||||
INLINE void apply_attribs(PandaNode *node, int attrib_types = ~0);
|
||||
INLINE void apply_attribs(PandaNode *node, const AccumulatedAttribs &attribs,
|
||||
int attrib_types, GeomTransformer &transformer);
|
||||
|
||||
int flatten(PandaNode *root, int combine_siblings_bits);
|
||||
|
||||
INLINE int collect_vertex_data(PandaNode *root, int collect_bits = ~0);
|
||||
|
||||
protected:
|
||||
void r_apply_attribs(PandaNode *node, const AccumulatedAttribs &attribs,
|
||||
int attrib_types, GeomTransformer &transformer);
|
||||
@ -92,6 +99,9 @@ protected:
|
||||
void choose_name(PandaNode *preserve, PandaNode *source1,
|
||||
PandaNode *source2);
|
||||
|
||||
int r_collect_vertex_data(PandaNode *node, int collect_bits,
|
||||
GeomTransformer &transformer);
|
||||
|
||||
private:
|
||||
GeomTransformer _transformer;
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user