introducing egg-optchar, rough draft so far

This commit is contained in:
David Rose 2003-07-19 02:50:04 +00:00
parent b64887d146
commit ffbc370236
37 changed files with 1210 additions and 36 deletions

View File

@ -0,0 +1,18 @@
#define LOCAL_LIBS \
eggcharbase converter eggbase progbase
#define OTHER_LIBS \
egg:c pandaegg:m \
pnmimagetypes:c pnmimage:c linmath:c putil:c panda:m \
express:c pandaexpress:m \
dtoolutil:c dtoolbase:c dconfig:c dtoolconfig:m dtool:m pystub
#define UNIX_SYS_LIBS m
#begin test_bin_target
#define TARGET egg-optchar
#define SOURCES \
config_egg_optchar.cxx config_egg_optchar.h \
eggOptchar.cxx eggOptchar.h \
eggOptcharUserData.I eggOptcharUserData.cxx eggOptcharUserData.h
#end test_bin_target

View File

@ -0,0 +1,48 @@
// Filename: config_egg_optchar.cxx
// Created by: drose (18Jul03)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001, 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://www.panda3d.org/license.txt .
//
// To contact the maintainers of this program write to
// panda3d@yahoogroups.com .
//
////////////////////////////////////////////////////////////////////
#include "config_egg_optchar.h"
#include "eggOptcharUserData.h"
#include "dconfig.h"
Configure(config_egg_optchar);
ConfigureFn(config_egg_optchar) {
init_egg_optchar();
}
////////////////////////////////////////////////////////////////////
// Function: init_libegg_optchar
// Description: Initializes the library. This must be called at
// least once before any of the functions or classes in
// this library can be used. Normally it will be
// called by the static initializers and need not be
// called explicitly, but special cases exist.
////////////////////////////////////////////////////////////////////
void
init_egg_optchar() {
static bool initialized = false;
if (initialized) {
return;
}
initialized = true;
EggOptcharUserData::init_type();
}

View File

@ -0,0 +1,26 @@
// Filename: config_egg_optchar.h
// Created by: drose (18Jul03)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001, 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://www.panda3d.org/license.txt .
//
// To contact the maintainers of this program write to
// panda3d@yahoogroups.com .
//
////////////////////////////////////////////////////////////////////
#ifndef CONFIG_EGG_OPTCHAR_H
#define CONFIG_EGG_OPTCHAR_H
#include "pandatoolbase.h"
void init_egg_optchar();
#endif /* __CONFIG_UTIL_H__ */

View File

