diff --git a/panda/src/char/Sources.pp b/panda/src/char/Sources.pp index bf05a8117c..bf26662325 100644 --- a/panda/src/char/Sources.pp +++ b/panda/src/char/Sources.pp @@ -14,21 +14,24 @@ characterJoint.h characterJointBundle.I \ characterJointBundle.h characterSlider.h computedVertices.I \ computedVertices.h computedVerticesMorph.I \ - computedVerticesMorph.h config_char.h dynamicVertices.h + computedVerticesMorph.h config_char.h dynamicVertices.h \ + jointVertexTransform.I jointVertexTransform.h #define INCLUDED_SOURCES \ character.cxx \ characterJoint.cxx characterJointBundle.cxx \ characterSlider.cxx computedVertices.cxx \ computedVerticesMorph.cxx config_char.cxx \ - dynamicVertices.cxx + dynamicVertices.cxx \ + jointVertexTransform.cxx #define INSTALL_HEADERS \ character.I character.h \ characterJoint.h characterJointBundle.I \ characterJointBundle.h characterSlider.h computedVertices.I \ computedVertices.h computedVerticesMorph.I computedVerticesMorph.h \ - config_char.h dynamicVertices.h + config_char.h dynamicVertices.h \ + jointVertexTransform.I jointVertexTransform.h #define IGATESCAN all diff --git a/panda/src/char/char_composite2.cxx b/panda/src/char/char_composite2.cxx index b6bfd490c4..b57997cefc 100644 --- a/panda/src/char/char_composite2.cxx +++ b/panda/src/char/char_composite2.cxx @@ -3,4 +3,5 @@ #include "computedVertices.cxx" #include "computedVerticesMorph.cxx" #include "dynamicVertices.cxx" +#include "jointVertexTransform.cxx" diff --git a/panda/src/char/characterJoint.cxx b/panda/src/char/characterJoint.cxx index 3f3c0ef3a1..67acbb33dc 100644 --- a/panda/src/char/characterJoint.cxx +++ b/panda/src/char/characterJoint.cxx @@ -18,6 +18,7 @@ #include "characterJoint.h" #include "config_char.h" +#include "jointVertexTransform.h" #include "datagram.h" #include "datagramIterator.h" @@ -68,6 +69,16 @@ CharacterJoint(PartGroup *parent, const string &name, _initial_net_transform_inverse = invert(_net_transform); } +//////////////////////////////////////////////////////////////////// +// Function: CharacterJoint::Destructor +// Access: Public, Virtual +// Description: +//////////////////////////////////////////////////////////////////// +CharacterJoint:: +~CharacterJoint() { + nassertv(_vertex_transforms.empty()); +} + //////////////////////////////////////////////////////////////////// // Function: CharacterJoint::make_copy // Access: Public, Virtual @@ -118,15 +129,25 @@ update_internals(PartGroup *parent, bool self_changed, bool parent_changed) { } } - if (net_changed && !_net_transform_nodes.empty()) { - CPT(TransformState) t = TransformState::make_mat(_net_transform); + if (net_changed) { + if (!_net_transform_nodes.empty()) { + CPT(TransformState) t = TransformState::make_mat(_net_transform); + + NodeList::iterator ai; + ai = _net_transform_nodes.begin(); + while (ai != _net_transform_nodes.end()) { + PandaNode *node = *ai; + node->set_transform(t); + ++ai; + } + } - NodeList::iterator ai; - ai = _net_transform_nodes.begin(); - while (ai != _net_transform_nodes.end()) { - PandaNode *node = *ai; - node->set_transform(t); - ++ai; + // Also tell our related JointVertexTransforms that they now need + // to recompute themselves. + VertexTransforms::iterator vti; + for (vti = _vertex_transforms.begin(); vti != _vertex_transforms.end(); ++vti) { + (*vti)->_matrix_stale = true; + (*vti)->mark_modified(); } } @@ -261,6 +282,18 @@ get_transform(LMatrix4f &transform) const { transform = _value; } +//////////////////////////////////////////////////////////////////// +// Function: CharacterJoint::get_net_transform +// Access: Published +// Description: Copies the joint's current net transform (composed +// from the root of the character joint hierarchy) into +// the indicated matrix. +//////////////////////////////////////////////////////////////////// +void CharacterJoint:: +get_net_transform(LMatrix4f &transform) const { + transform = _net_transform; +} + //////////////////////////////////////////////////////////////////// // Function: CharacterJoint::write_datagram // Access: Public diff --git a/panda/src/char/characterJoint.h b/panda/src/char/characterJoint.h index c8b699fb40..d8dee00c3b 100644 --- a/panda/src/char/characterJoint.h +++ b/panda/src/char/characterJoint.h @@ -24,6 +24,8 @@ #include "movingPartMatrix.h" #include "pandaNode.h" +class JointVertexTransform; + //////////////////////////////////////////////////////////////////// // Class : CharacterJoint // Description : This represents one joint of the character's @@ -37,6 +39,7 @@ protected: public: CharacterJoint(PartGroup *parent, const string &name, const LMatrix4f &initial_value); + virtual ~CharacterJoint(); virtual PartGroup *make_copy() const; @@ -55,12 +58,16 @@ PUBLISHED: void clear_local_transforms(); void get_transform(LMatrix4f &transform) const; + void get_net_transform(LMatrix4f &transform) const; private: typedef pset< PT(PandaNode) > NodeList; NodeList _net_transform_nodes; NodeList _local_transform_nodes; + typedef pset VertexTransforms; + VertexTransforms _vertex_transforms; + public: static void register_with_read_factory(void); virtual void write_datagram(BamWriter* manager, Datagram &me); @@ -104,6 +111,7 @@ private: static TypeHandle _type_handle; friend class Character; + friend class JointVertexTransform; }; #endif diff --git a/panda/src/char/config_char.cxx b/panda/src/char/config_char.cxx index 422ec994eb..a1890dedf9 100644 --- a/panda/src/char/config_char.cxx +++ b/panda/src/char/config_char.cxx @@ -24,6 +24,7 @@ #include "characterSlider.h" #include "computedVertices.h" #include "dynamicVertices.h" +#include "jointVertexTransform.h" #include "dconfig.h" #include "lmatrix4.h" @@ -65,6 +66,7 @@ init_libchar() { CharacterSlider::init_type(); ComputedVertices::init_type(); DynamicVertices::init_type(); + JointVertexTransform::init_type(); // This isn't defined in this package, but it *is* essential that it // be initialized. We have to do it explicitly here since template @@ -79,5 +81,6 @@ init_libchar() { CharacterJointBundle::register_with_read_factory(); CharacterSlider::register_with_read_factory(); ComputedVertices::register_with_read_factory(); + JointVertexTransform::register_with_read_factory(); } diff --git a/panda/src/char/jointVertexTransform.I b/panda/src/char/jointVertexTransform.I new file mode 100644 index 0000000000..b09426f3bf --- /dev/null +++ b/panda/src/char/jointVertexTransform.I @@ -0,0 +1,40 @@ +// Filename: jointVertexTransform.I +// Created by: drose (24Mar05) +// +//////////////////////////////////////////////////////////////////// +// +// 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: JointVertexTransform::get_from +// Access: Published +// Description: Returns the joint whose coordinate space this object +// moves vertices from. +//////////////////////////////////////////////////////////////////// +INLINE const CharacterJoint *JointVertexTransform:: +get_from() const { + return _from; +} + +//////////////////////////////////////////////////////////////////// +// Function: JointVertexTransform::get_to +// Access: Published +// Description: Returns the joint whose coordinate space this object +// moves vertices into. +//////////////////////////////////////////////////////////////////// +INLINE const CharacterJoint *JointVertexTransform:: +get_to() const { + return _to; +} diff --git a/panda/src/char/jointVertexTransform.cxx b/panda/src/char/jointVertexTransform.cxx new file mode 100644 index 0000000000..3f2104f9bb --- /dev/null +++ b/panda/src/char/jointVertexTransform.cxx @@ -0,0 +1,161 @@ +// Filename: jointVertexTransform.cxx +// Created by: drose (24Mar05) +// +//////////////////////////////////////////////////////////////////// +// +// 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 "jointVertexTransform.h" +#include "datagram.h" +#include "datagramIterator.h" +#include "bamReader.h" +#include "bamWriter.h" + +TypeHandle JointVertexTransform::_type_handle; + +//////////////////////////////////////////////////////////////////// +// Function: JointVertexTransform::Default Constructor +// Access: Private +// Description: Constructs an invalid object; used only by the bam +// loader. +//////////////////////////////////////////////////////////////////// +JointVertexTransform:: +JointVertexTransform() : + _matrix_stale(true) +{ +} + +//////////////////////////////////////////////////////////////////// +// Function: JointVertexTransform::Constructor +// Access: Published +// Description: Constructs a new object that converts vertices from +// the indicated joint's coordinate space, into the +// other indicated joint's space. +//////////////////////////////////////////////////////////////////// +JointVertexTransform:: +JointVertexTransform(CharacterJoint *from, CharacterJoint *to) : + _from(from), + _to(to), + _matrix_stale(true) +{ + // Tell the "to" joint that we need to be informed when it moves. + _to->_vertex_transforms.insert(this); +} + +//////////////////////////////////////////////////////////////////// +// Function: JointVertexTransform::Destructor +// Access: Published, Virtual +// Description: +//////////////////////////////////////////////////////////////////// +JointVertexTransform:: +~JointVertexTransform() { + // Tell the "to" joint to stop informing us about its motion. + _to->_vertex_transforms.erase(this); +} + +//////////////////////////////////////////////////////////////////// +// Function: JointVertexTransform::get_matrix +// Access: Published, Virtual +// Description: Stores the transform's matrix in the indicated object. +//////////////////////////////////////////////////////////////////// +void JointVertexTransform:: +get_matrix(LMatrix4f &matrix) const { + if (_matrix_stale) { + ((JointVertexTransform *)this)->_matrix = + _from->_initial_net_transform_inverse * + _to->_net_transform; + ((JointVertexTransform *)this)->_matrix_stale = false; + } + + matrix = _matrix; +} + +//////////////////////////////////////////////////////////////////// +// Function: JointVertexTransform::output +// Access: Published, Virtual +// Description: +//////////////////////////////////////////////////////////////////// +void JointVertexTransform:: +output(ostream &out) const { + out << _to->get_name(); +} + + +//////////////////////////////////////////////////////////////////// +// Function: JointVertexTransform::register_with_read_factory +// Access: Public, Static +// Description: Tells the BamReader how to create objects of type +// JointVertexTransform. +//////////////////////////////////////////////////////////////////// +void JointVertexTransform:: +register_with_read_factory() { + BamReader::get_factory()->register_factory(get_class_type(), make_from_bam); +} + +//////////////////////////////////////////////////////////////////// +// Function: JointVertexTransform::write_datagram +// Access: Public, Virtual +// Description: Writes the contents of this object to the datagram +// for shipping out to a Bam file. +//////////////////////////////////////////////////////////////////// +void JointVertexTransform:: +write_datagram(BamWriter *manager, Datagram &dg) { + VertexTransform::write_datagram(manager, dg); +} + +//////////////////////////////////////////////////////////////////// +// Function: JointVertexTransform::complete_pointers +// Access: Public, Virtual +// Description: Receives an array of pointers, one for each time +// manager->read_pointer() was called in fillin(). +// Returns the number of pointers processed. +//////////////////////////////////////////////////////////////////// +int JointVertexTransform:: +complete_pointers(TypedWritable **p_list, BamReader *manager) { + int pi = VertexTransform::complete_pointers(p_list, manager); + + return pi; +} + +//////////////////////////////////////////////////////////////////// +// Function: JointVertexTransform::make_from_bam +// Access: Protected, Static +// Description: This function is called by the BamReader's factory +// when a new object of type JointVertexTransform is encountered +// in the Bam file. It should create the JointVertexTransform +// and extract its information from the file. +//////////////////////////////////////////////////////////////////// +TypedWritable *JointVertexTransform:: +make_from_bam(const FactoryParams ¶ms) { + JointVertexTransform *object = new JointVertexTransform; + DatagramIterator scan; + BamReader *manager; + + parse_params(params, scan, manager); + object->fillin(scan, manager); + + return object; +} + +//////////////////////////////////////////////////////////////////// +// Function: JointVertexTransform::fillin +// Access: Protected +// Description: This internal function is called by make_from_bam to +// read in all of the relevant data from the BamFile for +// the new JointVertexTransform. +//////////////////////////////////////////////////////////////////// +void JointVertexTransform:: +fillin(DatagramIterator &scan, BamReader *manager) { + VertexTransform::fillin(scan, manager); +} diff --git a/panda/src/char/jointVertexTransform.h b/panda/src/char/jointVertexTransform.h new file mode 100644 index 0000000000..2ea97473e3 --- /dev/null +++ b/panda/src/char/jointVertexTransform.h @@ -0,0 +1,91 @@ +// Filename: jointVertexTransform.h +// Created by: drose (24Mar05) +// +//////////////////////////////////////////////////////////////////// +// +// 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 JOINTVERTEXTRANSFORM_H +#define JOINTVERTEXTRANSFORM_H + +#include "pandabase.h" +#include "characterJoint.h" +#include "vertexTransform.h" +#include "pointerTo.h" + +//////////////////////////////////////////////////////////////////// +// Class : JointVertexTransform +// Description : This is a specialization on VertexTransform that +// returns the relative transform from one joint's +// initial position to another joint's (or possibly the +// same joint's) current position. It is used to +// implement soft-skinned vertices for an animated +// character. +// +// This is part of the experimental Geom rewrite. +//////////////////////////////////////////////////////////////////// +class EXPCL_PANDA JointVertexTransform : public VertexTransform { +private: + JointVertexTransform(); + +PUBLISHED: + JointVertexTransform(CharacterJoint *from, CharacterJoint *to); + virtual ~JointVertexTransform(); + + INLINE const CharacterJoint *get_from() const; + INLINE const CharacterJoint *get_to() const; + + virtual void get_matrix(LMatrix4f &matrix) const; + + virtual void output(ostream &out) const; + +private: + PT(CharacterJoint) _from; + PT(CharacterJoint) _to; + + LMatrix4f _matrix; + bool _matrix_stale; + +public: + static void register_with_read_factory(); + virtual void write_datagram(BamWriter *manager, Datagram &dg); + virtual int complete_pointers(TypedWritable **plist, BamReader *manager); + +protected: + static TypedWritable *make_from_bam(const FactoryParams ¶ms); + void fillin(DatagramIterator &scan, BamReader *manager); + +public: + static TypeHandle get_class_type() { + return _type_handle; + } + static void init_type() { + VertexTransform::init_type(); + register_type(_type_handle, "JointVertexTransform", + VertexTransform::get_class_type()); + } + virtual TypeHandle get_type() const { + return get_class_type(); + } + virtual TypeHandle force_init_type() {init_type(); return get_class_type();} + +private: + static TypeHandle _type_handle; + + friend class CharacterJoint; +}; + +#include "jointVertexTransform.I" + +#endif diff --git a/panda/src/egg/eggVertexPool.cxx b/panda/src/egg/eggVertexPool.cxx index 7cb885670c..1896d10594 100644 --- a/panda/src/egg/eggVertexPool.cxx +++ b/panda/src/egg/eggVertexPool.cxx @@ -179,6 +179,20 @@ get_highest_index() const { return _highest_index; } +//////////////////////////////////////////////////////////////////// +// Function: EggVertexPool::set_highest_index +// Access: Public +// Description: Artificially changes the "highest index number", so +// that a newly created vertex will begin at this number +// plus 1. This can be used to default a vertex pool to +// start counting at 1 (or any other index number), +// instead of the default of 0. Use with caution. +//////////////////////////////////////////////////////////////////// +void EggVertexPool:: +set_highest_index(int highest_index) { + _highest_index = highest_index; +} + //////////////////////////////////////////////////////////////////// // Function: EggVertexPool::get_num_dimensions // Access: Public diff --git a/panda/src/egg/eggVertexPool.h b/panda/src/egg/eggVertexPool.h index 4b9ba04cdc..bde4db7376 100644 --- a/panda/src/egg/eggVertexPool.h +++ b/panda/src/egg/eggVertexPool.h @@ -91,6 +91,7 @@ PUBLISHED: // Returns 0 if the pool is empty. int get_highest_index() const; + void set_highest_index(int highest_index); int get_num_dimensions() const; bool has_normals() const; diff --git a/panda/src/egg/parser.yxx b/panda/src/egg/parser.yxx index ac4bbafede..1bf46e2d77 100644 --- a/panda/src/egg/parser.yxx +++ b/panda/src/egg/parser.yxx @@ -791,10 +791,14 @@ vertex_pool: if (pool->has_defined_vertices()) { eggyywarning("Duplicate vertex pool name " + name); pool = new EggVertexPool(name); + // The egg syntax starts counting at 1 by convention. + pool->set_highest_index(0); vertex_pools[name] = pool; } } else { pool = new EggVertexPool(name); + // The egg syntax starts counting at 1 by convention. + pool->set_highest_index(0); vertex_pools[name] = pool; } @@ -2623,6 +2627,8 @@ vertex_pool_name: if (vpi == vertex_pools.end()) { // This will become a forward reference. EggVertexPool *pool = new EggVertexPool(name); + // The egg syntax starts counting at 1 by convention. + pool->set_highest_index(0); vertex_pools[name] = pool; $$ = pool; } else { diff --git a/panda/src/gobj/qpgeomVertexData.cxx b/panda/src/gobj/qpgeomVertexData.cxx index 609272edd9..a30652b6b5 100644 --- a/panda/src/gobj/qpgeomVertexData.cxx +++ b/panda/src/gobj/qpgeomVertexData.cxx @@ -1173,7 +1173,7 @@ make_computed_vertices(qpGeomVertexData::CDWriter &cdata) { // array. cdata->_computed_vertices = replace_data_type (InternalName::get_transform_blend(), 0, qpGeomVertexDataType::NT_uint16, - qpGeomUsageHint::UH_dynamic, false); + min(get_usage_hint(), qpGeomUsageHint::UH_dynamic), false); // Now fill it up with the appropriate data. update_computed_vertices(cdata); diff --git a/panda/src/gobj/userVertexTransform.cxx b/panda/src/gobj/userVertexTransform.cxx index c9db457407..f2cc6832c1 100644 --- a/panda/src/gobj/userVertexTransform.cxx +++ b/panda/src/gobj/userVertexTransform.cxx @@ -36,7 +36,7 @@ UserVertexTransform(const string &name) : //////////////////////////////////////////////////////////////////// // Function: UserVertexTransform::get_matrix // Access: Published, Virtual -// Description: Stores the transform's matrix in the indicated value. +// Description: Stores the transform's matrix in the indicated object. //////////////////////////////////////////////////////////////////// void UserVertexTransform:: get_matrix(LMatrix4f &matrix) const { @@ -83,7 +83,7 @@ register_with_read_factory() { //////////////////////////////////////////////////////////////////// void UserVertexTransform:: write_datagram(BamWriter *manager, Datagram &dg) { - TypedWritable::write_datagram(manager, dg); + VertexTransform::write_datagram(manager, dg); manager->write_cdata(dg, _cycler); } @@ -117,7 +117,7 @@ make_from_bam(const FactoryParams ¶ms) { //////////////////////////////////////////////////////////////////// void UserVertexTransform:: fillin(DatagramIterator &scan, BamReader *manager) { - TypedWritable::fillin(scan, manager); + VertexTransform::fillin(scan, manager); manager->read_cdata(scan, _cycler); }