#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(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; }