*** empty log message ***

This commit is contained in:
David Rose 2001-02-26 23:52:36 +00:00
parent 68d3a0e64f
commit 2b36b8e1a6
31 changed files with 1308 additions and 339 deletions

View File

@ -7,24 +7,19 @@
#define SOURCES \
eggBase.cxx eggBase.h \
eggCharacterData.cxx eggCharacterData.h eggCharacterData.I \
eggCharacterFilter.cxx eggCharacterFilter.h \
eggConverter.cxx eggConverter.h eggFilter.cxx \
eggFilter.h eggJointData.cxx eggJointData.h eggJointData.I \
eggConverter.cxx eggConverter.h \
eggFilter.cxx eggFilter.h \
eggMultiBase.cxx eggMultiBase.h \
eggMultiFilter.cxx eggMultiFilter.h \
eggReader.cxx eggReader.h \
eggToSomething.cxx \
eggToSomething.h eggWriter.cxx eggWriter.h somethingToEgg.cxx \
somethingToEgg.h
eggToSomething.cxx eggToSomething.h \
eggWriter.cxx eggWriter.h \
somethingToEgg.cxx somethingToEgg.h
#define INSTALL_HEADERS \
eggBase.h eggCharacterData.h \
eggCharacterData.I eggCharacterFilter.h \
eggConverter.h eggFilter.h eggJointData.h eggJointData.I \
eggBase.h eggConverter.h eggFilter.h \
eggMultiBase.h eggMultiFilter.h \
eggReader.h \
eggToSomething.h eggWriter.h somethingToEgg.h
eggReader.h eggToSomething.h eggWriter.h somethingToEgg.h
#end ss_lib_target

View File

@ -1,27 +0,0 @@
// Filename: eggCharacterData.I
// Created by: drose (23Feb01)
//
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Function: EggCharacterData::get_num_eggs
// Access: Public
// Description: Returns the number of egg files that have
// successfully been added to the Character table.
////////////////////////////////////////////////////////////////////
INLINE int EggCharacterData::
get_num_eggs() const {
return _eggs.size();
}
////////////////////////////////////////////////////////////////////
// Function: EggCharacterData::get_egg
// Access: Public
// Description: Returns the ith egg file.
////////////////////////////////////////////////////////////////////
INLINE EggData *EggCharacterData::
get_egg(int i) const {
nassertr(i >= 0 && i < (int)_eggs.size(), (EggData *)NULL);
return _eggs[i]._egg;
}

View File

@ -1,82 +0,0 @@
// Filename: eggCharacterData.h
// Created by: drose (23Feb01)
//
////////////////////////////////////////////////////////////////////
#ifndef EGGCHARACTERDATA_H
#define EGGCHARACTERDATA_H
#include <pandatoolbase.h>
#include <eggData.h>
#include <eggNode.h>
#include <pointerTo.h>
class EggJointData;
class EggTable;
////////////////////////////////////////////////////////////////////
// Class : EggCharacterData
// Description : Represents a set of characters, as read and collected
// from several models and animation files. Each
// character is the root of a hierarchy of EggJointData
// nodes.
////////////////////////////////////////////////////////////////////
class EggCharacterData {
public:
EggCharacterData();
virtual ~EggCharacterData();
bool add_egg(EggData *egg);
INLINE int get_num_eggs() const;
INLINE EggData *get_egg(int i) const;
virtual void write(ostream &out, int indent_level = 0) const;
protected:
virtual EggJointData *make_joint_data();
EggJointData *get_root_joint(const string &character_name);
class EggInfo {
public:
PT(EggData) _egg;
typedef vector<PT(EggNode)> Models;
Models _models;
};
typedef vector<EggInfo> Eggs;
Eggs _eggs;
class CharacterInfo {
public:
string _name;
EggJointData *_root_joint;
};
typedef vector<CharacterInfo> Characters;
Characters _characters;
private:
bool scan_hierarchy(EggNode *egg_node);
void scan_for_top_joints(EggNode *egg_node, EggNode *model_root,
const string &character_name);
void scan_for_top_tables(EggTable *bundle, EggNode *model_root,
const string &character_name);
typedef vector<EggNode *> EggNodeList;
typedef map<EggNode *, EggNodeList> TopEggNodes;
typedef map<string, TopEggNodes> TopEggNodesByName;
TopEggNodesByName _top_egg_nodes;
void match_egg_nodes(EggJointData *joint_data, EggNodeList &egg_nodes,
int egg_index, int model_index);
void found_egg_node_match(EggJointData *data, EggNode *egg_node,
int egg_index, int model_index);
};
#include "eggCharacterData.I"
#endif

View File

@ -1,93 +0,0 @@
// Filename: eggJointData.cxx
// Created by: drose (23Feb01)
//
////////////////////////////////////////////////////////////////////
#include "eggJointData.h"
#include <indent.h>
////////////////////////////////////////////////////////////////////
// Function: EggJointData::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
EggJointData::
EggJointData() {
}
////////////////////////////////////////////////////////////////////
// Function: EggJointData::Destructor
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
EggJointData::
~EggJointData() {
}
////////////////////////////////////////////////////////////////////
// Function: EggJointData::matches_name
// Access: Public
// Description: Returns true if the indicated name matches any name
// that was ever matched with this particular joint,
// false otherwise.
////////////////////////////////////////////////////////////////////
bool EggJointData::
matches_name(const string &name) const {
return false;
}
////////////////////////////////////////////////////////////////////
// Function: EggJointData::add_egg_node
// Access: Public
// Description: Adds the indicated model joint or anim table to the
// data.
////////////////////////////////////////////////////////////////////
void EggJointData::
add_egg_node(int egg_index, int model_index, EggNode *egg_node) {
if (!has_name() && egg_node->has_name()) {
set_name(egg_node->get_name());
}
while ((int)_joints.size() <= egg_index) {
_joints.push_back(JointNodes());
}
JointNodes &nodes = _joints[egg_index];
while ((int)nodes.size() <= model_index) {
nodes.push_back((EggNode *)NULL);
}
nodes[model_index] = egg_node;
}
////////////////////////////////////////////////////////////////////
// Function: EggJointData::write
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
void EggJointData::
write(ostream &out, int indent_level) const {
indent(out, indent_level)
<< "Joint " << get_name()
<< " (models:";
for (size_t egg_index = 0; egg_index < _joints.size(); egg_index++) {
const JointNodes &nodes = _joints[egg_index];
if (nodes.size() == 1) {
out << " " << egg_index;
} else if (nodes.size() > 1) {
for (size_t model_index = 0; model_index < nodes.size(); model_index++) {
if (nodes[model_index] != (EggNode *)NULL) {
out << " " << egg_index << "/" << model_index;
}
}
}
}
out << ") {\n";
Children::const_iterator ci;
for (ci = _children.begin(); ci != _children.end(); ++ci) {
(*ci)->write(out, indent_level + 2);
}
indent(out, indent_level) << "}\n";
}

View File