@ -0,0 +1,309 @@
// Filename: eggOptchar.cxx
// Created by: drose (18Jul03)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001, 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://www.panda3d.org/license.txt .
//
// To contact the maintainers of this program write to
// panda3d@yahoogroups.com .
//
////////////////////////////////////////////////////////////////////
#include "eggOptchar.h"
#include "eggOptcharUserData.h"
#include "dcast.h"
#include "eggJointData.h"
#include "eggSliderData.h"
#include "eggCharacterCollection.h"
#include "eggCharacterData.h"
#include "eggJointPointer.h"
#include "eggTable.h"
#include "compose_matrix.h"
////////////////////////////////////////////////////////////////////
// Function: EggOptchar::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
EggOptchar::
EggOptchar() {
add_path_replace_options();
add_path_store_options();
set_program_description
("egg-optchar performs basic optimizations of a character model "
"and its associated animations, primarily by analyzing the "
"animation tables and removing unneeded joints and/or morphs. "
"It can also perform basic restructuring operations on the "
"character hierarchy.");
add_option
("ls", "", 0,
"List the joint hierarchy instead of performing any operations.",
&EggOptchar::dispatch_none, &_list_hierarchy);
}
////////////////////////////////////////////////////////////////////
// Function: EggOptchar::run
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
void EggOptchar::
run() {
int num_characters = _collection->get_num_characters();
int ci;
for (ci = 0; ci < num_characters; ci++) {
EggCharacterData *char_data = _collection->get_character(ci);
nout << "Processing " << char_data->get_name() << "\n";
analyze_joints(char_data->get_root_joint());
analyze_sliders(char_data);
}
if (_list_hierarchy) {
for (ci = 0; ci < num_characters; ci++) {
EggCharacterData *char_data = _collection->get_character(ci);
nout << "Character: " << char_data->get_name() << "\n";
list_joints(char_data->get_root_joint(), 0);
list_scalars(char_data);
}
} else {
// Now, trigger the actual rebuilding of all the joint data.
for (ci = 0; ci < num_characters; ci++) {
EggCharacterData *char_data = _collection->get_character(ci);
char_data->get_root_joint()->do_rebuild();
}
write_eggs();
}
}
////////////////////////////////////////////////////////////////////
// Function: EggOptchar::handle_args
// Access: Protected, Virtual
// Description: Does something with the additional arguments on the
// command line (after all the -options have been
// parsed). Returns true if the arguments are good,
// false otherwise.
////////////////////////////////////////////////////////////////////
bool EggOptchar::
handle_args(ProgramBase::Args &args) {
if (_list_hierarchy) {
_read_only = true;
}
return EggCharacterFilter::handle_args(args);
}
////////////////////////////////////////////////////////////////////
// Function: EggOptchar::analyze_joints
// Access: Private
// Description: Recursively walks the joint hierarchy for a
// particular character, indentifying properties of each
// joint.
////////////////////////////////////////////////////////////////////
void EggOptchar::
analyze_joints(EggJointData *joint_data) {
PT(EggOptcharUserData) user_data = new EggOptcharUserData;
joint_data->set_user_data(user_data);
// Analyze the table of matrices for this joint, checking to see if
// they're all the same across all frames, or if any of them are
// different; also look for empty joints (that control no vertices).
int num_mats = 0;
bool different_mat = false;
bool has_vertices = false;
int num_models = joint_data->get_num_models();
for (int i = 0; i < num_models; i++) {
if (joint_data->has_model(i)) {
EggBackPointer *model = joint_data->get_model(i);
if (model->has_vertices()) {
has_vertices = true;
}
int num_frames = joint_data->get_num_frames(i);
int f;
for (f = 0; f < num_frames && !different_mat; f++) {
LMatrix4d mat = joint_data->get_frame(i, f);
num_mats++;
if (num_mats == 1) {
// This is the first matrix.
user_data->_static_mat = mat;
} else {
// This is a second or later matrix.
if (!mat.almost_equal(user_data->_static_mat)) {
// It's different than the first one.
different_mat = true;
}
}
}
}
}
if (!different_mat) {
// All the mats are the same for this joint.
user_data->_flags |= EggOptcharUserData::F_static;
if (num_mats == 0 ||
user_data->_static_mat.almost_equal(LMatrix4d::ident_mat())) {
// It's not only static, but it's the identity matrix.
user_data->_flags |= EggOptcharUserData::F_identity;
}
}
if (!has_vertices) {
// There are no vertices in this joint.
user_data->_flags |= EggOptcharUserData::F_empty;
}
int num_children = joint_data->get_num_children();
for (int i = 0; i < num_children; i++) {
analyze_joints(joint_data->get_child(i));
}
}
////////////////////////////////////////////////////////////////////
// Function: EggOptchar::analyze_sliders
// Access: Private
// Description: Linearly walks the slider list for a particular
// character, indentifying properties of each slider.
////////////////////////////////////////////////////////////////////
void EggOptchar::
analyze_sliders(EggCharacterData *char_data) {
int num_sliders = char_data->get_num_sliders();
for (int si = 0; si < num_sliders; si++) {
EggSliderData *slider_data = char_data->get_slider(si);
PT(EggOptcharUserData) user_data = new EggOptcharUserData;
slider_data->set_user_data(user_data);
// Analyze the table of values for this slider, checking to see if
// they're all the same across all frames, or if any of them are
// different; also look for empty sliders (that control no vertices).
int num_values = 0;
bool different_value = false;
bool has_vertices = false;
int num_models = slider_data->get_num_models();
for (int i = 0; i < num_models; i++) {
if (slider_data->has_model(i)) {
EggBackPointer *model = slider_data->get_model(i);
if (model->has_vertices()) {
has_vertices = true;
}
int num_frames = slider_data->get_num_frames(i);
int f;
for (f = 0; f < num_frames && !different_value; f++) {
double value = slider_data->get_frame(i, f);
num_values++;
if (num_values == 1) {
// This is the first value.
user_data->_static_value = value;
} else {
// This is a second or later value.
if (!IS_NEARLY_EQUAL(value, user_data->_static_value)) {
// It's different than the first one.
different_value = true;
}
}
}
}
}
if (!different_value) {
// All the values are the same for this slider.
user_data->_flags |= EggOptcharUserData::F_static;
if (num_values == 0 || IS_NEARLY_EQUAL(user_data->_static_value, 0.0)) {
// It's not only static, but it's the identity value.
user_data->_flags |= EggOptcharUserData::F_identity;
}
}
if (!has_vertices) {
// There are no vertices in this slider.
user_data->_flags |= EggOptcharUserData::F_empty;
}
}
}
////////////////////////////////////////////////////////////////////
// Function: EggOptchar::list_joints
// Access: Private
// Description: Outputs a list of the joint hierarchy.
////////////////////////////////////////////////////////////////////
void EggOptchar::
list_joints(EggJointData *joint_data, int indent_level) {
// Don't list the root joint, which is artificially created when the
// character is loaded. Instead, list each child as it is
// encountered.
int num_children = joint_data->get_num_children();
for (int i = 0; i < num_children; i++) {
EggJointData *child_data = joint_data->get_child(i);
describe_component(child_data, indent_level);
list_joints(child_data, indent_level + 2);
}
}
////////////////////////////////////////////////////////////////////
// Function: EggOptchar::list_scalars
// Access: Private
// Description: Outputs a list of the scalars.
////////////////////////////////////////////////////////////////////
void EggOptchar::
list_scalars(EggCharacterData *char_data) {
int num_sliders = char_data->get_num_sliders();
for (int si = 0; si < num_sliders; si++) {
EggSliderData *slider_data = char_data->get_slider(si);
describe_component(slider_data, 0);
}
}
////////////////////////////////////////////////////////////////////
// Function: EggOptchar::describe_component
// Access: Private
// Description: Describes one particular slider or joint.
////////////////////////////////////////////////////////////////////
void EggOptchar::
describe_component(EggComponentData *comp_data, int indent_level) {
indent(nout, indent_level)
<< comp_data->get_name();
EggOptcharUserData *user_data =
DCAST(EggOptcharUserData, comp_data->get_user_data());
if (user_data->is_identity()) {
nout << " (identity)";
} else if (user_data->is_static()) {
nout << " (static)";
}
if (user_data->is_empty()) {
nout << " (empty)";
}
nout << "\n";
}
int main(int argc, char *argv[]) {
EggOptchar prog;
prog.parse_command_line(argc, argv);
prog.run();
return 0;
}

