/*
**	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 : WWPhys                                                       *
 *                                                                                             *
 *                     $Archive:: /Commando/Code/wwphys/staticphys.cpp                        $*
 *                                                                                             *
 *                       Author:: Greg Hjelstrom                                               *
 *                                                                                             *
 *                     $Modtime:: 3/29/02 2:49p                                               $*
 *                                                                                             *
 *                    $Revision:: 49                                                          $*
 *                                                                                             *
 *---------------------------------------------------------------------------------------------*
 * Functions:                                                                                  *
 *   StaticPhysClass::StaticPhysClass -- Constructor                                           *
 *   StaticPhysClass::~StaticPhysClass -- Destructor                                           *
 *   StaticPhysClass::Init -- Initialize this object from a definition                         *
 *   StaticPhysClass::Set_Vis_Sector_ID -- Sets the vis sector ID for this object              *
 *   StaticPhysClass::Set_Model -- Set the model for this static object                        *
 *   StaticPhysClass::Update_Cached_Model_Parameters -- update our state                       *
 *   StaticPhysClass::Render_Vis_Meshes -- renders any vis meshes in this model                *
 *   StaticPhysClass::Get_Bounding_Box -- Returns the bounding box of this object              *
 *   StaticPhysClass::Get_Transform -- Returns the transform of this object                    *
 *   StaticPhysClass::Set_Transform -- Set the transform for this object                       *
 *   StaticPhysClass::Is_Occluder -- Returns whether this static object is an occluder         *
 *   StaticPhysClass::Is_Model_Pre_Lit -- determines if the render object is pre-lit           *
 *   StaticPhysClass::Is_Vis_Sector -- Is_Vis_Sector                                           *
 *   StaticPhysClass::Update_Sun_Status -- determine if this object is in the sun              *
 *   StaticPhysClass::Get_Factory -- Returns the persist factory for StaticPhysClass           *
 *   StaticPhysClass::Save -- Save method, persistant object support                           *
 *   StaticPhysClass::Load -- Load method, persistant object support                           *
 *   StaticPhysClass::On_Post_Load -- Post-Load callback                                       *
 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */


#include "staticphys.h"
#include "colmathaabox.h"
#include "vistable.h"
#include "chunkio.h"
#include "assetmgr.h"
#include "progcall.h"
#include "matrix3.h"
#include "persistfactory.h"
#include "simpledefinitionfactory.h"
#include "wwphysids.h"
#include "wwhack.h"
#include "mesh.h"
#include "meshmdl.h"
#include "lightexclude.h"
#include <memory.h>
#include "part_emt.h"
#include "renegadeterrainpatch.h"

#if UMBRASUPPORT
#include <umbra.hpp>
#include "umbrasupport.h"
#endif

DECLARE_FORCE_LINK(staticphys);

 
/***********************************************************************************************
**
** StaticPhysClass Implementation
**
***********************************************************************************************/

bool StaticPhysClass::_DisableStaticPhysSimulation			= false;
bool StaticPhysClass::_DisableStaticPhysRendering			= false;


/*
** Declare a PersistFactory for StaticPhysClasses
*/
SimplePersistFactoryClass<StaticPhysClass,PHYSICS_CHUNKID_STATICPHYS>	_StaticPhysFactory;


/*
** Chunk-ID's used by StaticPhysClass
*/
enum 
{
	STATICPHYS_CHUNK_PHYS				= 14430100,
	STATICPHYS_CHUNK_VARIABLES,

	STATICPHYS_VARIABLE_VISOBJECTID	= 0x00,
	STATICPHYS_VARIABLE_VISSECTORID,
};


