Files
firestorm/Gameleap/code/mw4/Libraries/gosFX/EffectCloud.cpp
T
Cyd 2b8ca921cb Initial full mirror of c:\VWE (source + assets + toolchain + outputs) via Git LFS
Complete disaster-recovery snapshot: engine/game source, game data assets,
VC6 toolchain + DX SDKs, build outputs, deployed game, and _UNUSED archive.
Large binaries in Git LFS; text preserved byte-for-byte (core.autocrlf=false,
no eol attributes). See RECOVERY.md for the one-clone rebuild procedure.
2026-06-24 21:28:16 -05:00

402 lines
10 KiB
C++

#include "gosFXHeaders.hpp"
//==========================================================================//
// File: gosFX_EffectCloud.cpp //
// Project: gosFX //
// Contents: Base gosFX::EffectCloud Component //
//--------------------------------------------------------------------------//
// Date Who Modification //
// 09/28/98 JTR Created //
// //
//--------------------------------------------------------------------------//
// Copyright (C) 1997-1998, Virtual World Entertainment, Inc. //
// All Rights reserved worldwide //
// This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL //
//==========================================================================//
//------------------------------------------------------------------------------
//
gosFX::EffectCloud__Specification::EffectCloud__Specification(
Stuff::MemoryStream *stream,
int gfx_version
):
SpinningCloud__Specification(gosFX::EffectCloudClassID, stream, gfx_version)
{
Check_Pointer(this);
Check_Object(stream);
Verify(m_class == EffectCloudClassID);
m_totalParticleSize = gosFX::EffectCloud::ParticleSize;
m_particleClassSize = sizeof(gosFX::EffectCloud::Particle);
if (gfx_version >= 21)
{
Stuff::MString name;
*stream >> name;
Check_Object(EffectLibrary::Instance);
int id = EffectLibrary::Instance->Find(name);
Verify(id >= 0);
m_particleEffectID = id;
}
else
*stream >> m_particleEffectID;
}
//------------------------------------------------------------------------------
//
gosFX::EffectCloud__Specification::EffectCloud__Specification():
SpinningCloud__Specification(gosFX::EffectCloudClassID)
{
Check_Pointer(this);
m_totalParticleSize = gosFX::EffectCloud::ParticleSize;
m_particleClassSize = sizeof(gosFX::EffectCloud::Particle);
}
//------------------------------------------------------------------------------
//
gosFX::EffectCloud__Specification::~EffectCloud__Specification()
{
Check_Object(this);
}
//------------------------------------------------------------------------------
//
gosFX::EffectCloud__Specification*
gosFX::EffectCloud__Specification::Make(
Stuff::MemoryStream *stream,
int gfx_version
)
{
Check_Object(stream);
gos_PushCurrentHeap(Heap);
EffectCloud__Specification *spec =
new gosFX::EffectCloud__Specification(stream, gfx_version);
gos_PopCurrentHeap();
return spec;
}
//------------------------------------------------------------------------------
//
void
gosFX::EffectCloud__Specification::Save(Stuff::MemoryStream *stream)
{
Check_Object(this);
Check_Object(stream);
BaseClass::Save(stream);
Check_Object(EffectLibrary::Instance);
Effect::Specification *effect = EffectLibrary::Instance->Find(m_particleEffectID);
Check_Object(effect);
*stream << effect->m_name;
}
//------------------------------------------------------------------------------
//
void
gosFX::EffectCloud__Specification::Copy(EffectCloud__Specification *spec)
{
Check_Object(this);
Check_Object(spec);
BaseClass::Copy(spec);
m_particleEffectID = spec->m_particleEffectID;
}
//############################################################################
//############################## gosFX::EffectCloud ################################
//############################################################################
gosFX::EffectCloud::ClassData*
gosFX::EffectCloud::DefaultData = NULL;
//------------------------------------------------------------------------------
//
void
gosFX::EffectCloud::InitializeClass()
{
Verify(!DefaultData);
DefaultData =
new ClassData(
EffectCloudClassID,
"gosFX::EffectCloud",
BaseClass::DefaultData,
(Effect::Factory)&Make,
(Specification::Factory)&Specification::Make
);
Check_Object(DefaultData);
}
//------------------------------------------------------------------------------
//
void
gosFX::EffectCloud::TerminateClass()
{
Check_Object(DefaultData);
delete DefaultData;
DefaultData = NULL;
}
//------------------------------------------------------------------------------
//
gosFX::EffectCloud::EffectCloud(
Specification *spec,
unsigned flags
):
SpinningCloud(DefaultData, spec, flags)
{
Check_Object(spec);
}
//------------------------------------------------------------------------------
//
gosFX::EffectCloud::~EffectCloud()
{
if (m_activeParticleCount)
{
for (int i=0; i < m_activeParticleCount; i++)
{
Particle *particle = GetParticle(i);
Check_Object(particle);
if (particle->m_effect)
{
Check_Object(particle->m_effect);
delete particle->m_effect;
particle->m_effect = NULL;
}
}
}
}
//------------------------------------------------------------------------------
//
gosFX::EffectCloud*
gosFX::EffectCloud::Make(
Specification *spec,
unsigned flags
)
{
Check_Object(spec);
gos_PushCurrentHeap(Heap);
EffectCloud *cloud = new gosFX::EffectCloud(spec, flags);
gos_PopCurrentHeap();
return cloud;
}
//------------------------------------------------------------------------------
//
void
gosFX::EffectCloud::CreateNewParticle(
unsigned index,
Stuff::Point3D *translation
)
{
Check_Object(this);
//
//---------------------------
// Let our parent do creation
//---------------------------
//
BaseClass::CreateNewParticle(index, translation);
//
//----------------------------------------
// Now create a new effect under ourselves
//----------------------------------------
//
Specification *spec = GetSpecification();
Check_Object(spec);
Particle *particle = GetParticle(index);
Check_Object(particle);
particle->m_effect =
EffectLibrary::Instance->MakeEffect(
spec->m_particleEffectID,
ExecuteFlag|DynamicWorldSpaceSimulationMode
);
Effect *effect = particle->m_effect;
Check_Object(effect);
particle->m_radius = 0.0f;
//
//-------------------------------------------------------------
// Set the transform on the effect, then start the child effect
//-------------------------------------------------------------
//
effect->m_localToParent.BuildTranslation(particle->m_localTranslation);
effect->m_localToParent.BuildRotation(particle->m_localRotation);
ExecuteInfo
local_info(
m_lastRan,
&m_localToWorld,
NULL,
particle->m_seed
);
local_info.m_age = particle->m_age;
local_info.m_ageRate = particle->m_ageRate;
effect->Start(&local_info);
}
//------------------------------------------------------------------------------
//
bool
gosFX::EffectCloud::AnimateParticle(
unsigned index,
const Stuff::LinearMatrix4D *world_to_new_local,
Stuff::Time till
)
{
Check_Object(this);
PARTICLE_LOGIC("Effect");
//
//--------------------------------------------------------------------
// Make sure that we don't blow the age counters out of the base cloud
// effects
//--------------------------------------------------------------------
//
Particle *particle = GetParticle(index);
Check_Object(particle);
if (particle->m_age >= 1.0f)
particle->m_age = 1.0f - Stuff::SMALL;
BaseClass::AnimateParticle(index, world_to_new_local, till);
//
//---------------------------------
// Update the location of the cloud
//---------------------------------
//
Effect *effect = particle->m_effect;
Check_Object(effect);
effect->m_localToParent.BuildTranslation(particle->m_localTranslation);
effect->m_localToParent.BuildRotation(particle->m_localRotation);
//
//-----------------------
// Execute all the effect
//-----------------------
//
Stuff::OBB bounds;
ExecuteInfo
info(
till,
&m_localToWorld,
&bounds
);
if (effect->Execute(&info))
{
Stuff::Point3D center(bounds.localToParent);
particle->m_radius = center.GetLength() + bounds.sphereRadius + Stuff::SMALL;
return true;
}
particle->m_radius = 0.0f;
delete particle->m_effect;
particle->m_effect = NULL;
return false;
}
//------------------------------------------------------------------------------
//
void gosFX::EffectCloud::DestroyParticle(unsigned index)
{
Check_Object(this);
Particle *particle = GetParticle(index);
Check_Object(particle);
if (particle->m_effect)
{
Check_Object(particle->m_effect);
delete particle->m_effect;
particle->m_effect = NULL;
}
BaseClass::DestroyParticle(index);
}
//------------------------------------------------------------------------------
//
void gosFX::EffectCloud::Stop()
{
Check_Object(this);
//
//---------------------
// Stop ourselves first
//---------------------
//
BaseClass::Stop();
//
//---------------------------------------
// If we have active particles, stop them
//---------------------------------------
//
if (m_activeParticleCount)
{
for (int i=0; i < m_activeParticleCount; i++)
{
Particle *particle = GetParticle(i);
Check_Object(particle);
if (particle->m_age < 1.0f)
{
if (particle->m_effect)
{
Check_Object(particle->m_effect);
particle->m_effect->Stop();
}
}
}
}
}
//------------------------------------------------------------------------------
//
void gosFX::EffectCloud::Draw(DrawInfo *info)
{
Check_Object(this);
Check_Object(info);
GFX_RENDER("EffectCloud");
//
//---------------------------------------------------------
// If we have active particles, set up the draw information
//---------------------------------------------------------
//
if (m_activeParticleCount)
{
for (int i=0; i < m_activeParticleCount; i++)
{
Particle *particle = GetParticle(i);
Check_Object(particle);
//
//-----------------------------------------------------------------
// If the particle is still alive, concatenate into world space and
// issue the draw command
//-----------------------------------------------------------------
//
if (particle->m_age < 1.0f)
{
if (particle->m_effect)
{
Check_Object(particle->m_effect);
particle->m_effect->Draw(info);
}
}
}
}
BaseClass::Draw(info);
}
//------------------------------------------------------------------------------
//
void
gosFX::EffectCloud::TestInstance() const
{
Verify(IsDerivedFrom(DefaultData));
}