This repository has been archived on 2025-02-27. You can view files and clone it, but cannot push or open issues or pull requests.
CnC_Renegade/Code/ww3d2/collect.cpp

1104 lines
61 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/collect.cpp $*
* *
* Author:: Greg Hjelstrom *
* *
* $Modtime:: 1/08/01 10:04a $*
* *
* $Revision:: 1 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* CollectionClass::CollectionClass -- default constructor for collection render object *
* CollectionClass::CollectionClass -- constructor for collection render object *
* CollectionClass::CollectionClass -- copy constructor *
* CollectionClass::CollectionClass -- assignment operator *
* CollectionClass::~CollectionClass -- destructor *
* CollectionClass::Clone -- virtual copy constructor *
* CollectionClass::Free -- releases all assets in use by this collection *
* CollectionClass::Class_ID -- returns class id for collection render objects *
* CollectionClass::Get_Num_Polys -- returns the number of polygons in this collection *
* CollectionClass::Render -- render this collection *
* CollectionClass::Special_Render -- passes the special render call to all sub-objects *
* CollectionClass::Set_Transform -- set the transform for this collection *
* CollectionClass::Set_Position -- set the position for this collection *
* CollectionClass::Get_Num_Sub_Objects -- returns the number of sub objects *
* CollectionClass::Get_Sub_Object -- returns a pointer to the desired sub object *
* CollectionClass::Add_Sub_Object -- adds another object into this collection *
* CollectionClass::Remove_Sub_Object -- removes a sub object from this collection *
* CollectionClass::Cast_Ray -- passes the ray test to each sub object *
* CollectionClass::Cast_AABox -- passes the axis-aligned box test to each sub object *
* CollectionClass::Cast_OBBox -- passes the oriented box test to each sub object *
* CollectionClass::Intersect_AABox -- test for intersection with an AABox *
* CollectionClass::Intersect_OBBox -- test for intersection with an OBBox *
* CollectionClass::Get_Obj_Space_Bounding_Sphere -- returns the object space bounding spher *
* CollectionClass::Get_Obj_Space_Bounding_Box -- returns the object-space bounding box *
* CollectionClass::Snap_Point_Count -- returns the number of snap points in this collecion *
* CollectionClass::Get_Snap_Point -- return the desired snap point *
* CollectionClass::Scale -- scale the objects in this collection *
* CollectionClass::Scale -- scale the objects in this collection *
* CollectionClass::Update_Obj_Space_Bounding_Volumes -- recomputes the object space boundin *
* CollectionClass::Update_Sub_Object_Transforms -- recomputes all sub object transforms *
* CollectionLoaderClass::Load -- reads a collection from a w3d file *
* CollectionDefClass::CollectionDefClass -- constructor *
* CollectionDefClass::~CollectionDefClass -- destructor for collection definition *
* CollectionDefClass::Free -- releases assets in use by a collection definition *
* CollectionDefClass::Get_Name -- returns name of the collection *
* CollectionDefClass::Load -- loads a collection definition from a w3d file *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "collect.h"
#include "chunkio.h"
#include "camera.h"
#include "wwdebug.h"
#include "snappts.h"
#include "assetmgr.h"
#include "ww3d.h"
#include "w3derr.h"
//#include "sr.hpp"
CollectionLoaderClass _CollectionLoader;
/*
** CollectionDefClass. This is the "blueprint" for a collection object
** The asset manager will store these until someone actually asks it to
** create an instance of the collection object
*/
class CollectionDefClass
{
public:
CollectionDefClass(void);
~CollectionDefClass(void);
const char * Get_Name(void) const;
WW3DErrorType Load(ChunkLoadClass & cload);
protected:
void Free(void);
char Name[W3D_NAME_LEN];
DynamicVectorClass<char *> ObjectNames;
SnapPointsClass * SnapPoints;
DynamicVectorClass <ProxyClass> ProxyList;
friend class CollectionClass;
};
/*
** CollectionPrototypeClass this is the render object prototype for
** Collections.
*/
class CollectionPrototypeClass : public PrototypeClass
{
public:
CollectionPrototypeClass(CollectionDefClass * def) { ColDef = def; WWASSERT(ColDef); }
virtual ~CollectionPrototypeClass(void) { delete ColDef; }
virtual const char * Get_Name(void) const { return ColDef->Get_Name(); }
virtual int Get_Class_ID(void) const { return RenderObjClass::CLASSID_COLLECTION; }
virtual RenderObjClass * Create(void) { return NEW_REF( CollectionClass, (*ColDef)); }
CollectionDefClass * ColDef;
};
/***********************************************************************************************
* CollectionClass::CollectionClass -- default constructor for collection render object *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 23/8/00 GTH : Created. *
*=============================================================================================*/
CollectionClass::CollectionClass(void) :
SnapPoints(NULL)
{
Update_Obj_Space_Bounding_Volumes();
}
/***********************************************************************************************
* CollectionClass::CollectionClass -- constructor for collection render object *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 12/8/98 GTH : Created. *
*=============================================================================================*/
CollectionClass::CollectionClass(const CollectionDefClass & def) :
SubObjects(def.ObjectNames.Count()),
SnapPoints(NULL)
{
// Set our name
Set_Name (def.Get_Name ());
// create the sub objects
SubObjects.Resize(def.ObjectNames.Count());
for (int i=0; i<def.ObjectNames.Count(); i++) {
WWASSERT(SubObjects.Count() == i);
SubObjects.Add(WW3DAssetManager::Get_Instance()->Create_Render_Obj(def.ObjectNames[i]));
SubObjects[i]->Set_Container(this);
}
// Copy the list of placeholder objects from the definition
ProxyList = def.ProxyList;
// grab ahold of the snap points.
SnapPoints = def.SnapPoints;
if (SnapPoints) SnapPoints->Add_Ref();
// set up our collision typeas the union of all of our sub-objects
Update_Sub_Object_Bits();
// update the object bounding volumes
Update_Obj_Space_Bounding_Volumes();
}
/***********************************************************************************************
* CollectionClass::CollectionClass -- copy constructor *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 12/8/98 GTH : Created. *
*=============================================================================================*/
CollectionClass::CollectionClass(const CollectionClass & src) :
CompositeRenderObjClass(src),
SubObjects(src.SubObjects.Count()),
SnapPoints(NULL)
{
*this = src;
}
/***********************************************************************************************
* CollectionClass::CollectionClass -- assignment operator *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 12/8/98 GTH : Created. *
*=============================================================================================*/
CollectionClass & CollectionClass::operator = (const CollectionClass & that)
{
if (this != &that) {
Free();
CompositeRenderObjClass::operator = (that);
SubObjects.Resize(that.SubObjects.Count());
for (int i=0; i<that.SubObjects.Count(); i++) {
WWASSERT(SubObjects.Count() == i);
SubObjects.Add(that.SubObjects[i]->Clone());
SubObjects[i]->Set_Container(this);
}
// Copy the list of placeholder objects from the definition
ProxyList = that.ProxyList;
SnapPoints = that.SnapPoints;
if (SnapPoints) SnapPoints->Add_Ref();
Update_Sub_Object_Bits();
Update_Obj_Space_Bounding_Volumes();
}
return * this;
}
/***********************************************************************************************
* CollectionClass::~CollectionClass -- destructor *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 12/8/98 GTH : Created. *
*=============================================================================================*/
CollectionClass::~CollectionClass(void)
{
Free();
}
/***********************************************************************************************
* CollectionClass::Clone -- virtual copy constructor *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 12/8/98 GTH : Created. *
*=============================================================================================*/
RenderObjClass * CollectionClass::Clone(void) const
{
return NEW_REF( CollectionClass, (*this));
}
/***********************************************************************************************
* CollectionClass::Free -- releases all assets in use by this collection *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 12/8/98 GTH : Created. *
*=============================================================================================*/
void CollectionClass::Free(void)
{
for (int i=0; i<SubObjects.Count(); i++) {
SubObjects[i]->Set_Container(NULL);
SubObjects[i]->Release_Ref();
SubObjects[i] = NULL;
}
SubObjects.Delete_All();
ProxyList.Delete_All ();
REF_PTR_RELEASE(SnapPoints);
}
/***********************************************************************************************
* CollectionClass::Class_ID -- returns class id for collection render objects *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 12/8/98 GTH : Created. *
*=============================================================================================*/
int CollectionClass::Class_ID(void) const
{
return RenderObjClass::CLASSID_COLLECTION;
}
/***********************************************************************************************
* CollectionClass::Get_Num_Polys -- returns the number of polygons in this collection *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 12/8/98 GTH : Created. *
*=============================================================================================*/
int CollectionClass::Get_Num_Polys(void) const
{
int pcount = 0;
for (int i=0; i<SubObjects.Count(); i++) {
pcount += SubObjects[i]->Get_Num_Polys();
}
return pcount;
}
/***********************************************************************************************
* CollectionClass::Render -- render this collection *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 12/8/98 GTH : Created. *
*=============================================================================================*/
void CollectionClass::Render(RenderInfoClass & rinfo)
{
if (Is_Not_Hidden_At_All() == false) {
return;
}
if (Are_Sub_Object_Transforms_Dirty()) {
Update_Sub_Object_Transforms();
}
for (int i=0; i<SubObjects.Count(); i++) {
SubObjects[i]->Render(rinfo);
}
}
/***********************************************************************************************
* CollectionClass::Special_Render -- passes the special render call to all sub-objects *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 3/2/99 GTH : Created. *
*=============================================================================================*/
void CollectionClass::Special_Render(SpecialRenderInfoClass & rinfo)
{
if (Is_Not_Hidden_At_All() == false) {
return;
}
if (Are_Sub_Object_Transforms_Dirty()) {
Update_Sub_Object_Transforms();
}
for (int i=0; i<SubObjects.Count(); i++) {
SubObjects[i]->Special_Render(rinfo);
}
}
/***********************************************************************************************
* CollectionClass::Set_Transform -- set the transform for this collection *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 12/8/98 GTH : Created. *
*=============================================================================================*/
void CollectionClass::Set_Transform(const Matrix3D &m)
{
RenderObjClass::Set_Transform(m);
Set_Sub_Object_Transforms_Dirty(true);
}
/***********************************************************************************************
* CollectionClass::Set_Position -- set the position for this collection *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 12/8/98 GTH : Created. *
*=============================================================================================*/
void CollectionClass::Set_Position(const Vector3 &v)
{
RenderObjClass::Set_Position(v);
Set_Sub_Object_Transforms_Dirty(true);
}
/***********************************************************************************************
* CollectionClass::Get_Num_Sub_Objects -- returns the number of sub objects *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 12/8/98 GTH : Created. *
*=============================================================================================*/
int CollectionClass::Get_Num_Sub_Objects(void) const
{
return SubObjects.Count();
}
/***********************************************************************************************
* CollectionClass::Get_Sub_Object -- returns a pointer to the desired sub object *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 12/8/98 GTH : Created. *
*=============================================================================================*/
RenderObjClass * CollectionClass::Get_Sub_Object(int index) const
{
if (SubObjects[index]) {
SubObjects[index]->Add_Ref();
}
return SubObjects[index];
}
/***********************************************************************************************
* CollectionClass::Add_Sub_Object -- adds another object into this collection *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 12/8/98 GTH : Created. *
*=============================================================================================*/
int CollectionClass::Add_Sub_Object(RenderObjClass * subobj)
{
WWASSERT(subobj);
subobj->Add_Ref();
subobj->Set_Container(this);
subobj->Set_Transform(Transform);
int res = SubObjects.Add(subobj);
Update_Sub_Object_Bits();
Update_Obj_Space_Bounding_Volumes();
if (Is_In_Scene()) {
subobj->Notify_Added(Scene);
}
return res;
}
/***********************************************************************************************
* CollectionClass::Remove_Sub_Object -- removes a sub object from this collection *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 12/8/98 GTH : Created. *
*=============================================================================================*/
int CollectionClass::Remove_Sub_Object(RenderObjClass * robj)
{
if (robj == NULL) return 0;
int res = 0;
Matrix3D tm = Get_Transform();
for (int i=0; i<SubObjects.Count(); i++) {
if (robj == SubObjects[i]) {
if (Is_In_Scene()) {
SubObjects[i]->Notify_Removed(Scene);
}
SubObjects[i]->Set_Container(NULL);
SubObjects[i]->Set_Transform(tm);
SubObjects[i]->Release_Ref();
res = SubObjects.Delete(i);
break;
}
}
if (res != 0) {
Update_Sub_Object_Bits();
Update_Obj_Space_Bounding_Volumes();
}
return res;
}
/***********************************************************************************************
* CollectionClass::Cast_Ray -- passes the ray test to each sub object *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 12/8/98 GTH : Created. *
*=============================================================================================*/
bool CollectionClass::Cast_Ray(RayCollisionTestClass & raytest)
{
bool res = false;
for (int i=0; i<SubObjects.Count(); i++) {
res |= SubObjects[i]->Cast_Ray(raytest);
}
return res;
}
/***********************************************************************************************
* CollectionClass::Cast_AABox -- passes the axis-aligned box test to each sub object *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 12/8/98 GTH : Created. *
*=============================================================================================*/
bool CollectionClass::Cast_AABox(AABoxCollisionTestClass & boxtest)
{
bool res = false;
for (int i=0; i<SubObjects.Count(); i++) {
res |= SubObjects[i]->Cast_AABox(boxtest);
}
return res;
}
/***********************************************************************************************
* CollectionClass::Cast_OBBox -- passes the oriented box test to each sub object *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 12/8/98 GTH : Created. *
*=============================================================================================*/
bool CollectionClass::Cast_OBBox(OBBoxCollisionTestClass & boxtest)
{
bool res = false;
for (int i=0; i<SubObjects.Count(); i++) {
res |= SubObjects[i]->Cast_OBBox(boxtest);
}
return res;
}
/***********************************************************************************************
* CollectionClass::Intersect_AABox -- test for intersection with an AABox *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 1/19/00 gth : Created. *
*=============================================================================================*/
bool CollectionClass::Intersect_AABox(AABoxIntersectionTestClass & boxtest)
{
bool res = false;
for (int i=0; i<SubObjects.Count(); i++) {
res |= SubObjects[i]->Intersect_AABox(boxtest);
}
return res;
}
/***********************************************************************************************
* CollectionClass::Intersect_OBBox -- test for intersection with an OBBox *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 1/19/00 gth : Created. *
*=============================================================================================*/
bool CollectionClass::Intersect_OBBox(OBBoxIntersectionTestClass & boxtest)
{
bool res = false;
for (int i=0; i<SubObjects.Count(); i++) {
res |= SubObjects[i]->Intersect_OBBox(boxtest);
}
return res;
}
/***********************************************************************************************
* CollectionClass::Get_Obj_Space_Bounding_Sphere -- returns the object space bounding sphere. *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 12/8/98 GTH : Created. *
*=============================================================================================*/
void CollectionClass::Get_Obj_Space_Bounding_Sphere(SphereClass & sphere) const
{
sphere = BoundSphere;
}
/***********************************************************************************************
* CollectionClass::Get_Obj_Space_Bounding_Box -- returns the object-space bounding box *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 12/8/98 GTH : Created. *
*=============================================================================================*/
void CollectionClass::Get_Obj_Space_Bounding_Box(AABoxClass & box) const
{
box = BoundBox;
}
/***********************************************************************************************
* CollectionClass::Snap_Point_Count -- returns the number of snap points in this collecion *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 12/8/98 GTH : Created. *
*=============================================================================================*/
int CollectionClass::Snap_Point_Count(void)
{
if (SnapPoints) {
return SnapPoints->Count();
} else {
return 0;
}
}
/***********************************************************************************************
* CollectionClass::Get_Snap_Point -- return the desired snap point *
* *
* This function will set the passed vector to be equal to the object space coordinates of *
* the desired snap point. *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 12/8/98 GTH : Created. *
*=============================================================================================*/
void CollectionClass::Get_Snap_Point(int index,Vector3 * set)
{
WWASSERT(set != NULL);
if (SnapPoints) {
*set = (*SnapPoints)[index];
} else {
set->X = set->Y = set->Z = 0;
}
}
/***********************************************************************************************
* CollectionClass::Scale -- scale the objects in this collection *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 12/8/98 GTH : Created. *
*=============================================================================================*/
void CollectionClass::Scale(float scale)
{
for (int i=0; i<SubObjects.Count(); i++) {
SubObjects[i]->Scale(scale);
}
}
/***********************************************************************************************
* CollectionClass::Scale -- scale the objects in this collection *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 12/8/98 GTH : Created. *
*=============================================================================================*/
void CollectionClass::Scale(float scalex, float scaley, float scalez)
{
for (int i=0; i<SubObjects.Count(); i++) {
SubObjects[i]->Scale(scalex,scaley,scalez);
}
}
/***********************************************************************************************
* CollectionClass::Update_Obj_Space_Bounding_Volumes -- recomputes the object space bounding *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 12/8/98 GTH : Created. *
*=============================================================================================*/
void CollectionClass::Update_Obj_Space_Bounding_Volumes(void)
{
int i;
if (SubObjects.Count() <= 0) {
BoundSphere = SphereClass(Vector3(0,0,0),0);
BoundBox.Center.Set(0,0,0);
BoundBox.Extent.Set(0,0,0);
return;
}
Matrix3D tm = Get_Transform();
Set_Transform(Matrix3D(1));
// loop through all sub-objects, combining their bounding spheres.
BoundSphere = SubObjects[0]->Get_Bounding_Sphere();
for (i=1; i < SubObjects.Count(); i++) {
BoundSphere.Add_Sphere(SubObjects[i]->Get_Bounding_Sphere());
}
// loop through the sub-objects, computing a box in the root coordinate
// system which bounds all of the meshes. Note that we've set the
// root coordinate system to identity for this.
MinMaxAABoxClass box(Vector3(FLT_MAX,FLT_MAX,FLT_MAX),Vector3(-FLT_MAX,-FLT_MAX,-FLT_MAX));
for (i=0; i < SubObjects.Count(); i++) {
box.Add_Box(SubObjects[i]->Get_Bounding_Box());
}
BoundBox.Init(box);
Invalidate_Cached_Bounding_Volumes();
// Now update the object space bounding volumes of this object's container:
RenderObjClass *container = Get_Container();
if (container) container->Update_Obj_Space_Bounding_Volumes();
Set_Transform(tm);
}
/***********************************************************************************************
* CollectionClass::Update_Sub_Object_Transforms -- recomputes all sub object transforms *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 12/8/98 GTH : Created. *
*=============================================================================================*/
void CollectionClass::Update_Sub_Object_Transforms(void)
{
RenderObjClass::Update_Sub_Object_Transforms();
for (int i=0; i<SubObjects.Count(); i++) {
SubObjects[i]->Set_Transform(Transform);
SubObjects[i]->Update_Sub_Object_Transforms();
}
Set_Sub_Object_Transforms_Dirty(false);
}
/***********************************************************************************************
* CollectionClass::Get_Placeholder -- Returns information about a placeholder object.
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 4/28/99 PDS : Created. *
*=============================================================================================*/
bool CollectionClass::Get_Proxy (int index, ProxyClass &proxy) const
{
bool retval = false;
if (index >= 0 && index < ProxyList.Count ()) {
//
// Return the proxy information to the caller
//
proxy = ProxyList[index];
retval = true;
}
return retval;
}
/***********************************************************************************************
* CollectionClass::Get_Proxy_Count -- Returns the count of proxy objects in the collection.
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 4/28/99 PDS : Created. *
*=============================================================================================*/
int CollectionClass::Get_Proxy_Count (void) const
{
return ProxyList.Count ();
}
/***********************************************************************************************
* CollectionDefClass::CollectionDefClass -- constructor *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 12/8/98 GTH : Created. *
*=============================================================================================*/
CollectionDefClass::CollectionDefClass(void)
{
SnapPoints = NULL;
}
/***********************************************************************************************
* CollectionDefClass::~CollectionDefClass -- destructor for collection definition *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 12/8/98 GTH : Created. *
*=============================================================================================*/
CollectionDefClass::~CollectionDefClass(void)
{
Free();
}
/***********************************************************************************************
* CollectionDefClass::Free -- releases assets in use by a collection definition *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 12/8/98 GTH : Created. *
*=============================================================================================*/
void CollectionDefClass::Free(void)
{
for (int i=0; i<ObjectNames.Count(); i++) {
delete[] ObjectNames[i];
}
ProxyList.Delete_All ();
}
/***********************************************************************************************
* CollectionDefClass::Get_Name -- returns name of the collection *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 12/8/98 GTH : Created. *
*=============================================================================================*/
const char * CollectionDefClass::Get_Name(void) const
{
return Name;
}
/***********************************************************************************************
* CollectionDefClass::Load -- loads a collection definition from a w3d file *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 12/8/98 GTH : Created. *
*=============================================================================================*/
WW3DErrorType CollectionDefClass::Load(ChunkLoadClass & cload)
{
Free();
// open the header chunk and read it in
W3dCollectionHeaderStruct header;
if (!cload.Open_Chunk()) goto Error;
if (cload.Cur_Chunk_ID() != W3D_CHUNK_COLLECTION_HEADER) goto Error;
if (cload.Read(&header,sizeof(header)) != sizeof(header)) goto Error;
if (!cload.Close_Chunk()) goto Error;
strncpy(Name,header.Name,W3D_NAME_LEN);
ObjectNames.Resize(header.RenderObjectCount);
while (cload.Open_Chunk()) {
switch (cload.Cur_Chunk_ID())
{
case W3D_CHUNK_COLLECTION_OBJ_NAME:
{
WWASSERT(cload.Cur_Chunk_Length() > 0);
char * name = new char [cload.Cur_Chunk_Length()];
cload.Read(name,cload.Cur_Chunk_Length());
ObjectNames.Add(name);
break;
}
case W3D_CHUNK_PLACEHOLDER:
{
// Read the placeholder information from the chunk
WWASSERT(cload.Cur_Chunk_Length() > 0);
W3dPlaceholderStruct info;
cload.Read(&info, sizeof (info));
// Read the placeholder name from the chunk
char *name = new char[info.name_len + 1];
cload.Read(name, info.name_len);
name[info.name_len] = 0;
// Create a matrix from the data in the chunk
Matrix3D transform (info.transform[0][0], info.transform[1][0], info.transform[2][0], info.transform[3][0],
info.transform[0][1], info.transform[1][1], info.transform[2][1], info.transform[3][1],
info.transform[0][2], info.transform[1][2], info.transform[2][2], info.transform[3][2]);
// Add this placeholder to our list
ProxyList.Add (ProxyClass (name, transform));
// Free the name array
delete [] name;
break;
}
case W3D_CHUNK_POINTS:
SnapPoints = NEW_REF(SnapPointsClass, ());
SnapPoints->Load_W3D(cload);
break;
}
cload.Close_Chunk();
}
return WW3D_ERROR_OK;
Error:
return WW3D_ERROR_LOAD_FAILED;
}
/***********************************************************************************************
* CollectionLoaderClass::Load -- reads a collection from a w3d file *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 12/8/98 GTH : Created. *
*=============================================================================================*/
PrototypeClass * CollectionLoaderClass::Load_W3D(ChunkLoadClass & cload)
{
CollectionDefClass * def = new CollectionDefClass;
if (def == NULL) {
return NULL;
}
if (def->Load(cload) != WW3D_ERROR_OK) {
// load failed, delete the model and return an error
delete def;
return NULL;
} else {
// ok, accept this model!
CollectionPrototypeClass * proto = new CollectionPrototypeClass(def);
return proto;
}
}