/***********************************************************************************************
 * StaticPhysClass::StaticPhysClass -- Constructor                                             *
 *                                                                                             *
 * INPUT:                                                                                      *
 *                                                                                             *
 * OUTPUT:                                                                                     *
 *                                                                                             *
 * WARNINGS:                                                                                   *
 * I'm initializing the VisObjectID to zero, the "always visible" object ID                    *
 * I'm initializing the VisSectorID to -1 to indicate that no table is allocated for this obj  *
 *                                                                                             *
 * HISTORY:                                                                                    *
 *   1/10/00    gth : Created.                                                                 *
 *=============================================================================================*/
StaticPhysClass::StaticPhysClass(void) :
	VisSectorID(0xFFFFFFFF)
{
	Set_Collision_Group( 15 );	// HACK?  All terrain should be group 15?	
}


/***********************************************************************************************
 * StaticPhysClass::~StaticPhysClass -- Destructor                                             *
 *                                                                                             *
 * INPUT:                                                                                      *
 *                                                                                             *
 * OUTPUT:                                                                                     *
 *                                                                                             *
 * WARNINGS:                                                                                   *
 *                                                                                             *
 * HISTORY:                                                                                    *
 *   1/10/00    gth : Created.                                                                 *
 *=============================================================================================*/
StaticPhysClass::~StaticPhysClass(void)
{
}


/***********************************************************************************************
 * StaticPhysClass::Init -- Initialize this object from a definition                           *
 *                                                                                             *
 * INPUT:                                                                                      *
 *                                                                                             *
 * OUTPUT:                                                                                     *
 *                                                                                             *
 * WARNINGS:                                                                                   *
 *                                                                                             *
 * HISTORY:                                                                                    *
 *   1/10/00    gth : Created.                                                                 *
 *=============================================================================================*/
void StaticPhysClass::Init(const StaticPhysDefClass & def)
{
	PhysClass::Init(def);
	if (Model != NULL && Model->Class_ID () == RenderObjClass::CLASSID_PARTICLEEMITTER) {
		((ParticleEmitterClass *)Model)->Start ();
	}
}


/***********************************************************************************************
 * StaticPhysClass::Set_Vis_Sector_ID -- Sets the vis sector ID for this object                *
 *                                                                                             *
 * If a static object contains a VIS mesh, a vis sector ID is allocated for it.  This is the   *
 * ID of the visibility table for this object which tracks what objects are visible when the   *
 * camera is above one of its VIS meshes.                                                      *
 *                                                                                             *
 * INPUT:                                                                                      *
 *                                                                                             *
 * OUTPUT:                                                                                     *
 *                                                                                             *
 * WARNINGS:                                                                                   *
 *                                                                                             *
 * HISTORY:                                                                                    *
 *   6/27/2000  gth : Created.                                                                 *
 *=============================================================================================*/
void StaticPhysClass::Set_Vis_Sector_ID(int new_id)
{ 
	VisSectorID = new_id;
}

/***********************************************************************************************
 * StaticPhysClass::Set_Model -- Set the model for this static object                          *
 *                                                                                             *
 * INPUT:                                                                                      *
 *                                                                                             *
 * OUTPUT:                                                                                     *
 *                                                                                             *
 * WARNINGS:                                                                                   *
 *                                                                                             *
 * HISTORY:                                                                                    *
 *   1/10/00    gth : Created.                                                                 *
 *=============================================================================================*/
void StaticPhysClass::Set_Model(RenderObjClass * model)
{
	// call parent class
	PhysClass::Set_Model(model);
	
	Update_Cached_Model_Parameters();
}


/***********************************************************************************************
 * StaticPhysClass::Update_Cached_Model_Parameters -- update our state                         *
 *                                                                                             *
 * This function must be called in three places: In the constructor, whenever the model is     *
 * set, and in the post-load callback                                                          *
 *                                                                                             *
 * INPUT:                                                                                      *
 *                                                                                             *
 * OUTPUT:                                                                                     *
 *                                                                                             *
 * WARNINGS:                                                                                   *
 *                                                                                             *
 * HISTORY:                                                                                    *
 *   1/14/00    gth : Created.                                                                 *
 *=============================================================================================*/