View File

@ -0,0 +1,62 @@
// Filename: eggOptchar.h
// Created by: drose (18Jul03)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001, 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://www.panda3d.org/license.txt .
//
// To contact the maintainers of this program write to
// panda3d@yahoogroups.com .
//
////////////////////////////////////////////////////////////////////
#ifndef EGGOPTCHAR_H
#define EGGOPTCHAR_H
#include "pandatoolbase.h"
#include "eggCharacterFilter.h"
#include "luse.h"
#include "pvector.h"
class EggCharacterData;
class EggComponentData;
class EggJointData;
class EggSliderData;
////////////////////////////////////////////////////////////////////
// Class : EggOptchar
// Description : Performs basic optimizations of a character model and
// its associated animations, by analyzing the animation
// tables and removing unneeded joints and/or morphs.
// Can also be used to restructure the character
// hierarchy.
////////////////////////////////////////////////////////////////////
class EggOptchar : public EggCharacterFilter {
public:
EggOptchar();
void run();
protected:
virtual bool handle_args(Args &args);
private:
void analyze_joints(EggJointData *joint_data);
void analyze_sliders(EggCharacterData *char_data);
void list_joints(EggJointData *joint_data, int indent_level);
void list_scalars(EggCharacterData *char_data);
void describe_component(EggComponentData *comp_data, int indent_level);
bool _list_hierarchy;
};
#endif

View File

@ -0,0 +1,89 @@
// Filename: eggOptcharUserData.I
// Created by: drose (18Jul03)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001, 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://www.panda3d.org/license.txt .
//
// To contact the maintainers of this program write to
// panda3d@yahoogroups.com .
//
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Function: EggOptcharUserData::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE EggOptcharUserData::
EggOptcharUserData() {
_flags = 0;
_static_mat = LMatrix4d::ident_mat();
_static_value = 0.0;
}
////////////////////////////////////////////////////////////////////
// Function: EggOptcharUserData::Copy constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE EggOptcharUserData::
EggOptcharUserData(const EggOptcharUserData &copy) :
EggUserData(copy),
_flags(copy._flags),
_static_mat(copy._static_mat),
_static_value(copy._static_value)
{
}
////////////////////////////////////////////////////////////////////
// Function: EggOptcharUserData::Copy assignment operator
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE void EggOptcharUserData::
operator = (const EggOptcharUserData &copy) {
EggUserData::operator = (copy);
_flags = copy._flags;
_static_mat = copy._static_mat;
_static_value = copy._static_value;
}
////////////////////////////////////////////////////////////////////
// Function: EggOptcharUserData::is_static
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE bool EggOptcharUserData::
is_static() const {
return (_flags & F_static) != 0;
}
////////////////////////////////////////////////////////////////////
// Function: EggOptcharUserData::is_identity
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE bool EggOptcharUserData::
is_identity() const {
return (_flags & F_identity) != 0;
}
////////////////////////////////////////////////////////////////////
// Function: EggOptcharUserData::is_empty
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE bool EggOptcharUserData::
is_empty() const {
return (_flags & F_empty) != 0;
}

View File

@ -0,0 +1,21 @@
// Filename: eggOptcharUserData.cxx
// Created by: drose (18Jul03)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001, 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://www.panda3d.org/license.txt .
//
// To contact the maintainers of this program write to
// panda3d@yahoogroups.com .
//
////////////////////////////////////////////////////////////////////
#include "eggOptcharUserData.h"
TypeHandle EggOptcharUserData::_type_handle;

View File

