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.
346 lines
9.1 KiB
C++
346 lines
9.1 KiB
C++
#include "gosFXHeaders.hpp"
|
|
|
|
//==========================================================================//
|
|
// File: gosFX_Singleton.cpp //
|
|
// Project: gosFX //
|
|
// Contents: Base gosFX::Singleton 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::Singleton__Specification #############################
|
|
//############################################################################
|
|
|
|
//------------------------------------------------------------------------------
|
|
//
|
|
gosFX::Singleton__Specification::Singleton__Specification(
|
|
Stuff::RegisteredClass::ClassID class_id,
|
|
Stuff::MemoryStream *stream,
|
|
int gfx_version
|
|
):
|
|
Effect__Specification(class_id, stream, gfx_version)
|
|
{
|
|
Check_Pointer(this);
|
|
Check_Object(stream);
|
|
|
|
//
|
|
//-------------------
|
|
// Load in the curves
|
|
//-------------------
|
|
//
|
|
m_red.Load(stream, gfx_version);
|
|
m_green.Load(stream, gfx_version);
|
|
m_blue.Load(stream, gfx_version);
|
|
m_alpha.Load(stream, gfx_version);
|
|
if (gfx_version >= 22)
|
|
m_spin.Load(stream, gfx_version);
|
|
else
|
|
{
|
|
m_spin.m_ageCurve.SetCurve(0.0f);
|
|
m_spin.m_seeded = false;
|
|
m_spin.m_seedCurve.SetCurve(1.0f);
|
|
}
|
|
m_scale.Load(stream, gfx_version);
|
|
if (gfx_version >= 22)
|
|
*stream >> m_randomStartingRotation;
|
|
else
|
|
m_randomStartingRotation = false;
|
|
*stream >> m_alignZUsingX >> m_alignZUsingY;
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
//
|
|
gosFX::Singleton__Specification::Singleton__Specification(
|
|
Stuff::RegisteredClass::ClassID class_id
|
|
):
|
|
Effect__Specification(class_id)
|
|
{
|
|
Check_Pointer(this);
|
|
m_randomStartingRotation = false;
|
|
m_alignZUsingX = false;
|
|
m_alignZUsingY = false;
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
//
|
|
gosFX::Singleton__Specification::~Singleton__Specification()
|
|
{
|
|
Check_Object(this);
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
//
|
|
void
|
|
gosFX::Singleton__Specification::Save(Stuff::MemoryStream *stream)
|
|
{
|
|
Check_Object(this);
|
|
Check_Object(stream);
|
|
BaseClass::Save(stream);
|
|
|
|
//
|
|
//----------------
|
|
// Save our curves
|
|
//----------------
|
|
//
|
|
m_red.Save(stream);
|
|
m_green.Save(stream);
|
|
m_blue.Save(stream);
|
|
m_alpha.Save(stream);
|
|
m_spin.Save(stream);
|
|
m_scale.Save(stream);
|
|
*stream << m_randomStartingRotation << m_alignZUsingX << m_alignZUsingY;
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
//
|
|
void
|
|
gosFX::Singleton__Specification::BuildDefaults()
|
|
{
|
|
|
|
Check_Object(this);
|
|
BaseClass::BuildDefaults();
|
|
|
|
m_red.m_ageCurve.SetCurve(1.0f);
|
|
m_red.m_seeded = false;
|
|
m_red.m_seedCurve.SetCurve(1.0f);
|
|
|
|
m_green.m_ageCurve.SetCurve(1.0f);
|
|
m_green.m_seeded = false;
|
|
m_green.m_seedCurve.SetCurve(1.0f);
|
|
|
|
m_blue.m_ageCurve.SetCurve(1.0f);
|
|
m_blue.m_seeded = false;
|
|
m_blue.m_seedCurve.SetCurve(1.0f);
|
|
|
|
m_alpha.m_ageCurve.SetCurve(1.0f);
|
|
m_alpha.m_seeded = false;
|
|
m_alpha.m_seedCurve.SetCurve(1.0f);
|
|
|
|
m_spin.m_ageCurve.SetCurve(0.0f);
|
|
m_spin.m_seeded = false;
|
|
m_spin.m_seedCurve.SetCurve(1.0f);
|
|
|
|
m_scale.m_ageCurve.SetCurve(1.0f);
|
|
m_scale.m_seeded = false;
|
|
m_scale.m_seedCurve.SetCurve(1.0f);
|
|
|
|
m_randomStartingRotation = false;
|
|
m_alignZUsingX = false;
|
|
m_alignZUsingY = false;
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
//
|
|
bool
|
|
gosFX::Singleton__Specification::IsDataValid(bool fix_data)
|
|
{
|
|
|
|
Check_Object(this);
|
|
Stuff::Scalar min,max;
|
|
m_scale.ExpensiveComputeRange(&min,&max);
|
|
if (min<5.0f*Stuff::SMALL)
|
|
{
|
|
if (fix_data)
|
|
m_scale.SetMinimum(10.0f*Stuff::SMALL);
|
|
else
|
|
return false;
|
|
}
|
|
return BaseClass::IsDataValid(fix_data);
|
|
}
|
|
//------------------------------------------------------------------------------
|
|
//
|
|
void
|
|
gosFX::Singleton__Specification::Copy(Singleton__Specification *spec)
|
|
{
|
|
Check_Object(this);
|
|
Check_Object(spec);
|
|
|
|
BaseClass::Copy(spec);
|
|
|
|
//
|
|
//----------------
|
|
// Copy the curves
|
|
//----------------
|
|
//
|
|
gos_PushCurrentHeap(Heap);
|
|
m_red = spec->m_red;
|
|
m_green = spec->m_green;
|
|
m_blue = spec->m_blue;
|
|
m_alpha = spec->m_alpha;
|
|
m_spin = spec->m_spin;
|
|
m_scale = spec->m_scale;
|
|
m_randomStartingRotation = spec->m_randomStartingRotation;
|
|
m_alignZUsingX = spec->m_alignZUsingX;
|
|
m_alignZUsingY = spec->m_alignZUsingY;
|
|
gos_PopCurrentHeap();
|
|
}
|
|
|
|
//############################################################################
|
|
//############################ gosFX::Singleton ###############################
|
|
//############################################################################
|
|
|
|
gosFX::Singleton::ClassData*
|
|
gosFX::Singleton::DefaultData = NULL;
|
|
|
|
//------------------------------------------------------------------------------
|
|
//
|
|
void
|
|
gosFX::Singleton::InitializeClass()
|
|
{
|
|
Verify(!DefaultData);
|
|
DefaultData =
|
|
new ClassData(
|
|
SingletonClassID,
|
|
"gosFX::Singleton",
|
|
BaseClass::DefaultData,
|
|
NULL,
|
|
NULL
|
|
);
|
|
Check_Object(DefaultData);
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
//
|
|
void
|
|
gosFX::Singleton::TerminateClass()
|
|
{
|
|
Check_Object(DefaultData);
|
|
delete DefaultData;
|
|
DefaultData = NULL;
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
//
|
|
gosFX::Singleton::Singleton(
|
|
ClassData *class_data,
|
|
Specification *spec,
|
|
unsigned flags
|
|
):
|
|
Effect(class_data, spec, flags)
|
|
{
|
|
Check_Pointer(this);
|
|
Check_Object(spec);
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
//
|
|
void
|
|
gosFX::Singleton::TestInstance() const
|
|
{
|
|
Verify(IsDerivedFrom(DefaultData));
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
//
|
|
void
|
|
gosFX::Singleton::Start(ExecuteInfo *info)
|
|
{
|
|
Check_Object(this);
|
|
Check_Pointer(info);
|
|
|
|
BaseClass::Start(info);
|
|
|
|
//
|
|
//---------------------------------
|
|
// Figure out the particle rotation
|
|
//---------------------------------
|
|
//
|
|
Specification *spec = GetSpecification();
|
|
Check_Object(spec);
|
|
m_angularVelocity.x = spec->m_spin.ComputeValue(m_age, m_seed);
|
|
m_angularVelocity.y = spec->m_spin.ComputeValue(m_age, m_seed);
|
|
m_angularVelocity.z = spec->m_spin.ComputeValue(m_age, m_seed);
|
|
|
|
//
|
|
//-----------------------------------------------------
|
|
// If we are aligning with velocity, deal with that now
|
|
//-----------------------------------------------------
|
|
//
|
|
if (spec->m_randomStartingRotation)
|
|
{
|
|
Stuff::EulerAngles
|
|
rotation(
|
|
Stuff::Two_Pi*Stuff::Random::GetFraction(),
|
|
Stuff::Pi*Stuff::Random::GetFraction(),
|
|
Stuff::Two_Pi*Stuff::Random::GetFraction()
|
|
);
|
|
m_localRotation = rotation;
|
|
}
|
|
else
|
|
m_localRotation = Stuff::UnitQuaternion::Identity;
|
|
|
|
//
|
|
//-------------------------
|
|
// Set up the initial scale
|
|
//-------------------------
|
|
//
|
|
m_scale = spec->m_scale.ComputeValue(m_age, m_seed);
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
//
|
|
bool
|
|
gosFX::Singleton::Execute(ExecuteInfo *info)
|
|
{
|
|
Check_Object(this);
|
|
Check_Object(info);
|
|
GFX_LOGIC("Execute::Singleton");
|
|
|
|
if (!IsExecuted())
|
|
return false;
|
|
|
|
//
|
|
//---------------------
|
|
// Animate the rotation
|
|
//---------------------
|
|
//
|
|
Stuff::Scalar time_slice =
|
|
static_cast<Stuff::Scalar>(info->m_time - m_lastRan);
|
|
Stuff::Vector3D omega(m_angularVelocity);
|
|
omega *= time_slice;
|
|
Stuff::UnitQuaternion omega_q;
|
|
omega_q = omega;
|
|
m_localRotation.Multiply(omega_q, Stuff::UnitQuaternion(m_localRotation));
|
|
m_localRotation.Normalize();
|
|
m_localToParent.BuildRotation(m_localRotation);
|
|
|
|
//
|
|
//------------------------
|
|
// Call the base class now
|
|
//------------------------
|
|
//
|
|
if (!BaseClass::Execute(info))
|
|
return false;
|
|
|
|
//
|
|
//-----------------------------------------
|
|
// Animate the parent then get our pointers
|
|
//-----------------------------------------
|
|
//
|
|
Specification *spec = GetSpecification();
|
|
Check_Object(spec);
|
|
|
|
m_scale = spec->m_scale.ComputeValue(m_age, m_seed);
|
|
|
|
//
|
|
//------------------------------
|
|
// Calculate the bounding volume
|
|
//------------------------------
|
|
//
|
|
Stuff::OBB bounds;
|
|
bounds.sphereRadius = m_radius*m_scale;
|
|
if (bounds.sphereRadius < Stuff::SMALL)
|
|
bounds.sphereRadius = 0.01f;
|
|
bounds.localToParent = m_localToParent;
|
|
bounds.axisExtents = Stuff::Vector3D::Identity;
|
|
info->m_bounds->Union(*info->m_bounds, bounds);
|
|
return true;
|
|
}
|