void StaticPhysClass::Update_Cached_Model_Parameters(void)
{
	if (Model == NULL) return;

	// if the model is a light-mapped mesh, we want to exclude it from the static lights
	Enable_Is_Pre_Lit(Is_Model_Pre_Lit());

	// if our model is a mesh and its in world space, enable the world-space-mesh optimizations
	if ((Model->Class_ID() == RenderObjClass::CLASSID_MESH) && (Get_Transform() == Matrix3D::Identity)) {
		Enable_Is_World_Space_Mesh(true);
	} else {
		Enable_Is_World_Space_Mesh(false);
	}

#if (UMBRASUPPORT)
	// update the umbra model(s)
	Umbra::Model * test_model = NULL;
	
	if (Model->Class_ID() == RenderObjClass::CLASSID_MESH) {
		MeshClass & mesh = *((MeshClass *)Model);
		test_model = UmbraSupport::Create_Mesh_Model(mesh);		
	} else {
		AABoxClass obj_box;
		Model->Get_Obj_Space_Bounding_Box(obj_box);
		test_model = UmbraSupport::Create_Box_Model(obj_box);
	}

	UmbraObject->setTestModel(test_model);
	if ((Model->Class_ID() == RenderObjClass::CLASSID_MESH) && (Is_Occluder())) {
		test_model->set(Umbra::Model::WRITABLE,true);
		UmbraObject->setWriteModel(test_model);
	}
	//UmbraObject->setCost(100000,100000,5);
#endif //UMBRASUPPORT

}


/***********************************************************************************************
 * StaticPhysClass::Render_Vis_Meshes -- renders any vis meshes in this model                  *
 *                                                                                             *
 * INPUT:                                                                                      *
 *                                                                                             *
 * OUTPUT:                                                                                     *
 *                                                                                             *
 * WARNINGS:                                                                                   *
 *                                                                                             *
 * HISTORY:                                                                                    *
 *   3/17/2000  gth : Created.                                                                 *
 *=============================================================================================*/
void StaticPhysClass::Render_Vis_Meshes(RenderInfoClass & rinfo)
{
	if (Model == NULL) return;
	
	// Note, this only works with Mesh vis sectors.  Theoretically vis sectors could
	// be embedded in a hierarchical model as well...
	if (Model->Get_Collision_Type() & COLLISION_TYPE_VIS) { 

		// Force hidden meshes to render...
		int is_hidden = Model->Is_Hidden();
		int is_anim_hidden = Model->Is_Animation_Hidden();
		Model->Set_Hidden(false);
		Model->Set_Animation_Hidden(false);

		Model->Render(rinfo);

		Model->Set_Hidden(is_hidden);
		Model->Set_Animation_Hidden(is_anim_hidden);
	}
}


/***********************************************************************************************
 * StaticPhysClass::Get_Bounding_Box -- Returns the bounding box of this object                *
 *                                                                                             *
 * INPUT:                                                                                      *
 *                                                                                             *
 * OUTPUT:                                                                                     *
 *                                                                                             *
 * WARNINGS:                                                                                   *
 *                                                                                             *
 * HISTORY:                                                                                    *
 *   1/10/00    gth : Created.                                                                 *
 *=============================================================================================*/
const AABoxClass & StaticPhysClass::Get_Bounding_Box(void) const
{
	assert(Model);
	return Model->Get_Bounding_Box();
}


/***********************************************************************************************
 * StaticPhysClass::Get_Transform -- Returns the transform of this object                      *
 *                                                                                             *
 * INPUT:                                                                                      *
 *                                                                                             *
 * OUTPUT:                                                                                     *
 *                                                                                             *
 * WARNINGS:                                                                                   *
 *                                                                                             *
 * HISTORY:                                                                                    *
 *   1/10/00    gth : Created.                                                                 *
 *=============================================================================================*/
const Matrix3D & StaticPhysClass::Get_Transform(void) const
{
	assert(Model);
	return Model->Get_Transform();
}


