257 lines
11 KiB
C++
257 lines
11 KiB
C++
/*
|
|
** Command & Conquer Renegade(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/>.
|
|
*/
|
|
|
|
/***********************************************************************************************
|
|
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
|
|
***********************************************************************************************
|
|
* *
|
|
* Project Name : WW3D *
|
|
* *
|
|
* $Archive:: /Commando/Code/ww3d2/hmdldef.cpp $*
|
|
* *
|
|
* Author:: Greg_h *
|
|
* *
|
|
* $Modtime:: 1/08/01 10:04a $*
|
|
* *
|
|
* $Revision:: 1 $*
|
|
* *
|
|
*---------------------------------------------------------------------------------------------*
|
|
* Functions: *
|
|
* HModelDefClass::HModelDefClass -- Constructor *
|
|
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
|
|
|
|
|
#include "hmdldef.h"
|
|
#include <assert.h>
|
|
#include <string.h>
|
|
#include "w3d_file.h"
|
|
#include "chunkio.h"
|
|
#include "snappts.h"
|
|
|
|
|
|
/***********************************************************************************************
|
|
* HModelDefClass::HModelDefClass -- Constructor *
|
|
* *
|
|
* INPUT: *
|
|
* *
|
|
* OUTPUT: *
|
|
* *
|
|
* WARNINGS: *
|
|
* *
|
|
* HISTORY: *
|
|
* 12/15/97 GTH : Created. *
|
|
*=============================================================================================*/
|
|
HModelDefClass::HModelDefClass(void) :
|
|
SubObjectCount(0),
|
|
SubObjects(NULL),
|
|
SnapPoints(NULL)
|
|
{
|
|
|
|
}
|
|
|
|
/***********************************************************************************************
|
|
* HModelDefClass::~HModelDefClass -- destructor *
|
|
* *
|
|
* INPUT: *
|
|
* *
|
|
* OUTPUT: *
|
|
* *
|
|
* WARNINGS: *
|
|
* *
|
|
* HISTORY: *
|
|
* 08/11/1997 GH : Created. *
|
|
*=============================================================================================*/
|
|
HModelDefClass::~HModelDefClass(void)
|
|
{
|
|
Free();
|
|
}
|
|
|
|
/***********************************************************************************************
|
|
* HModelDefClass::Free -- de-allocate all memory in use *
|
|
* *
|
|
* INPUT: *
|
|
* *
|
|
* OUTPUT: *
|
|
* *
|
|
* WARNINGS: *
|
|
* *
|
|
* HISTORY: *
|
|
* 08/11/1997 GH : Created. *
|
|
*=============================================================================================*/
|
|
void HModelDefClass::Free(void)
|
|
{
|
|
if (SubObjects != NULL) {
|
|
delete[] SubObjects;
|
|
SubObjects = NULL;
|
|
}
|
|
SubObjectCount = 0;
|
|
|
|
if (SnapPoints != NULL) {
|
|
SnapPoints->Release_Ref();
|
|
SnapPoints = NULL;
|
|
}
|
|
}
|
|
|
|
|
|
/***********************************************************************************************
|
|
* HModelDefClass::Load -- load a set of mesh connections from a file *
|
|
* *
|
|
* INPUT: *
|
|
* *
|
|
* OUTPUT: *
|
|
* *
|
|
* WARNINGS: *
|
|
* *
|
|
* HISTORY: *
|
|
* 08/11/1997 GH : Created. *
|
|
*=============================================================================================*/
|
|
int HModelDefClass::Load_W3D(ChunkLoadClass & cload)
|
|
{
|
|
bool pre30 = false;
|
|
int subobjcounter = 0;
|
|
|
|
Free();
|
|
|
|
/*
|
|
** Read the first chunk, it should be the header
|
|
*/
|
|
if (!cload.Open_Chunk()) {
|
|
return false;
|
|
}
|
|
|
|
if (cload.Cur_Chunk_ID() != W3D_CHUNK_HMODEL_HEADER) {
|
|
goto Error;
|
|
}
|
|
|
|
/*
|
|
** read in the header
|
|
*/
|
|
W3dHModelHeaderStruct header;
|
|
if (cload.Read(&header,sizeof(W3dHModelHeaderStruct)) != sizeof(W3dHModelHeaderStruct)) {
|
|
goto Error;
|
|
}
|
|
|
|
cload.Close_Chunk();
|
|
|
|
/*
|
|
** process the header info
|
|
*/
|
|
strncpy(ModelName,header.Name,W3D_NAME_LEN);
|
|
ModelName[W3D_NAME_LEN - 1] = 0;
|
|
strncpy(BasePoseName,header.HierarchyName,W3D_NAME_LEN);
|
|
BasePoseName[W3D_NAME_LEN-1] = 0;
|
|
strcpy(Name,ModelName);
|
|
|
|
/*
|
|
** Just allocate a node for the number of sub objects we're expecting
|
|
*/
|
|
SubObjectCount = header.NumConnections;
|
|
SubObjects = new HmdlNodeDefStruct[SubObjectCount];
|
|
if (SubObjects == NULL) {
|
|
goto Error;
|
|
}
|
|
|
|
/*
|
|
** If this is pre-3.0 set a flag so that each render object's
|
|
** bone id will be incremented by one to account for the new
|
|
** root node added with version3.0 of the file format. Basically,
|
|
** I'm making all of the code assume that node 0 is the root and
|
|
** therefore, pre-3.0 files have to have it added and all of
|
|
** the indices adjusted
|
|
*/
|
|
if (header.Version < W3D_MAKE_VERSION(3,0)) {
|
|
pre30 = true;
|
|
}
|
|
|
|
/*
|
|
** Process the rest of the chunks
|
|
*/
|
|
subobjcounter = 0;
|
|
|
|
while (cload.Open_Chunk()) {
|
|
|
|
switch (cload.Cur_Chunk_ID()) {
|
|
|
|
case W3D_CHUNK_NODE:
|
|
case W3D_CHUNK_COLLISION_NODE:
|
|
case W3D_CHUNK_SKIN_NODE:
|
|
if (!read_connection(cload,&(SubObjects[subobjcounter]),pre30)) {
|
|
goto Error;
|
|
}
|
|
subobjcounter++;
|
|
break;
|
|
|
|
case W3D_CHUNK_POINTS:
|
|
SnapPoints = new SnapPointsClass;
|
|
SnapPoints->Load_W3D(cload);
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
cload.Close_Chunk();
|
|
}
|
|
|
|
return OK;
|
|
|
|
Error:
|
|
|
|
return LOAD_ERROR;
|
|
|
|
}
|
|
|
|
|
|
/***********************************************************************************************
|
|
* HModelDefClass::read_connection -- read a single connection from the file *
|
|
* *
|
|
* INPUT: *
|
|
* *
|
|
* OUTPUT: *
|
|
* *
|
|
* WARNINGS: *
|
|
* *
|
|
* HISTORY: *
|
|
* 08/11/1997 GH : Created. *
|
|
* 10/22/97 GH : Check for mesh connections with PivotID=-1 *
|
|
*=============================================================================================*/
|
|
bool HModelDefClass::read_connection(ChunkLoadClass & cload,HmdlNodeDefStruct * node,bool pre30)
|
|
{
|
|
|
|
W3dHModelNodeStruct con;
|
|
if (cload.Read(&con,sizeof(W3dHModelNodeStruct)) != sizeof(W3dHModelNodeStruct)) {
|
|
return false;
|
|
}
|
|
|
|
strcpy(node->RenderObjName,ModelName);
|
|
strcat(node->RenderObjName,".");
|
|
strcat(node->RenderObjName,con.RenderObjName);
|
|
|
|
if (pre30) {
|
|
if (con.PivotIdx == 65535) {
|
|
node->PivotID = 0;
|
|
} else {
|
|
node->PivotID = con.PivotIdx + 1;
|
|
}
|
|
} else {
|
|
assert(con.PivotIdx != 65535);
|
|
node->PivotID = con.PivotIdx;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|