#include "gosFXHeaders.hpp" #include static bool Disable_Fade; static bool __stdcall CheckDisableFade() {return Disable_Fade;} static void __stdcall EnableDisableFade() {Disable_Fade = !Disable_Fade;} static bool Disable_Cast; static bool __stdcall CheckDisableCast() {return Disable_Cast;} static void __stdcall EnableDisableCast() {Disable_Cast = !Disable_Cast;} //############################################################################ //######################## gosFX::Flare__Specification ############################# //############################################################################ //------------------------------------------------------------------------------ // gosFX::Flare__Specification::Flare__Specification( Stuff::MemoryStream *stream, int gfx_version ): Card__Specification(FlareClassID, stream, gfx_version) { Check_Pointer(this); Verify(m_class == FlareClassID); if (gfx_version>=20) *stream >> m_fadeInRate >> m_fadeOutRate >> m_rayCastTime; else { m_fadeInRate = 4.0f; m_fadeOutRate = 4.0f; m_rayCastTime = 0.25f; } } //------------------------------------------------------------------------------ // gosFX::Flare__Specification::Flare__Specification(): Card__Specification(gosFX::FlareClassID) { Check_Pointer(this); m_fadeInRate = 4.0f; m_fadeOutRate = 4.0f; m_rayCastTime = 0.25f; } //------------------------------------------------------------------------------ // gosFX::Flare__Specification::~Flare__Specification() { Check_Object(this); } //------------------------------------------------------------------------------ // gosFX::Flare__Specification* gosFX::Flare__Specification::Make( Stuff::MemoryStream *stream, int gfx_version ) { Check_Object(stream); gos_PushCurrentHeap(Heap); Flare__Specification *spec = new gosFX::Flare__Specification(stream, gfx_version); gos_PopCurrentHeap(); return spec; } //------------------------------------------------------------------------------ // void gosFX::Flare__Specification::Save(Stuff::MemoryStream *stream) { Check_Object(this); Check_Object(stream); BaseClass::Save(stream); *stream << m_fadeInRate << m_fadeOutRate << m_rayCastTime; } //------------------------------------------------------------------------------ // void gosFX::Flare__Specification::BuildDefaults() { Check_Object(this); BaseClass::BuildDefaults(); m_fadeInRate = 4.0f; m_fadeOutRate = 4.0f; m_rayCastTime = 0.25f; } //------------------------------------------------------------------------------ // bool gosFX::Flare__Specification::IsDataValid(bool fix_data) { Check_Object(this); return BaseClass::IsDataValid(fix_data); } //------------------------------------------------------------------------------ // void gosFX::Flare__Specification::Copy(Flare__Specification *spec) { Check_Object(this); Check_Object(spec); BaseClass::Copy(spec); m_fadeInRate = spec->m_fadeInRate; m_fadeOutRate = spec->m_fadeOutRate; m_rayCastTime = spec->m_rayCastTime; } //############################################################################ //############################## gosFX::Flare ################################ //############################################################################ gosFX::Flare::ClassData* gosFX::Flare::DefaultData = NULL; static bool stub_caster(Stuff::Line3D *line) { return false; } gosFX::Flare::RayCastMethod gosFX::Flare::RayCaster = stub_caster; //------------------------------------------------------------------------------ // void gosFX::Flare::InitializeClass() { Verify(!DefaultData); DefaultData = new ClassData( FlareClassID, "gosFX::Flare", BaseClass::DefaultData, (Effect::Factory)&Make, (Specification::Factory)&Specification::Make ); Register_Object(DefaultData); Disable_Fade = false; AddDebuggerMenuItem("Libraries\\gosFX\\Disable Flare Fade", CheckDisableFade, EnableDisableFade, 0 ); Disable_Cast = false; AddDebuggerMenuItem("Libraries\\gosFX\\Disable Flare Cast Delay", CheckDisableCast, EnableDisableCast, 0 ); } //------------------------------------------------------------------------------ // void gosFX::Flare::TerminateClass() { Check_Object(DefaultData); delete DefaultData; DefaultData = NULL; } //------------------------------------------------------------------------------ // gosFX::Flare::Flare( Specification *spec, unsigned flags ): Card(DefaultData, spec, flags) { Check_Object(spec); m_fadeLevel = 0.0f; } //------------------------------------------------------------------------------ // gosFX::Flare::~Flare() { } //------------------------------------------------------------------------------ // gosFX::Flare* gosFX::Flare::Make( Specification *spec, unsigned flags ) { Check_Object(spec); gos_PushCurrentHeap(Heap); Flare *cloud = new gosFX::Flare(spec, flags); gos_PopCurrentHeap(); return cloud; } //------------------------------------------------------------------------------ // void gosFX::Flare::Start(ExecuteInfo *info) { Check_Object(this); Check_Pointer(info); BaseClass::Start(info); // //------------------------------------------------ // Cast an initial ray to make sure its done right //------------------------------------------------ // Set_Statistic(Flare_Count, Flare_Count+1); Specification *spec = GetSpecification(); m_timeTillCast = spec->m_rayCastTime; Stuff::Line3D eye_line; eye_line.m_origin = LastCameraPosition; Stuff::Point3D to(m_localToWorld); Stuff::Vector3D dir; dir.Subtract(to, LastCameraPosition); eye_line.m_length = dir.GetLength(); if (!Stuff::Small_Enough(eye_line.m_length)) { Stuff::Scalar len = 1.0f / eye_line.m_length; eye_line.m_direction.x = dir.x * len; eye_line.m_direction.y = dir.y * len; eye_line.m_direction.z = dir.z * len; eye_line.m_length -= 0.5f; Check_Pointer(RayCaster); m_fadeTarget = ((*RayCaster)(&eye_line)) ? 0.0f : 1.0f; m_fadeLevel = m_fadeTarget; } else { m_fadeTarget = 0.0f; m_fadeLevel = 0.0f; } } //------------------------------------------------------------------------------ // bool gosFX::Flare::Execute(ExecuteInfo *info) { Check_Object(this); Check_Object(info); GFX_LOGIC("Execute::Flare"); if (!IsExecuted()) return false; // //------------------------ // Do the effect animation //------------------------ // Stuff::Scalar step = static_cast(info->m_time - m_lastRan); if (!BaseClass::Execute(info)) return false; // //---------------------------------- // See if we need to test visibility //---------------------------------- // Set_Statistic(Flare_Count, Flare_Count+1); Specification *spec = GetSpecification(); Check_Object(spec); m_timeTillCast -= step; if (m_timeTillCast <= 0.0f || Disable_Cast) { m_timeTillCast = spec->m_rayCastTime; Stuff::Line3D eye_line; eye_line.m_origin = LastCameraPosition; Stuff::Point3D to(m_localToWorld); Stuff::Vector3D dir; dir.Subtract(to, LastCameraPosition); eye_line.m_length = dir.GetLength(); if (!Stuff::Small_Enough(eye_line.m_length)) { Stuff::Scalar len = 1.0f / eye_line.m_length; eye_line.m_direction.x = dir.x * len; eye_line.m_direction.y = dir.y * len; eye_line.m_direction.z = dir.z * len; eye_line.m_length -= 0.5f; Check_Pointer(RayCaster); m_fadeTarget = ((*RayCaster)(&eye_line)) ? 0.0f : 1.0f; } } // //----------------------------------- // Adjust the fade level of the flare //----------------------------------- // if (m_age == 0.0f) m_fadeLevel = m_fadeTarget; else if (m_fadeTarget < m_fadeLevel) { m_fadeLevel -= step * spec->m_fadeOutRate; if (m_fadeLevel < m_fadeTarget || Disable_Fade) m_fadeLevel = m_fadeTarget; } else if (m_fadeTarget > m_fadeLevel) { m_fadeLevel += step * spec->m_fadeInRate; if (m_fadeLevel > m_fadeTarget || Disable_Fade) m_fadeLevel = m_fadeTarget; } return true; } //------------------------------------------------------------------------------ // void gosFX::Flare::Draw(DrawInfo *info) { Check_Object(this); Check_Object(info); GFX_RENDER("Flare"); // //------------------------------------------ // If the flare has faded out, don't draw it //------------------------------------------ // if (!m_fadeLevel) return; // //---------------------------- // Set up the common draw info //---------------------------- // MidLevelRenderer::DrawEffectInformation dInfo; dInfo.effect = m_cardCloud; Specification *spec = GetSpecification(); Check_Object(spec); dInfo.state.Combine(info->m_state, spec->m_state); dInfo.clippingFlags = info->m_clippingFlags; Stuff::LinearMatrix4D local_to_world; local_to_world.Multiply(m_localToParent, *info->m_parentToWorld); dInfo.effectToWorld = &local_to_world; // //--------------------- // Fill in the position //--------------------- // m_vertices[0].x = m_scale*m_halfX; m_vertices[0].y = -m_scale*m_halfY; m_vertices[0].z = 0.0f; m_vertices[1].x = -m_scale*m_halfX; m_vertices[1].y = -m_scale*m_halfY; m_vertices[1].z = 0.0f; m_vertices[2].x = -m_scale*m_halfX; m_vertices[2].y = m_scale*m_halfY; m_vertices[2].z = 0.0f; m_vertices[3].x = m_scale*m_halfX; m_vertices[3].y = m_scale*m_halfY; m_vertices[3].z = 0.0f; // //---------------- // Animate the uvs //---------------- // Stuff::Scalar u = spec->m_UOffset.ComputeValue(m_age, m_seed); Stuff::Scalar v = spec->m_VOffset.ComputeValue(m_age, m_seed); Stuff::Scalar u2 = spec->m_USize.ComputeValue(m_age, m_seed); Stuff::Scalar v2 = spec->m_VSize.ComputeValue(m_age, m_seed); // //-------------------------------------------------------------- // If we are animated, figure out the row/column to be displayed //-------------------------------------------------------------- // if (spec->m_animated) { BYTE columns = Stuff::Truncate_Float_To_Byte( spec->m_index.ComputeValue(m_age, m_seed) ); BYTE rows = static_cast(columns / spec->m_width); columns = static_cast(columns - rows*spec->m_width); // //--------------------------- // Now compute the end points //--------------------------- // u += u2*columns; v += v2*rows; } u2 += u; v2 += v; m_uvs[0].x = u; m_uvs[0].y = v2; m_uvs[1].x = u2; m_uvs[1].y = v2; m_uvs[2].x = u2; m_uvs[2].y = v; m_uvs[3].x = u; m_uvs[3].y = v; // //------------------ // Fill in the color //------------------ // m_color.red = m_fadeLevel*spec->m_red.ComputeValue(m_age, m_seed); m_color.green = m_fadeLevel*spec->m_green.ComputeValue(m_age, m_seed); m_color.blue = m_fadeLevel*spec->m_blue.ComputeValue(m_age, m_seed); m_color.alpha = spec->m_alpha.ComputeValue(m_age, m_seed); m_colors[0] = m_color; m_colors[1] = m_color; m_colors[2] = m_color; m_colors[3] = m_color; // //-------------------------------------------------------------- // Check the orientation mode. The first case is XY orientation //-------------------------------------------------------------- // if (spec->m_alignZUsingX) { Stuff::Point3D camera_in_world(info->m_clipper->GetCameraToWorldMatrix()); Stuff::Point3D card_in_world(local_to_world); Stuff::Vector3D look_at; look_at.Subtract(camera_in_world, card_in_world); if (spec->m_alignZUsingY) local_to_world.AlignLocalAxisToWorldVector( look_at, Stuff::Z_Axis, Stuff::Y_Axis, Stuff::X_Axis ); else local_to_world.AlignLocalAxisToWorldVector( look_at, Stuff::Z_Axis, Stuff::X_Axis, -1 ); } // //------------------------------------------------------- // Each matrix needs to be aligned to the camera around Y //------------------------------------------------------- // else if (spec->m_alignZUsingY) { Stuff::Point3D camera_in_world(info->m_clipper->GetCameraToWorldMatrix()); Stuff::Point3D card_in_world(local_to_world); Stuff::Vector3D look_at; look_at.Subtract(camera_in_world, card_in_world); local_to_world.AlignLocalAxisToWorldVector( look_at, Stuff::Z_Axis, Stuff::Y_Axis, -1 ); } // //--------------------- // Now just do the draw //--------------------- // info->m_clipper->DrawEffect(&dInfo); BaseClass::BaseClass::Draw(info); } //------------------------------------------------------------------------------ // void gosFX::Flare::Kill() { Check_Object(this); m_fadeTarget = 1.0f; m_fadeLevel = 1.0f; m_timeTillCast = 0.0f; BaseClass::Kill(); } //------------------------------------------------------------------------------ // void gosFX::Flare::TestInstance() const { Verify(IsDerivedFrom(DefaultData)); }