/***********************************************************************************************
 * StaticPhysClass::Set_Transform -- Set the transform for this object                         *
 *                                                                                             *
 * INPUT:                                                                                      *
 *                                                                                             *
 * OUTPUT:                                                                                     *
 *                                                                                             *
 * WARNINGS:                                                                                   *
 * The transform should not be changed in-game!                                                *
 *                                                                                             *
 * HISTORY:                                                                                    *
 *   1/10/00    gth : Created.                                                                 *
 *=============================================================================================*/
void StaticPhysClass::Set_Transform(const Matrix3D & m)
{
	// Note: this kind of object never collides with others so we
	// can just warp it to the users desired position.  However,
	// we do need to tell the scene so that it can update us in 
	// the culling system

	// Note #2: In-Game, these objects should never move!!! this
	// feature is used in the editor.  Moving one of these will
	// invalidate some or all of the nice pre-calculated lighting 
	// and culling data!

	assert(Model);
	Model->Set_Transform(m);
	Update_Cull_Box();
	Invalidate_Static_Lighting_Cache();

	// if our model is a mesh and its in world space, enable the world-space-mesh optimizations
	if ((Model->Class_ID() == RenderObjClass::CLASSID_MESH) && (m == Matrix3D::Identity)) {
		Enable_Is_World_Space_Mesh(true);
	} else {
		Enable_Is_World_Space_Mesh(false);
	}
}


/***********************************************************************************************
 * StaticPhysClass::Is_Occluder -- Returns whether this static object is an occluder           *
 *                                                                                             *
 * INPUT:                                                                                      *
 *                                                                                             *
 * OUTPUT:                                                                                     *
 *                                                                                             *
 * WARNINGS:                                                                                   *
 *                                                                                             *
 * HISTORY:                                                                                    *
 *   1/10/00    gth : Created.                                                                 *
 *=============================================================================================*/
int StaticPhysClass::Is_Occluder(void)
{
	StaticPhysDefClass * def = Get_StaticPhysDef();
	
	if ((def != NULL) && (def->IsNonOccluder)) {
		return false;
	} else if (Model) {
		if (Model->Is_Translucent()) {
			return false;
		}
		if (Model->Class_ID() == RenderObjClass::CLASSID_DAZZLE) {
			return false;
		}
	} 
	return true;
}


/***********************************************************************************************
 * StaticPhysClass::Is_Model_Pre_Lit -- determines if the render object is pre-lit             *
 *                                                                                             *
 * INPUT:                                                                                      *
 *                                                                                             *
 * OUTPUT:                                                                                     *
 *                                                                                             *
 * WARNINGS:                                                                                   *
 *                                                                                             *
 * HISTORY:                                                                                    *
 *   4/20/2000  gth : Created.                                                                 *
 *=============================================================================================*/
bool StaticPhysClass::Is_Model_Pre_Lit(void)
{
	// if the model is a light-mapped mesh, we want to exclude it from the static lights
	if (Model->Class_ID() == RenderObjClass::CLASSID_MESH) {
		MeshModelClass * mesh_model = ((MeshClass *)Model)->Get_Model();
		WWASSERT(mesh_model != NULL);
		if (mesh_model) {
			bool isprelit = (mesh_model->Get_Flag(MeshModelClass::PRELIT_MASK) != 0);
			mesh_model->Release_Ref();
			return isprelit;
		}
	} else if (Model->Class_ID() == RenderObjClass::CLASSID_RENEGADE_TERRAIN) {
		//return ((RenegadeTerrainPatchClass *)Model)->Is_Prelit ();
	}

	return false;
}

bool StaticPhysClass::Is_Model_User_Lit(void)
{
	if (Model != NULL) {
		return !!(Model->Has_User_Lighting());
	}
	return false;
}


