Files
firestorm/Gameleap/code/mw4/Libraries/Adept/BeamComponent.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

387 lines
9.1 KiB
C++

#include "AdeptHeaders.hpp"
#include "VideoHeaders.hpp"
#include <ElementRenderer\gosFXElement.hpp>
#include <gosFX\EffectLibrary.hpp>
#include <gosFX\Beam.hpp>
#include "Entity.hpp"
#include "Attribute.hpp"
//############################################################################
//########################### BeamComponent ################################
//############################################################################
//
// Class Data Support
//
Component::ClassData*
BeamComponent::DefaultData = NULL;
static DWORD
Beam_Effect_Count;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
BeamComponent::InitializeClass()
{
Verify(!DefaultData);
DefaultData =
new ClassData(
BeamComponentClassID,
"Adept::BeamComponent",
BaseClass::DefaultData,
0,
NULL
);
Register_Object(DefaultData);
Beam_Effect_Count = 0;
#if !defined(NO_STATS)
AddStatistic("Beam Effects Executed", "effects", gos_DWORD, &Beam_Effect_Count, Stat_AutoReset);
#endif
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
BeamComponent::TerminateClass()
{
Unregister_Object(DefaultData);
delete DefaultData;
DefaultData = NULL;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
BeamComponent::BeamComponent(
ClassData *class_data,
MemoryStream *stream,
VideoComponentWeb *owning_web
):
VideoComponent(
class_data,
stream,
owning_web,
ReadFX(stream, owning_web)
)
{
Check_Object(this);
ElementRenderer::gosFXElement *effect = GetElement();
Check_Object(effect);
gosFX::Effect *gos_effect = effect->GetEffect();
Check_Object(gos_effect);
//
//------------------------------------------------------
// Read the attribute id and find it in the web's entity
//------------------------------------------------------
//
int attribute_id;
*stream >> attribute_id;
owningEntity = owning_web->GetEntity();
Check_Object(owningEntity);
if (attribute_id != -1)
{
statusPointer = owningEntity->GetAttributeEntry(attribute_id);
Check_Object(statusPointer);
Verify(statusPointer->attributeType == BoolClassID);
}
else
{
statusPointer = NULL;
Verify(gos_effect->IsLooped());
Verify(gos_effect->IsExecuted());
}
//
//--------------------------------------------
// Start the effect if its execute flag is set
//--------------------------------------------
//
if (gos_effect->IsExecuted())
{
gosFX::Effect::ExecuteInfo
info(
gos_GetElapsedTime(),
&effect->GetLocalToWorld(),
NULL
);
gos_effect->Start(&info);
if(statusPointer)
{
bool result = true;
statusPointer->SetValue(owningEntity, &result);
}
}
//
//------------------------------------------------------
// Read the attribute id and find it in the web's entity
//------------------------------------------------------
//
*stream >> attribute_id;
Verify(attribute_id != -1);
endPointer = owningEntity->GetAttributeEntry(attribute_id);
Check_Object(endPointer);
Verify(endPointer->attributeType == Point3DClassID);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
ElementRenderer::gosFXElement* BeamComponent::ReadFX(
MemoryStream *stream,
VideoComponentWeb *owning_web
)
{
Check_Object(stream);
Check_Object(owning_web);
//
//----------------------------------------
// Figure out where the end of the beam is
//----------------------------------------
//
int end_id;
*stream >> end_id;
Entity *owning_entity = owning_web->GetEntity();
Check_Object(owning_entity);
Verify(end_id != -1);
AttributeEntry* end_pointer = owning_entity->GetAttributeEntry(end_id);
Check_Object(end_pointer);
Verify(end_pointer->attributeType == Point3DClassID);
Point3D end;
end_pointer->GetValue(owning_entity, &end);
//
//----------------------
// Compute the beam line
//----------------------
//
Line3D beam;
Element *element = owning_entity->GetElement();
Check_Object(element);
beam.m_origin = element->GetNewLocalToParent();
end -= beam.m_origin;
beam.m_length = end.GetLength();
if (beam.m_length>SMALL)
{
Scalar t = 1.0f/beam.m_length;
beam.m_direction.x = end.x * t;
beam.m_direction.y = end.y * t;
beam.m_direction.z = end.z * t;
}
else
{
beam.m_length = 0.0f;
beam.m_direction = UnitVector3D::Forward;
}
Point3D nearest;
beam.GetClosestPointTo(gosFX::Effect::LastCameraPosition, &nearest);
nearest -= gosFX::Effect::LastCameraPosition;
Scalar range = nearest.GetLengthSquared();
//
//---------------------------------------------
// Find the LOD distance we will be looking for
//---------------------------------------------
//
Scalar lod;
*stream >> lod;
int selected_id = -1;
while (lod != -1.0f)
{
int id;
*stream >> id;
if (selected_id == -1 && range > lod)
selected_id = id;
*stream >> lod;
}
//
//---------------------
// Get the gosFX number
//---------------------
//
int gfx_id;
unsigned flags;
*stream >> gfx_id >> flags;
if (selected_id != -1)
gfx_id = selected_id;
Check_Object(gosFX::EffectLibrary::Instance);
gosFX::Effect *gos_effect =
gosFX::EffectLibrary::Instance->MakeEffect(gfx_id, flags);
Register_Object(gos_effect);
gos_PushCurrentHeap(ElementRenderer::gosFXElement::s_Heap);
ElementRenderer::gosFXElement *effect = new ElementRenderer::gosFXElement(gos_effect);
gos_PopCurrentHeap();
Register_Object(effect);
return effect;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
BeamComponent::SkipStreamData(MemoryStream *stream)
{
Check_Object(this);
Check_Object(stream);
int id;
*stream >> id;
Scalar lod;
*stream >> lod;
while (lod != -1.0f)
*stream >> id;
unsigned flags;
*stream >> id >> flags;
BaseClass::SkipStreamData(stream);
*stream >> id >> id;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
BeamComponent*
BeamComponent::Create(
MemoryStream *stream,
VideoComponentWeb *owning_web
)
{
Check_Object(stream);
Check_Object(owning_web);
Component *component = DoesComponentExist(stream, owning_web);
BeamComponent *object;
if (component)
{
object = static_cast<BeamComponent*>(component);
Check_Object(object);
object->SkipStreamData(stream);
}
else
{
object = new BeamComponent(DefaultData, stream, owning_web);
Register_Object(object);
}
return object;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
BeamComponent::Execute()
{
Check_Object(this);
ElementRenderer::gosFXElement *effect = GetElement();
Check_Object(effect);
gosFX::Beam *gos_effect = Cast_Object(gosFX::Beam*, effect->GetEffect());
Check_Object(gos_effect);
Verify(
gos_effect->GetSimulationMode() != gosFX::Effect::DynamicWorldSpaceSimulationMode
|| !effect->IsMatrixDirty()
);
//
//------------------
// Execute the gosFX
//------------------
//
bool result = false;
if (gos_effect->IsExecuted())
{
Set_Statistic(Beam_Effect_Count, Beam_Effect_Count+1);
Point3D end;
endPointer->GetValue(owningEntity, &end);
gosFX::Beam::ExecuteInfo
info(
gos_GetElapsedTime(),
&effect->GetLocalToWorld(),
&end,
&effect->m_localOBB
);
{
Start_Timer(gosFX::Animation_Time);
result = gos_effect->Execute(&info);
Stop_Timer(gosFX::Animation_Time);
}
//
//---------------------------
// Update the bounding sphere
//---------------------------
//
if (result && effect->m_localOBB.sphereRadius > 0.0f)
effect->NeedNewBounds();
else
effect->SetNeverCullMode();
effect->Sync();
}
else
effect->SetAlwaysCullMode();
//
//------------------------------
// Set the status is appropriate
//------------------------------
//
if (statusPointer)
{
Check_Object(statusPointer);
Check_Object(owningEntity);
if(gos_effect->IsLooped())
result = true;
statusPointer->SetValue(owningEntity, &result);
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
BeamComponent::ChannelChanged(Channel *channel)
{
Check_Object(this);
Check_Object(channel);
STOP(("Broken"));
ElementRenderer::gosFXElement *effect = GetElement();
Check_Object(effect);
gosFX::Effect *gos_effect = effect->GetEffect();
Check_Object(gos_effect);
gosFX::Effect::ExecuteInfo
info(
gos_GetElapsedTime(),
&effect->GetLocalToWorld(),
NULL
);
switch (channel->GetCommand())
{
case VideoRenderer::StartEffectCommandID:
// Verify(!gos_effect->InWorldSpace() || !effect->IsMatrixDirty());
gos_effect->Start(&info);
break;
case VideoRenderer::StopEffectCommandID:
gos_effect->Stop();
break;
case VideoRenderer::KillEffectCommandID:
gos_effect->Kill();
break;
default:
BaseClass::ChannelChanged(channel);
break;
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
BeamComponent::TestInstance()
{
Verify(IsDerivedFrom(DefaultData));
}