| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307 |
- /*
- ** 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/stealtheffect.cpp $*
- * *
- * Original Author:: Greg Hjelstrom *
- * *
- * $Author:: Byon_g $*
- * *
- * $Modtime:: 12/20/01 6:32p $*
- * *
- * $Revision:: 12 $*
- * *
- *---------------------------------------------------------------------------------------------*
- * Functions: *
- * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- #include "stealtheffect.h"
- #include "matpass.h"
- #include "vertmaterial.h"
- #include "physresourcemgr.h"
- #include "phys.h"
- #include "rinfo.h"
- #include "camera.h"
- #include "chunkio.h"
- /*************************************************************************************************
- **
- ** StealthEffectClass Implementation
- **
- *************************************************************************************************/
- static float STEALTH_FRACTION_RATE = 0.5f; // rate at which the fraction approaches its target
- static float STEALTH_DEFAULT_FADE_DISTANCE= 25.0f; // distance at which the intensity starts to fade due to camera proximity
- static float STEALTH_ZNEAR_AMOUNT = 0.40f; // amount the intensity can change as it approaches the camera
- static float STEALTH_FRIENDLY_FRACTION = 0.75f; // fraction at which friendly stealthed objects appear
- static float STEALTH_BROKEN_FRACTION = 0.25f; // fraction at which broken stealthed objects appear
- static float STEALTH_DAMAGED_FRACTION = 0.6f; // fraction that is jumped to when an object gets damaged
- static Vector2 MAX_STEALTH_UV_RATE(2.75f,-3.0f);
- static Vector2 MIN_STEALTH_UV_RATE(0.5f,-0.5f);
- StealthEffectClass::StealthEffectClass(void) :
- IsStealthEnabled(false),
- IsFriendly(false),
- IsBroken(false),
- FadeDistance(STEALTH_DEFAULT_FADE_DISTANCE),
- CurrentFraction(0.0f),
- TargetFraction(1.0f),
- UVRate(0.5f,0.5f),
- RenderBaseMaterial(true),
- RenderStealthMaterial(true),
- IntensityScale(0.0f),
- UVOffset(0.0f,0.0f),
- Mapper(NULL),
- MaterialPass(NULL)
- {
- MaterialPass = NEW_REF(MaterialPassClass,());
-
- VertexMaterialClass * vmtl = NEW_REF(VertexMaterialClass,()); //PhysResourceMgrClass::Get_Stealth_Material();
- vmtl->Set_Ambient(0,0,0);
- vmtl->Set_Diffuse(0,0,0);
- vmtl->Set_Specular(0,0,0);
- vmtl->Set_Emissive(1.0f,1.0f,1.0f);
- vmtl->Set_Opacity(1.0f);
- vmtl->Set_Shininess(0.0f);
- vmtl->Set_Lighting(true);
- Mapper = NEW_REF(MatrixMapperClass,(0));
- Mapper->Set_Type(MatrixMapperClass::ORTHO_PROJECTION);
- Mapper->Set_Texture_Transform(Matrix4(1),64.0f);
- vmtl->Set_Mapper(Mapper,0);
- MaterialPass->Set_Material(vmtl);
- REF_PTR_RELEASE(vmtl);
-
- ShaderClass shader = ShaderClass::_PresetAdditiveShader;
- shader.Set_Primary_Gradient(ShaderClass::GRADIENT_ADD);
- MaterialPass->Set_Shader(ShaderClass::_PresetAdditiveShader);
- MaterialPass->Set_Texture(PhysResourceMgrClass::Peek_Stealth_Texture());
- MaterialPass->Enable_On_Translucent_Meshes( false );
- }
- StealthEffectClass::~StealthEffectClass(void)
- {
- REF_PTR_RELEASE(MaterialPass);
- REF_PTR_RELEASE(Mapper);
- }
- void StealthEffectClass::Enable_Stealth(bool onoff)
- {
- IsStealthEnabled = onoff;
- Update_Target_Fraction();
- }
- void StealthEffectClass::Set_Friendly(bool onoff)
- {
- IsFriendly = onoff;
- Update_Target_Fraction();
- }
- void StealthEffectClass::Set_Broken(bool onoff)
- {
- IsBroken = onoff;
- Update_Target_Fraction();
- }
- void StealthEffectClass::Damage_Occured(void)
- {
- if (IsStealthEnabled && (CurrentFraction > STEALTH_DAMAGED_FRACTION)) {
- CurrentFraction = STEALTH_DAMAGED_FRACTION;
- }
- }
- void StealthEffectClass::Update_Target_Fraction(void)
- {
- if (IsStealthEnabled) {
-
- if (IsBroken) {
- TargetFraction = STEALTH_BROKEN_FRACTION;
- } else if (IsFriendly) {
- TargetFraction = STEALTH_FRIENDLY_FRACTION;
- } else {
- TargetFraction = 1.0f;
- }
-
- } else {
- TargetFraction = 0.0f;
- }
- }
- void StealthEffectClass::Timestep(float dt)
- {
- /*
- ** Update the stealth fraction
- */
- float step = STEALTH_FRACTION_RATE * dt;
- if (step > WWMath::Fabs(TargetFraction - CurrentFraction)) {
- CurrentFraction = TargetFraction;
- } else {
- if (TargetFraction < CurrentFraction) {
- CurrentFraction -= step;
- } else {
- CurrentFraction += step;
- }
- }
- /*
- ** The Intensity is computed as a function of the stealth fraction
- */
- IntensityScale = 1.0f - 2.0f * WWMath::Fabs(CurrentFraction - 0.5f);
- /*
- ** Update the uv cycling animation. I'm deriving the UV animation rate
- ** from the intensity
- */
- Vector2 uv_rate = MIN_STEALTH_UV_RATE + IntensityScale * IntensityScale * (MAX_STEALTH_UV_RATE - MIN_STEALTH_UV_RATE);
- UVOffset += uv_rate * dt;
- UVOffset.X = fmod(UVOffset.X , 2.0f);
- UVOffset.Y = fmod(UVOffset.Y , 2.0f);
- /*
- ** The base pass gets rendered when the stealh fraction is < 0.5
- ** shadows are also suppressed.
- */
- RenderBaseMaterial = (CurrentFraction < 0.5f);
- Enable_Suppress_Shadows(CurrentFraction > 0.5f);
- }
- void StealthEffectClass::Render_Push(RenderInfoClass & rinfo,PhysClass * obj)
- {
- /*
- ** If we are in the (0.5,1.0) range of the fraction (object is hidden) then
- ** the distance from the camera to the object can affect the intensity.
- */
- Vector3 obj_pos;
- obj->Get_Position(&obj_pos);
- float xydist = (rinfo.Camera.Get_Position() - obj_pos).Quick_Length();
- if (xydist <= FadeDistance) {
- float intensity_delta = STEALTH_ZNEAR_AMOUNT * (FadeDistance - xydist) / FadeDistance;
- float intensity = WWMath::Min(IntensityScale + intensity_delta, 1.0f);
- IntensityScale = intensity;
- }
- /*
- ** The stealth material gets rendered if the intensity is greater than 0.0
- */
- RenderStealthMaterial = (IntensityScale > 0.0f);
-
- if (RenderStealthMaterial) {
-
- /*
- ** Update the material settings and texture transform
- */
- MaterialPass->Peek_Material()->Set_Emissive(Vector3(1,1,1) * IntensityScale);
-
- Matrix4 tm(1);
- tm[0][3] = UVOffset.X;
- tm[1][3] = UVOffset.Y;
- Mapper->Set_Texture_Transform(tm,64.0f);
- /*
- ** Add the material pass!
- */
- rinfo.Push_Material_Pass(MaterialPass);
- }
-
- if (RenderBaseMaterial == false) {
- rinfo.Push_Override_Flags(RenderInfoClass::RINFO_OVERRIDE_ADDITIONAL_PASSES_ONLY);
- }
- }
- void StealthEffectClass::Render_Pop(RenderInfoClass & rinfo)
- {
- if (RenderBaseMaterial == false) {
- rinfo.Pop_Override_Flags();
- }
- if (RenderStealthMaterial) {
- rinfo.Pop_Material_Pass();
- }
- }
- /************************************************************************************
- **
- ** Save-Load support
- **
- ************************************************************************************/
- enum
- {
- STEALTHEFFECT_CHUNK_VARIABLES = 0x055ffe07, // member variables.
- STEALTHEFFECT_VARIABLE_ISSTEALTHENABLED = 0x00,
- STEALTHEFFECT_VARIABLE_ISFRIENDLY,
- STEALTHEFFECT_VARIABLE_ISBROKEN,
- STEALTHEFFECT_VARIABLE_CURRENTFRACTION,
- STEALTHEFFECT_VARIABLE_TARGETFRACTION,
- STEALTHEFFECT_VARIABLE_UVRATE,
- STEALTHEFFECT_VARIABLE_FADEDISTANCE,
- };
- bool StealthEffectClass::Save(ChunkSaveClass & csave)
- {
- csave.Begin_Chunk(STEALTHEFFECT_CHUNK_VARIABLES);
- WRITE_MICRO_CHUNK(csave,STEALTHEFFECT_VARIABLE_ISSTEALTHENABLED,IsStealthEnabled);
- WRITE_MICRO_CHUNK(csave,STEALTHEFFECT_VARIABLE_ISFRIENDLY,IsFriendly);
- WRITE_MICRO_CHUNK(csave,STEALTHEFFECT_VARIABLE_ISBROKEN,IsBroken);
- WRITE_MICRO_CHUNK(csave,STEALTHEFFECT_VARIABLE_CURRENTFRACTION,CurrentFraction);
- WRITE_MICRO_CHUNK(csave,STEALTHEFFECT_VARIABLE_TARGETFRACTION,TargetFraction);
- WRITE_MICRO_CHUNK(csave,STEALTHEFFECT_VARIABLE_UVRATE,UVRate);
- WRITE_MICRO_CHUNK(csave,STEALTHEFFECT_VARIABLE_FADEDISTANCE,FadeDistance);
- csave.End_Chunk();
- return true;
- }
- bool StealthEffectClass::Load(ChunkLoadClass & cload)
- {
- while (cload.Open_Chunk()) {
- switch(cload.Cur_Chunk_ID()) {
- case STEALTHEFFECT_CHUNK_VARIABLES:
- while (cload.Open_Micro_Chunk()) {
- switch(cload.Cur_Micro_Chunk_ID()) {
- READ_MICRO_CHUNK(cload,STEALTHEFFECT_VARIABLE_ISSTEALTHENABLED,IsStealthEnabled);
- READ_MICRO_CHUNK(cload,STEALTHEFFECT_VARIABLE_ISFRIENDLY,IsFriendly);
- READ_MICRO_CHUNK(cload,STEALTHEFFECT_VARIABLE_ISBROKEN,IsBroken);
- READ_MICRO_CHUNK(cload,STEALTHEFFECT_VARIABLE_CURRENTFRACTION,CurrentFraction);
- READ_MICRO_CHUNK(cload,STEALTHEFFECT_VARIABLE_TARGETFRACTION,TargetFraction);
- READ_MICRO_CHUNK(cload,STEALTHEFFECT_VARIABLE_UVRATE,UVRate);
- READ_MICRO_CHUNK(cload,STEALTHEFFECT_VARIABLE_FADEDISTANCE,FadeDistance);
- }
- cload.Close_Micro_Chunk();
- }
- break;
- }
- cload.Close_Chunk();
- }
- return true;
- }
|