/***********************************************************************************************
 * StaticPhysClass::Is_Vis_Sector -- Is_Vis_Sector                                             *
 *                                                                                             *
 *    Searches the model to determine whether it defines a vis sector.  I.e. any of its polys  *
 *    are marked as VIS polys                                                                  *
 *                                                                                             *
 * INPUT:                                                                                      *
 *    model - typically leave the default of NULL, this function will be called recursively    *
 *            on sub-objects                                                                   *
 *                                                                                             *
 * OUTPUT:                                                                                     *
 *                                                                                             *
 * WARNINGS:                                                                                   *
 *                                                                                             *
 * HISTORY:                                                                                    *
 *   6/5/2000   gth : Created.                                                                 *
 *=============================================================================================*/
bool StaticPhysClass::Is_Vis_Sector(RenderObjClass * model) const
{
	bool retval = false;

	/*
	** If NULL was passed in, start with the render object for this StaticPhysClass.
	*/
	if (model == NULL) {
		model = Model;
	}


	/*
	** If we have a valid model to check; either recurse into its sub objects or 
	** check if it is a vis-collideable mesh
	*/
	if (model != NULL) {

		/*
		** Check each sub-object
		*/
		int count = model->Get_Num_Sub_Objects ();
		for (int index = 0; (index < count) && !retval; index ++) {
			
			RenderObjClass *sub_object = model->Get_Sub_Object (index);
			if (sub_object != NULL) {
				retval |= Is_Vis_Sector(sub_object);
				REF_PTR_RELEASE(sub_object);
			}
		}	

		/*
		** Check the model itself
		*/
		if ((model->Class_ID () == RenderObjClass::CLASSID_MESH) &&
			 (model->Get_Collision_Type () & COLLISION_TYPE_VIS))
		{
			retval = true;
		}
	}

	return retval;	
}


/***********************************************************************************************
 * StaticPhysClass::Update_Sun_Status -- determine if this object is in the sun                *
 *                                                                                             *
 * This updates the internal IS_IN_THE_SUN flag.                                               *
 *                                                                                             *
 * INPUT:                                                                                      *
 *                                                                                             *
 * OUTPUT:                                                                                     *
 *                                                                                             *
 * WARNINGS:                                                                                   *
 *                                                                                             *
 * HISTORY:                                                                                    *
 *   9/24/2000  gth : Created.                                                                 *
 *=============================================================================================*/
void StaticPhysClass::Update_Sun_Status(void)
{
	/*
	** Cant do sun occlusion very well for static objects... 
	** Just let the sun always apply?  
	*/
	Set_Flag(IS_IN_THE_SUN,true);
}


/***********************************************************************************************
 * StaticPhysClass::Get_Factory -- Returns the persist factory for StaticPhysClass             *
 *                                                                                             *
 *    All persistant object types need a persist factory which ties them to a unique chunk ID  *
 *    and links them into the save-load system                                                 *
 *                                                                                             *
 * INPUT:                                                                                      *
 *                                                                                             *
 * OUTPUT:                                                                                     *
 *                                                                                             *
 * WARNINGS:                                                                                   *
 *                                                                                             *
 * HISTORY:                                                                                    *
 *   1/10/00    gth : Created.                                                                 *
 *=============================================================================================*/
const PersistFactoryClass & StaticPhysClass::Get_Factory(void) const
{
	return _StaticPhysFactory;
}


/***********************************************************************************************
 * StaticPhysClass::Save -- Save method, persistant object support                             *
 *                                                                                             *
 * INPUT:                                                                                      *
 *                                                                                             *
 * OUTPUT:                                                                                     *
 *                                                                                             *
 * WARNINGS:                                                                                   *
 *                                                                                             *
 * HISTORY:                                                                                    *
 *   1/10/00    gth : Created.                                                                 *
 *=============================================================================================*/
