| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009 |
- /*
- ** Command & Conquer Generals(tm)
- ** Copyright 2025 Electronic Arts Inc.
- **
- ** This program is free software: you can redistribute it and/or modify
- ** it under the terms of the GNU General Public License as published by
- ** the Free Software Foundation, either version 3 of the License, or
- ** (at your option) any later version.
- **
- ** This program is distributed in the hope that it will be useful,
- ** but WITHOUT ANY WARRANTY; without even the implied warranty of
- ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- ** GNU General Public License for more details.
- **
- ** You should have received a copy of the GNU General Public License
- ** along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
- /* $Header: /Commando/Code/Tools/max2w3d/hiersave.cpp 56 10/30/00 6:58p Greg_h $ */
- /***********************************************************************************************
- *** Confidential - Westwood Studios ***
- ***********************************************************************************************
- * *
- * Project Name : Commando / G 3D Engine *
- * *
- * $Archive:: /Commando/Code/Tools/max2w3d/hiersave.cpp $*
- * *
- * $Author:: Greg_h $*
- * *
- * $Modtime:: 10/30/00 6:14p $*
- * *
- * $Revision:: 56 $*
- * *
- *---------------------------------------------------------------------------------------------*
- * Functions: *
- * HierarchySaveClass::HierarchySaveClass -- constructor *
- * HierarchySaveClass::HierarchySaveClass -- constructor *
- * HierarchySaveClass::HierarchySaveClass -- constructor *
- * HierarchySaveClass::~HierarchySaveClass -- destructor *
- * HierarchySaveClass::Free -- releases all allocated memory *
- * HierarchySaveClass::Get_Node_Transform -- returns the transformation matrix of specified n*
- * HierarchySaveClass::get_relative_transform -- retruns tm between this node and its parent *
- * HierarchySaveClass::Get_Name -- returns the name of this hierarchy *
- * HierarchySaveClass::Get_Node -- Get the Max INode *
- * HierarchySaveClass::Get_Node_Name -- returns name of this hierarchy node *
- * HierarchySaveClass::Find_Named_Node -- returns index of a named node *
- * HierarchySaveClass::Get_Export_Coordinate_System - find the bone and coordinate system *
- * HierarchySaveClass::Save -- write the hierarchy into a W3D file *
- * HierarchySaveClass::Load -- read the hierarchy from a W3D file *
- * HierarchySaveClass::add_tree -- adds a node and all of its children *
- * HierarchySaveClass::add_node -- adds a single node to the tree *
- * HierarchySaveClass::Get_Fixup_Transform -- gets the "fixup" transform for a node *
- * HierarchySaveClass::fixup_matrix -- conditions a matrix *
- * HierarchySaveClass::save_header -- writes the header into a W3D file *
- * HierarchySaveClass::save_pivots -- writes the pivots into a W3D file *
- * HierarchySaveClass::save_fixups -- writes the fixup transforms into a W3D file *
- * HierarchySaveClass::load_header -- reads the header from a W3D file *
- * HierarchySaveClass::load_pivots -- reads the pivots from a W3D file *
- * HierarchySaveClass::load_fixups -- reads the fixup transforms from a W3D file *
- * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- #include "hiersave.h"
- #include "w3d_file.h"
- #include "nodefilt.h"
- #include "euler.h"
- #include "util.h"
- #include "w3dappdata.h"
- #include "errclass.h"
- #include "exportlog.h"
- bool HierarchySaveClass::TerrainModeEnabled = false;
- /***********************************************************************************************
- * HierarchySaveClass::HierarchySaveClass -- constructor *
- * *
- * INPUT: *
- * root - root INode to construct the HTree from *
- * time - current time in Max, transforms at this time will be used *
- * treemeter - progress meter *
- * hname - name for the hierarchy tree *
- * fixup_type - can be used to force all transforms to be translation only *
- * fixuptree - htree loaded from a previous export *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 10/26/1997 GH : Created. *
- *=============================================================================================*/
- HierarchySaveClass::HierarchySaveClass
- (
- INode * root,
- TimeValue time,
- Progress_Meter_Class & treemeter,
- char * hname,
- int fixuptype,
- HierarchySaveClass * fixuptree
- ) :
- Node(DEFAULT_NODE_ARRAY_SIZE),
- CurNode(0),
- FixupType(fixuptype),
- FixupTree(fixuptree)
- {
- CurNode = 0;
- CurTime = time;
- /*
- ** This code-path is activated when the user has created a custom origin. In this case, we
- ** need to compute the transform which will make all bones relative to this origin.
- */
- OriginOffsetTransform = Inverse(root->GetNodeTM(CurTime));
-
- /*
- ** Build our tree from the given tree of nodes
- */
- int rootidx = add_node(NULL,-1);
- assert(rootidx == 0);
- add_tree(root,rootidx);
- HierarchyHeader.Version = W3D_CURRENT_HTREE_VERSION;
- Set_W3D_Name(HierarchyHeader.Name,hname);
- HierarchyHeader.NumPivots = CurNode;
- HierarchyHeader.Center.X = 0.0f;
- HierarchyHeader.Center.Y = 0.0f;
- HierarchyHeader.Center.Z = 0.0f;
- }
- /***********************************************************************************************
- * HierarchySaveClass::HierarchySaveClass -- constructor *
- * *
- * INPUT: *
- * *
- * rootlist - list of root nodes to add to the htree *
- * time - current time in Max, transforms at this time will be used *
- * treemeter - progress meter *
- * hname - name for the hierarchy tree *
- * fixup_type - can be used to force all transforms to be translation only *
- * fixuptree - htree loaded from a previous export *
- * origin_offset - origin offset transform *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 10/26/1997 GH : Created. *
- *=============================================================================================*/
- HierarchySaveClass::HierarchySaveClass
- (
- INodeListClass * rootlist,
- TimeValue time,
- Progress_Meter_Class & treemeter,
- char * hname,
- int fixuptype,
- HierarchySaveClass * fixuptree,
- const Matrix3 & origin_offset
- ) :
- Node(DEFAULT_NODE_ARRAY_SIZE),
- CurNode(0),
- FixupType(fixuptype),
- FixupTree(fixuptree),
- OriginOffsetTransform(origin_offset)
- {
- CurNode = 0;
- CurTime = time;
- /*
- ** Build the tree with all leaves of all of the nodes given
- */
- int rootidx = add_node(NULL,-1);
- assert(rootidx == 0);
- for (unsigned int i = 0; i < rootlist->Num_Nodes(); i++) {
- add_tree((*rootlist)[i],rootidx);
- }
- HierarchyHeader.Version = W3D_CURRENT_HTREE_VERSION;
- Set_W3D_Name(HierarchyHeader.Name,hname);
- HierarchyHeader.NumPivots = CurNode;
- HierarchyHeader.Center.X = 0.0f;
- HierarchyHeader.Center.Y = 0.0f;
- HierarchyHeader.Center.Z = 0.0f;
- }
- /***********************************************************************************************
- * HierarchySaveClass::HierarchySaveClass -- constructor *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 10/26/1997 GH : Created. *
- *=============================================================================================*/
- HierarchySaveClass::HierarchySaveClass():
- Node(NULL),
- CurNode(0),
- CurTime(0)
- {
- }
- /***********************************************************************************************
- * HierarchySaveClass::~HierarchySaveClass -- destructor *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 10/26/1997 GH : Created. *
- *=============================================================================================*/
- HierarchySaveClass::~HierarchySaveClass(void)
- {
- Free();
- }
- /***********************************************************************************************
- * HierarchySaveClass::Free -- releases all allocated memory *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 10/26/1997 GH : Created. *
- *=============================================================================================*/
- void HierarchySaveClass::Free(void)
- {
- Node.Clear();
- }
- /***********************************************************************************************
- * HierarchySaveClass::Get_Node_Transform -- returns the transformation matrix of specified no *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 10/26/1997 GH : Created. *
- *=============================================================================================*/
- Matrix3 HierarchySaveClass::Get_Node_Transform(int nodeidx) const
- {
- Matrix3 tm(1);
- int idx = nodeidx;
- while (idx != -1) {
- tm = tm * get_relative_transform(idx);
- idx = Node[idx].Pivot.ParentIdx;
- }
- return tm;
- }
- /***********************************************************************************************
- * HierarchySaveClass::get_relative_transform -- retruns tm between this node and its parent *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 10/26/1997 GH : Created. *
- *=============================================================================================*/
- Matrix3 HierarchySaveClass::get_relative_transform(int nodeidx) const
- {
- assert(nodeidx >= 0);
- assert(nodeidx < CurNode);
- Point3 trans;
- Quat rot;
- Matrix3 tm(true);
- Matrix3 rtm(true);
- trans.x = Node[nodeidx].Pivot.Translation.X;
- trans.y = Node[nodeidx].Pivot.Translation.Y;
- trans.z = Node[nodeidx].Pivot.Translation.Z;
- // WARNING! I had to fudge the orientation
- // quaternion (Max's representation seems to
- // rotate in the opposite sense as mine...)
- rot[0] = -Node[nodeidx].Pivot.Rotation.Q[0];
- rot[1] = -Node[nodeidx].Pivot.Rotation.Q[1];
- rot[2] = -Node[nodeidx].Pivot.Rotation.Q[2];
- rot[3] = Node[nodeidx].Pivot.Rotation.Q[3];
- tm.Translate(trans);
- rot.MakeMatrix(rtm);
- tm = rtm * tm;
- return tm;
- }
- /***********************************************************************************************
- * HierarchySaveClass::Get_Name -- returns the name of this hierarchy *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 10/26/1997 GH : Created. *
- *=============================================================================================*/
- const char * HierarchySaveClass::Get_Name(void) const
- {
- return HierarchyHeader.Name;
- }
- /***********************************************************************************************
- * HierarchySaveClass::Get_Node -- Get the Max INode *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 1/15/98 GTH : Created. *
- *=============================================================================================*/
- INode * HierarchySaveClass::Get_Node(int node) const
- {
- assert(node >= 0);
- assert(node < CurNode);
- return Node[node].MaxNode;
- }
- /***********************************************************************************************
- * HierarchySaveClass::Get_Node_Name -- returns name of this hierarchy node *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 10/26/1997 GH : Created. *
- *=============================================================================================*/
- const char * HierarchySaveClass::Get_Node_Name(int node) const
- {
- assert(node >= 0);
- assert(node < CurNode);
- return Node[node].Pivot.Name;
- }
- /***********************************************************************************************
- * HierarchySaveClass::Find_Named_Node -- returns index of a named node *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 10/26/1997 GH : Created. *
- *=============================================================================================*/
- int HierarchySaveClass::Find_Named_Node(const char * name) const
- {
- int match = -1;
- for (int index=0; index<CurNode; index++) {
- if (strcmp(Node[index].Pivot.Name,name) == 0) {
- match = index;
- }
- }
- return match;
- }
- /***********************************************************************************************
- * HierarchySaveClass::Get_Export_Coordinate_System - find the bone and coordinate system *
- * for the given object *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 10/17/2000 gth : Created. *
- *=============================================================================================*/
- void HierarchySaveClass::Get_Export_Coordinate_System
- (
- INode * node,
- int * set_bone_index,
- INode ** set_bone_node,
- Matrix3 * set_transform
- )
- {
- /*
- ** find the first parent of this node which
- ** is in the base pose. Note, we're finding the parent bone
- ** in our hierarchy with the same name as a bone in the "main"
- ** hierarchy. When we're exporting LOD models, there are multiple
- ** hierarchies...
- */
- bool done = false;
- int boneidx = -1;
- INode * pbone = node;
- while (!done) {
- char name[W3D_NAME_LEN];
- Set_W3D_Name(name,pbone->GetName());
- boneidx = Find_Named_Node(name);
- if (boneidx != -1) {
- /*
- ** We found the parent bone!
- */
- done = true;
- } else if (Is_Origin(pbone)) {
- /*
- ** Don't go up past our origin, use this as our bone.
- */
- boneidx = 0;
- done = true;
- } else {
- /*
- ** Nope, try the next parent
- */
- pbone = pbone->GetParentNode();
- assert(pbone != NULL);
- #if 0
- if (pbone == NULL) {
- /*
- ** mesh isn't connected to a bone, use the root
- */
- boneidx = 0;
- pbone = node;
- done = true;
- }
- #endif
- }
- }
-
- if (set_bone_index != NULL) {
- *set_bone_index = boneidx;
- }
- if (set_bone_node != NULL) {
- *set_bone_node = pbone;
- }
- if (set_transform != NULL) {
- *set_transform = Get_Fixup_Transform(boneidx) * pbone->GetNodeTM(CurTime);
- }
- }
- /***********************************************************************************************
- * HierarchySaveClass::Save -- write the hierarchy into a W3D file *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 10/26/1997 GH : Created. *
- *=============================================================================================*/
- bool HierarchySaveClass::Save(ChunkSaveClass & csave)
- {
- ExportLog::printf("\nSaving Hierarchy Tree %s.\n",HierarchyHeader.Name);
- ExportLog::printf("Node Count: %d\n",CurNode);
- ExportLog::printf("Nodes: \n");
- for (int inode = 0; inode < CurNode; inode++) {
- ExportLog::printf(" %s\n",Node[inode].Pivot.Name);
- }
- if (!csave.Begin_Chunk(W3D_CHUNK_HIERARCHY)) {
- return false;
- }
- if (!save_header(csave)) {
- return false;
- }
- if (!save_pivots(csave)) {
- return false;
- }
- if (!save_fixups(csave)) {
- return false;
- }
- if (!csave.End_Chunk()) {
- return false;
- }
-
- return true;
- }
- /***********************************************************************************************
- * HierarchySaveClass::Load -- read the hierarchy from a W3D file *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 10/26/1997 GH : Created. *
- *=============================================================================================*/
- bool HierarchySaveClass::Load(ChunkLoadClass & cload)
- {
- Free();
- bool error = false;
- while (cload.Open_Chunk()) {
- switch (cload.Cur_Chunk_ID()) {
- case W3D_CHUNK_HIERARCHY_HEADER:
- if (!load_header(cload)) error = true;
- break;
- case W3D_CHUNK_PIVOTS:
- if (!load_pivots(cload)) error = true;
- break;
- case W3D_CHUNK_PIVOT_FIXUPS:
- if (!load_fixups(cload)) error = true;
- break;
- default:
- break;
- }
- if (!cload.Close_Chunk() || error) {
- return false;
- }
- }
- CurNode = HierarchyHeader.NumPivots;
- return true;
- }
- /***********************************************************************************************
- * HierarchySaveClass::add_tree -- adds a node and all of its children *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 10/26/1997 GH : Created. *
- *=============================================================================================*/
- void HierarchySaveClass::add_tree(INode * node,int pidx)
- {
- int nextparent;
- if (node->IsHidden ()) {
- // if the node is hidden, do not add it but add its children to the current parent.
- nextparent = pidx;
- } else if (TerrainModeEnabled && (Is_Normal_Mesh(node) || Is_Null_Object(node))) {
- // terrain optimization, normal meshes are not allowed to have transforms
- nextparent = pidx;
- } else if (!Is_Bone(node)) {
-
- // This node isn't a bone, don't add it
- nextparent = pidx;
-
- } else {
- // Add new pivot! it will be parent of all below it.
- nextparent = add_node(node,pidx);
-
- }
- // Add all of this nodes children
- for (int i=0; i < node->NumberOfChildren(); i++) {
- add_tree(node->GetChildNode(i),nextparent);
- }
- }
- /***********************************************************************************************
- * HierarchySaveClass::add_node -- adds a single node to the tree *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 10/26/1997 GH : Created. *
- *=============================================================================================*/
- int HierarchySaveClass::add_node(INode * node,int pidx)
- {
- /*
- ** 'grow' the node array if necessary
- */
- if (CurNode >= Node.Length ()) {
- Node.Resize (Node.Length () + NODE_ARRAY_GROWTH_SIZE);
- }
- /*
- ** setup the pivot
- */
- Node[CurNode].MaxNode = node;
- Node[CurNode].Pivot.ParentIdx = pidx;
- if (node) {
- Set_W3D_Name(Node[CurNode].Pivot.Name,node->GetName());
- } else {
- Set_W3D_Name(Node[CurNode].Pivot.Name,"RootTransform");
- }
- /*
- ** Now, check if there is a bone with this W3D name already
- ** if there is, scold the user and bail out
- */
- if (Find_Named_Node(Node[CurNode].Pivot.Name) != -1) {
- char buf[128];
- sprintf(buf,"Bones with duplicate names found!\nDuplicated Name: %s\n",Node[CurNode].Pivot.Name);
- throw ErrorClass(buf);
- }
- /*
- ** Compute the transformation for this node
- */
- Matrix3 maxnodeTM(1);
- Matrix3 ournodeTM(1);
- Matrix3 fixupTM(1);
- Point3 trans(0,0,0);
- Quat rot(1);
- Point3 scale(1,1,1);
- if (node) {
- maxnodeTM = node->GetNodeTM(CurTime) * OriginOffsetTransform;
- } else {
- maxnodeTM = Matrix3(1);
- }
- /*
- ** If this tree is being "fixed up" the first thing we do
- ** is to transform Max's nodeTM by the fixup transform.
- ** This is done when a base pose was created using our own
- ** types of transforms and we want to apply the same
- ** changes to this tree.
- **
- ** Note that if FixupType is not "NONE", FixupTree must be NULL,
- */
- assert(!((FixupTree != NULL) && (FixupType != MATRIX_FIXUP_NONE)));
- if (FixupTree != NULL) {
- int fi = FixupTree->Find_Named_Node(Node[CurNode].Pivot.Name);
- if (fi == -1) {
- char buf[128];
- sprintf(buf,"Incompatible Base Pose!\nMissing Bone: %s\n",Node[CurNode].Pivot.Name);
- throw ErrorClass(buf);
- }
- Matrix3 fixup = FixupTree->Get_Fixup_Transform(fi);
- maxnodeTM = fixup * maxnodeTM;
- }
- ournodeTM = fixup_matrix(maxnodeTM);
- fixupTM = ournodeTM * Inverse(maxnodeTM);
- /*
- ** Now, make ournodeTM relative to its parent transform. We
- ** will always store relative transformations. (Also, note
- ** that it is relative to our version of the parent transform
- ** which is not necessarily the same as the MAX version...)
- */
- if (pidx != -1) {
- Matrix3 parentTM = Get_Node_Transform(pidx);
- Matrix3 pinv = Inverse(parentTM);
- ournodeTM = ournodeTM * pinv;
- }
- /*
- ** Break the matrix down into a rotation and translation.
- */
- DecomposeMatrix(ournodeTM,trans,rot,scale);
-
- /*
- ** Save the "fixup" matrix
- */
- for (int j=0;j<4;j++) {
- Point3 row = fixupTM.GetRow(j);
- Node[CurNode].Fixup.TM[j][0] = row.x;
- Node[CurNode].Fixup.TM[j][1] = row.y;
- Node[CurNode].Fixup.TM[j][2] = row.z;
- }
- /*
- ** Set the translation and rotation for this pivot.
- */
- Node[CurNode].Pivot.Translation.X = trans.x;
- Node[CurNode].Pivot.Translation.Y = trans.y;
- Node[CurNode].Pivot.Translation.Z = trans.z;
- Node[CurNode].Pivot.Rotation.Q[0] = -rot[0];
- Node[CurNode].Pivot.Rotation.Q[1] = -rot[1];
- Node[CurNode].Pivot.Rotation.Q[2] = -rot[2];
- Node[CurNode].Pivot.Rotation.Q[3] = rot[3];
- /*
- ** Compute the Euler angles and set them.
- */
- Matrix3 rotmat;
- rot.MakeMatrix(rotmat);
- EulerAnglesClass eangs(rotmat,EulerOrderXYZr);
- Node[CurNode].Pivot.EulerAngles.X = eangs.Get_Angle(0);
- Node[CurNode].Pivot.EulerAngles.Y = eangs.Get_Angle(1);
- Node[CurNode].Pivot.EulerAngles.Z = eangs.Get_Angle(2);
- return CurNode++;
- }
- /***********************************************************************************************
- * HierarchySaveClass::Get_Fixup_Transform -- gets the "fixup" transform for a node *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 10/26/1997 GH : Created. *
- *=============================================================================================*/
- Matrix3 HierarchySaveClass::Get_Fixup_Transform(int node) const
- {
- assert(node >= 0);
- assert(node < CurNode);
- Matrix3 m;
-
- for (int j=0;j<4;j++) {
- m.SetRow(j,Point3(Node[node].Fixup.TM[j][0],Node[node].Fixup.TM[j][1],Node[node].Fixup.TM[j][2]));
- }
-
- return m;
- }
- /***********************************************************************************************
- * HierarchySaveClass::fixup_matrix -- conditions a matrix *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 10/26/1997 GH : Created. *
- *=============================================================================================*/
- Matrix3 HierarchySaveClass::fixup_matrix(const Matrix3 & csrc) const
- {
- Matrix3 src = csrc; // the GetTrans function is not const correct...
- Matrix3 newtm(1);
- Point3 trans;
- Quat rot;
- Point3 scale;
- switch (FixupType) {
- case MATRIX_FIXUP_NONE:
- newtm = src;
- break;
- case MATRIX_FIXUP_TRANS:
- newtm.SetTrans(src.GetTrans());
- newtm = Cleanup_Orthogonal_Matrix(newtm);
- break;
- case MATRIX_FIXUP_TRANS_ROT:
- DecomposeMatrix(src,trans,rot,scale);
- rot.MakeMatrix(newtm);
- newtm.SetTrans(trans);
- newtm = Cleanup_Orthogonal_Matrix(newtm);
- break;
- };
- return newtm;
- }
- /***********************************************************************************************
- * HierarchySaveClass::save_header -- writes the header into a W3D file *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 10/26/1997 GH : Created. *
- *=============================================================================================*/
- bool HierarchySaveClass::save_header(ChunkSaveClass & csave)
- {
- if (!csave.Begin_Chunk(W3D_CHUNK_HIERARCHY_HEADER)) {
- return false;
- }
- if (csave.Write(&HierarchyHeader,sizeof(HierarchyHeader)) != sizeof(HierarchyHeader)) {
- return false;
- }
- if (!csave.End_Chunk()) {
- return false;
- }
- return true;
- }
- /***********************************************************************************************
- * HierarchySaveClass::save_pivots -- writes the pivots into a W3D file *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 10/26/1997 GH : Created. *
- *=============================================================================================*/
- bool HierarchySaveClass::save_pivots(ChunkSaveClass & csave)
- {
- if (!csave.Begin_Chunk(W3D_CHUNK_PIVOTS)) {
- return false;
- }
- for (uint32 i=0; i<HierarchyHeader.NumPivots; i++) {
- if (csave.Write(&Node[i].Pivot,sizeof(W3dPivotStruct)) != sizeof(W3dPivotStruct)) {
- return false;
- }
- }
- if (!csave.End_Chunk()) {
- return false;
- }
- return true;
- }
- /***********************************************************************************************
- * HierarchySaveClass::save_fixups -- writes the fixup transforms into a W3D file *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 10/26/1997 GH : Created. *
- *=============================================================================================*/
- bool HierarchySaveClass::save_fixups(ChunkSaveClass & csave)
- {
- if (!csave.Begin_Chunk(W3D_CHUNK_PIVOT_FIXUPS)) {
- return false;
- }
- for (uint32 i=0; i<HierarchyHeader.NumPivots; i++) {
- if (csave.Write(&Node[i].Fixup,sizeof(W3dPivotFixupStruct)) != sizeof(W3dPivotFixupStruct)) {
- return false;
- }
- }
- if (!csave.End_Chunk()) {
- return false;
- }
- return true;
- }
- /***********************************************************************************************
- * HierarchySaveClass::load_header -- reads the header from a W3D file *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 10/26/1997 GH : Created. *
- *=============================================================================================*/
- bool HierarchySaveClass::load_header(ChunkLoadClass & cload)
- {
- /*
- ** Load the header
- */
- if (cload.Read(&HierarchyHeader,sizeof(HierarchyHeader)) != sizeof(HierarchyHeader)) {
- return false;
- }
- /*
- ** Reset the current node count
- */
- CurNode = 0;
- Node.Resize(HierarchyHeader.NumPivots);
- /*
- ** Initialize everything to a default state (particularly the
- ** fixup matrices to identity...)
- */
- for (unsigned i=0; i < HierarchyHeader.NumPivots; i++) {
- memset(&(Node[i]),0,sizeof(HierarchyNodeStruct));
- Matrix3 ident(1);
- for (int j=0; j<3; j++) {
- Point3 row = ident.GetRow(j);
- Node[i].Fixup.TM[j][0] = row.x;
- Node[i].Fixup.TM[j][1] = row.y;
- Node[i].Fixup.TM[j][2] = row.z;
- }
- }
-
- return true;
- }
- /***********************************************************************************************
- * HierarchySaveClass::load_pivots -- reads the pivots from a W3D file *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 10/26/1997 GH : Created. *
- *=============================================================================================*/
- bool HierarchySaveClass::load_pivots(ChunkLoadClass & cload)
- {
- for (uint32 i=0; i<HierarchyHeader.NumPivots; i++) {
- Node[i].MaxNode = NULL;
- if (cload.Read(&Node[i].Pivot,sizeof(W3dPivotStruct)) != sizeof(W3dPivotStruct)) {
- return false;
- }
- }
- return true;
- }
- /***********************************************************************************************
- * HierarchySaveClass::load_fixups -- reads the fixup transforms from a W3D file *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 10/26/1997 GH : Created. *
- *=============================================================================================*/
- bool HierarchySaveClass::load_fixups(ChunkLoadClass & cload)
- {
- for (uint32 i=0; i<HierarchyHeader.NumPivots; i++) {
- if (cload.Read(&Node[i].Fixup,sizeof(W3dPivotFixupStruct)) != sizeof(W3dPivotFixupStruct)) {
- return false;
- }
- }
- return true;
- }
|