From bf68f75f917975de50cadd4dec47706c65433961 Mon Sep 17 00:00:00 2001 From: David Rose Date: Tue, 29 Mar 2005 01:12:09 +0000 Subject: [PATCH] egg loader defines morphs --- panda/src/char/Sources.pp | 12 +- panda/src/char/char_composite2.cxx | 1 + panda/src/char/characterSlider.cxx | 34 +++++ panda/src/char/characterSlider.h | 13 ++ panda/src/char/characterVertexSlider.I | 29 +++++ panda/src/char/characterVertexSlider.cxx | 142 ++++++++++++++++++++ panda/src/char/characterVertexSlider.h | 81 ++++++++++++ panda/src/char/config_char.cxx | 3 + panda/src/egg2pg/characterMaker.cxx | 21 +++ panda/src/egg2pg/characterMaker.h | 5 + panda/src/egg2pg/eggLoader.cxx | 158 ++++++++++++++++++++--- panda/src/egg2pg/eggLoader.h | 5 + panda/src/gobj/internalName.I | 13 ++ panda/src/gobj/internalName.h | 1 + panda/src/gobj/qpgeomVertexArrayFormat.I | 11 ++ panda/src/gobj/qpgeomVertexArrayFormat.h | 1 + panda/src/gobj/qpgeomVertexFormat.I | 11 ++ panda/src/gobj/qpgeomVertexFormat.h | 1 + panda/src/gobj/sliderTable.I | 22 ++++ panda/src/gobj/sliderTable.h | 2 + 20 files changed, 543 insertions(+), 23 deletions(-) create mode 100644 panda/src/char/characterVertexSlider.I create mode 100644 panda/src/char/characterVertexSlider.cxx create mode 100644 panda/src/char/characterVertexSlider.h diff --git a/panda/src/char/Sources.pp b/panda/src/char/Sources.pp index bf26662325..8342216cbd 100644 --- a/panda/src/char/Sources.pp +++ b/panda/src/char/Sources.pp @@ -12,7 +12,9 @@ #define SOURCES \ character.I character.h \ characterJoint.h characterJointBundle.I \ - characterJointBundle.h characterSlider.h computedVertices.I \ + characterJointBundle.h characterSlider.h \ + characterVertexSlider.I characterVertexSlider.h \ + computedVertices.I \ computedVertices.h computedVerticesMorph.I \ computedVerticesMorph.h config_char.h dynamicVertices.h \ jointVertexTransform.I jointVertexTransform.h @@ -20,7 +22,9 @@ #define INCLUDED_SOURCES \ character.cxx \ characterJoint.cxx characterJointBundle.cxx \ - characterSlider.cxx computedVertices.cxx \ + characterSlider.cxx \ + characterVertexSlider.cxx \ + computedVertices.cxx \ computedVerticesMorph.cxx config_char.cxx \ dynamicVertices.cxx \ jointVertexTransform.cxx @@ -28,7 +32,9 @@ #define INSTALL_HEADERS \ character.I character.h \ characterJoint.h characterJointBundle.I \ - characterJointBundle.h characterSlider.h computedVertices.I \ + characterJointBundle.h characterSlider.h \ + characterVertexSlider.I characterVertexSlider.h \ + computedVertices.I \ computedVertices.h computedVerticesMorph.I computedVerticesMorph.h \ config_char.h dynamicVertices.h \ jointVertexTransform.I jointVertexTransform.h diff --git a/panda/src/char/char_composite2.cxx b/panda/src/char/char_composite2.cxx index b57997cefc..f95773fee7 100644 --- a/panda/src/char/char_composite2.cxx +++ b/panda/src/char/char_composite2.cxx @@ -1,5 +1,6 @@ #include "characterSlider.cxx" +#include "characterVertexSlider.cxx" #include "computedVertices.cxx" #include "computedVerticesMorph.cxx" #include "dynamicVertices.cxx" diff --git a/panda/src/char/characterSlider.cxx b/panda/src/char/characterSlider.cxx index e5252bda97..a4b18fce6f 100644 --- a/panda/src/char/characterSlider.cxx +++ b/panda/src/char/characterSlider.cxx @@ -17,6 +17,7 @@ //////////////////////////////////////////////////////////////////// #include "characterSlider.h" +#include "characterVertexSlider.h" #include "datagram.h" #include "datagramIterator.h" #include "bamReader.h" @@ -54,6 +55,16 @@ CharacterSlider(PartGroup *parent, const string &name) : MovingPartScalar(parent, name) { } +//////////////////////////////////////////////////////////////////// +// Function: CharacterSlider::Destructor +// Access: Public, Virtual +// Description: +//////////////////////////////////////////////////////////////////// +CharacterSlider:: +~CharacterSlider() { + nassertv(_vertex_sliders.empty()); +} + //////////////////////////////////////////////////////////////////// // Function: CharacterSlider::make_copy // Access: Public, Virtual @@ -65,6 +76,29 @@ make_copy() const { return new CharacterSlider(*this); } +//////////////////////////////////////////////////////////////////// +// Function: CharacterSlider::update_internals +// Access: Public, Virtual +// Description: This is called by do_update() whenever the part or +// some ancestor has changed values. It is a hook for +// derived classes to update whatever cache they may +// have that depends on these. +// +// The return value is true if the part has changed as a +// result of the update, or false otherwise. +//////////////////////////////////////////////////////////////////// +bool CharacterSlider:: +update_internals(PartGroup *, bool, bool) { + // Tell our related CharacterVertexSliders that they now need to + // recompute themselves. + VertexSliders::iterator vsi; + for (vsi = _vertex_sliders.begin(); vsi != _vertex_sliders.end(); ++vsi) { + (*vsi)->mark_modified(); + } + + return true; +} + //////////////////////////////////////////////////////////////////// // Function: CharacterSlider::make_CharacterSlider // Access: Protected diff --git a/panda/src/char/characterSlider.h b/panda/src/char/characterSlider.h index e4e052216b..6d623fd3fe 100644 --- a/panda/src/char/characterSlider.h +++ b/panda/src/char/characterSlider.h @@ -23,6 +23,8 @@ #include "movingPartScalar.h" +class CharacterVertexSlider; + //////////////////////////////////////////////////////////////////// // Class : CharacterSlider // Description : This is a morph slider within the character. It's @@ -37,9 +39,18 @@ protected: public: CharacterSlider(PartGroup *parent, const string &name); + virtual ~CharacterSlider(); virtual PartGroup *make_copy() const; + virtual bool update_internals(PartGroup *parent, bool self_changed, + bool parent_changed); + +private: + typedef pset VertexSliders; + VertexSliders _vertex_sliders; + +public: static void register_with_read_factory(); static TypedWritable *make_CharacterSlider(const FactoryParams ¶ms); @@ -60,6 +71,8 @@ public: private: static TypeHandle _type_handle; + + friend class CharacterVertexSlider; }; #endif diff --git a/panda/src/char/characterVertexSlider.I b/panda/src/char/characterVertexSlider.I new file mode 100644 index 0000000000..e31ae72df0 --- /dev/null +++ b/panda/src/char/characterVertexSlider.I @@ -0,0 +1,29 @@ +// Filename: characterVertexSlider.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: CharacterVertexSlider::get_char_slider +// Access: Published +// Description: Returns the CharacterSlider object for which this +// object returns the slider value. +//////////////////////////////////////////////////////////////////// +INLINE const CharacterSlider *CharacterVertexSlider:: +get_char_slider() const { + return _char_slider; +} diff --git a/panda/src/char/characterVertexSlider.cxx b/panda/src/char/characterVertexSlider.cxx new file mode 100644 index 0000000000..e36316dff4 --- /dev/null +++ b/panda/src/char/characterVertexSlider.cxx @@ -0,0 +1,142 @@ +// Filename: characterVertexSlider.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 "characterVertexSlider.h" +#include "datagram.h" +#include "datagramIterator.h" +#include "bamReader.h" +#include "bamWriter.h" + +TypeHandle CharacterVertexSlider::_type_handle; + +//////////////////////////////////////////////////////////////////// +// Function: CharacterVertexSlider::Default Constructor +// Access: Private +// Description: Constructs an invalid object; used only by the bam +// loader. +//////////////////////////////////////////////////////////////////// +CharacterVertexSlider:: +CharacterVertexSlider() : + VertexSlider(InternalName::get_root()) +{ +} + +//////////////////////////////////////////////////////////////////// +// Function: CharacterVertexSlider::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. +//////////////////////////////////////////////////////////////////// +CharacterVertexSlider:: +CharacterVertexSlider(CharacterSlider *char_slider) : + VertexSlider(InternalName::make(char_slider->get_name())), + _char_slider(char_slider) +{ + // Tell the char_slider that we need to be informed when it moves. + _char_slider->_vertex_sliders.insert(this); +} + +//////////////////////////////////////////////////////////////////// +// Function: CharacterVertexSlider::Destructor +// Access: Published, Virtual +// Description: +//////////////////////////////////////////////////////////////////// +CharacterVertexSlider:: +~CharacterVertexSlider() { + // Tell the char_slider to stop informing us about its motion. + _char_slider->_vertex_sliders.erase(this); +} + +//////////////////////////////////////////////////////////////////// +// Function: CharacterVertexSlider::get_slider +// Access: Published, Virtual +// Description: Returns the current slider value. +//////////////////////////////////////////////////////////////////// +float CharacterVertexSlider:: +get_slider() const { + return _char_slider->_value; +} + +//////////////////////////////////////////////////////////////////// +// Function: CharacterVertexSlider::register_with_read_factory +// Access: Public, Static +// Description: Tells the BamReader how to create objects of type +// CharacterVertexSlider. +//////////////////////////////////////////////////////////////////// +void CharacterVertexSlider:: +register_with_read_factory() { + BamReader::get_factory()->register_factory(get_class_type(), make_from_bam); +} + +//////////////////////////////////////////////////////////////////// +// Function: CharacterVertexSlider::write_datagram +// Access: Public, Virtual +// Description: Writes the contents of this object to the datagram +// for shipping out to a Bam file. +//////////////////////////////////////////////////////////////////// +void CharacterVertexSlider:: +write_datagram(BamWriter *manager, Datagram &dg) { + VertexSlider::write_datagram(manager, dg); +} + +//////////////////////////////////////////////////////////////////// +// Function: CharacterVertexSlider::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 CharacterVertexSlider:: +complete_pointers(TypedWritable **p_list, BamReader *manager) { + int pi = VertexSlider::complete_pointers(p_list, manager); + + return pi; +} + +//////////////////////////////////////////////////////////////////// +// Function: CharacterVertexSlider::make_from_bam +// Access: Protected, Static +// Description: This function is called by the BamReader's factory +// when a new object of type CharacterVertexSlider is encountered +// in the Bam file. It should create the CharacterVertexSlider +// and extract its information from the file. +//////////////////////////////////////////////////////////////////// +TypedWritable *CharacterVertexSlider:: +make_from_bam(const FactoryParams ¶ms) { + CharacterVertexSlider *object = new CharacterVertexSlider; + DatagramIterator scan; + BamReader *manager; + + parse_params(params, scan, manager); + object->fillin(scan, manager); + + return object; +} + +//////////////////////////////////////////////////////////////////// +// Function: CharacterVertexSlider::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 CharacterVertexSlider. +//////////////////////////////////////////////////////////////////// +void CharacterVertexSlider:: +fillin(DatagramIterator &scan, BamReader *manager) { + VertexSlider::fillin(scan, manager); +} diff --git a/panda/src/char/characterVertexSlider.h b/panda/src/char/characterVertexSlider.h new file mode 100644 index 0000000000..3331baa2d2 --- /dev/null +++ b/panda/src/char/characterVertexSlider.h @@ -0,0 +1,81 @@ +// Filename: characterVertexSlider.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 CHARACTERVERTEXSLIDER_H +#define CHARACTERVERTEXSLIDER_H + +#include "pandabase.h" +#include "characterSlider.h" +#include "vertexSlider.h" +#include "pointerTo.h" + +//////////////////////////////////////////////////////////////////// +// Class : CharacterVertexSlider +// Description : This is a specialization on VertexSlider that +// returns the slider value associated with a particular +// CharacterSlider object. +// +// This is part of the experimental Geom rewrite. +//////////////////////////////////////////////////////////////////// +class EXPCL_PANDA CharacterVertexSlider : public VertexSlider { +private: + CharacterVertexSlider(); + +PUBLISHED: + CharacterVertexSlider(CharacterSlider *char_slider); + virtual ~CharacterVertexSlider(); + + INLINE const CharacterSlider *get_char_slider() const; + + virtual float get_slider() const; + +private: + PT(CharacterSlider) _char_slider; + +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() { + VertexSlider::init_type(); + register_type(_type_handle, "CharacterVertexSlider", + VertexSlider::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 CharacterSlider; +}; + +#include "characterVertexSlider.I" + +#endif diff --git a/panda/src/char/config_char.cxx b/panda/src/char/config_char.cxx index a1890dedf9..c228f80182 100644 --- a/panda/src/char/config_char.cxx +++ b/panda/src/char/config_char.cxx @@ -22,6 +22,7 @@ #include "characterJoint.h" #include "characterJointBundle.h" #include "characterSlider.h" +#include "characterVertexSlider.h" #include "computedVertices.h" #include "dynamicVertices.h" #include "jointVertexTransform.h" @@ -64,6 +65,7 @@ init_libchar() { CharacterJoint::init_type(); CharacterJointBundle::init_type(); CharacterSlider::init_type(); + CharacterVertexSlider::init_type(); ComputedVertices::init_type(); DynamicVertices::init_type(); JointVertexTransform::init_type(); @@ -80,6 +82,7 @@ init_libchar() { CharacterJoint::register_with_read_factory(); CharacterJointBundle::register_with_read_factory(); CharacterSlider::register_with_read_factory(); + CharacterVertexSlider::register_with_read_factory(); ComputedVertices::register_with_read_factory(); JointVertexTransform::register_with_read_factory(); } diff --git a/panda/src/egg2pg/characterMaker.cxx b/panda/src/egg2pg/characterMaker.cxx index 970e05513b..edf5ea2966 100644 --- a/panda/src/egg2pg/characterMaker.cxx +++ b/panda/src/egg2pg/characterMaker.cxx @@ -34,6 +34,7 @@ #include "eggSurface.h" #include "eggCurve.h" #include "modelNode.h" +#include "characterVertexSlider.h" #include "jointVertexTransform.h" #include "userVertexTransform.h" @@ -206,6 +207,26 @@ create_slider(const string &name) { return index; } +//////////////////////////////////////////////////////////////////// +// Function: CharacterMaker::egg_to_slider +// Access: Public +// Description: Returns the VertexSlider corresponding to the +// indicated egg slider name. +//////////////////////////////////////////////////////////////////// +VertexSlider *CharacterMaker:: +egg_to_slider(const string &name) { + VertexSliders::iterator vi = _vertex_sliders.find(name); + if (vi != _vertex_sliders.end()) { + return (*vi).second; + } + + int index = create_slider(name); + PT(VertexSlider) slider = + new CharacterVertexSlider(DCAST(CharacterSlider, _parts[index])); + _vertex_sliders[name] = slider; + return slider; +} + //////////////////////////////////////////////////////////////////// // Function: CharacterMaker::make_bundle diff --git a/panda/src/egg2pg/characterMaker.h b/panda/src/egg2pg/characterMaker.h index e7d74c41c4..6184ae2974 100644 --- a/panda/src/egg2pg/characterMaker.h +++ b/panda/src/egg2pg/characterMaker.h @@ -23,6 +23,7 @@ #include "computedVerticesMaker.h" #include "vertexTransform.h" +#include "vertexSlider.h" #include "character.h" #include "vector_PartGroupStar.h" #include "typedef.h" @@ -61,6 +62,7 @@ public: PandaNode *part_to_node(PartGroup *part) const; int create_slider(const string &name); + VertexSlider *egg_to_slider(const string &name); private: CharacterJointBundle *make_bundle(); @@ -88,6 +90,9 @@ private: VertexTransforms _vertex_transforms; PT(VertexTransform) _identity_transform; + typedef pmap VertexSliders; + VertexSliders _vertex_sliders; + EggLoader &_loader; EggGroup *_egg_root; PT(Character) _character_node; diff --git a/panda/src/egg2pg/eggLoader.cxx b/panda/src/egg2pg/eggLoader.cxx index 2c2fda5e79..89d54b2b68 100644 --- a/panda/src/egg2pg/eggLoader.cxx +++ b/panda/src/egg2pg/eggLoader.cxx @@ -1952,17 +1952,78 @@ make_vertex_data(const EggRenderState *render_state, PT(qpGeomVertexFormat) temp_format = new qpGeomVertexFormat(array_format); PT(TransformBlendPalette) blend_palette; - string name; + PT(SliderTable) slider_table; + string name = _data->get_egg_filename().get_basename_wo_extension(); if (is_dynamic) { - // If it's a dynamic object, we need a TransformBlendPalette, and - // another array that indexes into the palette per vertex. + // If it's a dynamic object, we need a TransformBlendPalette and + // maybe a SliderTable, and additional columns in the vertex data: + // one that indexes into the blend palette per vertex, and also + // one for each different type of morph delta. blend_palette = new TransformBlendPalette; - PT(qpGeomVertexArrayFormat) blend_array_format = new qpGeomVertexArrayFormat; - blend_array_format->add_data_type + + PT(qpGeomVertexArrayFormat) anim_array_format = new qpGeomVertexArrayFormat; + anim_array_format->add_data_type (InternalName::get_transform_blend(), 1, qpGeomVertexDataType::NT_uint16, qpGeomVertexDataType::C_index); - temp_format->add_array(blend_array_format); + temp_format->add_array(anim_array_format); + + pset slider_names; + EggVertexPool::const_iterator vi; + for (vi = vertex_pool->begin(); vi != vertex_pool->end(); ++vi) { + EggVertex *vertex = (*vi); + + EggMorphVertexList::const_iterator mvi; + for (mvi = vertex->_dxyzs.begin(); mvi != vertex->_dxyzs.end(); ++mvi) { + slider_names.insert((*mvi).get_name()); + record_morph(anim_array_format, character_maker, (*mvi).get_name(), + InternalName::get_vertex(), 3); + } + if (vertex->has_normal()) { + EggMorphNormalList::const_iterator mni; + for (mni = vertex->_dnormals.begin(); mni != vertex->_dnormals.end(); ++mni) { + slider_names.insert((*mni).get_name()); + record_morph(anim_array_format, character_maker, (*mni).get_name(), + InternalName::get_normal(), 3); + } + } + if (vertex->has_color()) { + EggMorphColorList::const_iterator mci; + for (mci = vertex->_drgbas.begin(); mci != vertex->_drgbas.end(); ++mci) { + slider_names.insert((*mci).get_name()); + record_morph(anim_array_format, character_maker, (*mci).get_name(), + InternalName::get_color(), 4); + } + } + EggVertex::const_uv_iterator uvi; + for (uvi = vertex->uv_begin(); uvi != vertex->uv_end(); ++uvi) { + EggVertexUV *egg_uv = (*uvi); + string name = egg_uv->get_name(); + if (name == "default") { + name = string(); + } + PT(InternalName) iname = InternalName::get_texcoord_name(name); + + EggMorphTexCoordList::const_iterator mti; + for (mti = egg_uv->_duvs.begin(); mti != egg_uv->_duvs.end(); ++mti) { + slider_names.insert((*mti).get_name()); + record_morph(anim_array_format, character_maker, (*mti).get_name(), + iname, 2); + } + } + } + + if (!slider_names.empty()) { + // If we have any sliders at all, create a table for them. + + slider_table = new SliderTable; + + pset::iterator si; + for (si = slider_names.begin(); si != slider_names.end(); ++si) { + VertexSlider *slider = character_maker->egg_to_slider(*si); + slider_table->add_slider(slider); + } + } // We'll also assign the character name to the vertex data, so it // will show up in PStats. @@ -1980,28 +2041,56 @@ make_vertex_data(const EggRenderState *render_state, PT(qpGeomVertexData) vertex_data = new qpGeomVertexData(name, format, qpGeomUsageHint::UH_static); - if (is_dynamic) { - vertex_data->set_transform_blend_palette(blend_palette); + vertex_data->set_transform_blend_palette(blend_palette); + if (slider_table != (SliderTable *)NULL) { + vertex_data->set_slider_table(SliderTable::register_table(slider_table)); } // And fill the data from the vertex pool. EggVertexPool::const_iterator vi; for (vi = vertex_pool->begin(); vi != vertex_pool->end(); ++vi) { - qpGeomVertexWriter gvi(vertex_data); + qpGeomVertexWriter gvw(vertex_data); EggVertex *vertex = (*vi); - gvi.set_vertex(vertex->get_index()); + gvw.set_vertex(vertex->get_index()); - gvi.set_data_type(InternalName::get_vertex()); - gvi.add_data4f(LCAST(float, vertex->get_pos4() * transform)); + gvw.set_data_type(InternalName::get_vertex()); + gvw.add_data4f(LCAST(float, vertex->get_pos4() * transform)); + + EggMorphVertexList::const_iterator mvi; + for (mvi = vertex->_dxyzs.begin(); mvi != vertex->_dxyzs.end(); ++mvi) { + const EggMorphVertex &morph = (*mvi); + CPT(InternalName) delta_name = + InternalName::get_morph(InternalName::get_vertex(), morph.get_name()); + gvw.set_data_type(delta_name); + gvw.add_data3f(LCAST(float, morph.get_offset() * transform)); + } if (vertex->has_normal()) { - gvi.set_data_type(InternalName::get_normal()); - gvi.add_data3f(LCAST(float, vertex->get_normal() * transform)); + gvw.set_data_type(InternalName::get_normal()); + gvw.add_data3f(LCAST(float, vertex->get_normal() * transform)); + + EggMorphNormalList::const_iterator mni; + for (mni = vertex->_dnormals.begin(); mni != vertex->_dnormals.end(); ++mni) { + const EggMorphNormal &morph = (*mni); + CPT(InternalName) delta_name = + InternalName::get_morph(InternalName::get_normal(), morph.get_name()); + gvw.set_data_type(delta_name); + gvw.add_data3f(LCAST(float, morph.get_offset() * transform)); + } } if (vertex->has_color()) { - gvi.set_data_type(InternalName::get_color()); - gvi.add_data4f(vertex->get_color()); + gvw.set_data_type(InternalName::get_color()); + gvw.add_data4f(vertex->get_color()); + + EggMorphColorList::const_iterator mci; + for (mci = vertex->_drgbas.begin(); mci != vertex->_drgbas.end(); ++mci) { + const EggMorphColor &morph = (*mci); + CPT(InternalName) delta_name = + InternalName::get_morph(InternalName::get_color(), morph.get_name()); + gvw.set_data_type(delta_name); + gvw.add_data4f(morph.get_offset()); + } } EggVertex::const_uv_iterator uvi; @@ -2014,7 +2103,7 @@ make_vertex_data(const EggRenderState *render_state, name = string(); } PT(InternalName) iname = InternalName::get_texcoord_name(name); - gvi.set_data_type(iname); + gvw.set_data_type(iname); BakeInUVs::const_iterator buv = render_state->_bake_in_uvs.find(iname); if (buv != render_state->_bake_in_uvs.end()) { @@ -2022,7 +2111,16 @@ make_vertex_data(const EggRenderState *render_state, uv = uv * (*buv).second->get_transform(); } - gvi.set_data2f(LCAST(float, uv)); + gvw.set_data2f(LCAST(float, uv)); + + EggMorphTexCoordList::const_iterator mti; + for (mti = egg_uv->_duvs.begin(); mti != egg_uv->_duvs.end(); ++mti) { + const EggMorphTexCoord &morph = (*mti); + CPT(InternalName) delta_name = + InternalName::get_morph(iname, morph.get_name()); + gvw.set_data_type(delta_name); + gvw.add_data2f(LCAST(float, morph.get_offset())); + } } if (is_dynamic) { @@ -2040,8 +2138,8 @@ make_vertex_data(const EggRenderState *render_state, blend.normalize_weights(); int palette_index = blend_palette->add_blend(blend); - gvi.set_data_type(InternalName::get_transform_blend()); - gvi.set_data1i(palette_index); + gvw.set_data_type(InternalName::get_transform_blend()); + gvw.set_data1i(palette_index); } } @@ -2052,6 +2150,26 @@ make_vertex_data(const EggRenderState *render_state, return vertex_data; } +//////////////////////////////////////////////////////////////////// +// Function: EggLoader::record_morph +// Access: Private +// Description: +//////////////////////////////////////////////////////////////////// +void EggLoader:: +record_morph(qpGeomVertexArrayFormat *array_format, + CharacterMaker *character_maker, + const string &morph_name, InternalName *data_type_name, + int num_components) { + CPT(InternalName) slider_name = InternalName::make(morph_name); + CPT(InternalName) delta_name = + InternalName::get_morph(data_type_name, morph_name); + if (!array_format->has_data_type(delta_name)) { + array_format->add_data_type + (delta_name, num_components, + qpGeomVertexDataType::NT_float32, qpGeomVertexDataType::C_morph_delta); + } +} + //////////////////////////////////////////////////////////////////// // Function: EggLoader::make_primitive // Access: Private diff --git a/panda/src/egg2pg/eggLoader.h b/panda/src/egg2pg/eggLoader.h index 2cb16907ce..0707b6cb84 100644 --- a/panda/src/egg2pg/eggLoader.h +++ b/panda/src/egg2pg/eggLoader.h @@ -146,6 +146,11 @@ private: (const EggRenderState *render_state, EggVertexPool *vertex_pool, const LMatrix4d &transform, bool is_dynamic, CharacterMaker *character_maker); + void record_morph + (qpGeomVertexArrayFormat *array_format, + CharacterMaker *character_maker, const string &morph_name, + InternalName *data_type_name, int num_components); + void make_primitive(const EggRenderState *render_state, EggPrimitive *egg_prim, Primitives &primitives); diff --git a/panda/src/gobj/internalName.I b/panda/src/gobj/internalName.I index fc734dad56..b84cdca1ea 100644 --- a/panda/src/gobj/internalName.I +++ b/panda/src/gobj/internalName.I @@ -191,6 +191,19 @@ get_transform_blend() { return _transform_blend; } +//////////////////////////////////////////////////////////////////// +// Function: InternalName::get_morph +// Access: Published, Static +// Description: Returns an InternalName suitable for defining the +// morph deltas in the GeomVertexData to apply to the +// indicated data type name, using the named slider. +//////////////////////////////////////////////////////////////////// +INLINE PT(InternalName) InternalName:: +get_morph(InternalName *data_type, const string &slider) { + // Returns data_type.morph.slider + return data_type->append("morph")->append(slider); +} + INLINE ostream & operator << (ostream &out, const InternalName &tcn) { tcn.output(out); diff --git a/panda/src/gobj/internalName.h b/panda/src/gobj/internalName.h index dc48136e07..31539a1345 100644 --- a/panda/src/gobj/internalName.h +++ b/panda/src/gobj/internalName.h @@ -72,6 +72,7 @@ PUBLISHED: INLINE static PT(InternalName) get_texcoord_name(const string &name); INLINE static PT(InternalName) get_color(); INLINE static PT(InternalName) get_transform_blend(); + INLINE static PT(InternalName) get_morph(InternalName *data_type, const string &slider); private: PT(InternalName) _parent; diff --git a/panda/src/gobj/qpgeomVertexArrayFormat.I b/panda/src/gobj/qpgeomVertexArrayFormat.I index fea157b1f7..eb0445a316 100644 --- a/panda/src/gobj/qpgeomVertexArrayFormat.I +++ b/panda/src/gobj/qpgeomVertexArrayFormat.I @@ -102,6 +102,17 @@ get_data_type(int i) const { return _data_types[i]; } +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexArrayFormat::has_data_type +// Access: Published +// Description: Returns true if the format has the named data type, +// false otherwise. +//////////////////////////////////////////////////////////////////// +INLINE bool qpGeomVertexArrayFormat:: +has_data_type(const InternalName *name) const { + return (get_data_type(name) != (qpGeomVertexDataType *)NULL); +} + //////////////////////////////////////////////////////////////////// // Function: qpGeomVertexArrayFormat::consider_sort_data_types // Access: Private diff --git a/panda/src/gobj/qpgeomVertexArrayFormat.h b/panda/src/gobj/qpgeomVertexArrayFormat.h index 52b2b84b6f..dafa843a36 100644 --- a/panda/src/gobj/qpgeomVertexArrayFormat.h +++ b/panda/src/gobj/qpgeomVertexArrayFormat.h @@ -106,6 +106,7 @@ PUBLISHED: const qpGeomVertexDataType *get_data_type(const InternalName *name) const; const qpGeomVertexDataType *get_data_type(int start_byte, int num_bytes) const; + INLINE bool has_data_type(const InternalName *name) const; bool is_data_subset_of(const qpGeomVertexArrayFormat &other) const; diff --git a/panda/src/gobj/qpgeomVertexFormat.I b/panda/src/gobj/qpgeomVertexFormat.I index 3ea6319df9..08f6affb64 100644 --- a/panda/src/gobj/qpgeomVertexFormat.I +++ b/panda/src/gobj/qpgeomVertexFormat.I @@ -93,6 +93,17 @@ get_array(int array) const { return _arrays[array]; } +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexFormat::has_data_type +// Access: Published +// Description: Returns true if the format has the named data type, +// false otherwise. +//////////////////////////////////////////////////////////////////// +INLINE bool qpGeomVertexFormat:: +has_data_type(const InternalName *name) const { + return (get_data_type(name) != (qpGeomVertexDataType *)NULL); +} + //////////////////////////////////////////////////////////////////// // Function: qpGeomVertexFormat::get_num_morphs // Access: Published diff --git a/panda/src/gobj/qpgeomVertexFormat.h b/panda/src/gobj/qpgeomVertexFormat.h index b8c26a88c0..7b6e9fb7ed 100644 --- a/panda/src/gobj/qpgeomVertexFormat.h +++ b/panda/src/gobj/qpgeomVertexFormat.h @@ -81,6 +81,7 @@ PUBLISHED: int get_array_with(const InternalName *name) const; const qpGeomVertexDataType *get_data_type(const InternalName *name) const; + INLINE bool has_data_type(const InternalName *name) const; void remove_data_type(const InternalName *name); diff --git a/panda/src/gobj/sliderTable.I b/panda/src/gobj/sliderTable.I index 403705da5a..2e418a9957 100644 --- a/panda/src/gobj/sliderTable.I +++ b/panda/src/gobj/sliderTable.I @@ -77,6 +77,28 @@ get_slider(const InternalName *name) const { return NULL; } +//////////////////////////////////////////////////////////////////// +// Function: SliderTable::has_slider +// Access: Published +// Description: Returns true if the table has a slider by the +// indicated name, false otherwise. +//////////////////////////////////////////////////////////////////// +INLINE bool SliderTable:: +has_slider(const InternalName *name) const { + return (get_slider(name) != (VertexSlider *)NULL); +} + +//////////////////////////////////////////////////////////////////// +// Function: SliderTable::is_empty +// Access: Published +// Description: Returns true if the table has no sliders, false if it +// has at least one. +//////////////////////////////////////////////////////////////////// +INLINE bool SliderTable:: +is_empty() const { + return _sliders.empty(); +} + //////////////////////////////////////////////////////////////////// // Function: SliderTable::get_modified // Access: Published diff --git a/panda/src/gobj/sliderTable.h b/panda/src/gobj/sliderTable.h index 406fd841e4..1e81830052 100644 --- a/panda/src/gobj/sliderTable.h +++ b/panda/src/gobj/sliderTable.h @@ -56,6 +56,8 @@ PUBLISHED: INLINE static CPT(SliderTable) register_table(SliderTable *table); INLINE const VertexSlider *get_slider(const InternalName *name) const; + INLINE bool has_slider(const InternalName *name) const; + INLINE bool is_empty() const; INLINE UpdateSeq get_modified() const; void remove_slider(const InternalName *name);