bool StaticPhysClass::Save(ChunkSaveClass &csave)
{
	csave.Begin_Chunk(STATICPHYS_CHUNK_PHYS);
	PhysClass::Save(csave);
	csave.End_Chunk();

	csave.Begin_Chunk(STATICPHYS_CHUNK_VARIABLES);
	WRITE_MICRO_CHUNK(csave,STATICPHYS_VARIABLE_VISOBJECTID,VisObjectID);
	WRITE_MICRO_CHUNK(csave,STATICPHYS_VARIABLE_VISSECTORID,VisSectorID);
	csave.End_Chunk();

	return true;
}


/***********************************************************************************************
 * StaticPhysClass::Load -- Load method, persistant object support                             *
 *                                                                                             *
 * INPUT:                                                                                      *
 *                                                                                             *
 * OUTPUT:                                                                                     *
 *                                                                                             *
 * WARNINGS:                                                                                   *
 *                                                                                             *
 * HISTORY:                                                                                    *
 *   1/10/00    gth : Created.                                                                 *
 *=============================================================================================*/
bool StaticPhysClass::Load(ChunkLoadClass &cload)
{
	while (cload.Open_Chunk()) {
		
		switch(cload.Cur_Chunk_ID()) 
		{
			case STATICPHYS_CHUNK_PHYS:
				PhysClass::Load(cload);
				break;

			case STATICPHYS_CHUNK_VARIABLES:
				while (cload.Open_Micro_Chunk()) {
					switch(cload.Cur_Micro_Chunk_ID()) {
						READ_MICRO_CHUNK(cload,STATICPHYS_VARIABLE_VISOBJECTID,VisObjectID);
						READ_MICRO_CHUNK(cload,STATICPHYS_VARIABLE_VISSECTORID,VisSectorID);
					}
					cload.Close_Micro_Chunk();
				}
				break;

			default:
				WWDEBUG_SAY(("Unhandled Chunk: 0x%X File: %s Line: %d\r\n",cload.Cur_Chunk_ID(),__FILE__,__LINE__));
				break;
		}
		
		cload.Close_Chunk();
	}

	SaveLoadSystemClass::Register_Post_Load_Callback(this);
	return true;
}


/***********************************************************************************************
 * StaticPhysClass::On_Post_Load -- Post-Load callback                                         *
 *                                                                                             *
 * INPUT:                                                                                      *
 *                                                                                             *
 * OUTPUT:                                                                                     *
 *                                                                                             *
 * WARNINGS:                                                                                   *
 *                                                                                             *
 * HISTORY:                                                                                    *
 *   1/10/00    gth : Created.                                                                 *
 *=============================================================================================*/
void StaticPhysClass::On_Post_Load(void)
{
	PhysClass::On_Post_Load();
	WWASSERT(Model);
	if (Model) {

		// Set our cull box but don't let the culling system re-insert us.
		Set_Cull_Box(Model->Get_Bounding_Box(),true);

		// If this is a light-mapped mesh, exclude ourselves from the static lights
		Update_Cached_Model_Parameters();

		// If this is a particle emitter, start it emitting
		if (Model->Class_ID () == RenderObjClass::CLASSID_PARTICLEEMITTER) {
			((ParticleEmitterClass *)Model)->Start ();
		}
	}
}


float	StaticPhysClass::Compute_Vis_Mesh_Ram(RenderObjClass * model)
{
	float total = 0.0f;

	if (model == NULL) {
		model = Model;
	}

	if (model != NULL) {
		if (model->Class_ID() == RenderObjClass::CLASSID_MESH) {

			if (model->Get_Collision_Type() & COLLISION_TYPE_VIS) {
				MeshModelClass * mdl = ((MeshClass *)model)->Get_Model();
				if (mdl != NULL) {
					total += sizeof(MeshClass) + sizeof(MeshModelClass);
					total += sizeof(Vector3) * mdl->Get_Vertex_Count();
					total += sizeof(TriIndex) * mdl->Get_Polygon_Count();
					total += sizeof(PlaneClass) * mdl->Get_Polygon_Count();
					mdl->Release_Ref();
				}
			}

		} else {
			for (int i=0; i<model->Get_Num_Sub_Objects(); i++) {
				RenderObjClass * sub_obj = model->Get_Sub_Object(i);
				if (sub_obj != NULL) {
					total += Compute_Vis_Mesh_Ram(sub_obj);
					REF_PTR_RELEASE(sub_obj);
				}
			}
		}
	}

	return total;
}


