#include "AdeptHeaders.hpp" #include "VideoHeaders.hpp" #include #include #include #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(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)); }