@ -0,0 +1,72 @@
// Filename: eggOptcharUserData.h
// Created by: drose (18Jul03)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001, 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://www.panda3d.org/license.txt .
//
// To contact the maintainers of this program write to
// panda3d@yahoogroups.com .
//
////////////////////////////////////////////////////////////////////
#ifndef EGGOPTCHARUSERDATA_H
#define EGGOPTCHARUSERDATA_H
#include "pandatoolbase.h"
#include "eggUserData.h"
#include "luse.h"
////////////////////////////////////////////////////////////////////
// Class : EggOptcharUserData
// Description : This class contains extra user data which is
// piggybacked onto EggGroup objects for the purpose of
// the maya converter.
////////////////////////////////////////////////////////////////////
class EggOptcharUserData : public EggUserData {
public:
INLINE EggOptcharUserData();
INLINE EggOptcharUserData(const EggOptcharUserData &copy);
INLINE void operator = (const EggOptcharUserData &copy);
INLINE bool is_static() const;
INLINE bool is_identity() const;
INLINE bool is_empty() const;
enum Flags {
F_static = 0x0001,
F_identity = 0x0002,
F_empty = 0x0004,
F_remove = 0x0008
};
int _flags;
LMatrix4d _static_mat;
double _static_value;
public:
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
EggUserData::init_type();
register_type(_type_handle, "EggOptcharUserData",
EggUserData::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;
};
#include "eggOptcharUserData.I"
#endif

View File

@ -32,11 +32,30 @@
#include "texturePosition.h"
#include "palettePage.h"
#include <dconfig.h>
#include "dconfig.h"
Configure(config_egg_palettize);
ConfigureFn(config_egg_palettize) {
init_egg_palettize();
}
////////////////////////////////////////////////////////////////////
// Function: init_libegg_palettize
// Description: Initializes the library. This must be called at
// least once before any of the functions or classes in
// this library can be used. Normally it will be
// called by the static initializers and need not be
// called explicitly, but special cases exist.
////////////////////////////////////////////////////////////////////
void
init_egg_palettize() {
static bool initialized = false;
if (initialized) {
return;
}
initialized = true;
Palettizer::init_type();
EggFile::init_type();
PaletteGroup::init_type();

View File

@ -19,8 +19,8 @@
#ifndef CONFIG_EGG_PALETTIZE_H
#define CONFIG_EGG_PALETTIZE_H
#include <pandatoolbase.h>
#include "pandatoolbase.h"
// No variables to declare here.
void init_egg_palettize();
#endif /* __CONFIG_UTIL_H__ */

View File

@ -56,6 +56,12 @@ EggMultiFilter(bool allow_empty) : _allow_empty(allow_empty) {
"for an output directory; however, it's risky because the original "
"input egg files are lost.",
&EggMultiFilter::dispatch_none, &_inplace);
// Derived programs will set this true when they discover some
// command-line option that will prevent the program from generating
// output. This removes some checks for an output specification in
// handle_args.
_read_only = false;
}
@ -76,7 +82,6 @@ handle_args(ProgramBase::Args &args) {
}
} else {
// These only apply if we have specified any egg files.
if (_got_output_filename && args.size() == 1) {
if (_got_output_dirname) {
nout << "Cannot specify both -o and -d.\n";
@ -97,8 +102,10 @@ handle_args(ProgramBase::Args &args) {
return false;
} else if (!_got_output_dirname && !_inplace) {
nout << "You must specify either -inplace or -d.\n";
return false;
if (!_read_only) {
nout << "You must specify either -inplace or -d.\n";
return false;
}
}
}
}
@ -181,6 +188,7 @@ get_output_filename(const Filename &source_filename) const {
////////////////////////////////////////////////////////////////////
void EggMultiFilter::
write_eggs() {
nassertv(!_read_only);
Eggs::iterator ei;
for (ei = _eggs.begin(); ei != _eggs.end(); ++ei) {
EggData *data = (*ei);

View File

@ -47,6 +47,8 @@ protected:
bool _got_output_dirname;
Filename _output_dirname;
bool _inplace;
bool _read_only;
};
#endif

View File

@ -13,7 +13,8 @@
eggCharacterData.h eggCharacterData.I eggCharacterFilter.h \
eggComponentData.h eggComponentData.I eggJointData.h \
eggJointData.I eggJointPointer.h eggJointNodePointer.h \
eggMatrixTablePointer.h eggSliderData.h eggSliderData.I \
eggMatrixTablePointer.h eggScalarTablePointer.h \
eggSliderData.h eggSliderData.I \
eggVertexPointer.h
#define INCLUDED_SOURCES \
@ -21,7 +22,8 @@
eggCharacterCollection.cxx eggCharacterData.cxx \
eggCharacterFilter.cxx eggComponentData.cxx eggJointData.cxx \
eggJointPointer.cxx eggJointNodePointer.cxx \
eggMatrixTablePointer.cxx eggSliderData.cxx \
eggMatrixTablePointer.cxx eggScalarTablePointer.cxx \
eggSliderData.cxx \
eggVertexPointer.cxx
#define INSTALL_HEADERS \
@ -33,6 +35,7 @@
eggJointPointer.h \
eggJointNodePointer.h \
eggMatrixTablePointer.h \
eggScalarTablePointer.h \
eggSliderData.I eggSliderData.h \
eggVertexPointer.h

View File

@ -18,12 +18,17 @@
#include "config_eggcharbase.h"
#include "eggBackPointer.h"
#include "eggComponentData.h"
#include "eggJointData.h"
#include "eggJointNodePointer.h"
#include "eggJointPointer.h"
#include "eggMatrixTablePointer.h"
#include "eggScalarTablePointer.h"
#include "eggSliderData.h"
#include "eggSliderPointer.h"
#include "eggVertexPointer.h"
#include <dconfig.h>
#include "dconfig.h"
Configure(config_eggcharbase);
@ -51,8 +56,13 @@ init_libeggcharbase() {
initialized = true;
EggBackPointer::init_type();
EggComponentData::init_type();
EggJointData::init_type();
EggJointNodePointer::init_type();
EggJointPointer::init_type();
EggMatrixTablePointer::init_type();
EggScalarTablePointer::init_type();
EggSliderData::init_type();
EggSliderPointer::init_type();
EggVertexPointer::init_type();
}

View File

@ -29,3 +29,16 @@ TypeHandle EggBackPointer::_type_handle;
EggBackPointer::
EggBackPointer() {
}
////////////////////////////////////////////////////////////////////
// Function: EggBackPointer::has_vertices
// Access: Public, Virtual
// Description: Returns true if there are any vertices referenced by
// the node this points to, false otherwise. For
// certain kinds of back pointers (e.g. table animation
// entries), this is always false.
////////////////////////////////////////////////////////////////////
bool EggBackPointer::
has_vertices() const {
return false;
}

View File

@ -19,9 +19,9 @@
#ifndef EGGBACKPOINTER_H
#define EGGBACKPOINTER_H
#include <pandatoolbase.h>
#include "pandatoolbase.h"
#include <typedObject.h>
#include "typedObject.h"
////////////////////////////////////////////////////////////////////
// Class : EggBackPointer
@ -40,6 +40,7 @@ class EggBackPointer : public TypedObject {
public:
EggBackPointer();
virtual bool has_vertices() const;
public:
static TypeHandle get_class_type() {

View File

@ -459,6 +459,7 @@ match_egg_nodes(EggCharacterData *char_data, EggJointData *joint_data,
EggNode *egg_node = (*ei);
EggJointData *data = make_joint_data(char_data);
joint_data->_children.push_back(data);
char_data->_components.push_back(data);
data->_parent = joint_data;
found_egg_match(char_data, data, egg_node, egg_index, model_index);
}
@ -564,6 +565,7 @@ match_egg_nodes(EggCharacterData *char_data, EggJointData *joint_data,
EggNode *egg_node = (*ei);
EggJointData *data = make_joint_data(char_data);
joint_data->_children.push_back(data);
char_data->_components.push_back(data);
data->_parent = joint_data;
found_egg_match(char_data, data, egg_node, egg_index, model_index);
}

View File

@ -93,3 +93,52 @@ INLINE EggJointData *EggCharacterData::
find_joint(const string &name) const {
return _root_joint->find_joint(name);
}
////////////////////////////////////////////////////////////////////
// Function: EggCharacterData::get_num_sliders
// Access: Public
// Description: Returns the number of sliders in the character
// slider list.
////////////////////////////////////////////////////////////////////
INLINE int EggCharacterData::
get_num_sliders() const {
return _sliders.size();
}
////////////////////////////////////////////////////////////////////
// Function: EggCharacterData::get_slider
// Access: Public
// Description: Returns the nth slider in the character slider list.
////////////////////////////////////////////////////////////////////
INLINE EggSliderData *EggCharacterData::
get_slider(int n) const {
nassertr(n >= 0 && n < (int)_sliders.size(), NULL);
return _sliders[n];
}
////////////////////////////////////////////////////////////////////
// Function: EggCharacterData::get_num_components
// Access: Public
// Description: Returns the total number of joints and sliders in
// the character.
////////////////////////////////////////////////////////////////////
INLINE int EggCharacterData::
get_num_components() const {
return _components.size();
}
////////////////////////////////////////////////////////////////////
// Function: EggCharacterData::get_component
// Access: Public
// Description: Returns the nth joint or slider in the character.
// This can be used to walk linearly through all joints
// and sliders in the character when you don't care
// about making a distinction between the two; it
// returns the same objects that can also be discovered
// via get_slider() and get_root_joint().
////////////////////////////////////////////////////////////////////
INLINE EggComponentData *EggCharacterData::
get_component(int n) const {
nassertr(n >= 0 && n < (int)_components.size(), NULL);
return _components[n];
}

View File

@ -32,6 +32,7 @@ EggCharacterData::
EggCharacterData(EggCharacterCollection *collection) {
_collection = collection;
_root_joint = _collection->make_joint_data(this);
// The fictitious root joint is not added to the _components list.
}
////////////////////////////////////////////////////////////////////
@ -45,7 +46,7 @@ EggCharacterData::
Sliders::iterator si;
for (si = _sliders.begin(); si != _sliders.end(); ++si) {
EggSliderData *slider = (*si).second;
EggSliderData *slider = (*si);
delete slider;
}
}
@ -71,6 +72,23 @@ add_model(int model_index, EggNode *model_root) {
_models.push_back(m);
}
////////////////////////////////////////////////////////////////////
// Function: EggCharacterData::find_slider
// Access: Public
// Description: Returns the slider with the indicated name, or NULL
// if no slider has that name.
////////////////////////////////////////////////////////////////////
EggSliderData *EggCharacterData::
find_slider(const string &name) const {
SlidersByName::const_iterator si;
si = _sliders_by_name.find(name);
if (si != _sliders_by_name.end()) {
return (*si).second;
}
return NULL;
}
////////////////////////////////////////////////////////////////////
// Function: EggCharacterData::make_slider
// Access: Public
@ -79,15 +97,17 @@ add_model(int model_index, EggNode *model_root) {
////////////////////////////////////////////////////////////////////
EggSliderData *EggCharacterData::
make_slider(const string &name) {
Sliders::iterator si;
si = _sliders.find(name);
if (si != _sliders.end()) {
SlidersByName::const_iterator si;
si = _sliders_by_name.find(name);
if (si != _sliders_by_name.end()) {
return (*si).second;
}
EggSliderData *slider = _collection->make_slider_data(this);
slider->set_name(name);
_sliders.insert(Sliders::value_type(name, slider));
_sliders_by_name.insert(SlidersByName::value_type(name, slider));
_sliders.push_back(slider);
_components.push_back(slider);
return slider;
}
@ -104,7 +124,7 @@ write(ostream &out, int indent_level) const {
Sliders::const_iterator si;
for (si = _sliders.begin(); si != _sliders.end(); ++si) {
EggSliderData *slider = (*si).second;
EggSliderData *slider = (*si);
slider->write(out, indent_level + 2);
}
}

View File

@ -72,8 +72,14 @@ public:
INLINE EggJointData *get_root_joint() const;
INLINE EggJointData *find_joint(const string &name) const;
INLINE int get_num_sliders() const;
INLINE EggSliderData *get_slider(int n) const;
EggSliderData *find_slider(const string &name) const;
EggSliderData *make_slider(const string &name);
INLINE int get_num_components() const;
INLINE EggComponentData *get_component(int n) const;
virtual void write(ostream &out, int indent_level = 0) const;
protected:
@ -88,8 +94,16 @@ protected:
EggCharacterCollection *_collection;
EggJointData *_root_joint;
typedef pmap<string, EggSliderData *> Sliders;
typedef pmap<string, EggSliderData *> SlidersByName;
SlidersByName _sliders_by_name;
typedef pvector<EggSliderData *> Sliders;
Sliders _sliders;
typedef pvector<EggComponentData *> Components;
Components _components;
friend class EggCharacterCollection;
};
#include "eggCharacterData.I"

View File

@ -21,6 +21,8 @@
#include "indent.h"
TypeHandle EggComponentData::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: EggComponentData::Constructor

View File

@ -21,12 +21,12 @@
#include "pandatoolbase.h"
#include "eggObject.h"
#include "namable.h"
class EggCharacterCollection;
class EggCharacterData;
class EggBackPointer;
class EggObject;
////////////////////////////////////////////////////////////////////
// Class : EggComponentData
@ -36,7 +36,7 @@ class EggObject;
// back pointers to the references to this component in
// all model and animation egg files read.
////////////////////////////////////////////////////////////////////
class EggComponentData : public Namable {
class EggComponentData : public EggObject, public Namable {
public:
EggComponentData(EggCharacterCollection *collection,
EggCharacterData *char_data);
@ -63,6 +63,24 @@ protected:
EggCharacterCollection *_collection;
EggCharacterData *_char_data;
public:
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
EggObject::init_type();
register_type(_type_handle, "EggComponentData",
EggObject::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;
};
#include "eggComponentData.I"

View File

@ -17,6 +17,16 @@
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Function: EggJointData::get_parent
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE EggJointData *EggJointData::
get_parent() const {
return _parent;
}
////////////////////////////////////////////////////////////////////
// Function: EggJointData::get_num_children
// Access: Public

View File

@ -25,6 +25,8 @@
#include "eggTable.h"
#include "indent.h"
TypeHandle EggJointData::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: EggJointData::Constructor

View File

@ -38,6 +38,7 @@ public:
EggJointData(EggCharacterCollection *collection,
EggCharacterData *char_data);
INLINE EggJointData *get_parent() const;
INLINE int get_num_children() const;
INLINE EggJointData *get_child(int n) const;
EggJointData *find_joint(const string &name);
@ -58,6 +59,24 @@ protected:
EggJointData *_parent;
friend class EggCharacterCollection;
public:
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
EggComponentData::init_type();
register_type(_type_handle, "EggJointData",
EggComponentData::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;
};
#include "eggJointData.I"

View File

@ -138,3 +138,20 @@ do_rebuild() {
_rebuild_frames.clear();
return true;
}
////////////////////////////////////////////////////////////////////
// Function: EggJointNodePointer::has_vertices
// Access: Public, Virtual
// Description: Returns true if there are any vertices referenced by
// the node this points to, false otherwise. For
// certain kinds of back pointers (e.g. table animation
// entries), this is always false.
////////////////////////////////////////////////////////////////////
bool EggJointNodePointer::
has_vertices() const {
if (_joint != (EggGroup *)NULL) {
return (_joint->vref_size() != 0);
}
return false;
}

View File

@ -41,6 +41,8 @@ public:
virtual bool add_rebuild_frame(const LMatrix4d &mat);
virtual bool do_rebuild();
virtual bool has_vertices() const;
private:
PT(EggGroup) _joint;

View File

@ -0,0 +1,66 @@
// Filename: eggScalarTablePointer.cxx
// Created by: drose (18Jul03)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001, 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://www.panda3d.org/license.txt .
//
// To contact the maintainers of this program write to
// panda3d@yahoogroups.com .
//
////////////////////////////////////////////////////////////////////
#include "eggScalarTablePointer.h"
#include "dcast.h"
TypeHandle EggScalarTablePointer::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: EggScalarTablePointer::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
EggScalarTablePointer::
EggScalarTablePointer(EggObject *object) {
_data = DCAST(EggSAnimData, object);
}
////////////////////////////////////////////////////////////////////
// Function: EggScalarTablePointer::get_num_frames
// Access: Public, Virtual
// Description: Returns the number of frames of animation for this
// particular slider.
////////////////////////////////////////////////////////////////////
int EggScalarTablePointer::
get_num_frames() const {
if (_data == (EggSAnimData *)NULL) {
return 0;
} else {
return _data->get_num_rows();
}
}
////////////////////////////////////////////////////////////////////
// Function: EggScalarTablePointer::get_frame
// Access: Public, Virtual
// Description: Returns the value corresponding to this
// slider position in the nth frame.
////////////////////////////////////////////////////////////////////
double EggScalarTablePointer::
get_frame(int n) const {
if (get_num_frames() == 1) {
// If we have exactly one frame, then we have as many frames as we
// want; just repeat the first frame.
n = 0;
}
nassertr(n >= 0 && n < get_num_frames(), 0.0);
return _data->get_value(n);
}

View File

@ -0,0 +1,66 @@
// Filename: eggScalarTablePointer.h
// Created by: drose (18Jul03)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001, 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://www.panda3d.org/license.txt .
//
// To contact the maintainers of this program write to
// panda3d@yahoogroups.com .
//
////////////////////////////////////////////////////////////////////
#ifndef EGGSCALARTABLEPOINTER_H
#define EGGSCALARTABLEPOINTER_H
#include "pandatoolbase.h"
#include "eggSliderPointer.h"
#include "eggSAnimData.h"
#include "pointerTo.h"
////////////////////////////////////////////////////////////////////
// Class : EggScalarTablePointer
// Description : This stores a pointer back to an EggSAnimData table
// (i.e. an <S$Anim> entry in an egg file),
// corresponding to the animation data from a single
// bundle for this slider.
////////////////////////////////////////////////////////////////////
class EggScalarTablePointer : public EggSliderPointer {
public:
EggScalarTablePointer(EggObject *object);
virtual int get_num_frames() const;
virtual double get_frame(int n) const;
private:
PT(EggSAnimData) _data;
public:
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
EggSliderPointer::init_type();
register_type(_type_handle, "EggScalarTablePointer",
EggSliderPointer::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

@ -18,11 +18,15 @@
#include "eggSliderData.h"
#include "eggVertexPointer.h"
#include "eggScalarTablePointer.h"
#include "eggSliderPointer.h"
#include <eggPrimitive.h>
#include <eggVertex.h>
#include <eggSAnimData.h>
#include <indent.h>
#include "eggPrimitive.h"
#include "eggVertex.h"
#include "eggSAnimData.h"
#include "indent.h"
TypeHandle EggSliderData::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: EggSliderData::Constructor
@ -36,6 +40,44 @@ EggSliderData(EggCharacterCollection *collection,
{
}
////////////////////////////////////////////////////////////////////
// Function: EggSliderData::get_num_frames
// Access: Public
// Description: Returns the number of frames of animation for this
// particular slider in the indicated model.
////////////////////////////////////////////////////////////////////
int EggSliderData::
get_num_frames(int model_index) const {
EggBackPointer *back = get_model(model_index);
if (back == (EggBackPointer *)NULL) {
return 0;
}
EggSliderPointer *slider;
DCAST_INTO_R(slider, back, 0);
return slider->get_num_frames();
}
////////////////////////////////////////////////////////////////////
// Function: EggSliderData::get_frame
// Access: Public
// Description: Returns the value corresponding to this slider
// position in the nth frame in the indicated model.
////////////////////////////////////////////////////////////////////
double EggSliderData::
get_frame(int model_index, int n) const {
EggBackPointer *back = get_model(model_index);
if (back == (EggBackPointer *)NULL) {
return 0.0;
}
EggSliderPointer *slider;
DCAST_INTO_R(slider, back, 0.0);
return slider->get_frame(n);
}
////////////////////////////////////////////////////////////////////
// Function: EggSliderData::add_back_pointer
// Access: Public, Virtual
@ -48,7 +90,7 @@ add_back_pointer(int model_index, EggObject *egg_object) {
// A primitive!
EggBackPointer *back = get_model(model_index);
if (back == (EggBackPointer *)NULL) {
back = new EggVertexPointer;
back = new EggVertexPointer(egg_object);
set_model(model_index, back);
}
@ -56,7 +98,7 @@ add_back_pointer(int model_index, EggObject *egg_object) {
// A vertex!
EggBackPointer *back = get_model(model_index);
if (back == (EggBackPointer *)NULL) {
back = new EggVertexPointer;
back = new EggVertexPointer(egg_object);
set_model(model_index, back);
}
@ -64,7 +106,7 @@ add_back_pointer(int model_index, EggObject *egg_object) {
// A slider animation table! Woo hoo!
EggBackPointer *back = get_model(model_index);
if (back == (EggBackPointer *)NULL) {
back = new EggVertexPointer;
back = new EggScalarTablePointer(egg_object);
set_model(model_index, back);
}

View File

@ -37,8 +37,29 @@ public:
EggSliderData(EggCharacterCollection *collection,
EggCharacterData *char_data);
int get_num_frames(int model_index) const;
double get_frame(int model_index, int n) const;
virtual void add_back_pointer(int model_index, EggObject *egg_object);
virtual void write(ostream &out, int indent_level = 0) const;
public:
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
EggComponentData::init_type();
register_type(_type_handle, "EggSliderData",
EggComponentData::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;
};
#include "eggSliderData.I"

View File

@ -0,0 +1,22 @@
// Filename: eggSliderPointer.cxx
// Created by: drose (18Jul03)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001, 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://www.panda3d.org/license.txt .
//
// To contact the maintainers of this program write to
// panda3d@yahoogroups.com .
//
////////////////////////////////////////////////////////////////////
#include "eggSliderPointer.h"
TypeHandle EggSliderPointer::_type_handle;

View File

@ -0,0 +1,58 @@
// Filename: eggSliderPointer.h
// Created by: drose (18Jul03)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001, 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://www.panda3d.org/license.txt .
//
// To contact the maintainers of this program write to
// panda3d@yahoogroups.com .
//
////////////////////////////////////////////////////////////////////
#ifndef EGGSLIDERPOINTER_H
#define EGGSLIDERPOINTER_H
#include "pandatoolbase.h"
#include "eggBackPointer.h"
#include "luse.h"
////////////////////////////////////////////////////////////////////
// Class : EggSliderPointer
// Description : This is a base class for EggVertexPointer and
// EggScalarTablePointer.
////////////////////////////////////////////////////////////////////
class EggSliderPointer : public EggBackPointer {
public:
virtual int get_num_frames() const=0;
virtual double get_frame(int n) const=0;
public:
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
EggBackPointer::init_type();
register_type(_type_handle, "EggSliderPointer",
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

@ -27,5 +27,41 @@ TypeHandle EggVertexPointer::_type_handle;
// Description:
////////////////////////////////////////////////////////////////////
EggVertexPointer::
EggVertexPointer() {
EggVertexPointer(EggObject *egg_object) {
}
////////////////////////////////////////////////////////////////////
// Function: EggVertexPointer::get_num_frames
// Access: Public, Virtual
// Description: Returns the number of frames of animation for this
// particular slider.
////////////////////////////////////////////////////////////////////
int EggVertexPointer::
get_num_frames() const {
return 0;
}
////////////////////////////////////////////////////////////////////
// Function: EggVertexPointer::get_frame
// Access: Public, Virtual
// Description: Returns the value corresponding to this
// slider position in the nth frame.
////////////////////////////////////////////////////////////////////
double EggVertexPointer::
get_frame(int n) const {
nassertr(false, 0.0);
return 0.0;
}
////////////////////////////////////////////////////////////////////
// Function: EggVertexPointer::has_vertices
// Access: Public, Virtual
// Description: Returns true if there are any vertices referenced by
// the node this points to, false otherwise. For
// certain kinds of back pointers (e.g. table animation
// entries), this is always false.
////////////////////////////////////////////////////////////////////
bool EggVertexPointer::
has_vertices() const {
return true;
}

View File

@ -21,7 +21,7 @@
#include "pandatoolbase.h"
#include "eggBackPointer.h"
#include "eggSliderPointer.h"
#include "eggGroup.h"
#include "pointerTo.h"
@ -32,18 +32,23 @@
// particular pritimive like a <Polygon>, representing a
// morph offset.
////////////////////////////////////////////////////////////////////
class EggVertexPointer : public EggBackPointer {
class EggVertexPointer : public EggSliderPointer {
public:
EggVertexPointer();
EggVertexPointer(EggObject *egg_object);
virtual int get_num_frames() const;
virtual double get_frame(int n) const;
virtual bool has_vertices() const;
public:
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
EggBackPointer::init_type();
EggSliderPointer::init_type();
register_type(_type_handle, "EggVertexPointer",
EggBackPointer::get_class_type());
EggSliderPointer::get_class_type());
}
virtual TypeHandle get_type() const {
return get_class_type();

View File

@ -9,6 +9,8 @@
#include "eggJointPointer.cxx"
#include "eggJointNodePointer.cxx"
#include "eggMatrixTablePointer.cxx"
#include "eggScalarTablePointer.cxx"
#include "eggSliderData.cxx"
#include "eggSliderPointer.cxx"
#include "eggVertexPointer.cxx"

View File

@ -19,10 +19,10 @@
#ifndef EGGTOPSTRIP_H
#define EGGTOPSTRIP_H
#include <pandatoolbase.h>
#include "pandatoolbase.h"
#include <eggCharacterFilter.h>
#include <luse.h>
#include "eggCharacterFilter.h"
#include "luse.h"
#include "pvector.h"