/**************************************************************************************
**
** StaticPhysDefClass Implementation
**
**************************************************************************************/

/*
** Persist factory for StaticPhysDefClass's
*/
SimplePersistFactoryClass<StaticPhysDefClass,PHYSICS_CHUNKID_STATICPHYSDEF>	_StaticPhysDefFactory;

/*
** Definition factory for StaticPhysDefClass.  This makes it show up in the editor
*/
DECLARE_DEFINITION_FACTORY(StaticPhysDefClass, CLASSID_STATICPHYSDEF, "StaticPhys") _StaticPhysDefDefFactory;

/*
** Chunk ID's used by StaticPhysDefClass
*/
enum 
{
	STATICPHYSDEF_CHUNK_PHYSDEF						= 0x01070002,			// (parent class)
	STATICPHYSDEF_CHUNK_VARIABLES,

	STATICPHYSDEF_VARIABLE_ISNONOCCLUDER			= 0,
};


StaticPhysDefClass::StaticPhysDefClass(void) :
	IsNonOccluder(true)
{
	EDITABLE_PARAM(StaticPhysDefClass, ParameterClass::TYPE_BOOL, IsNonOccluder);
}

uint32 StaticPhysDefClass::Get_Class_ID (void) const
{
	return CLASSID_STATICPHYSDEF; 
}

PersistClass * StaticPhysDefClass::Create(void) const
{
	StaticPhysClass * new_obj = NEW_REF(StaticPhysClass,());
	new_obj->Init(*this);
	return new_obj;
}

const char * StaticPhysDefClass::Get_Type_Name(void)
{ 
	return "StaticPhysDef"; 
}

bool StaticPhysDefClass::Is_Type(const char * type_name)
{
	if (stricmp(type_name,StaticPhysDefClass::Get_Type_Name()) == 0) {
		return true;
	} else {
		return PhysDefClass::Is_Type(type_name);
	}
}

const PersistFactoryClass & StaticPhysDefClass::Get_Factory (void) const
{
	return _StaticPhysDefFactory;
}

bool StaticPhysDefClass::Save(ChunkSaveClass &csave)
{
	csave.Begin_Chunk(STATICPHYSDEF_CHUNK_PHYSDEF);
	PhysDefClass::Save(csave);
	csave.End_Chunk();

	csave.Begin_Chunk(STATICPHYSDEF_CHUNK_VARIABLES);
	WRITE_MICRO_CHUNK(csave,STATICPHYSDEF_VARIABLE_ISNONOCCLUDER,IsNonOccluder);	
	csave.End_Chunk();
	return true;
}

bool StaticPhysDefClass::Load(ChunkLoadClass &cload)
{
	while (cload.Open_Chunk()) {

		switch(cload.Cur_Chunk_ID()) {

			case STATICPHYSDEF_CHUNK_PHYSDEF:
				PhysDefClass::Load(cload);
				break;

			case STATICPHYSDEF_CHUNK_VARIABLES:				
				while (cload.Open_Micro_Chunk()) {
					switch(cload.Cur_Micro_Chunk_ID()) {
						READ_MICRO_CHUNK(cload,STATICPHYSDEF_VARIABLE_ISNONOCCLUDER,IsNonOccluder);	
					}
					cload.Close_Micro_Chunk();	
				}
				break;

			default:
				WWDEBUG_SAY(("Unhandled Chunk: 0x%X File: %s Line: %d\r\n",cload.Cur_Chunk_ID(),__FILE__,__LINE__));
				break;
		}

		cload.Close_Chunk();
	}
	return true;
}
