72bool HierarchySaveClass::TerrainModeEnabled =
false;
102 Node(DEFAULT_NODE_ARRAY_SIZE),
104 FixupType(fixuptype),
114 OriginOffsetTransform =
Inverse(root->GetNodeTM(CurTime));
119 int rootidx = add_node(
NULL,-1);
120 assert(rootidx == 0);
121 add_tree(root,rootidx);
125 HierarchyHeader.NumPivots = CurNode;
126 HierarchyHeader.Center.X = 0.0f;
127 HierarchyHeader.Center.Y = 0.0f;
128 HierarchyHeader.Center.Z = 0.0f;
161 Node(DEFAULT_NODE_ARRAY_SIZE),
163 FixupType(fixuptype),
164 FixupTree(fixuptree),
165 OriginOffsetTransform(origin_offset)
173 int rootidx = add_node(
NULL,-1);
174 assert(rootidx == 0);
176 for (
unsigned int i = 0; i < rootlist->
Num_Nodes(); i++) {
177 add_tree((*rootlist)[i],rootidx);
182 HierarchyHeader.NumPivots = CurNode;
183 HierarchyHeader.Center.X = 0.0f;
184 HierarchyHeader.Center.Y = 0.0f;
185 HierarchyHeader.Center.Z = 0.0f;
237void HierarchySaveClass::Free(
void)
262 tm = tm * get_relative_transform(idx);
263 idx = Node[idx].Pivot.ParentIdx;
282Matrix3 HierarchySaveClass::get_relative_transform(
int nodeidx)
const
284 assert(nodeidx >= 0);
285 assert(nodeidx < CurNode);
292 trans.x =
Node[nodeidx].Pivot.Translation.X;
293 trans.y =
Node[nodeidx].Pivot.Translation.Y;
294 trans.z =
Node[nodeidx].Pivot.Translation.Z;
299 rot[0] = -
Node[nodeidx].Pivot.Rotation.Q[0];
300 rot[1] = -
Node[nodeidx].Pivot.Rotation.Q[1];
301 rot[2] = -
Node[nodeidx].Pivot.Rotation.Q[2];
302 rot[3] =
Node[nodeidx].Pivot.Rotation.Q[3];
326 return HierarchyHeader.Name;
345 assert(node < CurNode);
347 return Node[node].MaxNode;
365 assert(node < CurNode);
367 return Node[node].Pivot.Name;
386 for (
int index=0; index<CurNode; index++) {
387 if (strcmp(Node[index].Pivot.Name,name) == 0) {
411 int * set_bone_index,
412 INode ** set_bone_node,
425 INode * pbone = node;
454 pbone = pbone->GetParentNode();
455 assert(pbone !=
NULL);
471 if (set_bone_index !=
NULL) {
472 *set_bone_index = boneidx;
474 if (set_bone_node !=
NULL) {
475 *set_bone_node = pbone;
477 if (set_transform !=
NULL) {
499 for (
int inode = 0; inode < CurNode; inode++) {
507 if (!save_header(csave)) {
511 if (!save_pivots(csave)) {
515 if (!save_fixups(csave)) {
547 if (!load_header(cload)) error =
true;
550 if (!load_pivots(cload)) error =
true;
553 if (!load_fixups(cload)) error =
true;
564 CurNode = HierarchyHeader.NumPivots;
582void HierarchySaveClass::add_tree(INode * node,
int pidx)
586 if (node->IsHidden ()) {
604 nextparent = add_node(node,pidx);
609 for (
int i=0; i < node->NumberOfChildren(); i++) {
610 add_tree(node->GetChildNode(i),nextparent);
627int HierarchySaveClass::add_node(INode * node,
int pidx)
632 if (CurNode >= Node.Length ()) {
633 Node.Resize (Node.Length () + NODE_ARRAY_GROWTH_SIZE);
639 Node[CurNode].MaxNode = node;
640 Node[CurNode].Pivot.ParentIdx = pidx;
654 sprintf(buf,
"Bones with duplicate names found!\nDuplicated Name: %s\n",Node[CurNode].Pivot.Name);
655 throw ErrorClass(buf);
661 Matrix3 maxnodeTM(1);
662 Matrix3 ournodeTM(1);
669 maxnodeTM = node->GetNodeTM(CurTime) * OriginOffsetTransform;
671 maxnodeTM = Matrix3(1);
685 if (FixupTree !=
NULL) {
686 int fi = FixupTree->Find_Named_Node(Node[CurNode].Pivot.Name);
689 sprintf(buf,
"Incompatible Base Pose!\nMissing Bone: %s\n",Node[CurNode].Pivot.Name);
690 throw ErrorClass(buf);
693 Matrix3 fixup = FixupTree->Get_Fixup_Transform(fi);
695 maxnodeTM = fixup * maxnodeTM;
699 ournodeTM = fixup_matrix(maxnodeTM);
700 fixupTM = ournodeTM *
Inverse(maxnodeTM);
710 Matrix3 pinv =
Inverse(parentTM);
711 ournodeTM = ournodeTM * pinv;
718 DecomposeMatrix(ournodeTM,trans,rot,
scale);
723 for (
int j=0;j<4;j++) {
724 Point3 row = fixupTM.GetRow(j);
725 Node[CurNode].Fixup.TM[j][0] = row.x;
726 Node[CurNode].Fixup.TM[j][1] = row.y;
727 Node[CurNode].Fixup.TM[j][2] = row.z;
733 Node[CurNode].Pivot.Translation.X = trans.x;
734 Node[CurNode].Pivot.Translation.Y = trans.y;
735 Node[CurNode].Pivot.Translation.Z = trans.z;
737 Node[CurNode].Pivot.Rotation.Q[0] = -rot[0];
738 Node[CurNode].Pivot.Rotation.Q[1] = -rot[1];
739 Node[CurNode].Pivot.Rotation.Q[2] = -rot[2];
740 Node[CurNode].Pivot.Rotation.Q[3] = rot[3];
746 rot.MakeMatrix(rotmat);
749 Node[CurNode].Pivot.EulerAngles.X = eangs.Get_Angle(0);
750 Node[CurNode].Pivot.EulerAngles.Y = eangs.Get_Angle(1);
751 Node[CurNode].Pivot.EulerAngles.Z = eangs.Get_Angle(2);
771 assert(node < CurNode);
775 for (
int j=0;j<4;j++) {
776 m.SetRow(j,Point3(Node[node].Fixup.TM[j][0],Node[node].Fixup.TM[j][1],Node[node].Fixup.TM[j][2]));
794Matrix3 HierarchySaveClass::fixup_matrix(
const Matrix3 & csrc)
const
808 newtm.SetTrans(src.GetTrans());
813 DecomposeMatrix(src,trans,rot,
scale);
814 rot.MakeMatrix(newtm);
815 newtm.SetTrans(trans);
842 if (csave.
Write(&HierarchyHeader,
sizeof(HierarchyHeader)) !=
sizeof(HierarchyHeader)) {
872 for (
uint32 i=0; i<HierarchyHeader.NumPivots; i++) {
873 if (csave.
Write(&Node[i].Pivot,
sizeof(W3dPivotStruct)) !=
sizeof(W3dPivotStruct)) {
903 for (
uint32 i=0; i<HierarchyHeader.NumPivots; i++) {
904 if (csave.
Write(&Node[i].Fixup,
sizeof(W3dPivotFixupStruct)) !=
sizeof(W3dPivotFixupStruct)) {
934 if (cload.
Read(&HierarchyHeader,
sizeof(HierarchyHeader)) !=
sizeof(HierarchyHeader)) {
942 Node.Resize(HierarchyHeader.NumPivots);
948 for (
unsigned i=0; i < HierarchyHeader.NumPivots; i++) {
949 memset(&(Node[i]),0,
sizeof(HierarchyNodeStruct));
952 for (
int j=0; j<3; j++) {
953 Point3 row = ident.GetRow(j);
954 Node[i].Fixup.TM[j][0] = row.x;
955 Node[i].Fixup.TM[j][1] = row.y;
956 Node[i].Fixup.TM[j][2] = row.z;
978 for (
uint32 i=0; i<HierarchyHeader.NumPivots; i++) {
979 Node[i].MaxNode =
NULL;
980 if (cload.
Read(&Node[i].Pivot,
sizeof(W3dPivotStruct)) !=
sizeof(W3dPivotStruct)) {
1001 for (
uint32 i=0; i<HierarchyHeader.NumPivots; i++) {
1002 if (cload.
Read(&Node[i].Fixup,
sizeof(W3dPivotFixupStruct)) !=
sizeof(W3dPivotFixupStruct)) {
Color scale(const Color &a, const Color &b)
#define W3D_CURRENT_HTREE_VERSION
@ W3D_CHUNK_HIERARCHY_HEADER
uint32 Read(void *buf, uint32 nbytes)
uint32 Write(const void *buf, uint32 nbytes)
bool Begin_Chunk(uint32 id)
static void printf(char *,...)
int Find_Named_Node(const char *name) const
Matrix3 Get_Fixup_Transform(int node) const
bool Load(ChunkLoadClass &cload)
void Get_Export_Coordinate_System(INode *node, int *set_bone_index, INode **set_bone_node, Matrix3 *set_transform)
const char * Get_Name(void) const
Matrix3 Get_Node_Transform(int node) const
const char * Get_Node_Name(int node) const
INode * Get_Node(int node) const
bool Save(ChunkSaveClass &csave)
unsigned Num_Nodes(void) const
WWINLINE Quaternion Inverse(const Quaternion &a)
Matrix3 Cleanup_Orthogonal_Matrix(Matrix3 &mat)
void Set_W3D_Name(char *set_name, const char *src)
bool Is_Origin(INode *node)
bool Is_Normal_Mesh(INode *node)
bool Is_Null_Object(INode *node)
bool Is_Bone(INode *node)