#include "ElementRendererHeaders.hpp" //############################################################################ //############################ LODElement ################################ //############################################################################ HGOSHEAP ElementRenderer::LODElement::s_Heap = NULL; ElementRenderer::LODElement::ClassData* ElementRenderer::LODElement::DefaultData = NULL; ElementRenderer::Element::DrawMethod ElementRenderer::LODElement::DrawMethods[DrawStateCount]= { DRAW_METHOD(LODElement, Inherit), DRAW_METHOD(LODElement, Override) }; Stuff::Scalar ElementRenderer::LODElement::s_Offset = 0.0f; bool ElementRenderer::LODElement::s_ShadeLODs = false; Stuff::RGBAColor ElementRenderer::LODElement::s_Shades[6]={ Stuff::RGBAColor(1.0f, 1.0f, 1.0f, 1.0), Stuff::RGBAColor(1.0f, 0.0f, 0.0f, 1.0), Stuff::RGBAColor(0.0f, 1.0f, 0.0f, 1.0), Stuff::RGBAColor(0.0f, 0.0f, 1.0f, 1.0), Stuff::RGBAColor(1.0f, 1.0f, 0.0f, 1.0), Stuff::RGBAColor(1.0f, 0.0f, 1.0f, 1.0) }; static bool __stdcall Check100m() { return ElementRenderer::LODElement::s_Offset == 625.0f; } static bool __stdcall Check250m() { return ElementRenderer::LODElement::s_Offset == 2500.0f; } static bool __stdcall Check500m() { return ElementRenderer::LODElement::s_Offset == 10000.0f; } static void __stdcall Enable100m() { ElementRenderer::LODElement::s_Offset = (ElementRenderer::LODElement::s_Offset == 625.0f) ? 0.0f : 625.0f; } static void __stdcall Enable250m() { ElementRenderer::LODElement::s_Offset = (ElementRenderer::LODElement::s_Offset == 2500.0f) ? 0.0f : 2500.0f; } static void __stdcall Enable500m() { ElementRenderer::LODElement::s_Offset = (ElementRenderer::LODElement::s_Offset == 10000.0f) ? 0.0f : 10000.0f; } extern DWORD Disable_Lights; static bool __stdcall CheckShadeLODs() {return ElementRenderer::LODElement::s_ShadeLODs;} static void __stdcall EnableShadeLODs() { ElementRenderer::LODElement::s_ShadeLODs = !ElementRenderer::LODElement::s_ShadeLODs; if (ElementRenderer::LODElement::s_ShadeLODs) Disable_Lights = true; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void ElementRenderer::LODElement::InitializeClass(Stuff::NotationFile *startup_ini) { Verify(!s_Heap); s_Heap = gos_CreateMemoryHeap("LOD", 0, g_LibraryHeap); Check_Pointer(s_Heap); Verify(!DefaultData); DefaultData = new ClassData( LODElementClassID, "ElementRenderer::LODElement", BaseClass::DefaultData, reinterpret_cast(&Make) ); Register_Object(DefaultData); AddDebuggerMenuItem("Libraries\\ElementRenderer\\Shade LODs", CheckShadeLODs, EnableShadeLODs, 0 ); AddDebuggerMenuItem("Libraries\\Graphics Options\\+25m Shape LODs", Check100m, Enable100m, 0 ); AddDebuggerMenuItem("Libraries\\Graphics Options\\+50m Shape LODs", Check250m, Enable250m, 0 ); AddDebuggerMenuItem("Libraries\\Graphics Options\\+100m Shape LODs", Check500m, Enable500m, 0 ); if (startup_ini) { Check_Object(startup_ini); Stuff::Page *page = startup_ini->FindPage("Graphics Options"); if (page) { Check_Object(page); page->GetEntry("LOD", &s_Offset); } } } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void ElementRenderer::LODElement::TerminateClass(Stuff::NotationFile *startup_ini) { if (startup_ini) { Check_Object(startup_ini); Stuff::Page *page = startup_ini->SetPage("Graphics Options"); Check_Object(page); page->SetEntry("LOD", s_Offset); } Unregister_Object(DefaultData); delete DefaultData; DefaultData = NULL; Check_Pointer(s_Heap); gos_DestroyMemoryHeap(s_Heap); s_Heap = NULL; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // ElementRenderer::LODElement::LODElement( Stuff::MemoryStream *stream, int version, ShapeHolder shapes ): SwitchElement(DefaultData, stream, version, shapes) { Check_Pointer(this); Check_Object(stream); unsigned index = (m_state>>DrawStateBit) & DrawStateMask; Verify(index < DrawStateCount); m_draw = DrawMethods[index]; // //--------------------------------- // Create the shape from the stream //--------------------------------- // Verify(m_list.GetLength() < 65536); WORD lod_count = static_cast(m_list.GetLength()); m_LODs.SetLength(lod_count); for (WORD lod=0; lod> m_LODs[lod].m_nearSquared >> m_LODs[lod].m_farSquared; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // ElementRenderer::LODElement::LODElement(): SwitchElement(DefaultData) { Check_Pointer(this); unsigned index = (m_state>>DrawStateBit) & DrawStateMask; Verify(index < DrawStateCount); m_draw = DrawMethods[index]; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // ElementRenderer::LODElement::~LODElement() { Check_Object(this); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // ElementRenderer::LODElement* ElementRenderer::LODElement::Make( Stuff::MemoryStream *stream, int version, ShapeHolder shapes ) { Check_Object(stream); gos_PushCurrentHeap(s_Heap); LODElement *element = new LODElement(stream, version, shapes); gos_PopCurrentHeap(); return element; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void ElementRenderer::LODElement::Save(Stuff::MemoryStream *stream) { Check_Object(this); Check_Object(stream); BaseClass::Save(stream); // //-------------------- // Save each LOD entry //-------------------- // Verify(m_list.GetLength() < 65536); WORD lod_count = static_cast(m_LODs.GetLength()); for (WORD lod=0; lod(m_LODs.GetLength()); for (WORD i=0; im_nearSquared = 0.0f; entry->m_farSquared = 0.0f; break; } } BaseClass::DetachChild(child); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void ElementRenderer::LODElement::SetDrawState() { Check_Object(this); unsigned index = (m_state>>DrawStateBit) & DrawStateMask; Verify(index < DrawStateCount); m_draw = DrawMethods[index]; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void ElementRenderer::LODElement::InheritDrawMethod( CameraElement *camera, const StateChange *inherited_state, int culling_state ) { Check_Object(this); Check_Object(inherited_state); Check_Object(camera); Verify(culling_state != -1); // //-------------------------------------- // Draw our bounds if we are supposed to //-------------------------------------- // #if defined(LAB_ONLY) Callback *callback = GetCallbackSet(); unsigned index = GetCallbackIndex(); if (callback && callback[index]) { Check_Pointer(callback[index]); (*callback[index])(camera, inherited_state, culling_state, this); } #endif // //---------------------------------------------------------------------- // We need to find out which lod the camera should traverse into, so // transform the camera into LOD space and get the distance from the LOD //---------------------------------------------------------------------- // Stuff::Point3D camera_origin(camera->GetLocalToWorld()); Stuff::Point3D lod_origin(GetLocalToWorld()); camera_origin -= lod_origin; Stuff::Scalar distance = camera_origin.GetLengthSquared() + s_Offset; Min_Clamp(distance, 0.0f); // //--------------------------------------------------- // Search the lod entries looking for the first match //--------------------------------------------------- // for (WORD i=0; im_nearSquared <= distance && entry->m_farSquared >= distance) { #if defined(LAB_ONLY) Stuff::RGBAColor old_fade; if (s_ShadeLODs && iDrawElement(element, inherited_state); #if defined(LAB_ONLY) if (s_ShadeLODs && im_lights, m_stateChange->m_lights ); // //-------------------------------------- // Draw our bounds if we are supposed to //-------------------------------------- // #if defined(LAB_ONLY) Callback *callback = GetCallbackSet(); unsigned index = GetCallbackIndex(); if (callback && callback[index]) { Check_Pointer(callback[index]); (*callback[index])(camera, inherited_state, culling_state, this); } #endif // //---------------------------------------------------------------------- // We need to find out which lod the camera should traverse into, so // transform the camera into LOD space and get the distance from the LOD //---------------------------------------------------------------------- // Stuff::Point3D camera_origin(camera->GetLocalToWorld()); Stuff::Point3D lod_origin(GetLocalToWorld()); camera_origin -= lod_origin; Stuff::Scalar distance = camera_origin.GetLengthSquared() + s_Offset; Min_Clamp(distance, 0.0f); // //--------------------------------------------------- // Search the lod entries looking for the first match //--------------------------------------------------- // for (WORD i=0; im_nearSquared <= distance && entry->m_farSquared >= distance) { #if defined(LAB_ONLY) Stuff::RGBAColor old_fade; if (s_ShadeLODs && iDrawElement(element, &mixed); #if defined(LAB_ONLY) if (s_ShadeLODs && iCleanDamage(); } } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void ElementRenderer::LODElement::ApplyDamage( const Stuff::LinearMatrix4D &damage_spot, Stuff::Scalar radius ) { Check_Object(this); for(WORD i=0;iApplyDamage(damage_spot, radius); } } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void ElementRenderer::LODElement::ApplyDamageDecal( const Stuff::LinearMatrix4D &damage_spot, Stuff::Scalar radius, MidLevelRenderer::MLRTexture *texture ) { Check_Object(this); Check_Object(texture); for(WORD i=0;iApplyDamageDecal(damage_spot, radius, texture); } }