mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-03 18:31:55 -04:00
VertexRewriter; animation stats in cull
This commit is contained in:
parent
048f90a297
commit
29d51a723b
@ -33,7 +33,8 @@
|
||||
|
||||
TypeHandle Character::_type_handle;
|
||||
|
||||
PStatCollector Character::_anim_pcollector("App:Animation");
|
||||
PStatCollector Character::_app_animation_pcollector("App:Animation");
|
||||
PStatCollector Character::_cull_animation_pcollector("Cull:Animation");
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Character::Copy Constructor
|
||||
@ -46,7 +47,8 @@ Character(const Character ©) :
|
||||
_cv(DynamicVertices::deep_copy(copy._cv)),
|
||||
_computed_vertices(copy._computed_vertices),
|
||||
_parts(copy._parts),
|
||||
_char_pcollector(copy._char_pcollector)
|
||||
_app_char_pcollector(copy._app_char_pcollector),
|
||||
_cull_char_pcollector(copy._cull_char_pcollector)
|
||||
{
|
||||
// Now make a copy of the joint/slider hierarchy. We could just use
|
||||
// the copy_subgraph feature of the PartBundleNode's copy
|
||||
@ -64,7 +66,8 @@ Character(const Character ©) :
|
||||
Character::
|
||||
Character(const string &name) :
|
||||
PartBundleNode(name, new CharacterJointBundle(name)),
|
||||
_char_pcollector(_anim_pcollector, name)
|
||||
_app_char_pcollector(PStatCollector(_app_animation_pcollector, name), "Joints"),
|
||||
_cull_char_pcollector(PStatCollector(_cull_animation_pcollector, name), "Joints")
|
||||
{
|
||||
}
|
||||
|
||||
@ -158,7 +161,18 @@ cull_callback(CullTraverser *, CullTraverserData &) {
|
||||
// the view frustum. We may need a better way to do this
|
||||
// optimization later, to handle characters that might animate
|
||||
// themselves in front of the view frustum.
|
||||
update_to_now();
|
||||
|
||||
PStatTimer timer(_cull_char_pcollector);
|
||||
|
||||
double now = ClockObject::get_global_clock()->get_frame_time();
|
||||
get_bundle()->advance_time(now);
|
||||
|
||||
if (char_cat.is_spam()) {
|
||||
char_cat.spam() << "Animating " << *this << " at time " << now << "\n";
|
||||
}
|
||||
|
||||
do_update();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -193,9 +207,38 @@ update_to_now() {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void Character::
|
||||
update() {
|
||||
// Statistics
|
||||
PStatTimer timer(_char_pcollector);
|
||||
PStatTimer timer(_app_char_pcollector);
|
||||
do_update();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Character::force_update
|
||||
// Access: Published
|
||||
// Description: Recalculates the character even if we think it
|
||||
// doesn't need it.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void Character::
|
||||
force_update() {
|
||||
// Statistics
|
||||
PStatTimer timer(_app_char_pcollector);
|
||||
|
||||
// First, update all the joints and sliders.
|
||||
get_bundle()->force_update();
|
||||
|
||||
// Now update the vertices.
|
||||
if (_computed_vertices != (ComputedVertices *)NULL) {
|
||||
_computed_vertices->update(this);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Character::do_update
|
||||
// Access: Private
|
||||
// Description: The actual implementation of update(). Assumes the
|
||||
// appropriate PStatCollector has already been started.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void Character::
|
||||
do_update() {
|
||||
// First, update all the joints and sliders.
|
||||
bool any_changed;
|
||||
if (even_animation) {
|
||||
@ -213,26 +256,6 @@ update() {
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Character::force_update
|
||||
// Access: Published
|
||||
// Description: Recalculates the character even if we think it
|
||||
// doesn't need it.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void Character::
|
||||
force_update() {
|
||||
// Statistics
|
||||
PStatTimer timer(_char_pcollector);
|
||||
|
||||
// First, update all the joints and sliders.
|
||||
get_bundle()->force_update();
|
||||
|
||||
// Now update the vertices.
|
||||
if (_computed_vertices != (ComputedVertices *)NULL) {
|
||||
_computed_vertices->update(this);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Character::copy_joints
|
||||
// Access: Private
|
||||
@ -551,10 +574,12 @@ fillin(DatagramIterator &scan, BamReader *manager) {
|
||||
}
|
||||
|
||||
#ifdef DO_PSTATS
|
||||
// Reinitialize our collector with our name, now that we know it.
|
||||
// Reinitialize our collectors with our name, now that we know it.
|
||||
if (has_name()) {
|
||||
_char_pcollector =
|
||||
PStatCollector(_anim_pcollector, get_name());
|
||||
_app_char_pcollector =
|
||||
PStatCollector(PStatCollector(_app_animation_pcollector, get_name()), "Joints");
|
||||
_cull_char_pcollector =
|
||||
PStatCollector(PStatCollector(_cull_animation_pcollector, get_name()), "Joints");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -67,6 +67,7 @@ PUBLISHED:
|
||||
void force_update();
|
||||
|
||||
private:
|
||||
void do_update();
|
||||
void copy_joints(PartGroup *copy, PartGroup *orig);
|
||||
|
||||
typedef pmap<const PandaNode *, PandaNode *> NodeMap;
|
||||
@ -94,8 +95,10 @@ private:
|
||||
Parts _parts;
|
||||
|
||||
// Statistics
|
||||
PStatCollector _char_pcollector;
|
||||
static PStatCollector _anim_pcollector;
|
||||
PStatCollector _app_char_pcollector;
|
||||
PStatCollector _cull_char_pcollector;
|
||||
static PStatCollector _app_animation_pcollector;
|
||||
static PStatCollector _cull_animation_pcollector;
|
||||
|
||||
public:
|
||||
static void register_with_read_factory();
|
||||
|
@ -36,6 +36,7 @@
|
||||
qpgeomVertexDataType.h qpgeomVertexDataType.I \
|
||||
qpgeomVertexFormat.h qpgeomVertexFormat.I \
|
||||
qpgeomVertexReader.h qpgeomVertexReader.I \
|
||||
qpgeomVertexRewriter.h qpgeomVertexRewriter.I \
|
||||
qpgeomVertexWriter.h qpgeomVertexWriter.I \
|
||||
indexBufferContext.I indexBufferContext.h \
|
||||
internalName.I internalName.h \
|
||||
@ -82,6 +83,7 @@
|
||||
qpgeomVertexDataType.cxx \
|
||||
qpgeomVertexFormat.cxx \
|
||||
qpgeomVertexReader.cxx \
|
||||
qpgeomVertexRewriter.cxx \
|
||||
qpgeomVertexWriter.cxx \
|
||||
indexBufferContext.cxx \
|
||||
material.cxx \
|
||||
@ -126,6 +128,7 @@
|
||||
qpgeomVertexDataType.h qpgeomVertexDataType.I \
|
||||
qpgeomVertexFormat.h qpgeomVertexFormat.I \
|
||||
qpgeomVertexReader.h qpgeomVertexReader.I \
|
||||
qpgeomVertexRewriter.h qpgeomVertexRewriter.I \
|
||||
qpgeomVertexWriter.h qpgeomVertexWriter.I \
|
||||
indexBufferContext.I indexBufferContext.h \
|
||||
internalName.I internalName.h \
|
||||
|
@ -28,4 +28,5 @@
|
||||
#include "qpgeomVertexDataType.cxx"
|
||||
#include "qpgeomVertexFormat.cxx"
|
||||
#include "qpgeomVertexReader.cxx"
|
||||
#include "qpgeomVertexRewriter.cxx"
|
||||
#include "qpgeomVertexWriter.cxx"
|
||||
|
@ -38,7 +38,10 @@ get_name() const {
|
||||
INLINE void qpGeomVertexData::
|
||||
set_name(const string &name) {
|
||||
_name = name;
|
||||
_this_animate_vertices_pcollector = PStatCollector(_animate_vertices_pcollector, name);
|
||||
_app_char_pcollector =
|
||||
PStatCollector(PStatCollector(_app_animation_pcollector, name), "Vertices");
|
||||
_cull_char_pcollector =
|
||||
PStatCollector(PStatCollector(_cull_animation_pcollector, name), "Vertices");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -160,6 +163,43 @@ get_modified() const {
|
||||
return cdata->_modified;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexData::animate_vertices
|
||||
// Access: Published
|
||||
// Description: Returns a GeomVertexData that represents the results
|
||||
// of computing the vertex animation on the CPU for this
|
||||
// GeomVertexData.
|
||||
//
|
||||
// If there is no CPU-defined vertex animation on this
|
||||
// object, this just returns the original object.
|
||||
//
|
||||
// If there is vertex animation, but the VertexTransform
|
||||
// values have not changed since last time, this may
|
||||
// return the same pointer it returned previously. Even
|
||||
// if the VertexTransform values have changed, it may
|
||||
// still return the same pointer, but with its contents
|
||||
// modified (this is preferred, since it allows the
|
||||
// graphics backend to update vertex buffers optimally).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE CPT(qpGeomVertexData) qpGeomVertexData::
|
||||
animate_vertices() const {
|
||||
return do_animate_vertices(true);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexData::animate_vertices_cull
|
||||
// Access: Public
|
||||
// Description: Does exactly the same thing as animate_vertices(),
|
||||
// but when PStats is enabled, it records the time spent
|
||||
// as during the cull step instead of the app step.
|
||||
// This is intended to be called from the cull callback,
|
||||
// rather the called directly by the user.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE CPT(qpGeomVertexData) qpGeomVertexData::
|
||||
animate_vertices_cull() const {
|
||||
return do_animate_vertices(false);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexData::pack_8888
|
||||
// Access: Public, Static
|
||||
|
@ -30,7 +30,8 @@ TypeHandle qpGeomVertexData::_type_handle;
|
||||
PStatCollector qpGeomVertexData::_convert_pcollector("Cull:Munge:Convert");
|
||||
PStatCollector qpGeomVertexData::_scale_color_pcollector("Cull:Munge:Scale color");
|
||||
PStatCollector qpGeomVertexData::_set_color_pcollector("Cull:Munge:Set color");
|
||||
PStatCollector qpGeomVertexData::_animate_vertices_pcollector("Cull:Animate vertices");
|
||||
PStatCollector qpGeomVertexData::_app_animation_pcollector("App:Animation");
|
||||
PStatCollector qpGeomVertexData::_cull_animation_pcollector("Cull:Animation");
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexData::Default Constructor
|
||||
@ -40,7 +41,8 @@ PStatCollector qpGeomVertexData::_animate_vertices_pcollector("Cull:Animate vert
|
||||
////////////////////////////////////////////////////////////////////
|
||||
qpGeomVertexData::
|
||||
qpGeomVertexData() :
|
||||
_this_animate_vertices_pcollector(_animate_vertices_pcollector)
|
||||
_app_char_pcollector(_app_animation_pcollector),
|
||||
_cull_char_pcollector(_cull_animation_pcollector)
|
||||
{
|
||||
}
|
||||
|
||||
@ -56,7 +58,8 @@ qpGeomVertexData(const string &name,
|
||||
_name(name),
|
||||
_format(format),
|
||||
_usage_hint(usage_hint),
|
||||
_this_animate_vertices_pcollector(_animate_vertices_pcollector, name)
|
||||
_app_char_pcollector(PStatCollector(_app_animation_pcollector, name), "Vertices"),
|
||||
_cull_char_pcollector(PStatCollector(_cull_animation_pcollector, name), "Vertices")
|
||||
{
|
||||
nassertv(_format->is_registered());
|
||||
|
||||
@ -82,7 +85,8 @@ qpGeomVertexData(const qpGeomVertexData ©) :
|
||||
_name(copy._name),
|
||||
_format(copy._format),
|
||||
_cycler(copy._cycler),
|
||||
_this_animate_vertices_pcollector(copy._this_animate_vertices_pcollector)
|
||||
_app_char_pcollector(copy._app_char_pcollector),
|
||||
_cull_char_pcollector(copy._cull_char_pcollector)
|
||||
{
|
||||
}
|
||||
|
||||
@ -97,7 +101,8 @@ operator = (const qpGeomVertexData ©) {
|
||||
_name = copy._name;
|
||||
_format = copy._format;
|
||||
_cycler = copy._cycler;
|
||||
_this_animate_vertices_pcollector = copy._this_animate_vertices_pcollector;
|
||||
_app_char_pcollector = copy._app_char_pcollector;
|
||||
_cull_char_pcollector = copy._cull_char_pcollector;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -374,10 +379,10 @@ convert_to(const qpGeomVertexFormat *new_format) const {
|
||||
<< "generic copy " << *new_data_type << " from "
|
||||
<< *data_type << "\n";
|
||||
}
|
||||
qpGeomVertexReader from(this);
|
||||
from.set_data_type(i, data_type);
|
||||
qpGeomVertexWriter to(new_data);
|
||||
to.set_data_type(new_i, new_data_type);
|
||||
qpGeomVertexReader from(this);
|
||||
from.set_data_type(i, data_type);
|
||||
|
||||
while (!from.is_at_end()) {
|
||||
to.set_data4f(from.get_data4f());
|
||||
@ -424,8 +429,8 @@ scale_color(const LVecBase4f &color_scale, int num_components,
|
||||
contents, get_usage_hint(), true);
|
||||
|
||||
// Now go through and apply the scale, copying it to the new data.
|
||||
qpGeomVertexReader from(this, InternalName::get_color());
|
||||
qpGeomVertexWriter to(new_data, InternalName::get_color());
|
||||
qpGeomVertexReader from(this, InternalName::get_color());
|
||||
|
||||
for (int i = 0; i < num_vertices; i++) {
|
||||
Colorf color = from.get_data4f();
|
||||
@ -475,49 +480,6 @@ set_color(const Colorf &color, int num_components,
|
||||
return new_data;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexData::animate_vertices
|
||||
// Access: Published
|
||||
// Description: Returns a GeomVertexData that represents the results
|
||||
// of computing the vertex animation on the CPU for this
|
||||
// GeomVertexData.
|
||||
//
|
||||
// If there is no CPU-defined vertex animation on this
|
||||
// object, this just returns the original object.
|
||||
//
|
||||
// If there is vertex animation, but the VertexTransform
|
||||
// values have not changed since last time, this may
|
||||
// return the same pointer it returned previously. Even
|
||||
// if the VertexTransform values have changed, it may
|
||||
// still return the same pointer, but with its contents
|
||||
// modified (this is preferred, since it allows the
|
||||
// graphics backend to update vertex buffers optimally).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPT(qpGeomVertexData) qpGeomVertexData::
|
||||
animate_vertices() const {
|
||||
CDReader cdata(_cycler);
|
||||
if (cdata->_transform_blend_palette == (TransformBlendPalette *)NULL) {
|
||||
// No vertex animation.
|
||||
return this;
|
||||
}
|
||||
|
||||
if (cdata->_animated_vertices == (qpGeomVertexData *)NULL) {
|
||||
CDWriter cdataw(((qpGeomVertexData *)this)->_cycler, cdata);
|
||||
((qpGeomVertexData *)this)->make_animated_vertices(cdataw);
|
||||
return cdataw->_animated_vertices;
|
||||
} else {
|
||||
UpdateSeq blend_modified = cdata->_transform_blend_palette->get_modified();
|
||||
if (cdata->_animated_vertices_modified == blend_modified) {
|
||||
// No changes.
|
||||
return cdata->_animated_vertices;
|
||||
}
|
||||
CDWriter cdataw(((qpGeomVertexData *)this)->_cycler, cdata);
|
||||
cdataw->_animated_vertices_modified = blend_modified;
|
||||
((qpGeomVertexData *)this)->update_animated_vertices(cdataw);
|
||||
return cdataw->_animated_vertices;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexData::replace_data_type
|
||||
// Access: Published
|
||||
@ -673,6 +635,38 @@ get_array_info(const InternalName *name,
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexData::do_animate_vertices
|
||||
// Access: Private
|
||||
// Description: This is the private implementation of
|
||||
// animate_vertices() and animate_vertices_cull().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPT(qpGeomVertexData) qpGeomVertexData::
|
||||
do_animate_vertices(bool from_app) const {
|
||||
CDReader cdata(_cycler);
|
||||
if (cdata->_transform_blend_palette == (TransformBlendPalette *)NULL) {
|
||||
// No vertex animation.
|
||||
return this;
|
||||
}
|
||||
|
||||
if (cdata->_animated_vertices == (qpGeomVertexData *)NULL) {
|
||||
CDWriter cdataw(((qpGeomVertexData *)this)->_cycler, cdata);
|
||||
((qpGeomVertexData *)this)->make_animated_vertices(cdataw);
|
||||
((qpGeomVertexData *)this)->update_animated_vertices(cdataw, from_app);
|
||||
return cdataw->_animated_vertices;
|
||||
} else {
|
||||
UpdateSeq blend_modified = cdata->_transform_blend_palette->get_modified();
|
||||
if (cdata->_animated_vertices_modified == blend_modified) {
|
||||
// No changes.
|
||||
return cdata->_animated_vertices;
|
||||
}
|
||||
CDWriter cdataw(((qpGeomVertexData *)this)->_cycler, cdata);
|
||||
cdataw->_animated_vertices_modified = blend_modified;
|
||||
((qpGeomVertexData *)this)->update_animated_vertices(cdataw, from_app);
|
||||
return cdataw->_animated_vertices;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexData::bytewise_copy
|
||||
// Access: Private, Static
|
||||
@ -807,9 +801,6 @@ make_animated_vertices(qpGeomVertexData::CDWriter &cdata) {
|
||||
(InternalName::get_transform_blend(), 0, qpGeomVertexDataType::NT_uint16,
|
||||
qpGeomVertexDataType::C_index,
|
||||
min(get_usage_hint(), qpGeomUsageHint::UH_dynamic), false);
|
||||
|
||||
// Now fill it up with the appropriate data.
|
||||
update_animated_vertices(cdata);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -820,7 +811,7 @@ make_animated_vertices(qpGeomVertexData::CDWriter &cdata) {
|
||||
// existing animated_vertices object.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeomVertexData::
|
||||
update_animated_vertices(qpGeomVertexData::CDWriter &cdata) {
|
||||
update_animated_vertices(qpGeomVertexData::CDWriter &cdata, bool from_app) {
|
||||
int num_vertices = get_num_vertices();
|
||||
|
||||
if (gobj_cat.is_debug()) {
|
||||
@ -829,12 +820,16 @@ update_animated_vertices(qpGeomVertexData::CDWriter &cdata) {
|
||||
<< "\n";
|
||||
}
|
||||
|
||||
PStatTimer timer(_this_animate_vertices_pcollector);
|
||||
#ifdef DO_PSTATS
|
||||
PStatCollector &collector = from_app ? _app_char_pcollector : _cull_char_pcollector;
|
||||
PStatTimer timer(collector);
|
||||
#endif
|
||||
|
||||
CPT(TransformBlendPalette) palette = cdata->_transform_blend_palette;
|
||||
nassertv(palette != (TransformBlendPalette *)NULL);
|
||||
|
||||
// Recompute all the blends up front.
|
||||
// Recompute all the blends up front, so we don't have to test each
|
||||
// one for staleness at each vertex.
|
||||
int num_blends = palette->get_num_blends();
|
||||
int bi;
|
||||
for (bi = 0; bi < num_blends; bi++) {
|
||||
@ -843,10 +838,10 @@ update_animated_vertices(qpGeomVertexData::CDWriter &cdata) {
|
||||
|
||||
PT(qpGeomVertexData) new_data = cdata->_animated_vertices;
|
||||
|
||||
// Now go through and apply the scale, copying it to the new data.
|
||||
// Now go through and compute the animation.
|
||||
qpGeomVertexWriter to(new_data, InternalName::get_vertex());
|
||||
qpGeomVertexReader from(this, InternalName::get_vertex());
|
||||
qpGeomVertexReader blendi(this, InternalName::get_transform_blend());
|
||||
qpGeomVertexWriter to(new_data, InternalName::get_vertex());
|
||||
|
||||
if (from.get_data_type()->get_num_values() == 4) {
|
||||
for (int i = 0; i < num_vertices; i++) {
|
||||
|
@ -104,7 +104,7 @@ PUBLISHED:
|
||||
qpGeomVertexDataType::NumericType numeric_type,
|
||||
qpGeomVertexDataType::Contents contents) const;
|
||||
|
||||
CPT(qpGeomVertexData) animate_vertices() const;
|
||||
INLINE CPT(qpGeomVertexData) animate_vertices() const;
|
||||
|
||||
PT(qpGeomVertexData)
|
||||
replace_data_type(const InternalName *name, int num_components,
|
||||
@ -117,6 +117,8 @@ PUBLISHED:
|
||||
void write(ostream &out, int indent_level = 0) const;
|
||||
|
||||
public:
|
||||
INLINE CPT(qpGeomVertexData) animate_vertices_cull() const;
|
||||
|
||||
bool get_array_info(const InternalName *name,
|
||||
const qpGeomVertexArrayData *&array_data,
|
||||
int &num_components,
|
||||
@ -131,6 +133,8 @@ public:
|
||||
static INLINE unsigned int unpack_8888_d(PN_uint32 data);
|
||||
|
||||
private:
|
||||
CPT(qpGeomVertexData) do_animate_vertices(bool from_app) const;
|
||||
|
||||
static void bytewise_copy(unsigned char *to, int to_stride,
|
||||
const unsigned char *from, int from_stride,
|
||||
const qpGeomVertexDataType *from_type,
|
||||
@ -175,14 +179,16 @@ private:
|
||||
private:
|
||||
bool do_set_num_vertices(int n, CDWriter &cdata);
|
||||
void make_animated_vertices(CDWriter &cdata);
|
||||
void update_animated_vertices(CDWriter &cdata);
|
||||
void update_animated_vertices(CDWriter &cdata, bool from_app);
|
||||
|
||||
static PStatCollector _convert_pcollector;
|
||||
static PStatCollector _scale_color_pcollector;
|
||||
static PStatCollector _set_color_pcollector;
|
||||
static PStatCollector _animate_vertices_pcollector;
|
||||
static PStatCollector _app_animation_pcollector;
|
||||
static PStatCollector _cull_animation_pcollector;
|
||||
|
||||
PStatCollector _this_animate_vertices_pcollector;
|
||||
PStatCollector _app_char_pcollector;
|
||||
PStatCollector _cull_char_pcollector;
|
||||
|
||||
public:
|
||||
static void register_with_read_factory();
|
||||
|
@ -331,8 +331,7 @@ set_pointer(int vertex) {
|
||||
nassertv(_data_type != (qpGeomVertexDataType *)NULL);
|
||||
_read_vertex = vertex;
|
||||
CPT(qpGeomVertexArrayData) array_data = _vertex_data->get_array(_array);
|
||||
_data = array_data->get_data();
|
||||
_pointer = _data.p() + _data_type->get_start() + _stride * _read_vertex;
|
||||
_pointer = array_data->get_data() + _data_type->get_start() + _stride * _read_vertex;
|
||||
_num_vertices = array_data->get_num_vertices();
|
||||
}
|
||||
|
||||
@ -345,7 +344,7 @@ set_pointer(int vertex) {
|
||||
INLINE const unsigned char *qpGeomVertexReader::
|
||||
inc_pointer() {
|
||||
nassertr(_read_vertex < _num_vertices, NULL);
|
||||
nassertr(_pointer == _vertex_data->get_array(_array)->get_data().p() + _data_type->get_start() + _stride * _read_vertex, NULL);
|
||||
nassertr(_pointer == _vertex_data->get_array(_array)->get_data() + _data_type->get_start() + _stride * _read_vertex, NULL);
|
||||
|
||||
const unsigned char *orig_pointer = _pointer;
|
||||
_pointer += _stride;
|
||||
|
@ -40,6 +40,22 @@
|
||||
// for each vertex, it is faster to use a different
|
||||
// GeomVertexReader for each data type.
|
||||
//
|
||||
// Note that a GeomVertexReader does not keep a
|
||||
// reference count to the actual vertex data buffer (it
|
||||
// grabs the current data buffer from the GeomVertexData
|
||||
// whenever set_data_type() is called). This means that
|
||||
// it is important not to keep a GeomVertexReader object
|
||||
// around over a long period of time in which the data
|
||||
// buffer is likely to be deallocated; it is intended
|
||||
// for making a quick pass over the data in one session.
|
||||
//
|
||||
// It also means that you should create any
|
||||
// GeomVertexWriters *before* creating GeomVertexReaders
|
||||
// on the same data, since the writer itself might cause
|
||||
// the vertex buffer to be deallocated. Better yet, use
|
||||
// a GeomVertexRewriter if you are going to create both
|
||||
// of them anyway.
|
||||
//
|
||||
// This is part of the experimental Geom rewrite.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA qpGeomVertexReader {
|
||||
@ -88,7 +104,6 @@ private:
|
||||
const qpGeomVertexDataType *_data_type;
|
||||
int _stride;
|
||||
|
||||
CPTA_uchar _data;
|
||||
const unsigned char *_pointer;
|
||||
|
||||
int _start_vertex;
|
||||
|
261
panda/src/gobj/qpgeomVertexRewriter.I
Normal file
261
panda/src/gobj/qpgeomVertexRewriter.I
Normal file
@ -0,0 +1,261 @@
|
||||
// Filename: qpgeomVertexRewriter.I
|
||||
// Created by: drose (28Mar05)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d-general@lists.sourceforge.net .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexRewriter::Constructor
|
||||
// Access: Published
|
||||
// Description: Constructs a new rewriter to process the vertices of
|
||||
// the indicated data object.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE qpGeomVertexRewriter::
|
||||
qpGeomVertexRewriter(qpGeomVertexData *vertex_data) :
|
||||
qpGeomVertexWriter(vertex_data),
|
||||
qpGeomVertexReader(vertex_data)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexRewriter::Constructor
|
||||
// Access: Published
|
||||
// Description: Constructs a new rewriter to process the vertices of
|
||||
// the indicated data object. This flavor creates the
|
||||
// rewriter specifically to process the named data type.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE qpGeomVertexRewriter::
|
||||
qpGeomVertexRewriter(qpGeomVertexData *vertex_data, const string &name) :
|
||||
qpGeomVertexWriter(vertex_data),
|
||||
qpGeomVertexReader(vertex_data)
|
||||
{
|
||||
set_data_type(name);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexRewriter::Constructor
|
||||
// Access: Published
|
||||
// Description: Constructs a new rewriter to process the vertices of
|
||||
// the indicated data object. This flavor creates the
|
||||
// rewriter specifically to process the named data type.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE qpGeomVertexRewriter::
|
||||
qpGeomVertexRewriter(qpGeomVertexData *vertex_data, const InternalName *name) :
|
||||
qpGeomVertexWriter(vertex_data),
|
||||
qpGeomVertexReader(vertex_data)
|
||||
{
|
||||
set_data_type(name);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexRewriter::Destructor
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE qpGeomVertexRewriter::
|
||||
~qpGeomVertexRewriter() {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexRewriter::get_vertex_data
|
||||
// Access: Published
|
||||
// Description: Returns the vertex data object that the
|
||||
// rewriter is processing.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE qpGeomVertexData *qpGeomVertexRewriter::
|
||||
get_vertex_data() const {
|
||||
nassertr(qpGeomVertexWriter::get_vertex_data() ==
|
||||
qpGeomVertexReader::get_vertex_data(), NULL);
|
||||
return qpGeomVertexWriter::get_vertex_data();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexRewriter::set_data_type
|
||||
// Access: Published
|
||||
// Description: Sets up the rewriter to use the nth data type of the
|
||||
// GeomVertexFormat, numbering from 0.
|
||||
//
|
||||
// This also resets both the read and write vertex
|
||||
// numbers to the start vertex (the same value passed to
|
||||
// a previous call to set_vertex(), or 0 if set_vertex()
|
||||
// was never called.)
|
||||
//
|
||||
// The return value is true if the data type is valid,
|
||||
// false otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool qpGeomVertexRewriter::
|
||||
set_data_type(int data_type) {
|
||||
// It's important to invoke the writer first, then the reader. See
|
||||
// set_vertex().
|
||||
qpGeomVertexWriter::set_data_type(data_type);
|
||||
return qpGeomVertexReader::set_data_type(data_type);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexRewriter::set_data_type
|
||||
// Access: Published
|
||||
// Description: Sets up the rewriter to use the data type with the
|
||||
// indicated name.
|
||||
//
|
||||
// This also resets both the read and write vertex
|
||||
// numbers to the start vertex (the same value passed to
|
||||
// a previous call to set_vertex(), or 0 if set_vertex()
|
||||
// was never called.)
|
||||
//
|
||||
// The return value is true if the data type is valid,
|
||||
// false otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool qpGeomVertexRewriter::
|
||||
set_data_type(const string &name) {
|
||||
return set_data_type(InternalName::make(name));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexRewriter::set_data_type
|
||||
// Access: Published
|
||||
// Description: Sets up the rewriter to use the data type with the
|
||||
// indicated name.
|
||||
//
|
||||
// This also resets both the read and write vertex
|
||||
// numbers to the start vertex (the same value passed to
|
||||
// a previous call to set_vertex(), or 0 if set_vertex()
|
||||
// was never called.)
|
||||
//
|
||||
// The return value is true if the data type is valid,
|
||||
// false otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool qpGeomVertexRewriter::
|
||||
set_data_type(const InternalName *name) {
|
||||
// It's important to invoke the writer first, then the reader. See
|
||||
// set_vertex().
|
||||
qpGeomVertexWriter::set_data_type(name);
|
||||
return qpGeomVertexReader::set_data_type(name);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexRewriter::set_data_type
|
||||
// Access: Published
|
||||
// Description: Sets up the rewriter to use the indicated data_type
|
||||
// description on the given array.
|
||||
//
|
||||
// This also resets both the read and write vertex
|
||||
// numbers to the start vertex (the same value passed to
|
||||
// a previous call to set_vertex(), or 0 if set_vertex()
|
||||
// was never called.)
|
||||
//
|
||||
// The return value is true if the data type is valid,
|
||||
// false otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool qpGeomVertexRewriter::
|
||||
set_data_type(int array, const qpGeomVertexDataType *data_type) {
|
||||
// It's important to invoke the writer first, then the reader. See
|
||||
// set_vertex().
|
||||
qpGeomVertexWriter::set_data_type(array, data_type);
|
||||
return qpGeomVertexReader::set_data_type(array, data_type);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexRewriter::has_data_type
|
||||
// Access: Published
|
||||
// Description: Returns true if a valid data type has been
|
||||
// successfully set, or false if the data type does not
|
||||
// exist.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool qpGeomVertexRewriter::
|
||||
has_data_type() const {
|
||||
nassertr(qpGeomVertexWriter::get_data_type() ==
|
||||
qpGeomVertexReader::get_data_type(), false);
|
||||
return qpGeomVertexWriter::has_data_type();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexRewriter::get_array
|
||||
// Access: Published
|
||||
// Description: Returns the array index containing the data type that
|
||||
// the rewriter is working on.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int qpGeomVertexRewriter::
|
||||
get_array() const {
|
||||
nassertr(qpGeomVertexWriter::get_array() ==
|
||||
qpGeomVertexReader::get_array(), -1);
|
||||
return qpGeomVertexWriter::get_array();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexRewriter::get_data_type
|
||||
// Access: Published
|
||||
// Description: Returns the description of the data type that the
|
||||
// rewriter is working on.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const qpGeomVertexDataType *qpGeomVertexRewriter::
|
||||
get_data_type() const {
|
||||
nassertr(qpGeomVertexWriter::get_data_type() ==
|
||||
qpGeomVertexReader::get_data_type(), NULL);
|
||||
return qpGeomVertexWriter::get_data_type();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexRewriter::set_vertex
|
||||
// Access: Published
|
||||
// Description: Sets the start, write, and write index to the
|
||||
// indicated value. The rewriter will begin traversing
|
||||
// from the given vertex.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void qpGeomVertexRewriter::
|
||||
set_vertex(int vertex) {
|
||||
// It's important to invoke the Writer first, since that might force
|
||||
// a recopy of the array, which might invalidate the pointer already
|
||||
// stored by the Reader if we invoked the Reader first.
|
||||
qpGeomVertexWriter::set_vertex(vertex);
|
||||
qpGeomVertexReader::set_vertex(vertex);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexRewriter::get_start_vertex
|
||||
// Access: Published
|
||||
// Description: Returns the vertex index at which the rewriter
|
||||
// started. It will return to this vertex if you reset
|
||||
// the current data_type.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int qpGeomVertexRewriter::
|
||||
get_start_vertex() const {
|
||||
nassertr(qpGeomVertexWriter::get_start_vertex() ==
|
||||
qpGeomVertexReader::get_start_vertex(), 0);
|
||||
return qpGeomVertexWriter::get_start_vertex();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexRewriter::get_num_vertices
|
||||
// Access: Published
|
||||
// Description: Returns the number of vertices in the vertex data.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int qpGeomVertexRewriter::
|
||||
get_num_vertices() const {
|
||||
nassertr(qpGeomVertexWriter::get_num_vertices() ==
|
||||
qpGeomVertexReader::get_num_vertices(), 0);
|
||||
return qpGeomVertexWriter::get_num_vertices();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexRewriter::is_at_end
|
||||
// Access: Published
|
||||
// Description: Returns true if the reader or writer is currently at
|
||||
// the end of the list of vertices, false otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool qpGeomVertexRewriter::
|
||||
is_at_end() const {
|
||||
return qpGeomVertexWriter::is_at_end() || qpGeomVertexReader::is_at_end();
|
||||
}
|
19
panda/src/gobj/qpgeomVertexRewriter.cxx
Normal file
19
panda/src/gobj/qpgeomVertexRewriter.cxx
Normal file
@ -0,0 +1,19 @@
|
||||
// Filename: qpgeomVertexRewriter.cxx
|
||||
// Created by: drose (28Mar05)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d-general@lists.sourceforge.net .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "qpgeomVertexRewriter.h"
|
73
panda/src/gobj/qpgeomVertexRewriter.h
Normal file
73
panda/src/gobj/qpgeomVertexRewriter.h
Normal file
@ -0,0 +1,73 @@
|
||||
// Filename: qpgeomVertexRewriter.h
|
||||
// Created by: drose (28Mar05)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d-general@lists.sourceforge.net .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef qpGEOMVERTEXREWRITER_H
|
||||
#define qpGEOMVERTEXREWRITER_H
|
||||
|
||||
#include "pandabase.h"
|
||||
#include "qpgeomVertexReader.h"
|
||||
#include "qpgeomVertexWriter.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : qpGeomVertexRewriter
|
||||
// Description : This object provides the functionality of both a
|
||||
// GeomVertexReader and a GeomVertexWriter, combined
|
||||
// together into one convenient package. It is designed
|
||||
// for making a single pass over a GeomVertexData
|
||||
// object, modifying vertices as it goes.
|
||||
//
|
||||
// Although it doesn't provide any real performance
|
||||
// benefit over using a separate reader and writer
|
||||
// object, it should probably be used in preference to
|
||||
// separate objects, because it makes an effort to
|
||||
// manage the reference counts properly between the
|
||||
// reader and the writer to avoid accidentally
|
||||
// dereferencing either array while recopying.
|
||||
//
|
||||
// This is part of the experimental Geom rewrite.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA qpGeomVertexRewriter : public qpGeomVertexWriter, public qpGeomVertexReader {
|
||||
PUBLISHED:
|
||||
INLINE qpGeomVertexRewriter(qpGeomVertexData *vertex_data);
|
||||
INLINE qpGeomVertexRewriter(qpGeomVertexData *vertex_data,
|
||||
const string &name);
|
||||
INLINE qpGeomVertexRewriter(qpGeomVertexData *vertex_data,
|
||||
const InternalName *name);
|
||||
INLINE ~qpGeomVertexRewriter();
|
||||
|
||||
INLINE qpGeomVertexData *get_vertex_data() const;
|
||||
|
||||
INLINE bool set_data_type(int data_type);
|
||||
INLINE bool set_data_type(const string &name);
|
||||
INLINE bool set_data_type(const InternalName *name);
|
||||
INLINE bool set_data_type(int array, const qpGeomVertexDataType *data_type);
|
||||
|
||||
INLINE bool has_data_type() const;
|
||||
INLINE int get_array() const;
|
||||
INLINE const qpGeomVertexDataType *get_data_type() const;
|
||||
|
||||
INLINE void set_vertex(int vertex);
|
||||
|
||||
INLINE int get_start_vertex() const;
|
||||
INLINE int get_num_vertices() const;
|
||||
INLINE bool is_at_end() const;
|
||||
};
|
||||
|
||||
#include "qpgeomVertexRewriter.I"
|
||||
|
||||
#endif
|
@ -500,8 +500,7 @@ set_pointer(int vertex) {
|
||||
nassertv(_data_type != (qpGeomVertexDataType *)NULL);
|
||||
_write_vertex = vertex;
|
||||
PT(qpGeomVertexArrayData) array_data = _vertex_data->modify_array(_array);
|
||||
_data = array_data->modify_data();
|
||||
_pointer = _data.p() + _data_type->get_start() + _stride * _write_vertex;
|
||||
_pointer = array_data->modify_data() + _data_type->get_start() + _stride * _write_vertex;
|
||||
_num_vertices = array_data->get_num_vertices();
|
||||
}
|
||||
|
||||
@ -514,7 +513,7 @@ set_pointer(int vertex) {
|
||||
INLINE unsigned char *qpGeomVertexWriter::
|
||||
inc_pointer() {
|
||||
nassertr(_write_vertex < _num_vertices, NULL);
|
||||
nassertr(_pointer == _vertex_data->get_array(_array)->get_data().p() + _data_type->get_start() + _stride * _write_vertex, NULL);
|
||||
nassertr(_pointer == _vertex_data->get_array(_array)->get_data() + _data_type->get_start() + _stride * _write_vertex, NULL);
|
||||
|
||||
unsigned char *orig_pointer = _pointer;
|
||||
_pointer += _stride;
|
||||
|
@ -53,6 +53,21 @@
|
||||
// vertex, it is faster to use a different
|
||||
// GeomVertexWriter for each data type.
|
||||
//
|
||||
// Note that, like a GeomVertexReader, a
|
||||
// GeomVertexWriter does not keep a reference count to
|
||||
// the actual vertex data buffer. This means that it is
|
||||
// important not to keep a GeomVertexWriter object
|
||||
// around over a long period of time in which the data
|
||||
// buffer is likely to be deallocated; it is intended
|
||||
// for making a quick pass over the data in one session.
|
||||
//
|
||||
// It also means that you should create any
|
||||
// GeomVertexWriters *before* creating GeomVertexReaders
|
||||
// on the same data, since the writer itself might cause
|
||||
// the vertex buffer to be deallocated. Better yet, use
|
||||
// a GeomVertexRewriter if you are going to create both
|
||||
// of them anyway.
|
||||
//
|
||||
// This is part of the experimental Geom rewrite.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA qpGeomVertexWriter {
|
||||
@ -115,7 +130,6 @@ private:
|
||||
const qpGeomVertexDataType *_data_type;
|
||||
int _stride;
|
||||
|
||||
PTA_uchar _data;
|
||||
unsigned char *_pointer;
|
||||
|
||||
int _start_vertex;
|
||||
|
@ -38,7 +38,7 @@ munge_geom(const qpGeomMunger *munger) {
|
||||
_munger = munger;
|
||||
CPT(qpGeom) qpgeom = DCAST(qpGeom, _geom);
|
||||
qpgeom->munge_geom(munger, qpgeom, _munged_data);
|
||||
_munged_data = _munged_data->animate_vertices();
|
||||
_munged_data = _munged_data->animate_vertices_cull();
|
||||
_geom = qpgeom;
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user