| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804 |
- /*
- ** 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/phys.cpp $*
- * *
- * Author:: Greg Hjelstrom *
- * *
- * $Modtime:: 2/21/02 4:01p $*
- * *
- * $Revision:: 79 $*
- * *
- *---------------------------------------------------------------------------------------------*
- * Functions: *
- * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- #include "phys.h"
- #include "colmathaabox.h"
- #include "rendobj.h"
- #include "rinfo.h"
- #include "assetmgr.h"
- #include "ww3d.h"
- #include "wwdebug.h"
- #include "pscene.h"
- #include "cullsys.h"
- #include "chunkio.h"
- #include "saveload.h"
- #include "persistfactory.h"
- #include "physcoltest.h"
- #include "lightenvironment.h"
- #include "umbrasupport.h"
- #if (UMBRASUPPORT)
- #include <umbra.hpp>
- #endif
- #include "dx8wrapper.h"
- #include "dx8vertexbuffer.h"
- #include "dx8indexbuffer.h"
- const float DEBUG_RENDER_DIST2 = (50.0f*50.0f);
- const float SUN_CHECK_DISTANCE = 50.0f; //If a ray this long doesn't intersect, you can see the sun...
- /*
- ** create_render_obj_from_filename
- */
- RenderObjClass * create_render_obj_from_filename( const char * filename )
- {
- StringClass render_obj_name(filename,true);
- if ( ::strchr( filename, '\\' ) != 0 ) {
- render_obj_name = ::strrchr( filename, '\\' ) + 1;
- }
- render_obj_name.Erase( render_obj_name.Get_Length() - 4, 4 );
- RenderObjClass *model = WW3DAssetManager::Get_Instance()->Create_Render_Obj( render_obj_name );
- if ( model == NULL ) {
- WWDEBUG_SAY(("Failed to create %s from %s\n", (const char *)render_obj_name, filename));
- }
- return model;
- }
- /***********************************************************************************************
- **
- ** PhysClass Implementation
- **
- ***********************************************************************************************/
- /*
- ** Chunk ID's used by PhysClass
- */
- enum
- {
- PHYS_CHUNK_VARIABLES = 0x00660055,
- PHYS_CHUNK_MODEL,
- PHYS_VARIABLE_CULLABLE_PTR = 0x00,
- PHYS_VARIABLE_WIDGETUSER_PTR,
- PHYS_VARIABLE_EDITABLE_PTR,
- PHYS_VARIABLE_FLAGS,
- PHYS_VARIABLE_NAME,
- PHYS_VARIABLE_OBSERVER,
- PHYS_VARIABLE_DEFID,
- PHYS_VARIABLE_INSTANCEID,
- };
- PhysClass::PhysClass(void) :
- Flags(DEFAULT_FLAGS),
- Model(NULL),
- Observer(NULL),
- Definition(NULL),
- InstanceID(0),
- VisObjectID(0),
- LastVisibleFrame(0), // JANI TEMP TEST
- SunStatusLastUpdated(0),
- StaticLightingCache(NULL)
- #if (UMBRASUPPORT)
- ,UmbraObject(NULL)
- #endif
- {
- #if (UMBRASUPPORT)
- UmbraObject = new Umbra::Object(UmbraSupport::Peek_Dummy_Sphere());
- UmbraObject->setUserPointer(this);
- UmbraSupport::Install_Umbra_Object(this);
- #endif
- }
- PhysClass::~PhysClass(void)
- {
- if (Model) {
- Model->Release_Ref();
- Model = NULL;
- }
- if (StaticLightingCache) {
- delete StaticLightingCache;
- }
- #if (UMBRASUPPORT)
- if (UmbraObject) {
- UmbraSupport::Remove_Umbra_Object(this);
- UmbraObject->release();
- UmbraObject = NULL;
- }
- #endif
- }
- void PhysClass::Init(const PhysDefClass & def)
- {
- Definition = &def;
- Flags = DEFAULT_FLAGS;
- if (!def.ModelName.Is_Empty()) {
- RenderObjClass * model = NULL;
-
- if (::strchr(def.ModelName, '.') != NULL) {
- model = ::create_render_obj_from_filename(def.ModelName);
- } else {
- model = WW3DAssetManager::Get_Instance()->Create_Render_Obj(def.ModelName);
- }
- if ( model == NULL ) {
- WWDEBUG_SAY(( "*** FATAL ERROR : Failed to create model %s\n", def.ModelName ));
- }
- Set_Model(model);
- REF_PTR_RELEASE(model);
- }
- }
- void PhysClass::Set_Model(RenderObjClass * model)
- {
- PhysicsSceneClass * the_scene = PhysicsSceneClass::Get_Instance();
- bool in_scene = the_scene->Contains(this);
- if (Model) {
- // If we had an old model, copy the transform
- if ( model ) {
- model->Set_Transform( Model->Get_Transform() );
- }
- if (in_scene) Model->Notify_Removed(the_scene);
- Model->Release_Ref();
- }
- Model = model;
- if (Model) {
- Model->Add_Ref();
- if (in_scene) Model->Notify_Added(the_scene);
- }
- if ((Definition != NULL) && (Definition->IsPreLit)) {
- Enable_Is_Pre_Lit(true);
- }
- Invalidate_Static_Lighting_Cache ();
- }
-
- void PhysClass::Set_Model_By_Name(const char * model_type_name)
- {
- RenderObjClass * model = WW3DAssetManager::Get_Instance()->Create_Render_Obj(model_type_name);
- if ( model == NULL ) {
- WWDEBUG_SAY(( "%s failed to load\n", model_type_name ));
- }
- WWASSERT(model); // As above, PhysClasses cannot survive without a model...
- Set_Model(model);
- if (model) {
- model->Release_Ref();
- }
- }
- RenderObjClass * PhysClass::Get_Model(void)
- {
- if (Model) Model->Add_Ref();
- return Model;
- }
- void PhysClass::Set_Name(const char * name)
- {
- Name=name;
- }
- const char * PhysClass::Get_Name(void)
- {
- return Name;
- }
- void PhysClass::Get_Shadow_Blob_Box(AABoxClass * set_obj_space_box)
- {
- WWASSERT(set_obj_space_box != NULL);
- if (set_obj_space_box != NULL) {
- Model->Get_Obj_Space_Bounding_Box(*set_obj_space_box);
- set_obj_space_box->Extent *= 0.75f;
- }
- }
- void PhysClass::Render(RenderInfoClass & rinfo)
- {
- Push_Effects(rinfo);
- if (Model) {
- Model->Render(rinfo);
- }
- Pop_Effects(rinfo);
- }
- void PhysClass::Vis_Render(SpecialRenderInfoClass & rinfo)
- {
- if (Model) {
- Model->Special_Render(rinfo);
- }
- }
- void PhysClass::Invalidate_Static_Lighting_Cache(void)
- {
- Set_Flag(STATIC_LIGHTING_DIRTY,true);
- }
- LightEnvironmentClass * PhysClass::Get_Static_Lighting_Environment(void)
- {
- if (Is_Pre_Lit()) {
-
- /*
- ** This object doesn't need a lighting cache, make sure it doesn't have one
- */
- if (StaticLightingCache != NULL) {
- WWDEBUG_SAY(("Pre-Lit object %s has a lighting cache!\r\n",Model->Get_Name()));
- delete StaticLightingCache;
- StaticLightingCache = NULL;
- }
-
- } else if (Get_Flag(STATIC_LIGHTING_DIRTY)) {
- /*
- ** First, ensure that we have an allocated lighting cache
- */
- if (StaticLightingCache == NULL) {
- StaticLightingCache = new LightEnvironmentClass;
- }
- /*
- ** Next, update our sunlight status
- */
- Update_Sun_Status();
- /*
- ** Finally, ask the physics scene to re-compute our lighting cache
- */
- PhysicsSceneClass::Get_Instance()->Compute_Static_Lighting( StaticLightingCache,
- Model->Get_Bounding_Sphere().Center,
- Get_Flag(IS_IN_THE_SUN),
- Get_Vis_Object_ID() );
-
- Set_Flag(STATIC_LIGHTING_DIRTY,false);
- }
- /*
- ** Return our lighting cache to the caller
- */
- return StaticLightingCache;
- }
- void PhysClass::Update_Sun_Status(void)
- {
- // Update sun status only four times per second
- unsigned current_time=WW3D::Get_Sync_Time();
- if ((current_time-SunStatusLastUpdated)<250) return;
- SunStatusLastUpdated=current_time;
- PhysicsSceneClass * scene = PhysicsSceneClass::Get_Instance();
-
- Vector3 sunlight;
- scene->Get_Sun_Light_Vector(&sunlight);
- Vector3 center = Model->Get_Bounding_Sphere().Center;
- #pragma message ("(gth) Need a collision group for sun-rays")
- CastResultStruct sunresult;
- LineSegClass sunray(center,center - sunlight * SUN_CHECK_DISTANCE);
- PhysRayCollisionTestClass sunraytest(sunray,&sunresult,0,COLLISION_TYPE_PROJECTILE);
- sunraytest.CheckStaticObjs = true;
- sunraytest.CheckDynamicObjs = false;
- Inc_Ignore_Counter();
- scene->Cast_Ray(sunraytest);
- // if the ray hits a static object which is casting a projected shadow, ignore that object
- // and check again.
- if ( (sunresult.Fraction < 1.0f) &&
- (sunraytest.CollidedPhysObj != NULL) )
- {
- PhysClass * obj = sunraytest.CollidedPhysObj;
- if (obj->Is_Casting_Shadow()) {
- obj->Inc_Ignore_Counter();
- sunresult.Reset();
- scene->Cast_Ray(sunraytest);
- obj->Dec_Ignore_Counter();
- }
- }
- Dec_Ignore_Counter();
- Enable_Is_In_The_Sun(sunresult.Fraction == 1.0f);
- }
- void PhysClass::Push_Effects(RenderInfoClass & rinfo)
- {
- if (!MaterialEffectsOnMe.Is_Empty()) {
- RefMaterialEffectListIterator iterator(&MaterialEffectsOnMe);
- for ( ; !iterator.Is_Done() ; iterator.Next()) {
- iterator.Peek_Obj()->Render_Push(rinfo,this);
- }
- }
- #if 0
- if (!ProjectionsOnMe.Is_Empty()) {
- ShaderClass shader = ShaderClass::_PresetOpaqueShader;
- VertexMaterialClass * vmtl = VertexMaterialClass::Get_Preset(VertexMaterialClass::PRELIT_NODIFFUSE);
-
- DX8Wrapper::Set_Shader(shader);
- DX8Wrapper::Set_Material(vmtl);
- Matrix4 view,proj;
- Matrix4 identity(true);
- DX8Wrapper::Get_Transform(D3DTS_VIEW,view);
- DX8Wrapper::Get_Transform(D3DTS_PROJECTION,proj);
- DX8Wrapper::Set_Transform(D3DTS_WORLD,identity);
- DX8Wrapper::Set_Transform(D3DTS_VIEW,identity);
- DX8Wrapper::Set_Transform(D3DTS_PROJECTION,identity);
-
- TexProjListIterator iterator(&ProjectionsOnMe);
- for ( ; !iterator.Is_Done() ; iterator.Next()) {
- TextureClass * tex = iterator.Peek_Obj()->Peek_Material_Pass()->Peek_Texture(0);
- if (tex != NULL) {
- DX8Wrapper::Set_Texture(0,tex);
- DynamicVBAccessClass vbaccess(BUFFER_TYPE_DYNAMIC_DX8,4);
- {
- DynamicVBAccessClass::WriteLockClass lock(&vbaccess);
- VertexFormatXYZNDUV2 * verts = lock.Get_Formatted_Vertex_Array();
- verts[0].x = -1.0f;
- verts[0].y = 0.8f;
- verts[0].z = 0.0;
- verts[0].u1 = 0.0f;
- verts[0].v1 = 0.0f;
- verts[0].diffuse = 0xFFFFFFFF;
- verts[1].x = -1.0f;
- verts[1].y = 0.3f;
- verts[1].z = 0.0;
- verts[1].u1 = 0.0f;
- verts[1].v1 = 1.0f;
- verts[1].diffuse = 0xFFFFFFFF;
- verts[2].x = -0.5f;
- verts[2].y = 0.3f;
- verts[2].z = 0.0;
- verts[2].u1 = 1.0f;
- verts[2].v1 = 1.0f;
- verts[2].diffuse = 0xFFFFFFFF;
- verts[3].x = -0.5f;
- verts[3].y = 0.8f;
- verts[3].z = 0.0;
- verts[3].u1 = 1.0f;
- verts[3].v1 = 0.0f;
- verts[3].diffuse = 0xFFFFFFFF;
- }
- DynamicIBAccessClass ibaccess(BUFFER_TYPE_DYNAMIC_DX8,2*3);
- {
- DynamicIBAccessClass::WriteLockClass lock(&ibaccess);
- unsigned short * indices = lock.Get_Index_Array();
- indices[0] = 0;
- indices[1] = 1;
- indices[2] = 2;
- indices[3] = 0;
- indices[4] = 2;
- indices[5] = 3;
- }
- DX8Wrapper::Set_Vertex_Buffer(vbaccess);
- DX8Wrapper::Set_Index_Buffer(ibaccess,0);
- DX8Wrapper::Draw_Triangles(0,2,0,4);
- }
- }
- DX8Wrapper::Set_Transform(D3DTS_VIEW,view);
- DX8Wrapper::Set_Transform(D3DTS_PROJECTION,proj);
- REF_PTR_RELEASE(vmtl);
- }
- #endif
- }
- void PhysClass::Pop_Effects(RenderInfoClass & rinfo)
- {
- if (!MaterialEffectsOnMe.Is_Empty()) {
- RefMaterialEffectListIterator iterator(&MaterialEffectsOnMe);
-
- while (!iterator.Is_Done()) {
- MaterialEffectClass * effect = iterator.Peek_Obj();
- effect->Render_Pop(rinfo);
- if (effect->Is_Auto_Remove_Enabled()) {
- iterator.Remove_Current_Object();
- } else {
- iterator.Next();
- }
- }
- }
- }
- bool PhysClass::Save (ChunkSaveClass &csave)
- {
- CullableClass * cullable_ptr = (CullableClass *)this;
- WidgetUserClass * widgetuser_ptr = (WidgetUserClass *)this;
- EditableClass * editable_ptr = (EditableClass *)this;
- csave.Begin_Chunk(PHYS_CHUNK_VARIABLES);
- // (gth) not saving observer pointers any more!
- WRITE_MICRO_CHUNK(csave,PHYS_VARIABLE_CULLABLE_PTR,cullable_ptr);
- WRITE_MICRO_CHUNK(csave,PHYS_VARIABLE_WIDGETUSER_PTR,widgetuser_ptr);
- WRITE_MICRO_CHUNK(csave,PHYS_VARIABLE_EDITABLE_PTR,editable_ptr);
- WRITE_MICRO_CHUNK(csave,PHYS_VARIABLE_FLAGS,Flags);
- WRITE_MICRO_CHUNK(csave,PHYS_VARIABLE_INSTANCEID,InstanceID);
- if (Name.Get_Length() > 0) {
- csave.Begin_Micro_Chunk(PHYS_VARIABLE_NAME);
- WWASSERT(Name.Get_Length()+1 < 255);
- csave.Write(Name,Name.Get_Length() + 1);
- csave.End_Micro_Chunk();
- }
- if (Definition != NULL) {
- int defid = Definition->Get_ID();
- WRITE_MICRO_CHUNK(csave,PHYS_VARIABLE_DEFID,defid);
- }
- csave.End_Chunk();
-
- csave.Begin_Chunk(PHYS_CHUNK_MODEL);
- csave.Begin_Chunk(Model->Get_Factory().Chunk_ID());
- Model->Get_Factory().Save(csave,Model);
- csave.End_Chunk();
- csave.End_Chunk();
- return true;
- }
- bool PhysClass::Load (ChunkLoadClass &cload)
- {
- PersistFactoryClass * factory = NULL;
- CullableClass * cullable_ptr = NULL;
- WidgetUserClass * widgetuser_ptr = NULL;
- EditableClass * editable_ptr = NULL;
- int defid = -1;
- char tmpstring[256];
- tmpstring[0] = 0;
- RenderObjClass * render_model = NULL;
- while (cload.Open_Chunk()) {
-
- switch(cload.Cur_Chunk_ID())
- {
- case PHYS_CHUNK_VARIABLES:
- while (cload.Open_Micro_Chunk()) {
- switch(cload.Cur_Micro_Chunk_ID()) {
- // (gth) not saving observer pointers any more!
- READ_MICRO_CHUNK(cload,PHYS_VARIABLE_CULLABLE_PTR,cullable_ptr);
- READ_MICRO_CHUNK(cload,PHYS_VARIABLE_WIDGETUSER_PTR,widgetuser_ptr);
- READ_MICRO_CHUNK(cload,PHYS_VARIABLE_EDITABLE_PTR,editable_ptr);
- READ_MICRO_CHUNK(cload,PHYS_VARIABLE_FLAGS,Flags);
- READ_MICRO_CHUNK(cload,PHYS_VARIABLE_DEFID,defid);
- READ_MICRO_CHUNK(cload,PHYS_VARIABLE_INSTANCEID,InstanceID);
-
- case PHYS_VARIABLE_NAME:
- cload.Read(tmpstring,cload.Cur_Micro_Chunk_Length());
- break;
- }
- cload.Close_Micro_Chunk();
- }
- break;
- case PHYS_CHUNK_MODEL:
- cload.Open_Chunk();
- factory = SaveLoadSystemClass::Find_Persist_Factory(cload.Cur_Chunk_ID());
- WWASSERT(factory != NULL);
- if (factory != NULL) {
- render_model = (RenderObjClass *)factory->Load(cload);
- SET_REF_OWNER(render_model);
- }
- cload.Close_Chunk();
- break;
- default:
- WWDEBUG_SAY(("Unhandled Chunk: 0x%X File: %s Line: %d\r\n",cload.Cur_Chunk_ID(),__FILE__,__LINE__));
- break;
- }
-
- if (cullable_ptr != NULL) {
- SaveLoadSystemClass::Register_Pointer(cullable_ptr,(CullableClass *)this);
- }
- cload.Close_Chunk();
- }
- /*
- ** Set our name
- */
- if (strlen(tmpstring) > 0) {
- Set_Name(tmpstring);
- }
- /*
- ** Set our definition pointer
- */
- if (defid != -1) {
- Definition = (PhysDefClass *)_TheDefinitionMgr.Find_Definition(defid);
- } else {
- Definition = NULL;
- }
- /*
- ** Only install the model after our definition is installed
- */
- Set_Model(render_model);
- REF_PTR_RELEASE(render_model);
- /*
- ** Ask that our Observer pointer is re-mapped
- */
- if (Observer != NULL) {
- REQUEST_POINTER_REMAP((void**)&Observer);
- }
-
- /*
- ** Register all of the multiple-inheritance versions of our this pointer
- */
- if (cullable_ptr != NULL) {
- SaveLoadSystemClass::Register_Pointer(cullable_ptr,(CullableClass *)this);
- }
- if (widgetuser_ptr != NULL) {
- SaveLoadSystemClass::Register_Pointer(widgetuser_ptr,(WidgetUserClass *)this);
- }
- if (editable_ptr != NULL) {
- SaveLoadSystemClass::Register_Pointer(editable_ptr,(EditableClass *)this);
- }
- /*
- ** Mark our static lighting cache dirty
- */
- Invalidate_Static_Lighting_Cache();
- /*
- ** Update our Umbra object
- */
- #if (UMBRASUPPORT)
- UmbraSupport::Update_Umbra_Object(this);
- #endif
- return true;
- }
- #ifdef WWDEBUG
- void PhysClass::Add_Debug_Point(const Vector3 & p,const Vector3 & color)
- {
- if (Is_Debug_Display_Enabled()) {
- PhysicsSceneClass::Get_Instance()->Add_Debug_Point(p,color);
- }
- }
- #endif
- #ifdef WWDEBUG
- void PhysClass::Add_Debug_Vector(const Vector3 & p,const Vector3 & v,const Vector3 & color)
- {
- if (Is_Debug_Display_Enabled() && (v.Length2() > 0.0f)) {
- PhysicsSceneClass::Get_Instance()->Add_Debug_Vector(p,v,color);
- }
- }
- #endif
- #ifdef WWDEBUG
- void PhysClass::Add_Debug_AABox(const AABoxClass & box,const Vector3 & color,float opacity)
- {
- if (Is_Debug_Display_Enabled()) {
- PhysicsSceneClass::Get_Instance()->Add_Debug_AABox(box,color,opacity);
- }
- }
- #endif
- #ifdef WWDEBUG
- void PhysClass::Add_Debug_OBBox(const OBBoxClass & box,const Vector3 & color,float opacity)
- {
- if (Is_Debug_Display_Enabled()) {
- PhysicsSceneClass::Get_Instance()->Add_Debug_OBBox(box,color,opacity);
- }
- }
- #endif
- #ifdef WWDEBUG
- void PhysClass::Add_Debug_Axes(const Matrix3D & transform,const Vector3 & color)
- {
- if (Is_Debug_Display_Enabled()) {
- PhysicsSceneClass::Get_Instance()->Add_Debug_Axes(transform,color);
- }
- }
- #endif
- bool PhysClass::Is_Debug_Display_Enabled(void) const
- {
- PhysicsSceneClass * the_scene = PhysicsSceneClass::Get_Instance();
- Vector3 pos;
- Get_Position(&pos);
- float dist = (pos - the_scene->Get_Last_Camera_Position()).Length2();
- if (dist > DEBUG_RENDER_DIST2) {
- return false;
- }
- if (the_scene) {
- return (((Flags & DEBUGDISPLAY) == DEBUGDISPLAY) || the_scene->Is_Debug_Display_Enabled());
- } else {
- return ((Flags & DEBUGDISPLAY) == DEBUGDISPLAY);
- }
- }
- bool PhysClass::Expire(void)
- {
- ExpirationReactionType result = EXPIRATION_APPROVED;
- if (Observer != NULL) {
- result = Observer->Object_Expired(this);
- }
- if (result == EXPIRATION_APPROVED) {
- PhysicsSceneClass::Get_Instance()->Delayed_Remove_Object(this);
- return true;
- } else {
- return false;
- }
- }
- //
- // TSS added this... not efficient to use if you are also
- // setting position
- //
- void PhysClass::Set_Facing(float new_facing)
- {
- Vector3 pos;
- Get_Position(&pos);
- Matrix3D tm(1);
- tm.Translate(pos);
- tm.Rotate_Z(new_facing);
-
- Set_Transform(tm);
- }
- bool PhysClass::Do_Any_Effects_Suppress_Shadows(void)
- {
- RefMaterialEffectListIterator iterator(&MaterialEffectsOnMe);
- for ( ; !iterator.Is_Done() ; iterator.Next()) {
- if (iterator.Peek_Obj()->Are_Shadows_Suppressed()) {
- return true;
- }
- }
- return false;
- }
- /***********************************************************************************************
- **
- ** PhysDefClass Implementation
- ** This holds the description for a PhysClass. Since PhysClass's aren't concrete, this
- ** definition class isn't either and thus has no persist factory (required by PersistClass)
- ** or create method (required by DefinitionClass)
- **
- ***********************************************************************************************/
- enum
- {
- PHYSDEF_CHUNK_DEFINITION = 0x055ffe07, // parent class data.
- PHYSDEF_CHUNK_VARIABLES, // simple variables
- PHYSDEF_VARIABLE_FLAGS = 0x00,
- PHYSDEF_VARIABLE_MODELNAME,
- PHYSDEF_VARIABLE_ISPRELIT,
- };
- PhysDefClass::PhysDefClass(void) :
- ModelName ("NULL"),
- IsPreLit(false)
- {
- FILENAME_PARAM(PhysDefClass,ModelName, "Westwood 3D Files", ".w3d");
- }
- bool PhysDefClass::Is_Valid_Config (StringClass &message)
- {
- bool retval = true;
- if (ModelName.Is_Empty ()) {
- message += "ModelName is invalid!\n";
- retval = false;
- }
- return retval;
- }
- bool PhysDefClass::Save(ChunkSaveClass &csave)
- {
- csave.Begin_Chunk(PHYSDEF_CHUNK_DEFINITION);
- DefinitionClass::Save(csave);
- csave.End_Chunk();
- csave.Begin_Chunk(PHYSDEF_CHUNK_VARIABLES);
- WRITE_MICRO_CHUNK_WWSTRING(csave,PHYSDEF_VARIABLE_MODELNAME,ModelName);
- WRITE_MICRO_CHUNK(csave,PHYSDEF_VARIABLE_ISPRELIT,IsPreLit);
- csave.End_Chunk();
- return true;
- }
- bool PhysDefClass::Load(ChunkLoadClass &cload)
- {
- while (cload.Open_Chunk()) {
- switch(cload.Cur_Chunk_ID()) {
- case PHYSDEF_CHUNK_DEFINITION:
- DefinitionClass::Load(cload);
- break;
- case PHYSDEF_CHUNK_VARIABLES:
- WWASSERT(cload.Cur_Chunk_ID() == PHYSDEF_CHUNK_VARIABLES);
- while (cload.Open_Micro_Chunk()) {
- switch(cload.Cur_Micro_Chunk_ID()) {
- OBSOLETE_MICRO_CHUNK(PHYSDEF_VARIABLE_FLAGS);
- READ_MICRO_CHUNK_WWSTRING(cload,PHYSDEF_VARIABLE_MODELNAME,ModelName);
- READ_MICRO_CHUNK(cload,PHYSDEF_VARIABLE_ISPRELIT,IsPreLit);
- }
- cload.Close_Micro_Chunk();
- }
- break;
- }
- cload.Close_Chunk();
- }
- return true;
- }
- bool PhysDefClass::Is_Type(const char * type_name)
- {
- if (stricmp(type_name,PhysDefClass::Get_Type_Name()) == 0) {
- return true;
- } else {
- return false;
- }
- }
|