mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-04 10:54:24 -04:00
reduce memory usage for egg-optchar
This commit is contained in:
parent
fa2e6e4992
commit
9b67ed9caf
@ -13,8 +13,11 @@
|
|||||||
#define SOURCES \
|
#define SOURCES \
|
||||||
config_eggcharbase.h eggBackPointer.h \
|
config_eggcharbase.h eggBackPointer.h \
|
||||||
eggCharacterCollection.h eggCharacterCollection.I \
|
eggCharacterCollection.h eggCharacterCollection.I \
|
||||||
eggCharacterData.h eggCharacterData.I eggCharacterFilter.h \
|
eggCharacterData.h eggCharacterData.I \
|
||||||
eggComponentData.h eggComponentData.I eggJointData.h \
|
eggCharacterDb.I eggCharacterDb.h \
|
||||||
|
eggCharacterFilter.h \
|
||||||
|
eggComponentData.h eggComponentData.I \
|
||||||
|
eggJointData.h \
|
||||||
eggJointData.I eggJointPointer.h eggJointPointer.I \
|
eggJointData.I eggJointPointer.h eggJointPointer.I \
|
||||||
eggJointNodePointer.h \
|
eggJointNodePointer.h \
|
||||||
eggMatrixTablePointer.h eggScalarTablePointer.h \
|
eggMatrixTablePointer.h eggScalarTablePointer.h \
|
||||||
@ -24,6 +27,7 @@
|
|||||||
#define INCLUDED_SOURCES \
|
#define INCLUDED_SOURCES \
|
||||||
config_eggcharbase.cxx eggBackPointer.cxx \
|
config_eggcharbase.cxx eggBackPointer.cxx \
|
||||||
eggCharacterCollection.cxx eggCharacterData.cxx \
|
eggCharacterCollection.cxx eggCharacterData.cxx \
|
||||||
|
eggCharacterDb.cxx \
|
||||||
eggCharacterFilter.cxx eggComponentData.cxx eggJointData.cxx \
|
eggCharacterFilter.cxx eggComponentData.cxx eggJointData.cxx \
|
||||||
eggJointPointer.cxx eggJointNodePointer.cxx \
|
eggJointPointer.cxx eggJointNodePointer.cxx \
|
||||||
eggMatrixTablePointer.cxx eggScalarTablePointer.cxx \
|
eggMatrixTablePointer.cxx eggScalarTablePointer.cxx \
|
||||||
@ -34,7 +38,9 @@
|
|||||||
#define INSTALL_HEADERS \
|
#define INSTALL_HEADERS \
|
||||||
eggBackPointer.h \
|
eggBackPointer.h \
|
||||||
eggCharacterCollection.I eggCharacterCollection.h \
|
eggCharacterCollection.I eggCharacterCollection.h \
|
||||||
eggCharacterData.I eggCharacterData.h eggCharacterFilter.h \
|
eggCharacterData.I eggCharacterData.h \
|
||||||
|
eggCharacterDb.I eggCharacterDb.h \
|
||||||
|
eggCharacterFilter.h \
|
||||||
eggComponentData.I eggComponentData.h \
|
eggComponentData.I eggComponentData.h \
|
||||||
eggJointData.h eggJointData.I \
|
eggJointData.h eggJointData.I \
|
||||||
eggJointPointer.h eggJointPointer.I \
|
eggJointPointer.h eggJointPointer.I \
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
#include "eggCharacterData.h"
|
#include "eggCharacterData.h"
|
||||||
#include "eggCharacterCollection.h"
|
#include "eggCharacterCollection.h"
|
||||||
|
#include "eggCharacterDb.h"
|
||||||
#include "eggJointData.h"
|
#include "eggJointData.h"
|
||||||
#include "eggSliderData.h"
|
#include "eggSliderData.h"
|
||||||
#include "indent.h"
|
#include "indent.h"
|
||||||
@ -227,8 +228,13 @@ do_reparent() {
|
|||||||
// frame.
|
// frame.
|
||||||
Models::const_iterator mi;
|
Models::const_iterator mi;
|
||||||
for (mi = _models.begin(); mi != _models.end(); ++mi) {
|
for (mi = _models.begin(); mi != _models.end(); ++mi) {
|
||||||
|
EggCharacterDb db;
|
||||||
int model_index = (*mi)._model_index;
|
int model_index = (*mi)._model_index;
|
||||||
int num_frames = get_num_frames(model_index);
|
int num_frames = get_num_frames(model_index);
|
||||||
|
nout << " computing " << (mi - _models.begin()) + 1
|
||||||
|
<< " of " << _models.size()
|
||||||
|
<< ": " << (*mi)._egg_data->get_egg_filename()
|
||||||
|
<< " (" << num_frames << " frames)\n";
|
||||||
for (int f = 0; f < num_frames; f++) {
|
for (int f = 0; f < num_frames; f++) {
|
||||||
// First, walk through all the joints and flush the computed net
|
// First, walk through all the joints and flush the computed net
|
||||||
// transforms from before.
|
// transforms from before.
|
||||||
@ -242,20 +248,26 @@ do_reparent() {
|
|||||||
// caching net transforms as necessary.
|
// caching net transforms as necessary.
|
||||||
for (ji = _joints.begin(); ji != _joints.end(); ++ji) {
|
for (ji = _joints.begin(); ji != _joints.end(); ++ji) {
|
||||||
EggJointData *joint_data = (*ji);
|
EggJointData *joint_data = (*ji);
|
||||||
if (!joint_data->do_compute_reparent(model_index, f)) {
|
if (!joint_data->do_compute_reparent(model_index, f, db)) {
|
||||||
// Oops, we got an invalid transform.
|
// Oops, we got an invalid transform.
|
||||||
invalid_set.insert(joint_data);
|
invalid_set.insert(joint_data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Finally, apply the computations to the joints.
|
||||||
|
for (ji = _joints.begin(); ji != _joints.end(); ++ji) {
|
||||||
|
EggJointData *joint_data = (*ji);
|
||||||
|
if (!joint_data->do_joint_rebuild(model_index, db)) {
|
||||||
|
invalid_set.insert(joint_data);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now remove all of the old children and add in the new children.
|
// Now remove all of the old children and add in the new children.
|
||||||
for (ji = _joints.begin(); ji != _joints.end(); ++ji) {
|
for (ji = _joints.begin(); ji != _joints.end(); ++ji) {
|
||||||
EggJointData *joint_data = (*ji);
|
EggJointData *joint_data = (*ji);
|
||||||
if (!joint_data->do_finish_reparent()) {
|
joint_data->do_finish_reparent();
|
||||||
invalid_set.insert(joint_data);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Report the set of joints that failed. It really shouldn't be
|
// Report the set of joints that failed. It really shouldn't be
|
||||||
@ -299,19 +311,21 @@ do_reparent() {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void EggCharacterData::
|
void EggCharacterData::
|
||||||
choose_optimal_hierarchy() {
|
choose_optimal_hierarchy() {
|
||||||
|
EggCharacterDb db;
|
||||||
|
|
||||||
Joints::const_iterator ji, jj;
|
Joints::const_iterator ji, jj;
|
||||||
for (ji = _joints.begin(); ji != _joints.end(); ++ji) {
|
for (ji = _joints.begin(); ji != _joints.end(); ++ji) {
|
||||||
EggJointData *joint_data = (*ji);
|
EggJointData *joint_data = (*ji);
|
||||||
|
|
||||||
EggJointData *best_parent = joint_data->get_parent();
|
EggJointData *best_parent = joint_data->get_parent();
|
||||||
int best_score = joint_data->score_reparent_to(best_parent);
|
int best_score = joint_data->score_reparent_to(best_parent, db);
|
||||||
|
|
||||||
for (jj = _joints.begin(); jj != _joints.end(); ++jj) {
|
for (jj = _joints.begin(); jj != _joints.end(); ++jj) {
|
||||||
EggJointData *possible_parent = (*jj);
|
EggJointData *possible_parent = (*jj);
|
||||||
if (possible_parent != joint_data && possible_parent != best_parent &&
|
if (possible_parent != joint_data && possible_parent != best_parent &&
|
||||||
!joint_data->is_new_ancestor(possible_parent)) {
|
!joint_data->is_new_ancestor(possible_parent)) {
|
||||||
|
|
||||||
int score = joint_data->score_reparent_to(possible_parent);
|
int score = joint_data->score_reparent_to(possible_parent, db);
|
||||||
if (score >= 0 && (best_score < 0 || score < best_score)) {
|
if (score >= 0 && (best_score < 0 || score < best_score)) {
|
||||||
best_parent = possible_parent;
|
best_parent = possible_parent;
|
||||||
best_score = score;
|
best_score = score;
|
||||||
@ -322,7 +336,7 @@ choose_optimal_hierarchy() {
|
|||||||
// Also consider reparenting the node to the root.
|
// Also consider reparenting the node to the root.
|
||||||
EggJointData *possible_parent = get_root_joint();
|
EggJointData *possible_parent = get_root_joint();
|
||||||
if (possible_parent != best_parent) {
|
if (possible_parent != best_parent) {
|
||||||
int score = joint_data->score_reparent_to(possible_parent);
|
int score = joint_data->score_reparent_to(possible_parent, db);
|
||||||
if (score >= 0 && (best_score < 0 || score < best_score)) {
|
if (score >= 0 && (best_score < 0 || score < best_score)) {
|
||||||
best_parent = possible_parent;
|
best_parent = possible_parent;
|
||||||
best_score = score;
|
best_score = score;
|
||||||
@ -377,6 +391,36 @@ make_slider(const string &name) {
|
|||||||
return slider;
|
return slider;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: EggCharacterData::estimate_db_size
|
||||||
|
// Access: Public
|
||||||
|
// Description: Returns the estimated amount of memory, in megabytes,
|
||||||
|
// that will be required to perform the do_reparent()
|
||||||
|
// operation. This is used mainly be EggCharacterDb to
|
||||||
|
// decide up front whether to store this data in-RAM or
|
||||||
|
// on-disk.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
size_t EggCharacterData::
|
||||||
|
estimate_db_size() const {
|
||||||
|
// Count how much memory we will need to store the interim
|
||||||
|
// transforms. This is models * joints * frames * 3 *
|
||||||
|
// sizeof(LMatrix4d).
|
||||||
|
size_t mj_frames = 0;
|
||||||
|
Models::const_iterator mi;
|
||||||
|
for (mi = _models.begin(); mi != _models.end(); ++mi) {
|
||||||
|
int model_index = (*mi)._model_index;
|
||||||
|
size_t num_frames = (size_t)get_num_frames(model_index);
|
||||||
|
mj_frames += num_frames * _joints.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
// We do this operation a bit carefully, to guard against integer
|
||||||
|
// overflow.
|
||||||
|
size_t mb_needed = ((mj_frames * 3 / 1024) * sizeof(LMatrix4d)) / 1024;
|
||||||
|
|
||||||
|
return mb_needed;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: EggCharacterData::write
|
// Function: EggCharacterData::write
|
||||||
// Access: Public, Virtual
|
// Access: Public, Virtual
|
||||||
|
@ -22,7 +22,6 @@
|
|||||||
#include "pandatoolbase.h"
|
#include "pandatoolbase.h"
|
||||||
|
|
||||||
#include "eggJointData.h"
|
#include "eggJointData.h"
|
||||||
|
|
||||||
#include "eggNode.h"
|
#include "eggNode.h"
|
||||||
#include "eggData.h"
|
#include "eggData.h"
|
||||||
#include "pointerTo.h"
|
#include "pointerTo.h"
|
||||||
@ -33,6 +32,7 @@
|
|||||||
|
|
||||||
class EggCharacterCollection;
|
class EggCharacterCollection;
|
||||||
class EggSliderData;
|
class EggSliderData;
|
||||||
|
class EggCharacterDb;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Class : EggCharacterData
|
// Class : EggCharacterData
|
||||||
@ -81,6 +81,7 @@ public:
|
|||||||
INLINE EggJointData *make_new_joint(const string &name, EggJointData *parent);
|
INLINE EggJointData *make_new_joint(const string &name, EggJointData *parent);
|
||||||
INLINE int get_num_joints() const;
|
INLINE int get_num_joints() const;
|
||||||
INLINE EggJointData *get_joint(int n) const;
|
INLINE EggJointData *get_joint(int n) const;
|
||||||
|
|
||||||
bool do_reparent();
|
bool do_reparent();
|
||||||
void choose_optimal_hierarchy();
|
void choose_optimal_hierarchy();
|
||||||
|
|
||||||
@ -92,6 +93,8 @@ public:
|
|||||||
INLINE int get_num_components() const;
|
INLINE int get_num_components() const;
|
||||||
INLINE EggComponentData *get_component(int n) const;
|
INLINE EggComponentData *get_component(int n) const;
|
||||||
|
|
||||||
|
size_t estimate_db_size() const;
|
||||||
|
|
||||||
virtual void write(ostream &out, int indent_level = 0) const;
|
virtual void write(ostream &out, int indent_level = 0) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
47
pandatool/src/eggcharbase/eggCharacterDb.I
Normal file
47
pandatool/src/eggcharbase/eggCharacterDb.I
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
// Filename: eggCharacterDb.I
|
||||||
|
// Created by: drose (05Oct06)
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// PANDA 3D SOFTWARE
|
||||||
|
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
|
||||||
|
//
|
||||||
|
// All use of this software is subject to the terms of the Panda 3d
|
||||||
|
// Software license. You should have received a copy of this license
|
||||||
|
// along with this source code; you will also find a current copy of
|
||||||
|
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
|
||||||
|
//
|
||||||
|
// To contact the maintainers of this program write to
|
||||||
|
// panda3d-general@lists.sourceforge.net .
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: EggCharacterDb::Key::Constructor
|
||||||
|
// Access: Public
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE EggCharacterDb::Key::
|
||||||
|
Key(const EggJointPointer *joint, TableType table_type, int frame) :
|
||||||
|
_joint(joint),
|
||||||
|
_table_type(table_type),
|
||||||
|
_frame(frame)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: EggCharacterDb::Key::operator <
|
||||||
|
// Access: Public
|
||||||
|
// Description: Provides an arbitrary unique ordering for all keys.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE bool EggCharacterDb::Key::
|
||||||
|
operator < (const EggCharacterDb::Key &other) const {
|
||||||
|
if (_joint != other._joint) {
|
||||||
|
return _joint < other._joint;
|
||||||
|
}
|
||||||
|
if (_table_type != other._table_type) {
|
||||||
|
return _table_type < other._table_type;
|
||||||
|
}
|
||||||
|
return _frame < other._frame;
|
||||||
|
}
|
143
pandatool/src/eggcharbase/eggCharacterDb.cxx
Normal file
143
pandatool/src/eggcharbase/eggCharacterDb.cxx
Normal file
@ -0,0 +1,143 @@
|
|||||||
|
// Filename: eggCharacterDb.cxx
|
||||||
|
// Created by: drose (05Oct06)
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// PANDA 3D SOFTWARE
|
||||||
|
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
|
||||||
|
//
|
||||||
|
// All use of this software is subject to the terms of the Panda 3d
|
||||||
|
// Software license. You should have received a copy of this license
|
||||||
|
// along with this source code; you will also find a current copy of
|
||||||
|
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
|
||||||
|
//
|
||||||
|
// To contact the maintainers of this program write to
|
||||||
|
// panda3d-general@lists.sourceforge.net .
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include "eggCharacterDb.h"
|
||||||
|
#include "eggCharacterData.h"
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: EggCharacterDb::Constructor
|
||||||
|
// Access: Public
|
||||||
|
// Description: Constructs a database for storing the interim work
|
||||||
|
// for the indicated EggCharacterData. The parameter
|
||||||
|
// max_ram_mb indicates the maximum amount of RAM (in
|
||||||
|
// MB) that the database should consume; if it the
|
||||||
|
// database would roughly fit within this limit, it will
|
||||||
|
// be stored in RAM; otherwise, it will be written to
|
||||||
|
// disk (if Berkeley DB is available).
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
EggCharacterDb::
|
||||||
|
EggCharacterDb() {
|
||||||
|
/*
|
||||||
|
#ifdef HAVE_BDB
|
||||||
|
_db = NULL;
|
||||||
|
|
||||||
|
_db = new Db(NULL, 0);
|
||||||
|
_db_filename = Filename::temporary("", "eggc_", ".db");
|
||||||
|
|
||||||
|
string os_db_filename = _db_filename.to_os_specific();
|
||||||
|
_db->open(NULL, os_db_filename.c_str(), NULL,
|
||||||
|
DB_BTREE, DB_CREATE | DB_EXCL, 0);
|
||||||
|
|
||||||
|
nout << "Using " << os_db_filename << " for rebuild database.\n";
|
||||||
|
#endif // HAVE_BDB
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: EggCharacterDb::Destructor
|
||||||
|
// Access: Public
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
EggCharacterDb::
|
||||||
|
~EggCharacterDb() {
|
||||||
|
/*
|
||||||
|
#ifdef HAVE_BDB
|
||||||
|
if (_db != (Db *)NULL){
|
||||||
|
_db->close(0);
|
||||||
|
delete _db;
|
||||||
|
_db = NULL;
|
||||||
|
|
||||||
|
string os_db_filename = _db_filename.to_os_specific();
|
||||||
|
Db rmdb(NULL, 0);
|
||||||
|
rmdb.remove(os_db_filename.c_str(), NULL, 0);
|
||||||
|
}
|
||||||
|
#endif // HAVE_BDB
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: EggCharacterDb::get_matrix
|
||||||
|
// Access: Public
|
||||||
|
// Description: Looks up the data for the indicated joint, type, and
|
||||||
|
// frame, and fills it in result (and returns true) if
|
||||||
|
// it is found. Returns false if this data has not been
|
||||||
|
// stored in the database.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool EggCharacterDb::
|
||||||
|
get_matrix(const EggJointPointer *joint, TableType type,
|
||||||
|
int frame, LMatrix4d &mat) const {
|
||||||
|
Key key(joint, type, frame);
|
||||||
|
|
||||||
|
/*
|
||||||
|
#ifdef HAVE_BDB
|
||||||
|
if (_db != (Db *)NULL){
|
||||||
|
Dbt db_key(&key, sizeof(Key));
|
||||||
|
Dbt db_data(&mat, sizeof(LMatrix4d));
|
||||||
|
db_data.set_ulen(sizeof(LMatrix4d));
|
||||||
|
db_data.set_flags(DB_DBT_USERMEM);
|
||||||
|
|
||||||
|
int result = _db->get(NULL, &db_key, &db_data, 0);
|
||||||
|
if (result == DB_NOTFOUND) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
nassertr(result == 0, false);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
#endif // HAVE_BDB
|
||||||
|
*/
|
||||||
|
|
||||||
|
Table::const_iterator ti;
|
||||||
|
ti = _table.find(key);
|
||||||
|
if (ti == _table.end()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
mat = (*ti).second;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: EggCharacterDb::set_matrix
|
||||||
|
// Access: Public
|
||||||
|
// Description: Stores the matrix for the indicated joint, type, and
|
||||||
|
// frame in the database. It is an error to call this
|
||||||
|
// more than once for any given key combination (not for
|
||||||
|
// any technical reason, but because we don't expect
|
||||||
|
// this to happen).
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void EggCharacterDb::
|
||||||
|
set_matrix(const EggJointPointer *joint, TableType type,
|
||||||
|
int frame, const LMatrix4d &mat) {
|
||||||
|
Key key(joint, type, frame);
|
||||||
|
|
||||||
|
/*
|
||||||
|
#ifdef HAVE_BDB
|
||||||
|
if (_db != (Db *)NULL){
|
||||||
|
Dbt db_key(&key, sizeof(Key));
|
||||||
|
Dbt db_data((void *)&mat, sizeof(LMatrix4d));
|
||||||
|
int result = _db->put(NULL, &db_key, &db_data, DB_NOOVERWRITE);
|
||||||
|
nassertv(result != DB_KEYEXIST);
|
||||||
|
nassertv(result == 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif // HAVE_BDB
|
||||||
|
*/
|
||||||
|
|
||||||
|
bool inserted = _table.insert(Table::value_type(key, mat)).second;
|
||||||
|
nassertv(inserted);
|
||||||
|
}
|
93
pandatool/src/eggcharbase/eggCharacterDb.h
Normal file
93
pandatool/src/eggcharbase/eggCharacterDb.h
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
// Filename: eggCharacterDb.h
|
||||||
|
// Created by: drose (05Oct06)
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// PANDA 3D SOFTWARE
|
||||||
|
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
|
||||||
|
//
|
||||||
|
// All use of this software is subject to the terms of the Panda 3d
|
||||||
|
// Software license. You should have received a copy of this license
|
||||||
|
// along with this source code; you will also find a current copy of
|
||||||
|
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
|
||||||
|
//
|
||||||
|
// To contact the maintainers of this program write to
|
||||||
|
// panda3d-general@lists.sourceforge.net .
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef EGGCHARACTERDB_H
|
||||||
|
#define EGGCHARACTERDB_H
|
||||||
|
|
||||||
|
#include "pandatoolbase.h"
|
||||||
|
#include "pmap.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
#ifdef HAVE_BDB
|
||||||
|
|
||||||
|
// Apparently, we have to define this to make db_cxx files include the
|
||||||
|
// modern header files.
|
||||||
|
#define HAVE_CXX_STDHEADERS 1
|
||||||
|
#include <db_cxx.h>
|
||||||
|
|
||||||
|
#endif // HAVE_BDB
|
||||||
|
*/
|
||||||
|
|
||||||
|
class EggJointPointer;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Class : EggCharacterDb
|
||||||
|
// Description : This class is used during joint optimization or
|
||||||
|
// restructuring to store the table of interim joint
|
||||||
|
// computations.
|
||||||
|
//
|
||||||
|
// That is to say, this class provides an temporary data
|
||||||
|
// store for three tables of matrices per each
|
||||||
|
// EggJointPointer per frame.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
class EggCharacterDb {
|
||||||
|
public:
|
||||||
|
EggCharacterDb();
|
||||||
|
~EggCharacterDb();
|
||||||
|
|
||||||
|
enum TableType {
|
||||||
|
TT_rebuild_frame,
|
||||||
|
TT_net_frame,
|
||||||
|
TT_net_frame_inv,
|
||||||
|
};
|
||||||
|
|
||||||
|
bool get_matrix(const EggJointPointer *joint, TableType type,
|
||||||
|
int frame, LMatrix4d &mat) const;
|
||||||
|
void set_matrix(const EggJointPointer *joint, TableType type,
|
||||||
|
int frame, const LMatrix4d &mat);
|
||||||
|
|
||||||
|
private:
|
||||||
|
class Key {
|
||||||
|
public:
|
||||||
|
INLINE Key(const EggJointPointer *joint,
|
||||||
|
TableType table_type,
|
||||||
|
int frame);
|
||||||
|
INLINE bool operator < (const Key &other) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
const EggJointPointer *_joint;
|
||||||
|
TableType _table_type;
|
||||||
|
int _frame;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
#ifdef HAVE_BDB
|
||||||
|
Db *_db;
|
||||||
|
Filename _db_filename;
|
||||||
|
#endif // HAVE_BDB
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef pmap<Key, LMatrix4d> Table;
|
||||||
|
Table _table;
|
||||||
|
};
|
||||||
|
|
||||||
|
#include "eggCharacterDb.I"
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
@ -74,7 +74,7 @@ get_frame(int model_index, int n) const {
|
|||||||
// in the indicated model.
|
// in the indicated model.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
LMatrix4d EggJointData::
|
LMatrix4d EggJointData::
|
||||||
get_net_frame(int model_index, int n) const {
|
get_net_frame(int model_index, int n, EggCharacterDb &db) const {
|
||||||
EggBackPointer *back = get_model(model_index);
|
EggBackPointer *back = get_model(model_index);
|
||||||
if (back == (EggBackPointer *)NULL) {
|
if (back == (EggBackPointer *)NULL) {
|
||||||
return LMatrix4d::ident_mat();
|
return LMatrix4d::ident_mat();
|
||||||
@ -83,22 +83,17 @@ get_net_frame(int model_index, int n) const {
|
|||||||
EggJointPointer *joint;
|
EggJointPointer *joint;
|
||||||
DCAST_INTO_R(joint, back, LMatrix4d::ident_mat());
|
DCAST_INTO_R(joint, back, LMatrix4d::ident_mat());
|
||||||
|
|
||||||
if (joint->get_num_net_frames() < n) {
|
LMatrix4d mat;
|
||||||
// Recursively get the previous frame's net, so we have a place to
|
if (!db.get_matrix(joint, EggCharacterDb::TT_net_frame, n, mat)) {
|
||||||
// stuff this frame's value.
|
|
||||||
get_net_frame(model_index, n - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (joint->get_num_net_frames() == n) {
|
|
||||||
// Compute this frame's net, and stuff it in.
|
// Compute this frame's net, and stuff it in.
|
||||||
LMatrix4d mat = get_frame(model_index, n);
|
mat = get_frame(model_index, n);
|
||||||
if (_parent != (EggJointData *)NULL) {
|
if (_parent != (EggJointData *)NULL) {
|
||||||
mat = mat * _parent->get_net_frame(model_index, n);
|
mat = mat * _parent->get_net_frame(model_index, n, db);
|
||||||
}
|
}
|
||||||
joint->add_net_frame(mat);
|
db.set_matrix(joint, EggCharacterDb::TT_net_frame, n, mat);
|
||||||
}
|
}
|
||||||
|
|
||||||
return joint->get_net_frame(n);
|
return mat;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -107,7 +102,7 @@ get_net_frame(int model_index, int n) const {
|
|||||||
// Description: Returns the inverse of get_net_frame().
|
// Description: Returns the inverse of get_net_frame().
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
LMatrix4d EggJointData::
|
LMatrix4d EggJointData::
|
||||||
get_net_frame_inv(int model_index, int n) const {
|
get_net_frame_inv(int model_index, int n, EggCharacterDb &db) const {
|
||||||
EggBackPointer *back = get_model(model_index);
|
EggBackPointer *back = get_model(model_index);
|
||||||
if (back == (EggBackPointer *)NULL) {
|
if (back == (EggBackPointer *)NULL) {
|
||||||
return LMatrix4d::ident_mat();
|
return LMatrix4d::ident_mat();
|
||||||
@ -116,20 +111,15 @@ get_net_frame_inv(int model_index, int n) const {
|
|||||||
EggJointPointer *joint;
|
EggJointPointer *joint;
|
||||||
DCAST_INTO_R(joint, back, LMatrix4d::ident_mat());
|
DCAST_INTO_R(joint, back, LMatrix4d::ident_mat());
|
||||||
|
|
||||||
if (joint->get_num_net_frame_invs() < n) {
|
LMatrix4d mat;
|
||||||
// Recursively get the previous frame's net, so we have a place to
|
if (!db.get_matrix(joint, EggCharacterDb::TT_net_frame_inv, n, mat)) {
|
||||||
// stuff this frame's value.
|
|
||||||
get_net_frame_inv(model_index, n - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (joint->get_num_net_frame_invs() == n) {
|
|
||||||
// Compute this frame's net inverse, and stuff it in.
|
// Compute this frame's net inverse, and stuff it in.
|
||||||
LMatrix4d mat = get_net_frame(model_index, n);
|
LMatrix4d mat = get_net_frame(model_index, n, db);
|
||||||
mat.invert_in_place();
|
mat.invert_in_place();
|
||||||
joint->add_net_frame_inv(mat);
|
db.set_matrix(joint, EggCharacterDb::TT_net_frame_inv, n, mat);
|
||||||
}
|
}
|
||||||
|
|
||||||
return joint->get_net_frame_inv(n);
|
return mat;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -202,7 +192,7 @@ move_vertices_to(EggJointData *new_owner) {
|
|||||||
// error.
|
// error.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
int EggJointData::
|
int EggJointData::
|
||||||
score_reparent_to(EggJointData *new_parent) {
|
score_reparent_to(EggJointData *new_parent, EggCharacterDb &db) {
|
||||||
if (!FFTCompressor::is_compression_available()) {
|
if (!FFTCompressor::is_compression_available()) {
|
||||||
// If we don't have compression compiled in, we can't meaningfully
|
// If we don't have compression compiled in, we can't meaningfully
|
||||||
// score the joints.
|
// score the joints.
|
||||||
@ -232,17 +222,17 @@ score_reparent_to(EggJointData *new_parent) {
|
|||||||
|
|
||||||
} else if (_parent == (EggJointData *)NULL) {
|
} else if (_parent == (EggJointData *)NULL) {
|
||||||
// We are moving from outside the joint hierarchy to within it.
|
// We are moving from outside the joint hierarchy to within it.
|
||||||
transform = new_parent->get_net_frame_inv(model_index, n);
|
transform = new_parent->get_net_frame_inv(model_index, n, db);
|
||||||
|
|
||||||
} else if (new_parent == (EggJointData *)NULL) {
|
} else if (new_parent == (EggJointData *)NULL) {
|
||||||
// We are moving from within the hierarchy to outside it.
|
// We are moving from within the hierarchy to outside it.
|
||||||
transform = _parent->get_net_frame(model_index, n);
|
transform = _parent->get_net_frame(model_index, n, db);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// We are changing parents within the hierarchy.
|
// We are changing parents within the hierarchy.
|
||||||
transform =
|
transform =
|
||||||
_parent->get_net_frame(model_index, n) *
|
_parent->get_net_frame(model_index, n, db) *
|
||||||
new_parent->get_net_frame_inv(model_index, n);
|
new_parent->get_net_frame_inv(model_index, n, db);
|
||||||
}
|
}
|
||||||
|
|
||||||
transform = joint->get_frame(n) * transform;
|
transform = joint->get_frame(n) * transform;
|
||||||
@ -304,14 +294,14 @@ score_reparent_to(EggJointData *new_parent) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: EggJointData::do_rebuild
|
// Function: EggJointData::do_rebuild_all
|
||||||
// Access: Public
|
// Access: Public
|
||||||
// Description: Calls do_rebuild() on all models, and recursively on
|
// Description: Calls do_rebuild() on all models, and recursively on
|
||||||
// all joints at this node and below. Returns true if
|
// all joints at this node and below. Returns true if
|
||||||
// all models returned true, false otherwise.
|
// all models returned true, false otherwise.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
bool EggJointData::
|
bool EggJointData::
|
||||||
do_rebuild() {
|
do_rebuild_all(EggCharacterDb &db) {
|
||||||
bool all_ok = true;
|
bool all_ok = true;
|
||||||
|
|
||||||
BackPointers::iterator bpi;
|
BackPointers::iterator bpi;
|
||||||
@ -320,7 +310,7 @@ do_rebuild() {
|
|||||||
if (back != (EggBackPointer *)NULL) {
|
if (back != (EggBackPointer *)NULL) {
|
||||||
EggJointPointer *joint;
|
EggJointPointer *joint;
|
||||||
DCAST_INTO_R(joint, back, false);
|
DCAST_INTO_R(joint, back, false);
|
||||||
if (!joint->do_rebuild()) {
|
if (!joint->do_rebuild(db)) {
|
||||||
all_ok = false;
|
all_ok = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -329,7 +319,7 @@ do_rebuild() {
|
|||||||
Children::iterator ci;
|
Children::iterator ci;
|
||||||
for (ci = _children.begin(); ci != _children.end(); ++ci) {
|
for (ci = _children.begin(); ci != _children.end(); ++ci) {
|
||||||
EggJointData *child = (*ci);
|
EggJointData *child = (*ci);
|
||||||
if (!child->do_rebuild()) {
|
if (!child->do_rebuild_all(db)) {
|
||||||
all_ok = false;
|
all_ok = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -497,15 +487,6 @@ void EggJointData::
|
|||||||
do_begin_reparent() {
|
do_begin_reparent() {
|
||||||
_got_new_parent_depth = false;
|
_got_new_parent_depth = false;
|
||||||
_children.clear();
|
_children.clear();
|
||||||
|
|
||||||
int num_models = get_num_models();
|
|
||||||
for (int model_index = 0; model_index < num_models; model_index++) {
|
|
||||||
if (has_model(model_index)) {
|
|
||||||
EggJointPointer *joint;
|
|
||||||
DCAST_INTO_V(joint, get_model(model_index));
|
|
||||||
joint->begin_rebuild();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -568,7 +549,7 @@ do_begin_compute_reparent() {
|
|||||||
// false on failure.
|
// false on failure.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
bool EggJointData::
|
bool EggJointData::
|
||||||
do_compute_reparent(int model_index, int n) {
|
do_compute_reparent(int model_index, int n, EggCharacterDb &db) {
|
||||||
if (_computed_reparent) {
|
if (_computed_reparent) {
|
||||||
// We've already done this joint. This is possible because we
|
// We've already done this joint. This is possible because we
|
||||||
// have to recursively compute joints upwards, so we might visit
|
// have to recursively compute joints upwards, so we might visit
|
||||||
@ -597,52 +578,73 @@ do_compute_reparent(int model_index, int n) {
|
|||||||
LMatrix4d transform;
|
LMatrix4d transform;
|
||||||
if (_parent == (EggJointData *)NULL) {
|
if (_parent == (EggJointData *)NULL) {
|
||||||
// We are moving from outside the joint hierarchy to within it.
|
// We are moving from outside the joint hierarchy to within it.
|
||||||
transform = _new_parent->get_new_net_frame_inv(model_index, n);
|
transform = _new_parent->get_new_net_frame_inv(model_index, n, db);
|
||||||
|
|
||||||
} else if (_new_parent == (EggJointData *)NULL) {
|
} else if (_new_parent == (EggJointData *)NULL) {
|
||||||
// We are moving from within the hierarchy to outside it.
|
// We are moving from within the hierarchy to outside it.
|
||||||
transform = _parent->get_net_frame(model_index, n);
|
transform = _parent->get_net_frame(model_index, n, db);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// We are changing parents within the hierarchy.
|
// We are changing parents within the hierarchy.
|
||||||
transform =
|
transform =
|
||||||
_parent->get_net_frame(model_index, n) *
|
_parent->get_net_frame(model_index, n, db) *
|
||||||
_new_parent->get_new_net_frame_inv(model_index, n);
|
_new_parent->get_new_net_frame_inv(model_index, n, db);
|
||||||
}
|
}
|
||||||
|
|
||||||
nassertr(n == joint->get_num_rebuild_frames(), false);
|
db.set_matrix(joint, EggCharacterDb::TT_rebuild_frame, n,
|
||||||
|
joint->get_frame(n) * transform);
|
||||||
|
_computed_ok = true;
|
||||||
|
|
||||||
_computed_ok = joint->add_rebuild_frame(joint->get_frame(n) * transform);
|
|
||||||
return _computed_ok;
|
return _computed_ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: EggJointData::do_joint_rebuild
|
||||||
|
// Access: Protected
|
||||||
|
// Description: Calls do_rebuild() on the joint for the indicated
|
||||||
|
// model index. Returns true on success, false on
|
||||||
|
// failure (false shouldn't be possible).
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool EggJointData::
|
||||||
|
do_joint_rebuild(int model_index, EggCharacterDb &db) {
|
||||||
|
bool all_ok = true;
|
||||||
|
|
||||||
|
EggJointPointer *parent_joint = NULL;
|
||||||
|
if (_new_parent != NULL && _new_parent->has_model(model_index)) {
|
||||||
|
DCAST_INTO_R(parent_joint, _new_parent->get_model(model_index), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (has_model(model_index)) {
|
||||||
|
EggJointPointer *joint;
|
||||||
|
DCAST_INTO_R(joint, get_model(model_index), false);
|
||||||
|
if (!joint->do_rebuild(db)) {
|
||||||
|
all_ok = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return all_ok;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: EggJointData::do_finish_reparent
|
// Function: EggJointData::do_finish_reparent
|
||||||
// Access: Protected
|
// Access: Protected
|
||||||
// Description: Performs the actual reparenting operation
|
// Description: Performs the actual reparenting operation
|
||||||
// by removing all of the old children and replacing
|
// by removing all of the old children and replacing
|
||||||
// them with the set of new children. Returns true on
|
// them with the set of new children.
|
||||||
// success, false on failure.
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
bool EggJointData::
|
void EggJointData::
|
||||||
do_finish_reparent() {
|
do_finish_reparent() {
|
||||||
bool all_ok = true;
|
|
||||||
|
|
||||||
int num_models = get_num_models();
|
int num_models = get_num_models();
|
||||||
for (int model_index = 0; model_index < num_models; model_index++) {
|
for (int model_index = 0; model_index < num_models; model_index++) {
|
||||||
EggJointPointer *parent_joint = NULL;
|
EggJointPointer *parent_joint = NULL;
|
||||||
if (_new_parent != NULL && _new_parent->has_model(model_index)) {
|
if (_new_parent != NULL && _new_parent->has_model(model_index)) {
|
||||||
DCAST_INTO_R(parent_joint, _new_parent->get_model(model_index), false);
|
DCAST_INTO_V(parent_joint, _new_parent->get_model(model_index));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (has_model(model_index)) {
|
if (has_model(model_index)) {
|
||||||
EggJointPointer *joint;
|
EggJointPointer *joint;
|
||||||
DCAST_INTO_R(joint, get_model(model_index), false);
|
DCAST_INTO_V(joint, get_model(model_index));
|
||||||
joint->do_finish_reparent(parent_joint);
|
joint->do_finish_reparent(parent_joint);
|
||||||
joint->clear_net_frames();
|
|
||||||
if (!joint->do_rebuild()) {
|
|
||||||
all_ok = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -650,8 +652,6 @@ do_finish_reparent() {
|
|||||||
if (_parent != (EggJointData *)NULL) {
|
if (_parent != (EggJointData *)NULL) {
|
||||||
_parent->_children.push_back(this);
|
_parent->_children.push_back(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
return all_ok;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -760,11 +760,11 @@ is_new_ancestor(EggJointData *child) const {
|
|||||||
// useful only when called within do_compute_reparent().
|
// useful only when called within do_compute_reparent().
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
const LMatrix4d &EggJointData::
|
const LMatrix4d &EggJointData::
|
||||||
get_new_net_frame(int model_index, int n) {
|
get_new_net_frame(int model_index, int n, EggCharacterDb &db) {
|
||||||
if (!_got_new_net_frame) {
|
if (!_got_new_net_frame) {
|
||||||
_new_net_frame = get_new_frame(model_index, n);
|
_new_net_frame = get_new_frame(model_index, n, db);
|
||||||
if (_new_parent != (EggJointData *)NULL) {
|
if (_new_parent != (EggJointData *)NULL) {
|
||||||
_new_net_frame = _new_net_frame * _new_parent->get_new_net_frame(model_index, n);
|
_new_net_frame = _new_net_frame * _new_parent->get_new_net_frame(model_index, n, db);
|
||||||
}
|
}
|
||||||
_got_new_net_frame = true;
|
_got_new_net_frame = true;
|
||||||
}
|
}
|
||||||
@ -777,11 +777,11 @@ get_new_net_frame(int model_index, int n) {
|
|||||||
// Description: Returns the inverse of get_new_net_frame().
|
// Description: Returns the inverse of get_new_net_frame().
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
const LMatrix4d &EggJointData::
|
const LMatrix4d &EggJointData::
|
||||||
get_new_net_frame_inv(int model_index, int n) {
|
get_new_net_frame_inv(int model_index, int n, EggCharacterDb &db) {
|
||||||
if (!_got_new_net_frame_inv) {
|
if (!_got_new_net_frame_inv) {
|
||||||
_new_net_frame_inv.invert_from(get_new_frame(model_index, n));
|
_new_net_frame_inv.invert_from(get_new_frame(model_index, n, db));
|
||||||
if (_new_parent != (EggJointData *)NULL) {
|
if (_new_parent != (EggJointData *)NULL) {
|
||||||
_new_net_frame_inv = _new_parent->get_new_net_frame_inv(model_index, n) * _new_net_frame_inv;
|
_new_net_frame_inv = _new_parent->get_new_net_frame_inv(model_index, n, db) * _new_net_frame_inv;
|
||||||
}
|
}
|
||||||
_got_new_net_frame_inv = true;
|
_got_new_net_frame_inv = true;
|
||||||
}
|
}
|
||||||
@ -797,8 +797,8 @@ get_new_net_frame_inv(int model_index, int n) {
|
|||||||
// called.
|
// called.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
LMatrix4d EggJointData::
|
LMatrix4d EggJointData::
|
||||||
get_new_frame(int model_index, int n) {
|
get_new_frame(int model_index, int n, EggCharacterDb &db) {
|
||||||
do_compute_reparent(model_index, n);
|
do_compute_reparent(model_index, n, db);
|
||||||
|
|
||||||
EggBackPointer *back = get_model(model_index);
|
EggBackPointer *back = get_model(model_index);
|
||||||
if (back == (EggBackPointer *)NULL) {
|
if (back == (EggBackPointer *)NULL) {
|
||||||
@ -808,9 +808,12 @@ get_new_frame(int model_index, int n) {
|
|||||||
EggJointPointer *joint;
|
EggJointPointer *joint;
|
||||||
DCAST_INTO_R(joint, back, LMatrix4d::ident_mat());
|
DCAST_INTO_R(joint, back, LMatrix4d::ident_mat());
|
||||||
|
|
||||||
if (joint->get_num_rebuild_frames() > 0) {
|
LMatrix4d mat;
|
||||||
return joint->get_rebuild_frame(n);
|
if (!db.get_matrix(joint, EggCharacterDb::TT_rebuild_frame, n, mat)) {
|
||||||
} else {
|
// No rebuild frame; return the regular frame.
|
||||||
return joint->get_frame(n);
|
return joint->get_frame(n);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Return the rebuild frame, as computed.
|
||||||
|
return mat;
|
||||||
}
|
}
|
||||||
|
@ -20,12 +20,13 @@
|
|||||||
#define EGGJOINTDATA_H
|
#define EGGJOINTDATA_H
|
||||||
|
|
||||||
#include "pandatoolbase.h"
|
#include "pandatoolbase.h"
|
||||||
|
|
||||||
#include "eggComponentData.h"
|
#include "eggComponentData.h"
|
||||||
#include "eggGroup.h"
|
#include "eggGroup.h"
|
||||||
#include "luse.h"
|
#include "luse.h"
|
||||||
#include "pset.h"
|
#include "pset.h"
|
||||||
|
|
||||||
|
class EggCharacterDb;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Class : EggJointData
|
// Class : EggJointData
|
||||||
// Description : This is one node of a hierarchy of EggJointData
|
// Description : This is one node of a hierarchy of EggJointData
|
||||||
@ -45,8 +46,8 @@ public:
|
|||||||
INLINE EggJointData *find_joint(const string &name);
|
INLINE EggJointData *find_joint(const string &name);
|
||||||
|
|
||||||
LMatrix4d get_frame(int model_index, int n) const;
|
LMatrix4d get_frame(int model_index, int n) const;
|
||||||
LMatrix4d get_net_frame(int model_index, int n) const;
|
LMatrix4d get_net_frame(int model_index, int n, EggCharacterDb &db) const;
|
||||||
LMatrix4d get_net_frame_inv(int model_index, int n) const;
|
LMatrix4d get_net_frame_inv(int model_index, int n, EggCharacterDb &db) const;
|
||||||
|
|
||||||
INLINE bool has_rest_frame() const;
|
INLINE bool has_rest_frame() const;
|
||||||
INLINE bool rest_frames_differ() const;
|
INLINE bool rest_frames_differ() const;
|
||||||
@ -55,9 +56,9 @@ public:
|
|||||||
|
|
||||||
INLINE void reparent_to(EggJointData *new_parent);
|
INLINE void reparent_to(EggJointData *new_parent);
|
||||||
void move_vertices_to(EggJointData *new_owner);
|
void move_vertices_to(EggJointData *new_owner);
|
||||||
int score_reparent_to(EggJointData *new_parent);
|
int score_reparent_to(EggJointData *new_parent, EggCharacterDb &db);
|
||||||
|
|
||||||
bool do_rebuild();
|
bool do_rebuild_all(EggCharacterDb &db);
|
||||||
void optimize();
|
void optimize();
|
||||||
void expose(EggGroup::DCSType dcs_type = EggGroup::DC_default);
|
void expose(EggGroup::DCSType dcs_type = EggGroup::DC_default);
|
||||||
void zero_channels(const string &components);
|
void zero_channels(const string &components);
|
||||||
@ -70,8 +71,9 @@ protected:
|
|||||||
void do_begin_reparent();
|
void do_begin_reparent();
|
||||||
bool calc_new_parent_depth(pset<EggJointData *> &chain);
|
bool calc_new_parent_depth(pset<EggJointData *> &chain);
|
||||||
void do_begin_compute_reparent();
|
void do_begin_compute_reparent();
|
||||||
bool do_compute_reparent(int model_index, int n);
|
bool do_compute_reparent(int model_index, int n, EggCharacterDb &db);
|
||||||
bool do_finish_reparent();
|
bool do_joint_rebuild(int model_index, EggCharacterDb &db);
|
||||||
|
void do_finish_reparent();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
EggJointData *make_new_joint(const string &name);
|
EggJointData *make_new_joint(const string &name);
|
||||||
@ -79,9 +81,9 @@ private:
|
|||||||
EggJointData *find_joint_matches(const string &name);
|
EggJointData *find_joint_matches(const string &name);
|
||||||
|
|
||||||
bool is_new_ancestor(EggJointData *child) const;
|
bool is_new_ancestor(EggJointData *child) const;
|
||||||
const LMatrix4d &get_new_net_frame(int model_index, int n);
|
const LMatrix4d &get_new_net_frame(int model_index, int n, EggCharacterDb &db);
|
||||||
const LMatrix4d &get_new_net_frame_inv(int model_index, int n);
|
const LMatrix4d &get_new_net_frame_inv(int model_index, int n, EggCharacterDb &db);
|
||||||
LMatrix4d get_new_frame(int model_index, int n);
|
LMatrix4d get_new_frame(int model_index, int n, EggCharacterDb &db);
|
||||||
|
|
||||||
bool _has_rest_frame;
|
bool _has_rest_frame;
|
||||||
bool _rest_frames_differ;
|
bool _rest_frames_differ;
|
||||||
|
@ -140,23 +140,6 @@ move_vertices_to(EggJointPointer *new_joint) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
// Function: EggJointNodePointer::add_rebuild_frame
|
|
||||||
// Access: Public, Virtual
|
|
||||||
// Description: Adds a new frame to the set of rebuild frames. See
|
|
||||||
// begin_rebuild() and do_rebuild(). Returns true if
|
|
||||||
// this is valid, false otherwise (e.g. adding multiple
|
|
||||||
// frames to a static joint).
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
bool EggJointNodePointer::
|
|
||||||
add_rebuild_frame(const LMatrix4d &mat) {
|
|
||||||
if (!_rebuild_frames.empty()) {
|
|
||||||
// Only one frame may be added to a <Joint>.
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return EggJointPointer::add_rebuild_frame(mat);
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: EggJointNodePointer::do_rebuild
|
// Function: EggJointNodePointer::do_rebuild
|
||||||
// Access: Public, Virtual
|
// Access: Public, Virtual
|
||||||
@ -171,17 +154,18 @@ add_rebuild_frame(const LMatrix4d &mat) {
|
|||||||
// acceptable, or false if there is some problem.
|
// acceptable, or false if there is some problem.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
bool EggJointNodePointer::
|
bool EggJointNodePointer::
|
||||||
do_rebuild() {
|
do_rebuild(EggCharacterDb &db) {
|
||||||
if (_rebuild_frames.empty()) {
|
LMatrix4d mat;
|
||||||
|
if (!db.get_matrix(this, EggCharacterDb::TT_rebuild_frame, 0, mat)) {
|
||||||
|
// No rebuild frame; this is OK.
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_rebuild_frames.size() != 1) {
|
_joint->set_transform3d(mat);
|
||||||
return false;
|
|
||||||
}
|
// We shouldn't have a frame 1.
|
||||||
|
nassertr(!db.get_matrix(this, EggCharacterDb::TT_rebuild_frame, 1, mat), false);
|
||||||
|
|
||||||
_joint->set_transform3d(_rebuild_frames[0]);
|
|
||||||
_rebuild_frames.clear();
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,8 +41,7 @@ public:
|
|||||||
virtual void do_finish_reparent(EggJointPointer *new_parent);
|
virtual void do_finish_reparent(EggJointPointer *new_parent);
|
||||||
virtual void move_vertices_to(EggJointPointer *new_joint);
|
virtual void move_vertices_to(EggJointPointer *new_joint);
|
||||||
|
|
||||||
virtual bool add_rebuild_frame(const LMatrix4d &mat);
|
virtual bool do_rebuild(EggCharacterDb &db);
|
||||||
virtual bool do_rebuild();
|
|
||||||
virtual void expose(EggGroup::DCSType dcs_type);
|
virtual void expose(EggGroup::DCSType dcs_type);
|
||||||
|
|
||||||
virtual bool has_vertices() const;
|
virtual bool has_vertices() const;
|
||||||
|
@ -16,116 +16,3 @@
|
|||||||
//
|
//
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
// Function: EggJointPointer::get_num_rebuild_frames
|
|
||||||
// Access: Public
|
|
||||||
// Description: Returns the number of rebuild frames that have been
|
|
||||||
// added so far.
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
INLINE int EggJointPointer::
|
|
||||||
get_num_rebuild_frames() const {
|
|
||||||
return _rebuild_frames.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
// Function: EggJointPointer::get_rebuild_frame
|
|
||||||
// Access: Public
|
|
||||||
// Description: Returns the nth matrix that has been added to the set
|
|
||||||
// of rebuild frames.
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
INLINE const LMatrix4d &EggJointPointer::
|
|
||||||
get_rebuild_frame(int n) const {
|
|
||||||
nassertr(n >= 0 && n < (int)_rebuild_frames.size(), LMatrix4d::ident_mat());
|
|
||||||
return _rebuild_frames[n];
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
// Function: EggJointPointer::clear_net_frames
|
|
||||||
// Access: Public
|
|
||||||
// Description: Resets the cache of net frames for this joint.
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
INLINE void EggJointPointer::
|
|
||||||
clear_net_frames() {
|
|
||||||
_net_frames.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
// Function: EggJointPointer::add_net_frame
|
|
||||||
// Access: Public, Virtual
|
|
||||||
// Description: Adds a new frame to the set of net frames. This is
|
|
||||||
// used to cache the net transform from the root for
|
|
||||||
// this particular joint.
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
INLINE void EggJointPointer::
|
|
||||||
add_net_frame(const LMatrix4d &mat) {
|
|
||||||
_net_frames.push_back(mat);
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
// Function: EggJointPointer::get_num_net_frames
|
|
||||||
// Access: Public
|
|
||||||
// Description: Returns the number of net frames that have been
|
|
||||||
// added so far.
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
INLINE int EggJointPointer::
|
|
||||||
get_num_net_frames() const {
|
|
||||||
return _net_frames.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
// Function: EggJointPointer::get_net_frame
|
|
||||||
// Access: Public
|
|
||||||
// Description: Returns the nth matrix that has been added to the set
|
|
||||||
// of net frames.
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
INLINE const LMatrix4d &EggJointPointer::
|
|
||||||
get_net_frame(int n) const {
|
|
||||||
nassertr(n >= 0 && n < (int)_net_frames.size(), LMatrix4d::ident_mat());
|
|
||||||
return _net_frames[n];
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
// Function: EggJointPointer::clear_net_frame_invs
|
|
||||||
// Access: Public
|
|
||||||
// Description: Resets the cache of net_inv frames for this joint.
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
INLINE void EggJointPointer::
|
|
||||||
clear_net_frame_invs() {
|
|
||||||
_net_frame_invs.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
// Function: EggJointPointer::add_net_frame_inv
|
|
||||||
// Access: Public, Virtual
|
|
||||||
// Description: Adds a new frame to the set of net_inv frames. This is
|
|
||||||
// used to cache the inverse net transform from the root
|
|
||||||
// for this particular joint.
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
INLINE void EggJointPointer::
|
|
||||||
add_net_frame_inv(const LMatrix4d &mat) {
|
|
||||||
_net_frame_invs.push_back(mat);
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
// Function: EggJointPointer::get_num_net_frame_invs
|
|
||||||
// Access: Public
|
|
||||||
// Description: Returns the number of net_inv frames that have been
|
|
||||||
// added so far.
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
INLINE int EggJointPointer::
|
|
||||||
get_num_net_frame_invs() const {
|
|
||||||
return _net_frame_invs.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
// Function: EggJointPointer::get_net_frame_inv
|
|
||||||
// Access: Public
|
|
||||||
// Description: Returns the nth matrix that has been added to the set
|
|
||||||
// of net_inv frames.
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
INLINE const LMatrix4d &EggJointPointer::
|
|
||||||
get_net_frame_inv(int n) const {
|
|
||||||
nassertr(n >= 0 && n < (int)_net_frame_invs.size(), LMatrix4d::ident_mat());
|
|
||||||
return _net_frame_invs[n];
|
|
||||||
}
|
|
||||||
|
@ -44,35 +44,6 @@ void EggJointPointer::
|
|||||||
move_vertices_to(EggJointPointer *) {
|
move_vertices_to(EggJointPointer *) {
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
// Function: EggJointPointer::begin_rebuild
|
|
||||||
// Access: Public
|
|
||||||
// Description: Resets the set of rebuild frames in preparation for
|
|
||||||
// rebuilding the complete table of frames. Repeated
|
|
||||||
// calls to add_rebuild_frame() will build up the frames
|
|
||||||
// without changing the values returned by get_frame();
|
|
||||||
// the table will eventually be updated when do_rebuild
|
|
||||||
// is called.
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
void EggJointPointer::
|
|
||||||
begin_rebuild() {
|
|
||||||
_rebuild_frames.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
// Function: EggJointPointer::add_rebuild_frame
|
|
||||||
// Access: Public, Virtual
|
|
||||||
// Description: Adds a new frame to the set of rebuild frames. See
|
|
||||||
// begin_rebuild() and do_rebuild(). Returns true if
|
|
||||||
// this is valid, false otherwise (e.g. adding multiple
|
|
||||||
// frames to a static joint).
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
bool EggJointPointer::
|
|
||||||
add_rebuild_frame(const LMatrix4d &mat) {
|
|
||||||
_rebuild_frames.push_back(mat);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: EggJointPointer::do_rebuild
|
// Function: EggJointPointer::do_rebuild
|
||||||
// Access: Public, Virtual
|
// Access: Public, Virtual
|
||||||
@ -87,12 +58,8 @@ add_rebuild_frame(const LMatrix4d &mat) {
|
|||||||
// acceptable, or false if there is some problem.
|
// acceptable, or false if there is some problem.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
bool EggJointPointer::
|
bool EggJointPointer::
|
||||||
do_rebuild() {
|
do_rebuild(EggCharacterDb &db) {
|
||||||
if (_rebuild_frames.empty()) {
|
return true;
|
||||||
return true;
|
|
||||||
}
|
|
||||||
_rebuild_frames.clear();
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
|
@ -20,11 +20,12 @@
|
|||||||
#define EGGJOINTPOINTER_H
|
#define EGGJOINTPOINTER_H
|
||||||
|
|
||||||
#include "pandatoolbase.h"
|
#include "pandatoolbase.h"
|
||||||
|
|
||||||
#include "eggBackPointer.h"
|
#include "eggBackPointer.h"
|
||||||
#include "eggGroup.h"
|
#include "eggGroup.h"
|
||||||
#include "luse.h"
|
#include "luse.h"
|
||||||
|
|
||||||
|
class EggCharacterDb;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Class : EggJointPointer
|
// Class : EggJointPointer
|
||||||
// Description : This is a base class for EggJointNodePointer and
|
// Description : This is a base class for EggJointNodePointer and
|
||||||
@ -44,21 +45,7 @@ public:
|
|||||||
virtual void do_finish_reparent(EggJointPointer *new_parent)=0;
|
virtual void do_finish_reparent(EggJointPointer *new_parent)=0;
|
||||||
virtual void move_vertices_to(EggJointPointer *new_joint);
|
virtual void move_vertices_to(EggJointPointer *new_joint);
|
||||||
|
|
||||||
void begin_rebuild();
|
virtual bool do_rebuild(EggCharacterDb &db);
|
||||||
virtual bool add_rebuild_frame(const LMatrix4d &mat);
|
|
||||||
INLINE int get_num_rebuild_frames() const;
|
|
||||||
INLINE const LMatrix4d &get_rebuild_frame(int n) const;
|
|
||||||
virtual bool do_rebuild();
|
|
||||||
|
|
||||||
INLINE void clear_net_frames();
|
|
||||||
INLINE void add_net_frame(const LMatrix4d &mat);
|
|
||||||
INLINE int get_num_net_frames() const;
|
|
||||||
INLINE const LMatrix4d &get_net_frame(int n) const;
|
|
||||||
|
|
||||||
INLINE void clear_net_frame_invs();
|
|
||||||
INLINE void add_net_frame_inv(const LMatrix4d &mat);
|
|
||||||
INLINE int get_num_net_frame_invs() const;
|
|
||||||
INLINE const LMatrix4d &get_net_frame_inv(int n) const;
|
|
||||||
|
|
||||||
virtual void optimize();
|
virtual void optimize();
|
||||||
virtual void expose(EggGroup::DCSType dcs_type);
|
virtual void expose(EggGroup::DCSType dcs_type);
|
||||||
@ -67,12 +54,6 @@ public:
|
|||||||
|
|
||||||
virtual EggJointPointer *make_new_joint(const string &name)=0;
|
virtual EggJointPointer *make_new_joint(const string &name)=0;
|
||||||
|
|
||||||
protected:
|
|
||||||
typedef pvector<LMatrix4d> RebuildFrames;
|
|
||||||
RebuildFrames _rebuild_frames;
|
|
||||||
RebuildFrames _net_frames;
|
|
||||||
RebuildFrames _net_frame_invs;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static TypeHandle get_class_type() {
|
static TypeHandle get_class_type() {
|
||||||
return _type_handle;
|
return _type_handle;
|
||||||
|
@ -189,8 +189,10 @@ do_finish_reparent(EggJointPointer *new_parent) {
|
|||||||
// acceptable, or false if there is some problem.
|
// acceptable, or false if there is some problem.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
bool EggMatrixTablePointer::
|
bool EggMatrixTablePointer::
|
||||||
do_rebuild() {
|
do_rebuild(EggCharacterDb &db) {
|
||||||
if (_rebuild_frames.empty()) {
|
LMatrix4d mat;
|
||||||
|
if (!db.get_matrix(this, EggCharacterDb::TT_rebuild_frame, 0, mat)) {
|
||||||
|
// No rebuild frame; this is OK.
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -201,14 +203,19 @@ do_rebuild() {
|
|||||||
bool all_ok = true;
|
bool all_ok = true;
|
||||||
|
|
||||||
_xform->clear_data();
|
_xform->clear_data();
|
||||||
RebuildFrames::const_iterator fi;
|
if (!_xform->add_data(mat)) {
|
||||||
for (fi = _rebuild_frames.begin(); fi != _rebuild_frames.end(); ++fi) {
|
all_ok = false;
|
||||||
if (!_xform->add_data(*fi)) {
|
}
|
||||||
all_ok = false;
|
|
||||||
}
|
// Assume all frames will be contiguous.
|
||||||
|
int n = 1;
|
||||||
|
while (db.get_matrix(this, EggCharacterDb::TT_rebuild_frame, n, mat)) {
|
||||||
|
if (!_xform->add_data(mat)) {
|
||||||
|
all_ok = false;
|
||||||
|
}
|
||||||
|
++n;
|
||||||
}
|
}
|
||||||
|
|
||||||
_rebuild_frames.clear();
|
|
||||||
return all_ok;
|
return all_ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,7 +46,7 @@ public:
|
|||||||
|
|
||||||
virtual void do_finish_reparent(EggJointPointer *new_parent);
|
virtual void do_finish_reparent(EggJointPointer *new_parent);
|
||||||
|
|
||||||
virtual bool do_rebuild();
|
virtual bool do_rebuild(EggCharacterDb &db);
|
||||||
|
|
||||||
virtual void optimize();
|
virtual void optimize();
|
||||||
virtual void zero_channels(const string &components);
|
virtual void zero_channels(const string &components);
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
#include "eggBackPointer.cxx"
|
#include "eggBackPointer.cxx"
|
||||||
#include "eggCharacterCollection.cxx"
|
#include "eggCharacterCollection.cxx"
|
||||||
#include "eggCharacterData.cxx"
|
#include "eggCharacterData.cxx"
|
||||||
|
#include "eggCharacterDb.cxx"
|
||||||
#include "eggCharacterFilter.cxx"
|
#include "eggCharacterFilter.cxx"
|
||||||
#include "eggComponentData.cxx"
|
#include "eggComponentData.cxx"
|
||||||
#include "eggJointData.cxx"
|
#include "eggJointData.cxx"
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
#include "eggJointData.h"
|
#include "eggJointData.h"
|
||||||
#include "eggCharacterCollection.h"
|
#include "eggCharacterCollection.h"
|
||||||
#include "eggCharacterData.h"
|
#include "eggCharacterData.h"
|
||||||
|
#include "eggCharacterDb.h"
|
||||||
#include "eggJointPointer.h"
|
#include "eggJointPointer.h"
|
||||||
#include "eggTable.h"
|
#include "eggTable.h"
|
||||||
#include "compose_matrix.h"
|
#include "compose_matrix.h"
|
||||||
@ -127,9 +128,10 @@ run() {
|
|||||||
keep_names.insert(*si);
|
keep_names.insert(*si);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EggCharacterDb db;
|
||||||
EggJointData *root_joint = char_data->get_root_joint();
|
EggJointData *root_joint = char_data->get_root_joint();
|
||||||
retarget_anim(char_data, root_joint, reference_model, keep_names);
|
retarget_anim(char_data, root_joint, reference_model, keep_names, db);
|
||||||
root_joint->do_rebuild();
|
root_joint->do_rebuild_all(db);
|
||||||
|
|
||||||
write_eggs();
|
write_eggs();
|
||||||
}
|
}
|
||||||
@ -143,7 +145,8 @@ run() {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void EggRetargetAnim::
|
void EggRetargetAnim::
|
||||||
retarget_anim(EggCharacterData *char_data, EggJointData *joint_data,
|
retarget_anim(EggCharacterData *char_data, EggJointData *joint_data,
|
||||||
int reference_model, const pset<string> &keep_names) {
|
int reference_model, const pset<string> &keep_names,
|
||||||
|
EggCharacterDb &db) {
|
||||||
if (keep_names.find(joint_data->get_name()) != keep_names.end()) {
|
if (keep_names.find(joint_data->get_name()) != keep_names.end()) {
|
||||||
// Don't retarget this joint; keep the translation and scale and whatever.
|
// Don't retarget this joint; keep the translation and scale and whatever.
|
||||||
|
|
||||||
@ -177,10 +180,8 @@ retarget_anim(EggCharacterData *char_data, EggJointData *joint_data,
|
|||||||
<< "\n";
|
<< "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!joint->add_rebuild_frame(mat)) {
|
db.set_matrix(joint, EggCharacterDb::TT_rebuild_frame,
|
||||||
nout << "Unable to combine animations.\n";
|
f, mat);
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -190,7 +191,7 @@ retarget_anim(EggCharacterData *char_data, EggJointData *joint_data,
|
|||||||
int num_children = joint_data->get_num_children();
|
int num_children = joint_data->get_num_children();
|
||||||
for (int i = 0; i < num_children; i++) {
|
for (int i = 0; i < num_children; i++) {
|
||||||
EggJointData *next_joint_data = joint_data->get_child(i);
|
EggJointData *next_joint_data = joint_data->get_child(i);
|
||||||
retarget_anim(char_data, next_joint_data, reference_model, keep_names);
|
retarget_anim(char_data, next_joint_data, reference_model, keep_names, db);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,6 +28,7 @@
|
|||||||
|
|
||||||
class EggCharacterData;
|
class EggCharacterData;
|
||||||
class EggJointData;
|
class EggJointData;
|
||||||
|
class EggCharacterDb;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Class : EggRetargetAnim
|
// Class : EggRetargetAnim
|
||||||
@ -43,7 +44,8 @@ public:
|
|||||||
void run();
|
void run();
|
||||||
|
|
||||||
void retarget_anim(EggCharacterData *char_data, EggJointData *joint_data,
|
void retarget_anim(EggCharacterData *char_data, EggJointData *joint_data,
|
||||||
int reference_model, const pset<string> &keep_names);
|
int reference_model, const pset<string> &keep_names,
|
||||||
|
EggCharacterDb &db);
|
||||||
|
|
||||||
Filename _reference_filename;
|
Filename _reference_filename;
|
||||||
vector_string _keep_joints;
|
vector_string _keep_joints;
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
#include "eggJointData.h"
|
#include "eggJointData.h"
|
||||||
#include "eggCharacterCollection.h"
|
#include "eggCharacterCollection.h"
|
||||||
#include "eggCharacterData.h"
|
#include "eggCharacterData.h"
|
||||||
|
#include "eggCharacterDb.h"
|
||||||
#include "eggJointPointer.h"
|
#include "eggJointPointer.h"
|
||||||
#include "eggTable.h"
|
#include "eggTable.h"
|
||||||
#include "compose_matrix.h"
|
#include "compose_matrix.h"
|
||||||
@ -125,6 +126,8 @@ run() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Now process each character.
|
// Now process each character.
|
||||||
|
EggCharacterDb db;
|
||||||
|
|
||||||
int ci;
|
int ci;
|
||||||
for (ci = 0; ci < num_characters; ci++) {
|
for (ci = 0; ci < num_characters; ci++) {
|
||||||
EggCharacterData *char_data = _collection->get_character(ci);
|
EggCharacterData *char_data = _collection->get_character(ci);
|
||||||
@ -163,7 +166,7 @@ run() {
|
|||||||
int num_children = root_joint->get_num_children();
|
int num_children = root_joint->get_num_children();
|
||||||
for (int i = 0; i < num_children; i++) {
|
for (int i = 0; i < num_children; i++) {
|
||||||
EggJointData *joint_data = root_joint->get_child(i);
|
EggJointData *joint_data = root_joint->get_child(i);
|
||||||
strip_anim(char_data, joint_data, from_model, from_char, top_joint);
|
strip_anim(char_data, joint_data, from_model, from_char, top_joint, db);
|
||||||
}
|
}
|
||||||
|
|
||||||
// We also need to transform the vertices for any models involved
|
// We also need to transform the vertices for any models involved
|
||||||
@ -173,7 +176,7 @@ run() {
|
|||||||
EggNode *node = char_data->get_model_root(m);
|
EggNode *node = char_data->get_model_root(m);
|
||||||
if (!node->is_of_type(EggTable::get_class_type())) {
|
if (!node->is_of_type(EggTable::get_class_type())) {
|
||||||
strip_anim_vertices(node, char_data->get_model_index(m),
|
strip_anim_vertices(node, char_data->get_model_index(m),
|
||||||
from_model, top_joint);
|
from_model, top_joint, db);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -181,7 +184,7 @@ run() {
|
|||||||
// Now, trigger the actual rebuilding of all the joint data.
|
// Now, trigger the actual rebuilding of all the joint data.
|
||||||
for (ci = 0; ci < num_characters; ci++) {
|
for (ci = 0; ci < num_characters; ci++) {
|
||||||
EggCharacterData *char_data = _collection->get_character(ci);
|
EggCharacterData *char_data = _collection->get_character(ci);
|
||||||
char_data->get_root_joint()->do_rebuild();
|
char_data->get_root_joint()->do_rebuild_all(db);
|
||||||
}
|
}
|
||||||
|
|
||||||
write_eggs();
|
write_eggs();
|
||||||
@ -235,11 +238,10 @@ check_transform_channels() {
|
|||||||
void EggTopstrip::
|
void EggTopstrip::
|
||||||
strip_anim(EggCharacterData *char_data, EggJointData *joint_data,
|
strip_anim(EggCharacterData *char_data, EggJointData *joint_data,
|
||||||
int from_model, EggCharacterData *from_char,
|
int from_model, EggCharacterData *from_char,
|
||||||
EggJointData *top_joint) {
|
EggJointData *top_joint, EggCharacterDb &db) {
|
||||||
int num_models = joint_data->get_num_models();
|
int num_models = joint_data->get_num_models();
|
||||||
for (int i = 0; i < num_models; i++) {
|
for (int i = 0; i < num_models; i++) {
|
||||||
int model = (from_model < 0) ? i : from_model;
|
int model = (from_model < 0) ? i : from_model;
|
||||||
|
|
||||||
if (joint_data->has_model(i)) {
|
if (joint_data->has_model(i)) {
|
||||||
if (!top_joint->has_model(model)) {
|
if (!top_joint->has_model(model)) {
|
||||||
nout << "Warning: Joint " << top_joint->get_name()
|
nout << "Warning: Joint " << top_joint->get_name()
|
||||||
@ -258,23 +260,16 @@ strip_anim(EggCharacterData *char_data, EggJointData *joint_data,
|
|||||||
DCAST_INTO_V(joint, back);
|
DCAST_INTO_V(joint, back);
|
||||||
|
|
||||||
// Compute and apply the new transforms.
|
// Compute and apply the new transforms.
|
||||||
joint->begin_rebuild();
|
|
||||||
|
|
||||||
int f;
|
int f;
|
||||||
for (f = 0; f < num_frames; f++) {
|
for (f = 0; f < num_frames; f++) {
|
||||||
LMatrix4d into = joint_data->get_frame(i, f % num_into_frames);
|
LMatrix4d into = joint_data->get_frame(i, f % num_into_frames);
|
||||||
LMatrix4d from = top_joint->get_net_frame(model, f % num_from_frames);
|
LMatrix4d from = top_joint->get_net_frame(model, f % num_from_frames, db);
|
||||||
|
|
||||||
adjust_transform(from);
|
adjust_transform(from);
|
||||||
|
|
||||||
if (!joint->add_rebuild_frame(into * from)) {
|
db.set_matrix(joint, EggCharacterDb::TT_rebuild_frame,
|
||||||
nout <<
|
f, into * from);
|
||||||
"Cannot apply multiple frames of animation to a model file.\n"
|
|
||||||
"In general, -r cannot be used when a model file is being "
|
|
||||||
"adjusted, unless the named source is a one-frame animation "
|
|
||||||
"file, or another model file.\n";
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -288,7 +283,7 @@ strip_anim(EggCharacterData *char_data, EggJointData *joint_data,
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void EggTopstrip::
|
void EggTopstrip::
|
||||||
strip_anim_vertices(EggNode *egg_node, int into_model, int from_model,
|
strip_anim_vertices(EggNode *egg_node, int into_model, int from_model,
|
||||||
EggJointData *top_joint) {
|
EggJointData *top_joint, EggCharacterDb &db) {
|
||||||
int model = (from_model < 0) ? into_model : from_model;
|
int model = (from_model < 0) ? into_model : from_model;
|
||||||
if (!top_joint->has_model(model)) {
|
if (!top_joint->has_model(model)) {
|
||||||
nout << "Warning: Joint " << top_joint->get_name()
|
nout << "Warning: Joint " << top_joint->get_name()
|
||||||
@ -296,7 +291,7 @@ strip_anim_vertices(EggNode *egg_node, int into_model, int from_model,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
LMatrix4d from = top_joint->get_net_frame(model, 0);
|
LMatrix4d from = top_joint->get_net_frame(model, 0, db);
|
||||||
adjust_transform(from);
|
adjust_transform(from);
|
||||||
|
|
||||||
egg_node->transform_vertices_only(from);
|
egg_node->transform_vertices_only(from);
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
#include "pvector.h"
|
#include "pvector.h"
|
||||||
|
|
||||||
class EggCharacterData;
|
class EggCharacterData;
|
||||||
|
class EggCharacterDb;
|
||||||
class EggJointData;
|
class EggJointData;
|
||||||
class EggJointPointer;
|
class EggJointPointer;
|
||||||
|
|
||||||
@ -47,9 +48,10 @@ public:
|
|||||||
|
|
||||||
void strip_anim(EggCharacterData *char_data, EggJointData *joint_data,
|
void strip_anim(EggCharacterData *char_data, EggJointData *joint_data,
|
||||||
int from_model, EggCharacterData *from_char,
|
int from_model, EggCharacterData *from_char,
|
||||||
EggJointData *top_joint);
|
EggJointData *top_joint, EggCharacterDb &db);
|
||||||
void strip_anim_vertices(EggNode *egg_node, int into_model,
|
void strip_anim_vertices(EggNode *egg_node, int into_model,
|
||||||
int from_model, EggJointData *top_joint);
|
int from_model, EggJointData *top_joint,
|
||||||
|
EggCharacterDb &db);
|
||||||
|
|
||||||
void adjust_transform(LMatrix4d &mat) const;
|
void adjust_transform(LMatrix4d &mat) const;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user