one side of animation is good while the other side is bad. A good point to save

This commit is contained in:
Asad M. Zaman 2003-11-14 23:20:10 +00:00
parent 4d37f8fe6d
commit 58e5f08e5d
6 changed files with 777 additions and 452 deletions

View File

@ -38,9 +38,12 @@ SoftNodeDesc(SoftNodeDesc *parent, const string &name) :
// Add ourselves to our parent.
if (_parent != (SoftNodeDesc *)NULL) {
cout << "parent name " << _parent->get_name();
_parent->_children.push_back(this);
}
vpool = NULL;
fullname = NULL;
numTexLoc = 0;
@ -92,6 +95,8 @@ set_model(SAA_Elem *model) {
void SoftNodeDesc::
set_parent(SoftNodeDesc *parent) {
if (_parent) {
cout << endl;
/*
cout << " expected _parent to be null!?\n";
if (_parent == parent)
cout << " parent already set\n";
@ -99,9 +104,14 @@ set_parent(SoftNodeDesc *parent) {
cout << " current parent " << _parent->get_name() << " new parent "
<< parent << endl;
}
*/
return;
}
_parent = parent;
cout << " set parent to " << _parent->get_name() << endl;
// Add ourselves to our parent.
_parent->_children.push_back(this);
}
////////////////////////////////////////////////////////////////////
@ -139,6 +149,17 @@ is_joint() const {
return _joint_type == JT_joint || _joint_type == JT_pseudo_joint;
}
////////////////////////////////////////////////////////////////////
// Function: SoftNodeDesc::is_junk
// Access: Private
// Description: Returns true if the node should be treated as a junk
// by the converter.
////////////////////////////////////////////////////////////////////
bool SoftNodeDesc::
is_junk() const {
return _joint_type == JT_junk;
}
////////////////////////////////////////////////////////////////////
// Function: SoftNodeDesc::set_joint
// Access: Private
@ -146,9 +167,8 @@ is_joint() const {
////////////////////////////////////////////////////////////////////
void SoftNodeDesc::
set_joint() {
_joint_type = JT_joint; // || _joint_type == JT_pseudo_joint;
_joint_type = JT_joint;
}
#if 0
////////////////////////////////////////////////////////////////////
// Function: SoftNodeDesc::is_joint_parent
// Access: Private
@ -189,9 +209,77 @@ void SoftNodeDesc::
mark_joint_parent() {
if (_joint_type == JT_none) {
_joint_type = JT_joint_parent;
cout << " marked parent " << get_name();
}
else
cout << " ?parent " << get_name() << " joint type " << _joint_type;
if (_parent != (SoftNodeDesc *)NULL) {
_parent->mark_joint_parent();
}
cout << endl;
}
////////////////////////////////////////////////////////////////////
// Function: SoftNodeDesc::check_joint_parent
// Access: Private
// Description: Walks the hierarchy, if a node is joint, make
// sure all its parents are marked JT_joint_parent
////////////////////////////////////////////////////////////////////
void SoftNodeDesc::
check_joint_parent() {
Children::const_iterator ci;
for (ci = _children.begin(); ci != _children.end(); ++ci) {
SoftNodeDesc *child = (*ci);
if (child->is_joint()) {
cout << "child " << child->get_name();
mark_joint_parent();
}
child->check_joint_parent();
}
}
///////////////////////////////////////////////////////////////////////
// Function: SoftNodeTree::check_junk
// Access: Public
// Description: check to see if this is a branch we don't want to
// descend - this will prevent creating geometry for
// animation control structures
///////////////////////////////////////////////////////////////////////
void SoftNodeDesc::
check_junk(bool parent_junk) {
const char *name = get_name().c_str();
if (parent_junk) {
_joint_type = JT_junk;
cout << "junk node " << get_name() << endl;
}
if ( (strstr(name, "con-") != NULL) ||
(strstr(name, "con_") != NULL) ||
(strstr(name, "fly_") != NULL) ||
(strstr(name, "fly-") != NULL) ||
(strstr(name, "camRIG") != NULL) ||
(strstr(name, "cam_rig") != NULL) ||
(strstr(name, "bars") != NULL) )
// split
/*
(!_search_prefix || (strstr(name, _search_prefix) != NULL)) )
*/
{
_joint_type = JT_junk;
cout << "junk node " << get_name() << endl;
parent_junk = true;
Children::const_iterator ci;
for (ci = _children.begin(); ci != _children.end(); ++ci) {
SoftNodeDesc *child = (*ci);
cout << child->get_name() << ",";
}
cout << endl;
}
Children::const_iterator ci;
for (ci = _children.begin(); ci != _children.end(); ++ci) {
SoftNodeDesc *child = (*ci);
child->check_junk(parent_junk);
}
}
@ -210,6 +298,7 @@ check_pseudo_joints(bool joint_above) {
// (JT_joint_parent is set), and it is the child of a joint
// (joint_above is set).
_joint_type = JT_pseudo_joint;
cout << "pseudo " << get_name() << " case1\n";
}
if (_joint_type == JT_joint) {
@ -218,9 +307,9 @@ check_pseudo_joints(bool joint_above) {
joint_above = true;
}
// Don't bother traversing further if _joint_type is none, since
// Don't bother traversing further if _joint_type is none or junk, since
// that means this node has no joint children.
if (_joint_type != JT_none) {
if (_joint_type != JT_none && _joint_type != JT_junk) {
bool any_joints = false;
Children::const_iterator ci;
@ -228,6 +317,7 @@ check_pseudo_joints(bool joint_above) {
SoftNodeDesc *child = (*ci);
child->check_pseudo_joints(joint_above);
if (child->is_joint()) {
cout << get_name() << " any_joint true by " << child->get_name() << endl;
any_joints = true;
}
}
@ -240,21 +330,45 @@ check_pseudo_joints(bool joint_above) {
SoftNodeDesc *child = (*ci);
if (child->_joint_type == JT_joint_parent) {
child->_joint_type = JT_pseudo_joint;
} else if (child->_joint_type == JT_none) {
cout << "pseudo " << child->get_name() << " case2 by parent " << get_name() << "\n";
} else if (child->_joint_type == JT_none || child->_joint_type == JT_junk) {
all_joints = false;
}
}
if (all_joints) {
// Finally, if all children are joints, then we are too.
if (all_joints || any_joints) {
// Finally, if all children or at least one is a joint, then we are too.
if (_joint_type == JT_joint_parent) {
_joint_type = JT_pseudo_joint;
cout << "pseudo " << get_name() << " case3\n";
}
}
}
}
else
cout << "found null joint " << get_name() << endl;
}
////////////////////////////////////////////////////////////////////
// Function: SoftToEggConverter::create_vpool
// Access: Public
// Description: Creates a new vpool for future soft skining,
// this is a one to one reference to external index.
////////////////////////////////////////////////////////////////////
void SoftNodeDesc::
create_vpool(string vpool_name) {
vpool = new EggVertexPool(vpool_name);
}
////////////////////////////////////////////////////////////////////
// Function: SoftToEggConverter::get_vpool
// Access: Public
// Description: Get vpool
////////////////////////////////////////////////////////////////////
EggVertexPool *SoftNodeDesc::
get_vpool() {
return vpool;
}
#endif
////////////////////////////////////////////////////////////////////
// Function: SoftToEggConverter::get_transform
@ -263,24 +377,43 @@ check_pseudo_joints(bool joint_above) {
// and applies it to the corresponding Egg node.
////////////////////////////////////////////////////////////////////
void SoftNodeDesc::
get_transform(SAA_Scene *scene, EggGroup *egg_group, bool set_transform) {
get_transform(SAA_Scene *scene, EggGroup *egg_group, bool global) {
// Get the model's matrix
int scale_joint = 0;
if ( strstr( _parent->get_name().c_str(), "scale" ) != NULL ) {
scale_joint = 1;
cout << "scale joint flag set!\n";
}
if (!global && _parent->is_joint() && !stec.flatten && !scale_joint) {
SAA_modelGetMatrix( scene, get_model(), SAA_COORDSYS_LOCAL, matrix );
cout << get_name() << " using local matrix :parent ";
} else {
SAA_modelGetMatrix( scene, get_model(), SAA_COORDSYS_GLOBAL, matrix );
cout << get_name() << " using global matrix :parent ";
}
cout << _parent->get_name() << endl;
cout << "model matrix = " << matrix[0][0] << " " << matrix[0][1] << " " << matrix[0][2] << " " << matrix[0][3] << "\n";
cout << "model matrix = " << matrix[1][0] << " " << matrix[1][1] << " " << matrix[1][2] << " " << matrix[1][3] << "\n";
cout << "model matrix = " << matrix[2][0] << " " << matrix[2][1] << " " << matrix[2][2] << " " << matrix[2][3] << "\n";
cout << "model matrix = " << matrix[3][0] << " " << matrix[3][1] << " " << matrix[3][2] << " " << matrix[3][3] << "\n";
if (set_transform) {
if (!global && is_joint()) {
LMatrix4d m4d(matrix[0][0], matrix[0][1], matrix[0][2], matrix[0][3],
matrix[1][0], matrix[1][1], matrix[1][2], matrix[1][3],
matrix[2][0], matrix[2][1], matrix[2][2], matrix[2][3],
matrix[3][0], matrix[3][1], matrix[3][2], matrix[3][3]);
if (!m4d.almost_equal(LMatrix4d::ident_mat(), 0.0001)) {
// if (!m4d.almost_equal(LMatrix4d::ident_mat(), 0.0001)) {
egg_group->set_transform(m4d);
cout << "set transform in egg_group\n";
}
// }
}
return;
}
@ -298,7 +431,7 @@ get_transform(SAA_Scene *scene, EggGroup *egg_group, bool set_transform) {
// anim (EffXfmSAnim) class (masad).
////////////////////////////////////////////////////////////////////
void SoftNodeDesc::
get_joint_transform(SAA_Scene *scene, EggGroup *egg_group, EggXfmSAnim *anim) {
get_joint_transform(SAA_Scene *scene, EggGroup *egg_group, EggXfmSAnim *anim, bool global) {
// SI_Error result;
SAA_Elem *skeletonPart = _model;
const char *name = get_name().c_str();
@ -310,6 +443,12 @@ get_joint_transform(SAA_Scene *scene, EggGroup *egg_group, EggXfmSAnim *anim) {
int size;
SAA_Boolean globalFlag = FALSE;
SAA_Boolean bigEndian;
int scale_joint = 0;
if ( strstr( _parent->get_name().c_str(), "scale" ) != NULL ) {
scale_joint = 1;
cout << "scale joint flag set!\n";
}
cout << "\n\nanimating child " << name << endl;
@ -319,22 +458,8 @@ get_joint_transform(SAA_Scene *scene, EggGroup *egg_group, EggXfmSAnim *anim) {
SAA_elementGetUserData( scene, skeletonPart, "GLOBAL",
sizeof( SAA_Boolean), &bigEndian, (void *)&globalFlag );
if ( globalFlag ) {
cout << " using global matrix\n";
//get SAA orientation
SAA_modelGetRotation( scene, skeletonPart, SAA_COORDSYS_GLOBAL,
&p, &h, &r );
//get SAA translation
SAA_modelGetTranslation( scene, skeletonPart, SAA_COORDSYS_GLOBAL,
&x, &y, &z );
//get SAA scaling
SAA_modelGetScaling( scene, skeletonPart, SAA_COORDSYS_GLOBAL,
&i, &j, &k );
}
else {
// if ( global ) {
if (_parent->is_joint() && !stec.flatten && !scale_joint ) {
cout << "using local matrix\n";
//get SAA orientation
@ -348,6 +473,20 @@ get_joint_transform(SAA_Scene *scene, EggGroup *egg_group, EggXfmSAnim *anim) {
//get SAA scaling
SAA_modelGetScaling( scene, skeletonPart, SAA_COORDSYS_LOCAL,
&i, &j, &k );
} else {
cout << " using global matrix\n";
//get SAA orientation
SAA_modelGetRotation( scene, skeletonPart, SAA_COORDSYS_GLOBAL,
&p, &h, &r );
//get SAA translation
SAA_modelGetTranslation( scene, skeletonPart, SAA_COORDSYS_GLOBAL,
&x, &y, &z );
//get SAA scaling
SAA_modelGetScaling( scene, skeletonPart, SAA_COORDSYS_GLOBAL,
&i, &j, &k );
}
cout << "\nanim data: " << i << " " << j << " " << k << endl;
@ -399,6 +538,10 @@ load_model(SAA_Scene *scene, SAA_ModelType type) {
fullname = name;
// if making a pose - get deformed geometry
if ( stec.make_pose )
gtype = SAA_GEOM_DEFORMED;
// If the model is a NURBS in soft, set its step before tesselating
if ( type == SAA_MNSRF )
SAA_nurbsSurfaceSetStep( scene, _model, stec.nurbs_step, stec.nurbs_step );
@ -583,6 +726,7 @@ load_model(SAA_Scene *scene, SAA_ModelType type) {
}
cout << "got textures" << endl;
}
//
//
//

View File

@ -28,6 +28,8 @@
#include "pandatoolbase.h"
#include "eggVertex.h"
#include "eggVertexPool.h"
#include "referenceCount.h"
#include "pointerTo.h"
#include "namable.h"
@ -56,8 +58,9 @@ public:
SAA_Elem *get_model() const;
bool is_joint() const;
bool is_junk() const;
void set_joint();
// bool is_joint_parent() const;
bool is_joint_parent() const;
SoftNodeDesc *_parent;
typedef pvector< PT(SoftNodeDesc) > Children;
@ -65,8 +68,10 @@ public:
private:
void clear_egg();
// void mark_joint_parent();
// void check_pseudo_joints(bool joint_above);
void mark_joint_parent();
void check_joint_parent();
void check_junk(bool parent_junk);
void check_pseudo_joints(bool joint_above);
SAA_ModelType type;
const char *fullname;
@ -83,6 +88,7 @@ private:
JT_pseudo_joint, // Not a joint in Soft, but treated just like a
// joint for the purposes of the converter.
JT_joint_parent, // A parent or ancestor of a joint or pseudo joint.
JT_junk, // originated from con-/fly-/car_rig/bars etc.
};
JointType _joint_type;
@ -110,10 +116,17 @@ public:
SAA_SubElem *triangles;
SAA_GeomType gtype;
void get_transform(SAA_Scene *scene, EggGroup *egg_group, bool set_transform=FALSE);
void get_joint_transform(SAA_Scene *scene, EggGroup *egg_group, EggXfmSAnim *anim);
EggGroup *get_egg_group()const {return _egg_group;}
void get_transform(SAA_Scene *scene, EggGroup *egg_group, bool global);
void get_joint_transform(SAA_Scene *scene, EggGroup *egg_group, EggXfmSAnim *anim, bool global);
void load_model(SAA_Scene *scene, SAA_ModelType type);
EggVertexPool *vpool;
EggVertexPool *get_vpool();
void create_vpool(string vpool_name);
static TypeHandle get_class_type() {
return _type_handle;
}

View File

@ -38,7 +38,7 @@
////////////////////////////////////////////////////////////////////
SoftNodeTree::
SoftNodeTree() {
_root = new SoftNodeDesc;
_root = new SoftNodeDesc(NULL, "----root");
_fps = 0.0;
_use_prefix = 0;
_search_prefix = NULL;
@ -168,6 +168,7 @@ GetRootName( const char *name ) {
bool SoftNodeTree::
build_complete_hierarchy(SAA_Scene &scene, SAA_Database &database) {
SI_Error status;
SoftNodeDesc *node;
// Get the entire Soft scene.
int numModels;
@ -193,17 +194,22 @@ build_complete_hierarchy(SAA_Scene &scene, SAA_Database &database) {
cout << " level " << level << endl;
cout << " status is " << status << "\n";
// if (!level) {
build_node(&scene, &models[i]);
// }
node = build_node(&scene, &models[i]);
if (!level && node)
node->set_parent(_root);
}
}
}
# if 0
if (all_ok) {
// check the nodes that are junk for animation/artist control purposes
_root->check_junk(false);
// check the nodes that are parent of ancestors of a joint
_root->check_joint_parent();
// check the nodes that are pseudo joints
_root->check_pseudo_joints(false);
}
#endif
return all_ok;
}
#if 0
@ -295,6 +301,20 @@ get_node(int n) const {
return _nodes[n];
}
////////////////////////////////////////////////////////////////////
// Function: SoftNodeTree::get_node
// Access: Public
// Description: Returns the node named 'name' in the hierarchy, in
// an arbitrary ordering.
////////////////////////////////////////////////////////////////////
SoftNodeDesc *SoftNodeTree::
get_node(string name) const {
NodesByName::const_iterator ni = _nodes_by_name.find(name);
if (ni != _nodes_by_name.end())
return (*ni).second;
return NULL;
}
////////////////////////////////////////////////////////////////////
// Function: SoftNodeTree::clear_egg
// Access: Public
@ -305,7 +325,7 @@ get_node(int n) const {
void SoftNodeTree::
clear_egg(EggData *egg_data, EggGroupNode *egg_root,
EggGroupNode *skeleton_node) {
// _root->clear_egg();
_root->clear_egg();
_egg_data = egg_data;
_egg_root = egg_root;
_skeleton_node = skeleton_node;
@ -322,8 +342,14 @@ EggGroup *SoftNodeTree::
get_egg_group(SoftNodeDesc *node_desc) {
nassertr(_egg_root != (EggGroupNode *)NULL, NULL);
cout << node_desc->_egg_group << endl;
cout << node_desc->_parent << endl;
// lets print some relationship
cout << " group " << node_desc->get_name() << "(" << node_desc->_egg_group << ")";
if (node_desc->_parent)
cout << " parent " << node_desc->_parent->get_name() << "(" << node_desc->_parent << ")";
else
cout << " parent " << node_desc->_parent;
cout << endl;
if (node_desc->_egg_group == (EggGroup *)NULL) {
// We need to make a new group node.
EggGroup *egg_group;
@ -335,6 +361,7 @@ get_egg_group(SoftNodeDesc *node_desc) {
if (!node_desc->_parent || node_desc->_parent == _root) {
// The parent is the root.
cout << "came hereeeee\n";
_egg_root->add_child(egg_group);
} else {
// The parent is another node.
@ -342,96 +369,6 @@ get_egg_group(SoftNodeDesc *node_desc) {
parent_egg_group->add_child(egg_group);
}
#if 0
SoftEggGroupUserData *parent_user_data = NULL;
if (node_desc->_parent == _root) {
// The parent is the root.
_egg_root->add_child(egg_group);
} else {
// The parent is another node.
EggGroup *parent_egg_group = get_egg_group(node_desc->_parent);
parent_egg_group->add_child(egg_group);
if (parent_egg_group->has_user_data()) {
DCAST_INTO_R(parent_user_data, parent_egg_group->get_user_data(), NULL);
}
}
if (node_desc->has_models()) {
// Check for an object type setting, from Oliver's plug-in.
MObject dag_object = node_desc->get_dag_path().node();
string object_type;
if (get_enum_attribute(dag_object, "eggObjectTypes1", object_type)) {
egg_group->add_object_type(object_type);
}
if (get_enum_attribute(dag_object, "eggObjectTypes2", object_type)) {
egg_group->add_object_type(object_type);
}
if (get_enum_attribute(dag_object, "eggObjectTypes3", object_type)) {
egg_group->add_object_type(object_type);
}
// Is the node flagged to be invisible? If it is, and is has no
// other egg flags, it is implicitly tagged "backstage", so it
// won't get converted. (But it might be an invisible collision
// solid, which is why we do this only if it has no other egg
// flags.)
bool visible = true;
get_bool_attribute(dag_object, "visibility", visible);
if (!visible && egg_group->get_num_object_types() == 0) {
egg_group->add_object_type("backstage");
}
// We treat the object type "billboard" as a special case: we
// apply this one right away and also flag the group as an
// instance.
if (egg_group->has_object_type("billboard")) {
egg_group->remove_object_type("billboard");
egg_group->set_group_type(EggGroup::GT_instance);
egg_group->set_billboard_type(EggGroup::BT_axis);
} else if (egg_group->has_object_type("billboard-point")) {
egg_group->remove_object_type("billboard-point");
egg_group->set_group_type(EggGroup::GT_instance);
egg_group->set_billboard_type(EggGroup::BT_point_camera_relative);
}
// We also treat the object type "dcs" and "model" as a special
// case, so we can test for these flags later.
if (egg_group->has_object_type("dcs")) {
egg_group->remove_object_type("dcs");
egg_group->set_dcs_type(EggGroup::DC_default);
}
if (egg_group->has_object_type("model")) {
egg_group->remove_object_type("model");
egg_group->set_model_flag(true);
}
// And "vertex-color" and "double-sided" have meaning only to
// this converter.
SoftEggGroupUserData *user_data;
if (parent_user_data == (SoftEggGroupUserData *)NULL) {
user_data = new SoftEggGroupUserData;
} else {
// Inherit the flags from above.
user_data = new SoftEggGroupUserData(*parent_user_data);
}
if (egg_group->has_object_type("vertex-color")) {
egg_group->remove_object_type("vertex-color");
user_data->_vertex_color = true;
}
if (egg_group->has_object_type("double-sided")) {
egg_group->remove_object_type("double-sided");
user_data->_double_sided = true;
}
egg_group->set_user_data(user_data);
}
#endif
// EggUserData *user_data = new EggUserData;
// egg_group->set_user_data(user_data);
node_desc->_egg_group = egg_group;
}
@ -450,6 +387,14 @@ get_egg_table(SoftNodeDesc *node_desc) {
nassertr(_skeleton_node != (EggGroupNode *)NULL, NULL);
nassertr(node_desc->is_joint(), NULL);
// lets print some relationship
cout << " group " << node_desc->get_name() << "(" << node_desc->_egg_group << ")";
if (node_desc->_parent)
cout << " parent " << node_desc->_parent->get_name() << "(" << node_desc->_parent << ")";
else
cout << " parent " << node_desc->_parent;
cout << endl;
if (node_desc->_egg_table == (EggTable *)NULL) {
cout << "creating a new table\n";
// We need to make a new table node.
@ -460,16 +405,16 @@ get_egg_table(SoftNodeDesc *node_desc) {
node_desc->_anim->set_fps(_fps);
egg_table->add_child(node_desc->_anim);
if (!node_desc->_parent || node_desc->_parent == _root) {
// if (!node_desc->_parent->is_joint()) {
// The parent is not a joint; put it at the top.
_skeleton_node->add_child(egg_table);
/*
} else {
// The parent is another joint.
EggTable *parent_egg_table = get_egg_table(node_desc->_parent);
parent_egg_table->add_child(egg_table);
}
*/
node_desc->_egg_table = egg_table;
}
@ -489,6 +434,50 @@ get_egg_anim(SoftNodeDesc *node_desc) {
return node_desc->_anim;
}
////////////////////////////////////////////////////////////////////
// Function: SoftNodeTree::handle_null
// Access: Public
// Description: Sets joint information for MNILL node
////////////////////////////////////////////////////////////////////
void SoftNodeTree::
handle_null(SAA_Scene *scene, SoftNodeDesc *node_desc, char *node_name) {
const char *name = node_name;
SAA_AlgorithmType algo;
SAA_Elem *model = node_desc->get_model();
SAA_modelGetAlgorithm( scene, model, &algo );
cout << " null algorithm: " << algo << endl;
if ( algo == SAA_ALG_INV_KIN ) {
// MakeJoint( &scene, lastJoint, lastAnim, model, name );
node_desc->set_joint();
cout << " encountered IK root: " << name << endl;
}
else if ( algo == SAA_ALG_INV_KIN_LEAF ) {
// MakeJoint( &scene, lastJoint, lastAnim, model, name );
node_desc->set_joint();
cout << " encountered IK leaf: " << name << endl;
}
else if ( algo == SAA_ALG_STANDARD ) {
SAA_Boolean isSkeleton = FALSE;
cout << " encountered Standard null: " << name << endl;
SAA_modelIsSkeleton( scene, model, &isSkeleton );
// check to see if this NULL is used as a skeleton
// or is animated via constraint only ( these nodes are
// tagged by the animator with the keyword "joint"
// somewhere in the nodes name)
if ( isSkeleton || (strstr( name, "joint" ) != NULL) ) {
// MakeJoint( &scene, lastJoint, lastAnim, model, name );
node_desc->set_joint();
cout << " animating Standard null!!!\n";
}
}
else
cout << " encountered some other NULL: " << algo << endl;
}
////////////////////////////////////////////////////////////////////
// Function: SoftNodeTree::build_node
// Access: Public
@ -496,13 +485,14 @@ get_egg_anim(SoftNodeDesc *node_desc) {
// indicated dag_path object, creating it first if
// necessary.
////////////////////////////////////////////////////////////////////
void SoftNodeTree::
SoftNodeDesc *SoftNodeTree::
build_node(SAA_Scene *scene, SAA_Elem *model) {
char *name;
string node_name;
int numChildren;
int thisChild;
SAA_Elem *children;
SAA_ModelType type;
SAA_Boolean isSkeleton = FALSE;
if (_use_prefix)
@ -512,28 +502,19 @@ build_node(SAA_Scene *scene, SAA_Elem *model) {
node_name = name;
///////////////////////////////////////////////////////////////////////
// check to see if this is a branch we don't want to descend - this
// will prevent creating geometry for animation control structures
///////////////////////////////////////////////////////////////////////
/*
if ( (strstr(name, "con-") == NULL) &&
(strstr(name, "con_") == NULL) &&
(strstr(name, "fly_") == NULL) &&
(strstr(name, "fly-") == NULL) &&
(strstr(name, "camRIG") == NULL) &&
(strstr(name, "bars") == NULL) &&
// split
(!_search_prefix || (strstr(name, _search_prefix) != NULL)) )
{
*/
SoftNodeDesc *node_desc = r_build_node(NULL, node_name);
node_desc->set_model(model);
SAA_modelIsSkeleton( scene, model, &isSkeleton );
if (isSkeleton || (strstr(node_desc->get_name().c_str(), "joint") != NULL))
node_desc->set_joint();
// find out what type of node we're dealing with
SAA_modelGetType( scene, node_desc->get_model(), &type );
// treat the MNILL differently, because it needs to detect and set some joints
if (type == SAA_MNILL)
handle_null(scene, node_desc, name);
SAA_modelGetNbChildren( scene, model, &numChildren );
cout << " Model " << node_name << " children: " << numChildren << endl;
@ -560,8 +541,7 @@ build_node(SAA_Scene *scene, SAA_Elem *model) {
node_child->set_joint();
}
}
// }
return;
return node_desc;
}
////////////////////////////////////////////////////////////////////
@ -574,27 +554,27 @@ r_build_node(SoftNodeDesc *parent_node, const string &name) {
SoftNodeDesc *node_desc;
// If we have already encountered this pathname, return the
// corresponding MayaNodeDesc immediately.
// corresponding SoftNodeDesc immediately.
NodesByName::const_iterator ni = _nodes_by_name.find(name);
if (ni != _nodes_by_name.end()) {
cout << (*ni).first << endl;
cout << " already built node " << (*ni).first;
node_desc = (*ni).second;
if (stec.flatten)
node_desc->set_parent(_root);
else
node_desc->set_parent(parent_node);
return node_desc;
}
// Otherwise, we have to create it. Do this recursively, so we
// create each node along the path.
/*
if (!parent_node) {
node_desc = _root;
}
else {
*/
if (stec.flatten)
node_desc = new SoftNodeDesc(_root, name);
else
node_desc = new SoftNodeDesc(parent_node, name);
/*
}
*/
cout << " node name : " << name << endl;
_nodes.push_back(node_desc);
@ -602,7 +582,6 @@ r_build_node(SoftNodeDesc *parent_node, const string &name) {
return node_desc;
}
//
//
//

View File

@ -39,12 +39,14 @@ class EggGroupNode;
class SoftNodeTree {
public:
SoftNodeTree();
void build_node(SAA_Scene *scene, SAA_Elem *model);
SoftNodeDesc *build_node(SAA_Scene *scene, SAA_Elem *model);
bool build_complete_hierarchy(SAA_Scene &scene, SAA_Database &database);
void handle_null(SAA_Scene *scene, SoftNodeDesc *node_desc, char *node_name);
// bool build_selected_hierarchy(SAA_Scene *s, SAA_Database *d, char *scene_name);
int get_num_nodes() const;
SoftNodeDesc *get_node(int n) const;
SoftNodeDesc *get_node(string name) const;
char *GetRootName(const char *);
char *GetModelNoteInfo(SAA_Scene *, SAA_Elem *);

View File

@ -279,7 +279,7 @@ HandleGetopts(int &idx, int argc, char **argv)
if ( strcmp( argv[idx+1], "" ) ) {
// Get model name.
model_name = argv[idx+1];
softegg_cat.info() << "loading model %s\n" << model_name;
softegg_cat.info() << "loading model " << model_name << endl;
}
++idx;
break;
@ -288,7 +288,7 @@ HandleGetopts(int &idx, int argc, char **argv)
if ( strcmp( argv[idx+1], "" ) ) {
// Get tex path name.
tex_path = argv[idx+1];
softegg_cat.info() << "texture path: %s\n" << tex_path;
softegg_cat.info() << "texture path: " << tex_path << endl;
}
++idx;
break;
@ -297,7 +297,7 @@ HandleGetopts(int &idx, int argc, char **argv)
if ( strcmp( argv[idx+1], "") ) {
// Get the name.
tex_filename = argv[idx+1];
softegg_cat.info() << "creating texture list file: %s\n" << tex_filename;
softegg_cat.info() << "creating texture list file: " << tex_filename << endl;
}
++idx;
break;
@ -305,7 +305,7 @@ HandleGetopts(int &idx, int argc, char **argv)
case 'S': // Set NURBS step.
if ( strcmp( argv[idx+1], "" ) ) {
nurbs_step = atoi(argv[idx+1]);
softegg_cat.info() << "NURBS step: %d\n" << nurbs_step;
softegg_cat.info() << "NURBS step: " << nurbs_step << endl;
}
++idx;
break;
@ -313,7 +313,7 @@ HandleGetopts(int &idx, int argc, char **argv)
case 'M': // Set model output file name.
if ( strcmp( argv[idx+1], "" ) ) {
eggFileName = argv[idx+1];
softegg_cat.info() << "Model output filename: %s\n" << eggFileName;
softegg_cat.info() << "Model output filename: " << eggFileName << endl;
}
++idx;
break;
@ -321,7 +321,7 @@ HandleGetopts(int &idx, int argc, char **argv)
case 'A': // Set anim output file name.
if ( strcmp( argv[idx+1], "" ) ) {
animFileName = argv[idx+1];
softegg_cat.info() << "Anim output filename: %s\n" << animFileName;
softegg_cat.info() << "Anim output filename: " << animFileName << endl;
}
++idx;
break;
@ -329,7 +329,7 @@ HandleGetopts(int &idx, int argc, char **argv)
case 'N': // Set egg model name.
if ( strcmp( argv[idx+1], "" ) ) {
eggGroupName = argv[idx+1];
softegg_cat.info() << "Egg group name: %s\n" << eggGroupName;
softegg_cat.info() << "Egg group name: " << eggGroupName << endl;
}
++idx;
break;
@ -337,7 +337,7 @@ HandleGetopts(int &idx, int argc, char **argv)
case 'o': // Set search_prefix.
if ( strcmp( argv[idx+1], "" ) ) {
search_prefix = argv[idx+1];
softegg_cat.info() << "Only converting models with prefix: %s\n" << search_prefix;
softegg_cat.info() << "Only converting models with prefix: " << search_prefix << endl;
}
++idx;
break;
@ -382,7 +382,7 @@ HandleGetopts(int &idx, int argc, char **argv)
if ( strcmp( argv[idx+1], "" ) ) {
make_pose = TRUE;
pose_frame = atoi(argv[idx+1]);
softegg_cat.info() << "generating static pose from frame %d\n" << pose_frame;
softegg_cat.info() << "generating static pose from frame " << pose_frame << endl;
}
++idx;
break;
@ -416,7 +416,7 @@ HandleGetopts(int &idx, int argc, char **argv)
case 'v': // print debug messages.
if ( strcmp( argv[idx+1], "" ) ) {
verbose = atoi(argv[idx+1]);
softegg_cat.info() << "using debug level %d\n" << verbose;
softegg_cat.info() << "using debug level " << verbose << endl;
}
++idx;
break;
@ -424,14 +424,15 @@ HandleGetopts(int &idx, int argc, char **argv)
case 'b': // Set animation start frame.
if ( strcmp( argv[idx+1], "" ) ) {
anim_start = atoi(argv[idx+1]);
softegg_cat.info() << "animation starting at frame: %d\n" << anim_start;
softegg_cat.info() << "animation starting at frame: " << anim_start << endl;
}
++idx;
break;
case 'e': /// Set animation end frame.
if ( strcmp( argv[idx+1], "" ) ) {
anim_end = atoi(argv[idx+1]);
softegg_cat.info() << "animation ending at frame: %d\n" << anim_end;
softegg_cat.info() << "animation ending at frame: " << anim_end << endl;
}
++idx;
break;
@ -439,7 +440,7 @@ HandleGetopts(int &idx, int argc, char **argv)
case 'f': /// Set animation frame rate.
if ( strcmp( argv[idx+1], "" ) ) {
anim_rate = atoi(argv[idx+1]);
softegg_cat.info() << "animation frame rate: %d\n" << anim_rate;
softegg_cat.info() << "animation frame rate: " << anim_rate << endl;
}
++idx;
break;
@ -484,6 +485,17 @@ get_extension() const {
return "mb";
}
////////////////////////////////////////////////////////////////////
// Function: SoftToEggConverter::get_name
// Access: Public, Virtual
// Description: Returns the English name of the file type this
// converter supports.
////////////////////////////////////////////////////////////////////
SoftNodeDesc *SoftToEggConverter::
find_node(string name) {
return _tree.get_node(name);
}
////////////////////////////////////////////////////////////////////
// Function: GetTextureName
// Access: Public
@ -574,9 +586,13 @@ convert_soft(bool from_selection) {
_tree._use_prefix = use_prefix;
_tree._search_prefix = search_prefix;
all_ok = _tree.build_complete_hierarchy(scene, database);
// Lets see if we have gotten the hierarchy right
//_tree.print_hierarchy();
//exit(1);
char *root_name = _tree.GetRootName( eggFileName );
cout << "main group name: " << root_name << endl;
if (root_name)
_character_name = root_name;
@ -586,6 +602,11 @@ convert_soft(bool from_selection) {
all_ok = false;
}
// generate soft skinning assignments if desired
if (!make_soft_skin()) {
all_ok = false;
}
// reparent_decals(&get_egg_data());
cout << softegg_cat.info() << "Converted Softimage file\n";
@ -703,7 +724,7 @@ convert_char_model() {
}
#endif
cout << "character name " << _character_name << "\n";
EggGroup *char_node = new EggGroup(_character_name);
EggGroup *char_node = new EggGroup(eggGroupName);
get_egg_data().add_child(char_node);
char_node->set_dart_type(EggGroup::DT_default);
@ -728,11 +749,15 @@ convert_char_chan() {
EggTable *root_table_node = new EggTable();
get_egg_data().add_child(root_table_node);
EggTable *bundle_node = new EggTable(_character_name);
EggTable *bundle_node = new EggTable(eggGroupName);
bundle_node->set_table_type(EggTable::TT_bundle);
root_table_node->add_child(bundle_node);
EggTable *skeleton_node = new EggTable("<skeleton>");
bundle_node->add_child(skeleton_node);
#if 0
EggTable *root_node = new EggTable("root");
skeleton_node->add_child(root_node);
#endif
// Set the frame rate before we start asking for anim tables to be
// created.
@ -744,6 +769,7 @@ convert_char_chan() {
cout << "animation frame inc: " << frame_inc << endl;
_tree._fps = output_frame_rate / frame_inc;
// _tree.clear_egg(&get_egg_data(), NULL, root_node);
_tree.clear_egg(&get_egg_data(), NULL, skeleton_node);
// Now we can get the animation data by walking through all of the
@ -760,9 +786,20 @@ convert_char_chan() {
// MTime frame(start_frame, MTime::uiUnit());
// MTime frame_stop(end_frame, MTime::uiUnit());
// start at first frame and go to last
if (make_pose) {
start_frame = pose_frame;
end_frame = pose_frame;
}
if (anim_start > 0)
start_frame = anim_start;
if (anim_end > 0)
end_frame = anim_end;
for ( frame = start_frame; frame <= end_frame; frame += frame_inc) {
SAA_frame2Seconds( &scene, frame, &time );
// cout << "got time " << time << endl;
if (!make_pose) {
SAA_updatelistEvalScene( &scene, time );
}
cout << "\n> animating frame " << frame << endl;
// if (softegg_cat.is_debug()) {
@ -778,13 +815,10 @@ convert_char_chan() {
for (i = 0; i < num_nodes; i++) {
SoftNodeDesc *node_desc = _tree.get_node(i);
if (node_desc->is_joint()) {
if (softegg_cat.is_spam()) {
softegg_cat.spam()
<< "joint " << node_desc->get_name() << "\n";
}
cout << "-----joint " << node_desc->get_name() << "\n";
EggXfmSAnim *anim = _tree.get_egg_anim(node_desc);
// following function fills in the anim structure
node_desc->get_joint_transform(&scene, tgroup, anim);
node_desc->get_joint_transform(&scene, tgroup, anim, TRUE);
}
}
@ -843,29 +877,23 @@ process_model_node(SoftNodeDesc *node_desc) {
char *fullname = NULL;
SAA_ModelType type;
#if 0
// Get the name of the model
if ( use_prefix ) {
// Get the FULL name of the model
name = fullname = _tree.GetFullName( &scene, node_desc->get_model() );
}
else {
// Get the name of the trim curve
name = _tree.GetName( &scene, node_desc->get_model() );
}
#endif
name = node_desc->get_name().c_str();
cout << "element name <" << name << ">\n";
// find out what type of node we're dealing with
result = SAA_modelGetType( &scene, node_desc->get_model(), &type );
if (node_desc->is_junk()) {
cout << "no processing, it is junk\n";
return true;
}
egg_group = _tree.get_egg_group(node_desc);
// find out what type of node we're dealing with
SAA_modelGetType( &scene, node_desc->get_model(), &type );
cout << "encountered ";
switch(type){
case SAA_MNILL:
cout << "null\n";
node_desc->get_transform(&scene, egg_group);
handle_null(node_desc->get_model(), egg_group, type, name);
break;
case SAA_MPTCH:
cout << "patch\n";
@ -875,11 +903,12 @@ process_model_node(SoftNodeDesc *node_desc) {
break;
case SAA_MSMSH:
cout << "mesh\n";
node_desc->get_transform(&scene, egg_group);
node_desc->get_transform(&scene, egg_group, TRUE);
make_polyset(node_desc, egg_group, type);
break;
case SAA_MJNT:
cout << "joint\n";
cout << "joint";
cout << " joint type " << node_desc->is_joint() << endl;
break;
case SAA_MSPLN:
cout << "spline\n";
@ -901,7 +930,7 @@ process_model_node(SoftNodeDesc *node_desc) {
}
if (node_desc->is_joint())
node_desc->get_transform(&scene, egg_group, TRUE);
node_desc->get_transform(&scene, egg_group, FALSE);
return true;
}
@ -951,6 +980,12 @@ make_polyset(SoftNodeDesc *node_desc, EggGroup *egg_group, SAA_ModelType type) {
EggVertexPool *vpool = new EggVertexPool(vpool_name);
egg_group->add_child(vpool);
/*
// create a copy of vpool in node_desc which will be used later
// for soft_skinning
node_desc->create_vpool(vpool_name);
*/
// little detour...bear with me for now...TODO: move these to a new function
// We will need to transform all vertices from world coordinate
@ -1098,6 +1133,17 @@ make_polyset(SoftNodeDesc *node_desc, EggGroup *egg_group, SAA_ModelType type) {
}
vert.set_external_index(indices[i]);
egg_poly->add_vertex(vpool->create_unique_vertex(vert));
/*
// keep a one to one copy in this node's vpool
EggVertex *t_vert = new EggVertex(vert);
if (!t_vert) {
cout << "out of memeory " << endl;
nassertv(t_vert != NULL);
}
node_desc->get_vpool()->add_vertex(t_vert, indices[i]);
*/
cout << "\n";
}
@ -1117,116 +1163,346 @@ make_polyset(SoftNodeDesc *node_desc, EggGroup *egg_group, SAA_ModelType type) {
}
}
}
#if 0
come back to it later
}
}
////////////////////////////////////////////////////////////////////
// Function: FindClosestTriVert
// Access: Public
// Description: Given an egg vertex pool, map each vertex therein to
// a vertex within an array of SAA model vertices of
// size numVert. Mapping is done by closest proximity.
////////////////////////////////////////////////////////////////////
int *SoftToEggConverter::
FindClosestTriVert( EggVertexPool *vpool, SAA_DVector *vertices, int numVert ) {
int i,j;
int *vertMap = NULL;
int vpoolSize = (int)vpool->size();
float closestDist;
float thisDist;
int closest;
vertMap = new int[vpoolSize];
i = 0;
EggVertexPool::iterator vi;
for (vi = vpool->begin(); vi != vpool->end(); ++vi, ++i) {
EggVertex *vert = (*vi);
cout << "vert external index = " << vert->get_external_index() << endl;
// cout << "found vert " << vert << endl;
// cout << "vert [" << i << "] " << vpool->get_vertex(i+1);
LPoint3d p3d = vert->get_pos3();
// find closest model vertex
for ( j = 0; j < numVert-1; j++ ) {
// calculate distance
thisDist = sqrtf(
powf( p3d[0] - vertices[j].x , 2 ) +
powf( p3d[1] - vertices[j].y , 2 ) +
powf( p3d[2] - vertices[j].z , 2 ) );
// remember this if its the closest so far
if ( !j || ( thisDist < closestDist ) ) {
closest = j;
closestDist = thisDist;
}
}
vertMap[i] = closest;
cout << "mapping v " << i << " of " << vpoolSize-1 << ":( "
<< p3d[0] << " "
<< p3d[1] << " "
<< p3d[2] << ")\n";
cout << " to cv " << closest << " of " << numVert-1 << ":( "
<< vertices[closest].x << " "
<< vertices[closest].y << " "
<< vertices[closest].z << " )\tdelta = " << closestDist << endl;
}
return vertMap;
}
////////////////////////////////////////////////////////////////////
// Function: SoftToEggConverter::make_soft_skin
// Access: Private
// Description: make soft skin assignments to the mesh
// finally call cleanup_soft_skin to clean it up
////////////////////////////////////////////////////////////////////
bool SoftToEggConverter::
make_soft_skin() {
int num_nodes = _tree.get_num_nodes();
SoftNodeDesc *node_desc;
SAA_Boolean isSkeleton;
cout << endl << "----------------------------------------------------------------" << endl;
for (int i = 0; i < num_nodes; i++) {
node_desc = _tree.get_node(i);
SAA_modelIsSkeleton( &scene, node_desc->get_model(), &isSkeleton );
if (isSkeleton && node_desc->is_joint()) {
// Now that we've added all the polygons (and created all the
// vertices), go back through the vertex pool and set up the
// appropriate joint membership for each of the vertices.
bool got_weights = false;
pvector<EggGroup *> joints;
MFloatArray weights;
if (_animation_convert == AC_model) {
got_weights =
get_vertex_weights(dag_path, mesh, joints, weights);
// check for envelops
int numEnv;
SAA_ModelType type;
SAA_Elem *envelopes;
SAA_Elem *model = node_desc->get_model();
EggGroup *joint = NULL;
EggVertexPool *vpool;
SAA_skeletonGetNbEnvelopes( &scene, model, &numEnv );
if ( numEnv == 0 ) {
cout << "no soft skinning for joint " << node_desc->get_name() << endl;
continue;
}
if (got_weights && !joints.empty()) {
int num_joints = joints.size();
int num_weights = (int)weights.length();
int num_verts = num_weights / num_joints;
// The number of weights should be an even multiple of verts *
// joints.
nassertv(num_weights == num_verts * num_joints);
// it's got envelopes - must be soft skinned
cout << endl << "found skeleton part( " << node_desc->get_name() << ")!\n";
cout << "numEnv = " << numEnv << endl;
// allocate envelope array
envelopes = new SAA_Elem[numEnv];
if ( envelopes == NULL ) {
cout << "Out Of Memory" << endl;
exit(1);
}
int thisEnv;
SAA_EnvType envType;
bool hasEnvVertices = 0;
EggVertexPool::iterator vi;
for (vi = vpool->begin(); vi != vpool->end(); ++vi) {
EggVertex *vert = (*vi);
int maya_vi = vert->get_external_index();
nassertv(maya_vi >= 0 && maya_vi < num_verts);
SAA_skeletonGetEnvelopes( &scene, model, numEnv, envelopes );
for ( thisEnv = 0; thisEnv < numEnv; thisEnv++ ) {
cout << "env[" << thisEnv << "]: ";
SAA_envelopeGetType( &scene, &envelopes[thisEnv], &envType );
for (int ji = 0; ji < num_joints; ++ji) {
float weight = weights[maya_vi * num_joints + ji];
if (weight != 0.0f) {
EggGroup *joint = joints[ji];
if (joint != (EggGroup *)NULL) {
joint->ref_vertex(vert, weight);
if ( envType == SAA_ENVTYPE_NONE ) {
cout << "envType = none\n";
}
else if ( envType == SAA_ENVTYPE_FLXLCL ) {
cout << "envType = flexible, local\n";
hasEnvVertices = 1;
}
else if ( envType == SAA_ENVTYPE_FLXGLB ) {
cout << "envType = flexible, global\n";
hasEnvVertices = 1;
}
else if ( envType == SAA_ENVTYPE_RGDGLB ) {
cout << "envType = rigid, global\n";
hasEnvVertices = 1;
}
else {
cout << "envType = unknown\n";
}
#endif
}
}
////////////////////////////////////////////////////////////////////
// Function: SoftToEggConverter::make_polyset
// Access: Private
// Description: Converts the indicated Soft polyset to a bunch of
// EggPolygons and parents them to the indicated egg
// group.
////////////////////////////////////////////////////////////////////
void SoftToEggConverter::
handle_null(SAA_Elem *model, EggGroup *egg_group, SAA_ModelType type, const char *node_name) {
const char *name = node_name;
SAA_AlgorithmType algo;
SAA_modelGetAlgorithm( &scene, model, &algo );
cout << "null algorithm: " << algo << endl;
}
if ( !hasEnvVertices )
continue;
if ( algo == SAA_ALG_INV_KIN ) {
// MakeJoint( &scene, lastJoint, lastAnim, model, name );
cout << "encountered IK root: " << name << endl;
}
else if ( algo == SAA_ALG_INV_KIN_LEAF ) {
// MakeJoint( &scene, lastJoint, lastAnim, model, name );
cout << "encountered IK leaf: " << name << endl;
}
else if ( algo == SAA_ALG_STANDARD ) {
SAA_Boolean isSkeleton = FALSE;
cout << "encountered Standard null: " << name << endl;
SAA_SubElem *envVertices = NULL;
int *numEnvVertices;
int i,j,k;
SAA_modelIsSkeleton( &scene, model, &isSkeleton );
numEnvVertices = new int[numEnv];
// check to see if this NULL is used as a skeleton
// or is animated via constraint only ( these nodes are
// tagged by the animator with the keyword "joint"
// somewhere in the nodes name)
if ( isSkeleton || (strstr( name, "joint" ) != NULL) ) {
// MakeJoint( &scene, lastJoint, lastAnim, model, name );
cout << "animating Standard null!!!\n";
if ( numEnvVertices != NULL ) {
SAA_envelopeGetNbCtrlVertices( &scene, model, numEnv, envelopes, numEnvVertices );
int totalEnvVertices = 0;
for( i = 0; i < numEnv; i++ ) {
totalEnvVertices += numEnvVertices[i];
cout << "numEnvVertices[" << i << "] = " << numEnvVertices[i] << endl;
}
cout << "total env verts = " << totalEnvVertices << endl;
if ( totalEnvVertices == 0 )
continue;
envVertices = new SAA_SubElem[totalEnvVertices];
if ( envVertices != NULL ) {
result = SAA_envelopeGetCtrlVertices( &scene, model,
numEnv, envelopes, numEnvVertices, envVertices);
if (result != SI_SUCCESS) {
cout << "error: GetCtrlVertices\n";
exit(1);
}
// loop through for each envelope
for ( i = 0; i < numEnv; i++ ) {
float *weights = NULL;
int vertArrayOffset = 0;
cout << "envelope[" << i << "]: ";
weights = new float[numEnvVertices[i]];
if ( weights ) {
char *envName;
int *vpoolMap = NULL;
for ( j = 0; j < i; j++ )
vertArrayOffset += numEnvVertices[j];
cout << "envVertArray offset = " << vertArrayOffset;
/*
if (vertArrayOffset == totalEnvVertices) {
cout << endl; vpoolMap = FindClosestTriVert( vpool, globalModelVertices, modelNumVert );
break;
}
*/
// get the weights of the envelope vertices
result = SAA_ctrlVertexGetEnvelopeWeights( &scene, model, &envelopes[i],
numEnvVertices[i],
&envVertices[vertArrayOffset], weights );
// Get the name of the envelope model
if ( use_prefix ) {
// Get the FULL name of the envelope
envName = _tree.GetFullName( &scene, &envelopes[i] );
}
else {
// Get the name of the envelope
envName = _tree.GetName( &scene, &envelopes[i] );
}
cout << " envelop name is [" << envName << "]" << endl;
if (result != SI_SUCCESS) {
cout << "warning: this envelop doesn't have any weights\n";
continue;
}
result = SAA_modelGetType( &scene, &envelopes[i], &type );
if (result != SI_SUCCESS) {
cout << "choked on get type\n";
exit(1);
}
cout << "envelope model type ";
if ( type == SAA_MSMSH )
cout << "MESH\n";
else if ( type == SAA_MNSRF )
cout << "NURBS\n";
else
cout << "encountered some other NULL: " << algo << endl;
cout << "OTHER\n";
#if 0 // no need to follow children, _tree already contains all the model nodes
// check for children...
int numChildren;
int thisChild;
SAA_Elem *children;
int *envVtxIndices = NULL;
envVtxIndices = new int[numEnvVertices[i]];
SAA_modelGetNbChildren( &scene, model, &numChildren );
cout << "Model children: " << numChildren << endl;
// Get the envelope vertex indices
result = SAA_ctrlVertexGetIndices( &scene, &envelopes[i], numEnvVertices[i],
&envVertices[vertArrayOffset], envVtxIndices );
if ( numChildren ) {
children = new SAA_Elem[numChildren];
SAA_modelGetChildren( &scene, model, numChildren, children );
if ( children != NULL ) {
for ( thisChild = 0; thisChild < numChildren; thisChild++ ) {
cout << "\negging child " << thisChild << "...\n";
// MakeEgg( parent, lastJoint, lastAnim, scene,
// &children[thisChild] );
}
}
else
cout << "Not enough Memory for children...\n";
}
else
cout << "Don't descend this branch!\n";
#endif
if (result != SI_SUCCESS) {
cout << "error: choked on get indices\n";
exit(1);
}
// find out how many vertices the model has
int modelNumVert;
SAA_modelGetNbVertices( &scene, &envelopes[i], &modelNumVert );
SAA_DVector *modelVertices = NULL;
modelVertices = new SAA_DVector[modelNumVert];
// get the model vertices
SAA_modelGetVertices( &scene, &envelopes[i],
SAA_GEOM_ORIGINAL, 0, modelNumVert,
modelVertices );
// create array of global model coords
SAA_DVector *globalModelVertices = NULL;
globalModelVertices = new SAA_DVector[modelNumVert];
float matrix[4][4];
// tranform local model vert coords to global
// first get the global matrix
SAA_modelGetMatrix( &scene, &envelopes[i], SAA_COORDSYS_GLOBAL, matrix );
// populate array of global model verts
for ( j = 0; j < modelNumVert; j++ ) {
_VCT_X_MAT( globalModelVertices[j],
modelVertices[j], matrix );
}
// Get the vpool
string s_name = envName;
SoftNodeDesc *mesh_node = find_node(s_name);
if (!mesh_node) {
cout << "error: node " << s_name << " not found in tree\n";
exit(1);
}
string vpool_name = s_name + ".verts";
DCAST_INTO_R(vpool, mesh_node->get_egg_group()->find_child(vpool_name), NULL);
// find the mapping of the vertices that match this envelop
if (vpool) {
cout << "found vpool of size " << vpool->size() << endl;
if ( !make_nurbs || (type == SAA_MSMSH) ) {
vpoolMap = FindClosestTriVert( vpool, globalModelVertices, modelNumVert );
}
}
else {
cout << "error: vpool " << vpool_name << " not found\n";
exit(1);
}
joint = node_desc->get_egg_group();
// for every envelope vertex
for (j = 0; j < numEnvVertices[i]; j++) {
double scaledWeight = weights[j]/ 100.0f;
// make sure its in legal range
if (( envVtxIndices[j] < modelNumVert )
&& ( envVtxIndices[j] >= 0 )) {
if ( (type == SAA_MNSRF) && make_nurbs ) {
// assign all referenced control vertices
EggVertex *vert = vpool->get_vertex(envVtxIndices[j]+1);
joint->ref_vertex( vert, scaledWeight );
cout << j << ": adding vref to cv " << envVtxIndices[j]
<< " with weight " << scaledWeight << endl;
/*
envPool->Vertex(envVtxIndices[j])->AddJoint( joint, scaledWeight );
// set flag to show this vertex has
// been assigned
envPool->Vertex(envVtxIndices[j])->multipleJoints = 1;
*/
}
else {
//assign all the tri verts associated
// with this control vertex to joint
cout << j << "--trying to find " << envVtxIndices[j] << endl;
for ( k = 0; k < (int)vpool->size(); k++ ) {
if ( vpoolMap[k] == envVtxIndices[j] ) {
EggVertex *vert = vpool->get_vertex(k+1);
// EggVertex *vert = mesh_node->get_vpool()->get_vertex(vpoolMap[k]+1);
if (!vert) {
cout << "possible error: index " << k+1 << ": vert is " << vert << endl;
break;
}
joint->ref_vertex(vert, scaledWeight);
cout << j << ": adding vref from cv " << envVtxIndices[j]
<< " to vert " << k+1 << " with weight " << scaledWeight
<< "(vpool)\n";
/*
envPool->Vertex(k)->AddJoint( joint, scaledWeight );
// set flag to show this vertex has
// been assigned
envPool->Vertex(k)->multipleJoints = 1;
*/
}
}
}
}
}
}
}
}
}
}
}
return true;
}
#if 0
////////////////////////////////////////////////////////////////////
// Function: SoftToEggConverter::make_locator
@ -1259,7 +1535,7 @@ make_locator(const MDagPath &dag_path, const MFnDagNode &dag_node,
}
LPoint3d p3d;
if (!get_vec3d_attribute(locator, "localPosition", p3d)) {
if (!get_vec3d_attribute(locator, "localPosition", p3d _tree.build_node(joint_dag_path))) {
softegg_cat.error()
<< "Couldn't get position of locator "
<< dag_path.fullPathName().asChar() << "\n";
@ -1284,99 +1560,6 @@ make_locator(const MDagPath &dag_path, const MFnDagNode &dag_node,
egg_group->add_translate(p3d);
}
////////////////////////////////////////////////////////////////////
// Function: SoftToEggConverter::get_vertex_weights
// Access: Private
// Description:
////////////////////////////////////////////////////////////////////
bool SoftToEggConverter::
get_vertex_weights(const MDagPath &dag_path, const MFnMesh &mesh,
pvector<EggGroup *> &joints, MFloatArray &weights) {
MStatus status;
// Since we are working with a mesh the input attribute that
// creates the mesh is named "inMesh"
//
MObject attr = mesh.attribute("inMesh");
// Create the plug to the "inMesh" attribute then use the
// DG iterator to walk through the DG, at the node level.
//
MPlug history(mesh.object(), attr);
MItDependencyGraph it(history, MFn::kDependencyNode,
MItDependencyGraph::kUpstream,
MItDependencyGraph::kDepthFirst,
MItDependencyGraph::kNodeLevel);
while (!it.isDone()) {
// We will walk along the node level of the DG until we
// spot a skinCluster node.
//
MObject c_node = it.thisNode();
if (c_node.hasFn(MFn::kSkinClusterFilter)) {
// We've found the cluster handle. Try to get the weight
// data.
//
MFnSkinCluster cluster(c_node, &status);
if (!status) {
status.perror("MFnSkinCluster constructor");
return false;
}
// Get the set of objects that influence the vertices of this
// mesh. Hopefully these will all be joints.
MDagPathArray influence_objects;
cluster.influenceObjects(influence_objects, &status);
if (!status) {
status.perror("MFnSkinCluster::influenceObjects");
} else {
// Fill up the vector with the corresponding table of egg
// groups for each joint.
joints.clear();
for (unsigned oi = 0; oi < influence_objects.length(); oi++) {
MDagPath joint_dag_path = influence_objects[oi];
SoftNodeDesc *joint_node_desc = _tree.build_node(joint_dag_path);
EggGroup *joint = _tree.get_egg_group(joint_node_desc);
joints.push_back(joint);
}
// Now use a component object to retrieve all of the weight
// data in one API call.
MFnSingleIndexedComponent sic;
MObject sic_object = sic.create(MFn::kMeshVertComponent);
sic.setCompleteData(mesh.numVertices());
unsigned influence_count;
status = cluster.getWeights(dag_path, sic_object,
weights, influence_count);
if (!status) {
status.perror("MFnSkinCluster::getWeights");
} else {
if (influence_count != influence_objects.length()) {
softegg_cat.error()
<< "MFnSkinCluster::influenceObjects() returns "
<< influence_objects.length()
<< " objects, but MFnSkinCluster::getWeights() reports "
<< influence_count << " objects.\n";
} else {
// We've got the weights and the set of objects. That's all
// we need.
return true;
}
}
}
}
it.next();
}
softegg_cat.error()
<< "Unable to find a cluster handle for the DG node.\n";
return false;
}
#endif
////////////////////////////////////////////////////////////////////

View File

@ -67,6 +67,9 @@ public:
bool HandleGetopts(int &idx, int argc, char **argv);
bool DoGetopts(int &argc, char **&argv);
SoftNodeDesc *find_node(string name);
int *FindClosestTriVert( EggVertexPool *vpool, SAA_DVector *vertices, int numVert );
virtual SomethingToEggConverter *make_copy();
virtual string get_name() const;
virtual string get_extension() const;
@ -80,8 +83,9 @@ private:
bool convert_flip(double start_frame, double end_frame,
double frame_inc, double output_frame_rate);
bool convert_char_model();
bool make_soft_skin();
bool convert_char_chan();
bool convert_char_model();
bool convert_hierarchy(EggGroupNode *egg_root);
bool process_model_node(SoftNodeDesc *node_desc);
@ -102,13 +106,12 @@ private:
const MFnNurbsCurve &curve,
EggGroup *group);
*/
void make_polyset(SoftNodeDesc *node_Desc, EggGroup *egg_group, SAA_ModelType type);
void handle_null(SAA_Elem *model, EggGroup *egg_group, SAA_ModelType type, const char *node_name);
void make_polyset(SoftNodeDesc *node_desc, EggGroup *egg_group, SAA_ModelType type);
/*
void make_locator(const MDagPath &dag_path, const MFnDagNode &dag_node,
EggGroup *egg_group);
bool get_vertex_weights(const MDagPath &dag_path, const MFnMesh &mesh,
pvector<EggGroup *> &joints, MFloatArray &weights);
bool get_vertex_weights(SoftNodeDesc *node_desc,
pvector<EggGroup *> &joints, vector<float> &weights);
*/
void set_shader_attributes(SoftNodeDesc *node_desc, EggPrimitive &primitive, char *texName);
void apply_texture_properties(EggTexture &tex, int uRepeat, int vRepeat);
@ -124,12 +127,13 @@ private:
SoftNodeTree _tree;
SI_Error result;
SAA_Scene scene;
SAA_Elem model;
SAA_Database database;
public:
SAA_Scene scene;
char *_getopts;
// This is argv[0].