@ -0,0 +1,33 @@
#begin ss_lib_target
#define TARGET eggcharbase
#define LOCAL_LIBS \
eggbase progbase
#define OTHER_LIBS \
egg:c panda:m
#define SOURCES \
eggBackPointer.cxx eggBackPointer.h \
eggCharacterCollection.cxx eggCharacterCollection.h \
eggCharacterCollection.I \
eggCharacterData.cxx eggCharacterData.h eggCharacterData.I \
eggCharacterFilter.cxx eggCharacterFilter.h \
eggComponentData.cxx eggComponentData.h eggComponentData.I \
eggJointData.cxx eggJointData.h eggJointData.I \
eggJointPointer.cxx eggJointPointer.h \
eggMatrixTablePointer.cxx eggMatrixTablePointer.h \
eggSliderData.cxx eggSliderData.h eggSliderData.I \
eggVertexPointer.cxx eggVertexPointer.h
#define INSTALL_HEADERS \
eggBackPointer.h \
eggCharacterCollection.I eggCharacterCollection.h \
eggCharacterData.I eggCharacterData.h eggCharacterFilter.h \
eggComponentData.I eggComponentData.h \
eggJointData.h eggJointData.I \
eggJointPointer.h \
eggMatrixTablePointer.h \
eggSliderData.I eggSliderData.h \
eggVertexPointer.h
#end ss_lib_target

View File

@ -0,0 +1,18 @@
// Filename: eggBackPointer.cxx
// Created by: drose (26Feb01)
//
////////////////////////////////////////////////////////////////////
#include "eggBackPointer.h"
TypeHandle EggBackPointer::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: EggBackPointer::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
EggBackPointer::
EggBackPointer() {
}

View File

