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.
402 lines
10 KiB
C++
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));
|
|
}
|