@ -0,0 +1,51 @@
// Filename: eggBackPointer.h
// Created by: drose (26Feb01)
//
////////////////////////////////////////////////////////////////////
#ifndef EGGBACKPOINTER_H
#define EGGBACKPOINTER_H
#include <pandatoolbase.h>
#include <typeHandle.h>
////////////////////////////////////////////////////////////////////
// Class : EggBackPointer
// Description : This stores a pointer from an EggJointData or
// EggSlider object back to the referencing data in an
// egg file. One of these objects corresponds to each
// model appearing in an egg file, and may reference
// either a single node, or a table, or a slew of
// vertices and primitives, depending on the type of
// data stored.
//
// This is just an abstract base class. The actual
// details are stored in the various subclasses.
////////////////////////////////////////////////////////////////////
class EggBackPointer : public TypedObject {
public:
EggBackPointer();
public:
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
TypedObject::init_type();
register_type(_type_handle, "EggBackPointer",
TypedObject::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;
};
#endif

View File

@ -0,0 +1,50 @@
// Filename: eggCharacterCollection.I
// Created by: drose (26Feb01)
//
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Function: EggCharacterCollection::get_num_eggs
// Access: Public
// Description: Returns the number of egg files that have
// successfully been added to the Character table.
////////////////////////////////////////////////////////////////////
INLINE int EggCharacterCollection::
get_num_eggs() const {
return _eggs.size();
}
////////////////////////////////////////////////////////////////////
// Function: EggCharacterCollection::get_egg
// Access: Public
// Description: Returns the ith egg file.
////////////////////////////////////////////////////////////////////
INLINE EggData *EggCharacterCollection::
get_egg(int i) const {
nassertr(i >= 0 && i < (int)_eggs.size(), (EggData *)NULL);
return _eggs[i]._egg;
}
////////////////////////////////////////////////////////////////////
// Function: EggCharacterCollection::get_num_characters
// Access: Public
// Description: Returns the number of separate Characters that have
// been discovered in the various egg files added to the
// collection.
////////////////////////////////////////////////////////////////////
INLINE int EggCharacterCollection::
get_num_characters() const {
return _characters.size();
}
////////////////////////////////////////////////////////////////////
// Function: EggCharacterCollection::get_character
// Access: Public
// Description: Returns the ith character in the collection.
////////////////////////////////////////////////////////////////////
INLINE EggCharacterData *EggCharacterCollection::
get_character(int i) const {
nassertr(i >= 0 && i < (int)_characters.size(), (EggCharacterData *)NULL);
return _characters[i];
}

View File

@ -1,44 +1,51 @@
// Filename: eggCharacterData.cxx
// Created by: drose (23Feb01)
// Filename: eggCharacterCollection.cxx
// Created by: drose (26Feb01)
//
////////////////////////////////////////////////////////////////////
#include "eggCharacterCollection.h"
#include "eggCharacterData.h"
#include "eggJointData.h"
#include "eggGroup.h"
#include "eggTable.h"
#include "eggSliderData.h"
#include <eggGroup.h>
#include <eggTable.h>
#include <eggPrimitive.h>
#include <eggVertex.h>
#include <eggMorphList.h>
#include <eggSAnimData.h>
#include <indirectCompareNames.h>
#include <indent.h>
#include <algorithm>
////////////////////////////////////////////////////////////////////
// Function: EggCharacterData::Constructor
// Function: EggCharacterCollection::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
EggCharacterData::
EggCharacterData() {
EggCharacterCollection::
EggCharacterCollection() {
_next_model_index = 0;
}
////////////////////////////////////////////////////////////////////
// Function: EggCharacterData::Destructor
// Function: EggCharacterCollection::Destructor
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
EggCharacterData::
~EggCharacterData() {
EggCharacterCollection::
~EggCharacterCollection() {
Characters::iterator ci;
for (ci = _characters.begin(); ci != _characters.end(); ++ci) {
CharacterInfo &character_info = (*ci);
delete character_info._root_joint;
delete (*ci);
}
}
////////////////////////////////////////////////////////////////////
// Function: EggCharacterData::add_egg
// Function: EggCharacterCollection::add_egg
// Access: Public
// Description: Adds a new egg file to the list of models and
// animation files for this particular character.
@ -49,7 +56,7 @@ EggCharacterData::
// If the joint hierarchy does not match the existing
// joint hierarchy, a best match is attempted.
////////////////////////////////////////////////////////////////////
bool EggCharacterData::
bool EggCharacterCollection::
add_egg(EggData *egg) {
_top_egg_nodes.clear();
@ -68,16 +75,21 @@ add_egg(EggData *egg) {
for (tni = _top_egg_nodes.begin(); tni != _top_egg_nodes.end(); ++tni) {
string character_name = (*tni).first;
TopEggNodes &top_nodes = (*tni).second;
EggCharacterData *char_data = make_character(character_name);
EggJointData *root_joint = char_data->get_root_joint();
TopEggNodes::iterator ti;
for (ti = top_nodes.begin(); ti != top_nodes.end(); ++ti) {
EggNode *model = (*ti).first;
EggNode *model_root = (*ti).first;
EggNodeList &egg_nodes = (*ti).second;
int model_index = egg_info._models.size();
egg_info._models.push_back(model);
match_egg_nodes(get_root_joint(character_name),
egg_nodes, egg_index, model_index);
int model_index = _next_model_index++;
egg_info._models.push_back(model_root);
match_egg_nodes(char_data, root_joint, egg_nodes,
egg_index, model_index);
scan_for_morphs(model_root, model_index, char_data);
scan_for_sliders(model_root, model_index, char_data);
}
}
@ -85,50 +97,95 @@ add_egg(EggData *egg) {
}
////////////////////////////////////////////////////////////////////
// Function: EggCharacterData::get_root_joint
// Access: Protected
// Description: Returns the root of the joint hierarchy for the named
// character. This is actually a fictitious node that
// does not correspond to any particular nodes in the
// character hierarchy; it exists to hold all of the top
// joints (if any) read from the character hierarchy.
// Function: EggCharacterCollection::get_character_by_name
// Access: Public
// Description: Returns the Character with the indicated name, if it
// exists in the collection, or NULL if it does not.
////////////////////////////////////////////////////////////////////
EggJointData *EggCharacterData::
get_root_joint(const string &character_name) {
EggCharacterData *EggCharacterCollection::
get_character_by_name(const string &character_name) const {
Characters::const_iterator ci;
for (ci = _characters.begin(); ci != _characters.end(); ++ci) {
EggCharacterData *char_data = (*ci);
if (char_data->get_name() == character_name) {
return char_data;
}
}
return (EggCharacterData *)NULL;
}
////////////////////////////////////////////////////////////////////
// Function: EggCharacterCollection::make_character_data
// Access: Public, Virtual
// Description: Allocates and returns a new EggCharacterData
// structure. This is primarily intended as a hook so
// derived classes can customize the type of
// EggCharacterData nodes used to represent the
// characters in this collection.
////////////////////////////////////////////////////////////////////
EggCharacterData *EggCharacterCollection::
make_character_data() {
return new EggCharacterData(this);
}
////////////////////////////////////////////////////////////////////
// Function: EggCharacterCollection::make_joint_data
// Access: Public, Virtual
// Description: Allocates and returns a new EggJointData structure
// for the given character. This is primarily intended
// as a hook so derived classes can customize the type
// of EggJointData nodes used to represent the joint
// hierarchy.
////////////////////////////////////////////////////////////////////
EggJointData *EggCharacterCollection::
make_joint_data(EggCharacterData *char_data) {
return new EggJointData(this, char_data);
}
////////////////////////////////////////////////////////////////////
// Function: EggCharacterCollection::make_slider_data
// Access: Public, Virtual
// Description: Allocates and returns a new EggSliderData structure
// for the given character. This is primarily intended
// as a hook so derived classes can customize the type
// of EggSliderData nodes used to represent the slider
// list.
////////////////////////////////////////////////////////////////////
EggSliderData *EggCharacterCollection::
make_slider_data(EggCharacterData *char_data) {
return new EggSliderData(this, char_data);
}
////////////////////////////////////////////////////////////////////
// Function: EggCharacterCollection::make_character
// Access: Protected
// Description: Allocates and returns a new EggCharacterData object
// representing the named character, if there is not
// already a character by that name.
////////////////////////////////////////////////////////////////////
EggCharacterData *EggCharacterCollection::
make_character(const string &character_name) {
// Does the named character exist yet?
Characters::iterator ci;
for (ci = _characters.begin(); ci != _characters.end(); ++ci) {
CharacterInfo &character_info = (*ci);
if (character_info._name == character_name) {
return character_info._root_joint;
EggCharacterData *char_data = (*ci);
if (char_data->get_name() == character_name) {
return char_data;
}
}
// Define a new character.
_characters.push_back(CharacterInfo());
CharacterInfo &character_info = _characters.back();
character_info._name = character_name;
character_info._root_joint = make_joint_data();
return character_info._root_joint;
}
////////////////////////////////////////////////////////////////////
// Function: EggCharacterData::make_joint_data
// Access: Protected, Virtual
// Description: Allocates and returns a new EggJointData structure.
// This is primarily intended as a hook so derived
// classes can customize the type of EggJointData nodes
// used to represent the joint hierarchy.
////////////////////////////////////////////////////////////////////
EggJointData *EggCharacterData::
make_joint_data() {
return new EggJointData;
EggCharacterData *char_data = make_character_data();
char_data->set_name(character_name);
_characters.push_back(char_data);
return char_data;
}
////////////////////////////////////////////////////////////////////
// Function: EggCharacterData::scan_hierarchy
// Function: EggCharacterCollection::scan_hierarchy
// Access: Private
// Description: Walks the given egg data's hierarchy, looking for
// either the start of an animation channel or the start
@ -139,7 +196,7 @@ make_joint_data() {
// Fills up the _top_egg_nodes according to the nodes
// found.
////////////////////////////////////////////////////////////////////
bool EggCharacterData::
bool EggCharacterCollection::
scan_hierarchy(EggNode *egg_node) {
if (egg_node->is_of_type(EggGroup::get_class_type())) {
EggGroup *group = DCAST(EggGroup, egg_node);
@ -173,13 +230,13 @@ scan_hierarchy(EggNode *egg_node) {
}
////////////////////////////////////////////////////////////////////
// Function: EggCharacterData::scan_for_top_joints
// Function: EggCharacterCollection::scan_for_top_joints
// Access: Private
// Description: Once a character model has been found, continue
// scanning the egg hierarchy to look for the topmost
// <Joint> nodes encountered.
////////////////////////////////////////////////////////////////////
void EggCharacterData::
void EggCharacterCollection::
scan_for_top_joints(EggNode *egg_node, EggNode *model_root,
const string &character_name) {
if (egg_node->is_of_type(EggGroup::get_class_type())) {
@ -206,13 +263,13 @@ scan_for_top_joints(EggNode *egg_node, EggNode *model_root,
}
////////////////////////////////////////////////////////////////////
// Function: EggCharacterData::scan_for_top_tables
// Function: EggCharacterCollection::scan_for_top_tables
// Access: Private
// Description: Once an animation has been found, continue scanning
// the egg hierarchy to look for the topmost <Table>
// nodes encountered.
////////////////////////////////////////////////////////////////////
void EggCharacterData::
void EggCharacterCollection::
scan_for_top_tables(EggTable *bundle, EggNode *model_root,
const string &character_name) {
// We really only need to check the immediate children of the bundle
@ -239,7 +296,121 @@ scan_for_top_tables(EggTable *bundle, EggNode *model_root,
}
////////////////////////////////////////////////////////////////////
// Function: EggCharacterData::match_egg_nodes
// Function: EggCharacterCollection::scan_for_morphs
// Access: Private
// Description: Go back through a model's hierarchy and look for
// morph targets on the vertices and primitives.
////////////////////////////////////////////////////////////////////
void EggCharacterCollection::
scan_for_morphs(EggNode *egg_node, int model_index,
EggCharacterData *char_data) {
if (egg_node->is_of_type(EggPrimitive::get_class_type())) {
EggPrimitive *prim = DCAST(EggPrimitive, egg_node);
// Check for morphs on the primitive.
add_morph_back_pointers(prim, prim, model_index, char_data);
// Also check for morphs on each of the prim's vertices.
EggPrimitive::const_iterator vi;
for (vi = prim->begin(); vi != prim->end(); ++vi) {
EggVertex *vertex = (*vi);
add_morph_back_pointers(vertex, vertex, model_index, char_data);
EggMorphVertexList::const_iterator mvi;
for (mvi = vertex->_dxyzs.begin();
mvi != vertex->_dxyzs.end();
++mvi) {
const EggMorphVertex &morph = (*mvi);
char_data->make_slider(morph.get_name())->add_back_pointer(model_index, vertex);
}
}
}
if (egg_node->is_of_type(EggGroupNode::get_class_type())) {
EggGroupNode *group = DCAST(EggGroupNode, egg_node);
EggGroupNode::iterator gi;
for (gi = group->begin(); gi != group->end(); ++gi) {
scan_for_morphs(*gi, model_index, char_data);
}
}
}
////////////////////////////////////////////////////////////////////
// Function: EggCharacterCollection::scan_for_sliders
// Access: Private
// Description: Go back to the animation tables and look for morph
// slider animation channels.
////////////////////////////////////////////////////////////////////
void EggCharacterCollection::
scan_for_sliders(EggNode *egg_node, int model_index,
EggCharacterData *char_data) {
if (egg_node->is_of_type(EggTable::get_class_type())) {
EggTable *bundle = DCAST(EggTable, egg_node);
// We really only need to check the immediate children of the
// bundle for a table node called "morph". This is a sibling of
// "<skeleton>", which we found a minute ago, but we weren't ready
// to scan for the morph sliders at the time, so we have to look
// again now.
EggGroupNode::iterator gi;
for (gi = bundle->begin(); gi != bundle->end(); ++gi) {
EggNode *child = (*gi);
if (child->is_of_type(EggTable::get_class_type())) {
EggTable *table = DCAST(EggTable, child);
if (table->get_name() == "morph") {
// Here it is! Now the immediate children of this node are
// all the slider channels.
EggGroupNode::iterator cgi;
for (cgi = table->begin(); cgi != table->end(); ++cgi) {
EggNode *grandchild = (*cgi);
if (grandchild->is_of_type(EggSAnimData::get_class_type())) {
char_data->make_slider(grandchild->get_name())->add_back_pointer(model_index, grandchild);
}
}
}
}
}
}
}
////////////////////////////////////////////////////////////////////
// Function: EggCharacterCollection::add_morph_back_pointers
// Access: Private
// Description: Adds the back pointers for the kinds of morphs we
// might find in an EggAttributes object.
////////////////////////////////////////////////////////////////////
void EggCharacterCollection::
add_morph_back_pointers(EggAttributes *attrib, EggObject *egg_object,
int model_index, EggCharacterData *char_data) {
EggMorphNormalList::const_iterator mni;
for (mni = attrib->_dnormals.begin();
mni != attrib->_dnormals.end();
++mni) {
const EggMorphNormal &morph = (*mni);
char_data->make_slider(morph.get_name())->add_back_pointer(model_index, egg_object);
}
EggMorphTexCoordList::const_iterator mti;
for (mti = attrib->_duvs.begin();
mti != attrib->_duvs.end();
++mti) {
const EggMorphTexCoord &morph = (*mti);
char_data->make_slider(morph.get_name())->add_back_pointer(model_index, egg_object);
}
EggMorphColorList::const_iterator mci;
for (mci = attrib->_drgbas.begin();
mci != attrib->_drgbas.end();
++mci) {
const EggMorphColor &morph = (*mci);
char_data->make_slider(morph.get_name())->add_back_pointer(model_index, egg_object);
}
}
////////////////////////////////////////////////////////////////////
// Function: EggCharacterCollection::match_egg_nodes
// Access: Private
// Description: Attempts to match up the indicated list of egg_nodes
// with the children of the given joint_data, by name if
@ -248,9 +419,9 @@ scan_for_top_tables(EggTable *bundle, EggNode *model_root,
// Also recurses on each matched joint to build up the
// entire joint hierarchy.
////////////////////////////////////////////////////////////////////
void EggCharacterData::
match_egg_nodes(EggJointData *joint_data, EggNodeList &egg_nodes,
int egg_index, int model_index) {
void EggCharacterCollection::
match_egg_nodes(EggCharacterData *char_data, EggJointData *joint_data,
EggNodeList &egg_nodes, int egg_index, int model_index) {
// Sort the list of egg_nodes in order by name. This will make the
// matching up by names easier and more reliable.
sort(egg_nodes.begin(), egg_nodes.end(), IndirectCompareNames<Namable>());
@ -261,9 +432,9 @@ match_egg_nodes(EggJointData *joint_data, EggNodeList &egg_nodes,
EggNodeList::iterator ei;
for (ei = egg_nodes.begin(); ei != egg_nodes.end(); ++ei) {
EggNode *egg_node = (*ei);
EggJointData *data = make_joint_data();
EggJointData *data = make_joint_data(char_data);
joint_data->_children.push_back(data);
found_egg_node_match(data, egg_node, egg_index, model_index);
found_egg_match(char_data, data, egg_node, egg_index, model_index);
}
} else {
@ -295,7 +466,7 @@ match_egg_nodes(EggJointData *joint_data, EggNodeList &egg_nodes,
} else {
// Hey, these two match! Hooray!
found_egg_node_match(data, egg_node, egg_index, model_index);
found_egg_match(char_data, data, egg_node, egg_index, model_index);
++ei;
++di;
}
@ -335,7 +506,7 @@ match_egg_nodes(EggJointData *joint_data, EggNodeList &egg_nodes,
EggJointData *data = (*di);
if (data->matches_name(egg_node->get_name())) {
matched = true;
found_egg_node_match(data, egg_node, egg_index, model_index);
found_egg_match(char_data, data, egg_node, egg_index, model_index);
extra_data.erase(di);
}
}
@ -357,7 +528,7 @@ match_egg_nodes(EggJointData *joint_data, EggNodeList &egg_nodes,
for (i = 0; i < extra_egg_nodes.size(); i++) {
EggNode *egg_node = extra_egg_nodes[i];
EggJointData *data = extra_data[i];
found_egg_node_match(data, egg_node, egg_index, model_index);
found_egg_match(char_data, data, egg_node, egg_index, model_index);
}
} else {
@ -365,9 +536,9 @@ match_egg_nodes(EggJointData *joint_data, EggNodeList &egg_nodes,
EggNodeList::iterator ei;
for (ei = extra_egg_nodes.begin(); ei != extra_egg_nodes.end(); ++ei) {
EggNode *egg_node = (*ei);
EggJointData *data = make_joint_data();
EggJointData *data = make_joint_data(char_data);
joint_data->_children.push_back(data);
found_egg_node_match(data, egg_node, egg_index, model_index);
found_egg_match(char_data, data, egg_node, egg_index, model_index);
}
}
}
@ -380,16 +551,19 @@ match_egg_nodes(EggJointData *joint_data, EggNodeList &egg_nodes,
}
////////////////////////////////////////////////////////////////////
// Function: EggCharacterData::found_egg_node_match
// Function: EggCharacterCollection::found_egg_match
// Access: Private
// Description: Marks a one-to-one association between the indicated
// EggJointData and the indicated EggNode, and then
// recurses below.
////////////////////////////////////////////////////////////////////
void EggCharacterData::
found_egg_node_match(EggJointData *data, EggNode *egg_node,
int egg_index, int model_index) {
data->add_egg_node(egg_index, model_index, egg_node);
void EggCharacterCollection::
found_egg_match(EggCharacterData *char_data, EggJointData *joint_data,
EggNode *egg_node, int egg_index, int model_index) {
if (egg_node->has_name()) {
joint_data->add_name(egg_node->get_name());
}
joint_data->add_back_pointer(model_index, egg_node);
if (egg_node->is_of_type(EggGroupNode::get_class_type())) {
EggGroupNode *group_node = DCAST(EggGroupNode, egg_node);
@ -429,24 +603,23 @@ found_egg_node_match(EggJointData *data, EggNode *egg_node,
}
if (!egg_nodes.empty()) {
match_egg_nodes(data, egg_nodes, egg_index, model_index);
match_egg_nodes(char_data, joint_data, egg_nodes,
egg_index, model_index);
}
}
}
////////////////////////////////////////////////////////////////////
// Function: EggCharacterData::write
// Function: EggCharacterCollection::write
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
void EggCharacterData::
void EggCharacterCollection::
write(ostream &out, int indent_level) const {
Characters::const_iterator ci;
for (ci = _characters.begin(); ci != _characters.end(); ++ci) {
const CharacterInfo &character_info = (*ci);
indent(out, indent_level)
<< "Character " << character_info._name << ":\n";
character_info._root_joint->write(out, indent_level + 2);
EggCharacterData *char_data = (*ci);
char_data->write(out, indent_level);
}
}

View File

@ -0,0 +1,93 @@
// Filename: eggCharacterCollection.h
// Created by: drose (26Feb01)
//
////////////////////////////////////////////////////////////////////
#ifndef EGGCHARACTERCOLLECTION_H
#define EGGCHARACTERCOLLECTION_H
#include <pandatoolbase.h>
#include "eggCharacterData.h"
#include <eggData.h>
#include <eggNode.h>
#include <pointerTo.h>
class EggTable;
class EggAttributes;
////////////////////////////////////////////////////////////////////
// Class : EggCharacterCollection
// Description : Represents a set of characters, as read and collected
// from possibly several model and/or animation egg
// files.
////////////////////////////////////////////////////////////////////
class EggCharacterCollection {
public:
EggCharacterCollection();
virtual ~EggCharacterCollection();
bool add_egg(EggData *egg);
INLINE int get_num_eggs() const;
INLINE EggData *get_egg(int i) const;
INLINE int get_num_characters() const;
INLINE EggCharacterData *get_character(int i) const;
EggCharacterData *get_character_by_name(const string &character_name) const;
virtual void write(ostream &out, int indent_level = 0) const;
virtual EggCharacterData *make_character_data();
virtual EggJointData *make_joint_data(EggCharacterData *char_data);
virtual EggSliderData *make_slider_data(EggCharacterData *char_data);
public:
EggCharacterData *make_character(const string &character_name);
class EggInfo {
public:
PT(EggData) _egg;
typedef vector<PT(EggNode)> Models;
Models _models;
};
typedef vector<EggInfo> Eggs;
Eggs _eggs;
typedef vector<EggCharacterData *> Characters;
Characters _characters;
private:
bool scan_hierarchy(EggNode *egg_node);
void scan_for_top_joints(EggNode *egg_node, EggNode *model_root,
const string &character_name);
void scan_for_top_tables(EggTable *bundle, EggNode *model_root,
const string &character_name);
void scan_for_morphs(EggNode *egg_node, int model_index,
EggCharacterData *char_data);
void scan_for_sliders(EggNode *egg_node, int model_index,
EggCharacterData *char_data);
void add_morph_back_pointers(EggAttributes *attrib, EggObject *egg_object,
int model_index, EggCharacterData *char_data);
typedef vector<EggNode *> EggNodeList;
typedef map<EggNode *, EggNodeList> TopEggNodes;
typedef map<string, TopEggNodes> TopEggNodesByName;
TopEggNodesByName _top_egg_nodes;
int _next_model_index;
void match_egg_nodes(EggCharacterData *char_Data, EggJointData *joint_data,
EggNodeList &egg_nodes, int egg_index, int model_index);
void found_egg_match(EggCharacterData *char_data, EggJointData *joint_data,
EggNode *egg_node, int egg_index, int model_index);
};
#include "eggCharacterCollection.I"
#endif

View File

@ -0,0 +1,20 @@
// Filename: eggCharacterData.I
// Created by: drose (23Feb01)
//
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Function: EggCharacterData::get_root_joint
// Access: Public
// Description: Returns the root joint of the character hierarchy.
// This root joint does not represent an actual joint in
// the hierarchy, but instead is a fictitious joint that
// is the parent of all the top joints in the hierarchy
// (since the hierarchy may actually contain zero or
// more top joints).
////////////////////////////////////////////////////////////////////
INLINE EggJointData *EggCharacterData::
get_root_joint() const {
return _root_joint;
}

View File

@ -0,0 +1,76 @@
// Filename: eggCharacterData.cxx
// Created by: drose (23Feb01)
//
////////////////////////////////////////////////////////////////////
#include "eggCharacterData.h"
#include "eggCharacterCollection.h"
#include "eggJointData.h"
#include "eggSliderData.h"
#include <indent.h>
////////////////////////////////////////////////////////////////////
// Function: EggCharacterData::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
EggCharacterData::
EggCharacterData(EggCharacterCollection *collection) {
_collection = collection;
_root_joint = _collection->make_joint_data(this);
}
////////////////////////////////////////////////////////////////////
// Function: EggCharacterData::Destructor
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
EggCharacterData::
~EggCharacterData() {
delete _root_joint;
Sliders::iterator si;
for (si = _sliders.begin(); si != _sliders.end(); ++si) {
EggSliderData *slider = (*si).second;
delete slider;
}
}
////////////////////////////////////////////////////////////////////
// Function: EggCharacterData::make_slider
// Access: Public
// Description: Returns the slider matching the indicated name. If
// no such slider exists already, creates a new one.
////////////////////////////////////////////////////////////////////
EggSliderData *EggCharacterData::
make_slider(const string &name) {
Sliders::iterator si;
si = _sliders.find(name);
if (si != _sliders.end()) {
return (*si).second;
}
EggSliderData *slider = _collection->make_slider_data(this);
slider->set_name(name);
_sliders.insert(Sliders::value_type(name, slider));
return slider;
}
////////////////////////////////////////////////////////////////////
// Function: EggCharacterData::write
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
void EggCharacterData::
write(ostream &out, int indent_level) const {
indent(out, indent_level)
<< "Character " << get_name() << ":\n";
get_root_joint()->write(out, indent_level + 2);
Sliders::const_iterator si;
for (si = _sliders.begin(); si != _sliders.end(); ++si) {
EggSliderData *slider = (*si).second;
slider->write(out, indent_level + 2);
}
}

View File

@ -0,0 +1,66 @@
// Filename: eggCharacterData.h
// Created by: drose (23Feb01)
//
////////////////////////////////////////////////////////////////////
#ifndef EGGCHARACTERDATA_H
#define EGGCHARACTERDATA_H
#include <pandatoolbase.h>
#include <namable.h>
#include <map>
class EggCharacterCollection;
class EggJointData;
class EggSliderData;
////////////////////////////////////////////////////////////////////
// Class : EggCharacterData
// Description : Represents a single character, as read and collected
// from several models and animation files. This
// contains a hierarchy of EggJointData nodes
// representing the skeleton, as well as a list of
// EggSliderData nodes representing the morph channels
// for the character.
//
// This is very similar to the Character class from
// Panda, in that it's capable of associating
// skeleton-morph animation channels with models and
// calculating the vertex position for each frame. To
// some degree, it duplicates the functionality of
// Character. However, it differs in one fundamental
// principle: it is designed to be a non-real-time
// operation, working directly on the Egg structures as
// they are, instead of first boiling the Egg data into
// native Panda Geom tables for real-time animation.
// Because of this, it is (a) double-precision instead
// of single precision, (b) capable of generating
// modified Egg files, and (c) about a hundred times
// slower than the Panda Character class.
////////////////////////////////////////////////////////////////////
class EggCharacterData : public Namable {
public:
EggCharacterData(EggCharacterCollection *collection);
virtual ~EggCharacterData();
INLINE EggJointData *get_root_joint() const;
EggSliderData *make_slider(const string &name);
virtual void write(ostream &out, int indent_level = 0) const;
protected:
EggCharacterCollection *_collection;
EggJointData *_root_joint;
typedef map<string, EggSliderData *> Sliders;
Sliders _sliders;
};
#include "eggCharacterData.I"
#endif

View File

@ -4,7 +4,7 @@
////////////////////////////////////////////////////////////////////
#include "eggCharacterFilter.h"
#include "eggCharacterData.h"
#include "eggCharacterCollection.h"
////////////////////////////////////////////////////////////////////
@ -14,7 +14,7 @@
////////////////////////////////////////////////////////////////////
EggCharacterFilter::
EggCharacterFilter() : EggMultiFilter(false) {
_character_data = (EggCharacterData *)NULL;
_collection = (EggCharacterCollection *)NULL;
}
////////////////////////////////////////////////////////////////////
@ -24,8 +24,8 @@ EggCharacterFilter() : EggMultiFilter(false) {
////////////////////////////////////////////////////////////////////
EggCharacterFilter::
~EggCharacterFilter() {
if (_character_data != (EggCharacterData *)NULL) {
delete _character_data;
if (_collection != (EggCharacterCollection *)NULL) {
delete _collection;
}
}
@ -37,8 +37,8 @@ EggCharacterFilter::
////////////////////////////////////////////////////////////////////
bool EggCharacterFilter::
post_command_line() {
if (_character_data == (EggCharacterData *)NULL) {
_character_data = make_character_data();
if (_collection == (EggCharacterCollection *)NULL) {
_collection = make_collection();
}
if (!EggMultiFilter::post_command_line()) {
@ -49,27 +49,28 @@ post_command_line() {
for (ei = _eggs.begin(); ei != _eggs.end(); ++ei) {
EggData *data = (*ei);
if (!_character_data->add_egg(data)) {
if (!_collection->add_egg(data)) {
nout << data->get_egg_filename().get_basename()
<< " does not contain a character model or animation channel.\n";
return false;
}
}
_character_data->write(cerr);
_collection->write(cerr);
return true;
}
////////////////////////////////////////////////////////////////////
// Function: EggCharacterFilter::make_character_data
// Function: EggCharacterFilter::make_collection
// Access: Protected, Virtual
// Description: Allocates and returns a new EggCharacterData structure.
// This is primarily intended as a hook so derived
// classes can customize the type of EggCharacterData nodes
// used to represent the character information.
// Description: Allocates and returns a new EggCharacterCollection
// structure. This is primarily intended as a hook so
// derived classes can customize the type of
// EggCharacterCollection object used to represent the
// character information.
////////////////////////////////////////////////////////////////////
EggCharacterData *EggCharacterFilter::
make_character_data() {
return new EggCharacterData;
EggCharacterCollection *EggCharacterFilter::
make_collection() {
return new EggCharacterCollection;
}

View File

@ -11,6 +11,7 @@
#include "eggMultiFilter.h"
class EggCharacterData;
class EggCharacterCollection;
////////////////////////////////////////////////////////////////////
// Class : EggCharacterFilter
@ -31,9 +32,9 @@ public:
protected:
virtual bool post_command_line();
virtual EggCharacterData *make_character_data();
virtual EggCharacterCollection *make_collection();
EggCharacterData *_character_data;
EggCharacterCollection *_collection;
};
#endif

View File

@ -0,0 +1,49 @@
// Filename: eggComponentData.I
// Created by: drose (26Feb01)
//
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Function: EggComponentData::get_num_back_pointers
// Access: Public
// Description: Returns the maximum number of back pointers this
// component may have. The component may store a back
// pointer for models indexed 0 .. num_back_pointers -
// 1. You must call has_back_pointer() on each model
// index to confirm whether a particular model in that
// range has a back pointer.
////////////////////////////////////////////////////////////////////
INLINE int EggComponentData::
get_num_back_pointers() const {
return _back_pointers.size();
}
////////////////////////////////////////////////////////////////////
// Function: EggComponentData::has_back_pointer
// Access: Public
// Description: Returns true if the component has a back pointer to
// an egg file somewhere for the indicated model, false
// otherwise.
////////////////////////////////////////////////////////////////////
INLINE bool EggComponentData::
has_back_pointer(int model_index) const {
if (model_index >= 0 && model_index < (int)_back_pointers.size()) {
return _back_pointers[model_index] != (EggBackPointer *)NULL;
}
return false;
}
////////////////////////////////////////////////////////////////////
// Function: EggComponentData::get_back_pointer
// Access: Public
// Description: Returns the back pointer to an egg file for the
// indicated model if it exists, or NULL if it does not.
////////////////////////////////////////////////////////////////////
INLINE EggBackPointer *EggComponentData::
get_back_pointer(int model_index) const {
if (model_index >= 0 && model_index < (int)_back_pointers.size()) {
return _back_pointers[model_index];
}
return (EggBackPointer *)NULL;
}

View File

@ -0,0 +1,87 @@
// Filename: eggComponentData.cxx
// Created by: drose (26Feb01)
//
////////////////////////////////////////////////////////////////////
#include "eggComponentData.h"
#include "eggBackPointer.h"
#include <indent.h>
////////////////////////////////////////////////////////////////////
// Function: EggComponentData::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
EggComponentData::
EggComponentData(EggCharacterCollection *collection,
EggCharacterData *char_data) :
_collection(collection),
_char_data(char_data)
{
}
////////////////////////////////////////////////////////////////////
// Function: EggComponentData::Destructor
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
EggComponentData::
~EggComponentData() {
BackPointers::iterator bpi;
for (bpi = _back_pointers.begin(); bpi != _back_pointers.end(); ++bpi) {
EggBackPointer *back = (*bpi);
if (back != (EggBackPointer *)NULL) {
delete back;
}
}
}
////////////////////////////////////////////////////////////////////
// Function: EggComponentData::add_name
// Access: Public
// Description: Adds the indicated name to the set of names that this
// component can be identified with. If this is the
// first name added, it becomes the primary name of the
// component; later names added do not replace the
// primary name, but do get added to the list of names
// that will be accepted by matched_name().
////////////////////////////////////////////////////////////////////
void EggComponentData::
add_name(const string &name) {
if (!has_name()) {
set_name(name);
}
}
////////////////////////////////////////////////////////////////////
// Function: EggComponentData::matches_name
// Access: Public
// Description: Returns true if the indicated name matches any name
// that was ever matched with this particular joint,
// false otherwise.
////////////////////////////////////////////////////////////////////
bool EggComponentData::
matches_name(const string &name) const {
return false;
}
////////////////////////////////////////////////////////////////////
// Function: EggComponentData::set_back_pointer
// Access: Public
// Description: Sets the back_pointer associated with the given
// model_index.
////////////////////////////////////////////////////////////////////
void EggComponentData::
set_back_pointer(int model_index, EggBackPointer *back) {
while ((int)_back_pointers.size() <= model_index) {
_back_pointers.push_back((EggBackPointer *)NULL);
}
if (_back_pointers[model_index] != (EggBackPointer *)NULL) {
nout << "Warning: deleting old back pointer.\n";
delete _back_pointers[model_index];
}
_back_pointers[model_index] = back;
}

View File

@ -0,0 +1,59 @@
// Filename: eggComponentData.h
// Created by: drose (26Feb01)
//
////////////////////////////////////////////////////////////////////
#ifndef EGGCOMPONENTDATA_H
#define EGGCOMPONENTDATA_H
#include <pandatoolbase.h>
#include <namable.h>
class EggCharacterCollection;
class EggCharacterData;
class EggBackPointer;
class EggObject;
////////////////////////////////////////////////////////////////////
// Class : EggComponentData
// Description : This is the base class of both EggJointData and
// EggSliderData. It represents a single component of a
// character, either a joint or a slider, along with
// back pointers to the references to this component in
// all model and animation egg files read.
////////////////////////////////////////////////////////////////////
class EggComponentData : public Namable {
public:
EggComponentData(EggCharacterCollection *collection,
EggCharacterData *char_data);
virtual ~EggComponentData();
void add_name(const string &name);
bool matches_name(const string &name) const;
virtual void add_back_pointer(int model_index, EggObject *egg_object)=0;
virtual void write(ostream &out, int indent_level = 0) const=0;
INLINE int get_num_back_pointers() const;
INLINE bool has_back_pointer(int model_index) const;
INLINE EggBackPointer *get_back_pointer(int model_index) const;
void set_back_pointer(int model_index, EggBackPointer *back);
protected:
// This points back to all the egg structures that reference this
// particular table or slider.
typedef vector<EggBackPointer *> BackPointers;
BackPointers _back_pointers;
EggCharacterCollection *_collection;
EggCharacterData *_char_data;
};
#include "eggComponentData.I"
#endif

View File

@ -0,0 +1,74 @@
// Filename: eggJointData.cxx
// Created by: drose (23Feb01)
//
////////////////////////////////////////////////////////////////////
#include "eggJointData.h"
#include "eggJointPointer.h"
#include "eggMatrixTablePointer.h"
#include <eggGroup.h>
#include <eggTable.h>
#include <indent.h>
////////////////////////////////////////////////////////////////////
// Function: EggJointData::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
EggJointData::
EggJointData(EggCharacterCollection *collection,
EggCharacterData *char_data) :
EggComponentData(collection, char_data)
{
}
////////////////////////////////////////////////////////////////////
// Function: EggJointData::add_back_pointer
// Access: Public, Virtual
// Description: Adds the indicated model joint or anim table to the
// data.
////////////////////////////////////////////////////////////////////
void EggJointData::
add_back_pointer(int model_index, EggObject *egg_object) {
if (egg_object->is_of_type(EggGroup::get_class_type())) {
// It must be a <Joint>.
EggJointPointer *joint = new EggJointPointer(egg_object);
set_back_pointer(model_index, joint);
} else if (egg_object->is_of_type(EggTable::get_class_type())) {
// It's a <Table> with an "xform" child beneath it.
EggMatrixTablePointer *xform = new EggMatrixTablePointer(egg_object);
set_back_pointer(model_index, xform);
} else {
nout << "Invalid object added to joint for back pointer.\n";
}
}
////////////////////////////////////////////////////////////////////
// Function: EggJointData::write
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
void EggJointData::
write(ostream &out, int indent_level) const {
indent(out, indent_level)
<< "Joint " << get_name()
<< " (models:";
int num_back_pointers = get_num_back_pointers();
for (int model_index = 0; model_index < num_back_pointers; model_index++) {
if (has_back_pointer(model_index)) {
out << " " << model_index;
}
}
out << ") {\n";
Children::const_iterator ci;
for (ci = _children.begin(); ci != _children.end(); ++ci) {
(*ci)->write(out, indent_level + 2);
}
indent(out, indent_level) << "}\n";
}

View File

@ -8,11 +8,7 @@
#include <pandatoolbase.h>
#include <eggNode.h>
#include <pointerTo.h>
#include <namable.h>
class EggGroup;
#include "eggComponentData.h"
////////////////////////////////////////////////////////////////////
// Class : EggJointData
@ -22,42 +18,24 @@ class EggGroup;
// various models, the LOD's of each model, and the
// various animation channel files.
////////////////////////////////////////////////////////////////////
class EggJointData : public Namable {
class EggJointData : public EggComponentData {
public:
EggJointData();
virtual ~EggJointData();
EggJointData(EggCharacterCollection *collection,
EggCharacterData *char_data);
INLINE int get_num_children() const;
INLINE EggJointData *get_child(int n) const;
bool matches_name(const string &name) const;
void add_egg_node(int egg_index, int model_index, EggNode *egg_node);
virtual void add_back_pointer(int model_index, EggObject *egg_object);
virtual void write(ostream &out, int indent_level = 0) const;
protected:
typedef vector<PT(EggNode)> JointNodes;
typedef vector<JointNodes> Joints;
Joints _tables;
// _tables[i][anim] is the table for the animth bundle of the ith
// file.
Joints _joints;
// _joints[i][model] is the joint for the modelth lod of the ith
// file.
LMatrix4d _rest_transform;
LMatrix4d _net_rest_transform;
typedef vector<EggJointData *> Children;
Children _children;
friend class EggCharacterData;
friend class EggCharacterCollection;
};
#include "eggJointData.I"
#endif

View File

@ -0,0 +1,19 @@
// Filename: eggJointPointer.cxx
// Created by: drose (26Feb01)
//
////////////////////////////////////////////////////////////////////
#include "eggJointPointer.h"
TypeHandle EggJointPointer::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: EggJointPointer::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
EggJointPointer::
EggJointPointer(EggObject *object) {
_joint = DCAST(EggGroup, object);
}

View File

@ -0,0 +1,47 @@
// Filename: eggJointPointer.h
// Created by: drose (26Feb01)
//
////////////////////////////////////////////////////////////////////
#ifndef EGGJOINTPOINTER_H
#define EGGJOINTPOINTER_H
#include <pandatoolbase.h>
#include "eggBackPointer.h"
#include <eggGroup.h>
#include <pointerTo.h>
////////////////////////////////////////////////////////////////////
// Class : EggJointPointer
// Description : This stores a pointer back to a <Joint> node.
////////////////////////////////////////////////////////////////////
class EggJointPointer : public EggBackPointer {
public:
EggJointPointer(EggObject *object);
private:
PT(EggGroup) _joint;
public:
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
EggBackPointer::init_type();
register_type(_type_handle, "EggJointPointer",
EggBackPointer::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;
};
#endif

View File

@ -0,0 +1,45 @@
// Filename: eggMatrixTablePointer.cxx
// Created by: drose (26Feb01)
//
////////////////////////////////////////////////////////////////////
#include "eggMatrixTablePointer.h"
#include <eggXfmAnimData.h>
#include <eggXfmSAnim.h>
TypeHandle EggMatrixTablePointer::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: EggMatrixTablePointer::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
EggMatrixTablePointer::
EggMatrixTablePointer(EggObject *object) {
_table = DCAST(EggTable, object);
if (_table != (EggTable *)NULL) {
// Now search for the child named "xform". This contains the
// actual table data.
EggGroupNode::iterator ci;
bool found = false;
for (ci = _table->begin(); ci != _table->end() && !found; ++ci) {
EggNode *child = (*ci);
if (child->get_name() == "xform") {
if (child->is_of_type(EggXfmSAnim::get_class_type())) {
_xform = DCAST(EggXfmSAnim, child);
found = true;
} else if (child->is_of_type(EggXfmAnimData::get_class_type())) {
// Quietly replace old-style XfmAnim tables with new-style
// XfmSAnim tables.
PT(EggXfmAnimData) anim = DCAST(EggXfmAnimData, child);
_xform = new EggXfmSAnim(*anim);
_table->replace(ci, _xform.p());
found = true;
}
}
}
}
}

View File

@ -0,0 +1,52 @@
// Filename: eggMatrixTablePointer.h
// Created by: drose (26Feb01)
//
////////////////////////////////////////////////////////////////////
#ifndef EGGMATRIXTABLEPOINTER_H
#define EGGMATRIXTABLEPOINTER_H
#include <pandatoolbase.h>
#include "eggBackPointer.h"
#include <eggTable.h>
#include <eggXfmSAnim.h>
#include <pointerTo.h>
////////////////////////////////////////////////////////////////////
// Class : EggMatrixTablePointer
// Description : This stores a pointer back to an EggXfmSAnim table
// (i.e. an <Xfm$Anim_S$> entry in an egg file),
// corresponding to the animation data from a single
// bundle for this joint.
////////////////////////////////////////////////////////////////////
class EggMatrixTablePointer : public EggBackPointer {
public:
EggMatrixTablePointer(EggObject *object);
private:
PT(EggTable) _table;
PT(EggXfmSAnim) _xform;
public:
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
EggBackPointer::init_type();
register_type(_type_handle, "EggMatrixTablePointer",
EggBackPointer::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;
};
#endif

View File

@ -0,0 +1,4 @@
// Filename: eggSliderData.I
// Created by: drose (26Feb01)
//
////////////////////////////////////////////////////////////////////

View File

@ -0,0 +1,80 @@
// Filename: eggSliderData.cxx
// Created by: drose (26Feb01)
//
////////////////////////////////////////////////////////////////////
#include "eggSliderData.h"
#include "eggVertexPointer.h"
#include <eggPrimitive.h>
#include <eggVertex.h>
#include <eggSAnimData.h>
#include <indent.h>
////////////////////////////////////////////////////////////////////
// Function: EggSliderData::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
EggSliderData::
EggSliderData(EggCharacterCollection *collection,
EggCharacterData *char_data) :
EggComponentData(collection, char_data)
{
}
////////////////////////////////////////////////////////////////////
// Function: EggSliderData::add_back_pointer
// Access: Public, Virtual
// Description: Adds the indicated vertex, primitive, or morph table
// to the data.
////////////////////////////////////////////////////////////////////
void EggSliderData::
add_back_pointer(int model_index, EggObject *egg_object) {
if (egg_object->is_of_type(EggPrimitive::get_class_type())) {
// A primitive!
EggBackPointer *back = get_back_pointer(model_index);
if (back == (EggBackPointer *)NULL) {
back = new EggVertexPointer;
set_back_pointer(model_index, back);
}
} else if (egg_object->is_of_type(EggVertex::get_class_type())) {
// A vertex!
EggBackPointer *back = get_back_pointer(model_index);
if (back == (EggBackPointer *)NULL) {
back = new EggVertexPointer;
set_back_pointer(model_index, back);
}
} else if (egg_object->is_of_type(EggSAnimData::get_class_type())) {
// A slider animation table! Woo hoo!
EggBackPointer *back = get_back_pointer(model_index);
if (back == (EggBackPointer *)NULL) {
back = new EggVertexPointer;
set_back_pointer(model_index, back);
}
} else {
nout << "Invalid object added to slider for back pointer.\n";
}
}
////////////////////////////////////////////////////////////////////
// Function: EggSliderData::write
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
void EggSliderData::
write(ostream &out, int indent_level) const {
indent(out, indent_level)
<< "Slider " << get_name()
<< " (models:";
int num_back_pointers = get_num_back_pointers();
for (int model_index = 0; model_index < num_back_pointers; model_index++) {
if (has_back_pointer(model_index)) {
out << " " << model_index;
}
}
out << ")\n";
}

View File

@ -0,0 +1,35 @@
// Filename: eggSliderData.h
// Created by: drose (26Feb01)
//
////////////////////////////////////////////////////////////////////
#ifndef EGGSLIDERDATA_H
#define EGGSLIDERDATA_H
#include <pandatoolbase.h>
#include "eggComponentData.h"
////////////////////////////////////////////////////////////////////
// Class : EggSliderData
// Description : This corresponds to a single morph slider control.
// It contains back pointers to all the vertices and
// primitives that reference this slider across all
// models, as well as all the tables in which it appears
// in all animation files.
////////////////////////////////////////////////////////////////////
class EggSliderData : public EggComponentData {
public:
EggSliderData(EggCharacterCollection *collection,
EggCharacterData *char_data);
virtual void add_back_pointer(int model_index, EggObject *egg_object);
virtual void write(ostream &out, int indent_level = 0) const;
};
#include "eggSliderData.I"
#endif

View File

@ -0,0 +1,18 @@
// Filename: eggVertexPointer.cxx
// Created by: drose (26Feb01)
//
////////////////////////////////////////////////////////////////////
#include "eggVertexPointer.h"
TypeHandle EggVertexPointer::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: EggVertexPointer::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
EggVertexPointer::
EggVertexPointer() {
}

View File

@ -0,0 +1,46 @@
// Filename: eggVertexPointer.h
// Created by: drose (26Feb01)
//
////////////////////////////////////////////////////////////////////
#ifndef EGGVERTEXPOINTER_H
#define EGGVERTEXPOINTER_H
#include <pandatoolbase.h>
#include "eggBackPointer.h"
#include <eggGroup.h>
#include <pointerTo.h>
////////////////////////////////////////////////////////////////////
// Class : EggVertexPointer
// Description : This stores a pointer back to a <Vertex>, or to a
// particular pritimive like a <Polygon>, representing a
// morph offset.
////////////////////////////////////////////////////////////////////
class EggVertexPointer : public EggBackPointer {
public:
EggVertexPointer();
public:
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
EggBackPointer::init_type();
register_type(_type_handle, "EggVertexPointer",
EggBackPointer::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;
};
#endif

View File

@ -22,6 +22,7 @@
#end bin_target
#begin noinst_bin_target
#define LOCAL_LIBS eggcharbase $[LOCAL_LIBS]
#define TARGET egg-topstrip
#define SOURCES \