?? effect.cpp
字號:
m_children(NULL),
m_event(&spec->m_events)
{
Check_Pointer(this);
Check_Object(spec);
Verify(gos_GetCurrentHeap() == Heap);
m_specification = spec;
m_age = 0.0f;
m_flags = flags;
m_lastRan = -1.0f;
m_localToParent = Stuff::LinearMatrix4D::Identity;
}
//------------------------------------------------------------------------------
//
gosFX::Effect::~Effect()
{
Check_Object(this);
Stuff::ChainIteratorOf<gosFX::Effect*> children(&m_children);
children.DeletePlugs();
}
//------------------------------------------------------------------------------
//
gosFX::Effect*
gosFX::Effect::Make(
Specification *spec,
unsigned flags
)
{
Check_Object(spec);
gos_PushCurrentHeap(Heap);
Effect *effect = new gosFX::Effect(DefaultData, spec, flags);
gos_PopCurrentHeap();
return effect;
}
//------------------------------------------------------------------------------
//
void
gosFX::Effect::TestInstance() const
{
Verify(IsDerivedFrom(DefaultData));
}
//------------------------------------------------------------------------------
//
void
gosFX::Effect::Start(ExecuteInfo *info)
{
Check_Object(this);
Check_Pointer(info);
gos_PushCurrentHeap(Heap);
//
//---------------------------------------------------------------------
// Don't override m_lastran if we are issuing a Start command while the
// effect is already running
//---------------------------------------------------------------------
//
if (!IsExecuted() || m_lastRan == -1.0)
m_lastRan = info->m_time;
SetExecuteOn();
//
//-------------------------------------------
// If no seed was provided, pick one randomly
//-------------------------------------------
//
m_seed = (info->m_seed == -1.0f) ? Stuff::Random::GetFraction() : info->m_seed;
Verify(m_seed >= 0.0f && m_seed <= 1.0f);
//
//--------------------------------------------------------------------
// Figure out how long the emitter will live and its initial age based
// upon the effect seed
//--------------------------------------------------------------------
//
Check_Object(m_specification);
if (info->m_age == -1.0f)
{
Stuff::Scalar lifetime =
m_specification->m_lifeSpan.ComputeValue(m_seed, 0.0f);
Min_Clamp(lifetime, 0.033333f);
m_ageRate = 1.0f / lifetime;
m_age = 0;
}
else
{
m_age = info->m_age;
m_ageRate = info->m_ageRate;
Verify(m_age >= 0.0f && m_age <= 1.0f);
}
//
//--------------------
// Set up the matrices
//--------------------
//
Check_Object(info->m_parentToWorld);
m_localToWorld.Multiply(m_localToParent, *info->m_parentToWorld);
//
//-------------------------
// Set up the event pointer
//-------------------------
//
m_event.First();
gos_PopCurrentHeap();
}
//------------------------------------------------------------------------------
//
bool gosFX::Effect::Execute(ExecuteInfo *info)
{
Check_Object(this);
Check_Pointer(info);
Verify(IsExecuted());
gos_PushCurrentHeap(Heap);
//
//-----------------------------------------------------
// If a new seed is provided, override the current seed
//-----------------------------------------------------
//
if (info->m_seed != -1.0f)
{
Verify(info->m_seed>=0.0f && info->m_seed<1.0f);
m_seed = info->m_seed;
}
//
//--------------------------------------------
// Figure out the new age and clear the bounds
//--------------------------------------------
//
Stuff::Scalar age =
m_age + static_cast<Stuff::Scalar>(info->m_time - m_lastRan) * m_ageRate;
Verify(age >= 0.0f && age >= m_age);
*info->m_bounds = Stuff::OBB::Identity;
//
//--------------------------------
// Update the effectToWorld matrix
//--------------------------------
//
Check_Object(info->m_parentToWorld);
m_localToWorld.Multiply(m_localToParent, *info->m_parentToWorld);
//
//--------------------------------------------------
// Check to see if the top event needs to be handled
//--------------------------------------------------
//
Check_Object(m_specification);
Event *event;
while ((event = m_event.GetCurrent()) != NULL)
{
Check_Object(event);
if (event->m_time > m_age)
break;
//
//-------------------------------------------------------------
// This event needs to go, so spawn and bump the effect pointer
//-------------------------------------------------------------
//
unsigned flags = ExecuteFlag;
if ((event->m_flags&SimulationModeMask) == ParentSimulationMode)
{
Verify((m_flags&SimulationModeMask) != ParentSimulationMode);
flags |= m_flags&SimulationModeMask;
}
else
flags |= event->m_flags&SimulationModeMask;
Effect* effect =
EffectLibrary::Instance->MakeEffect(
event->m_effectID,
flags
);
Register_Object(effect);
m_children.Add(effect);
m_event.Next();
//
//---------------------------------------------
// Now set the info for starting the new effect
//---------------------------------------------
//
effect->m_localToParent = event->m_localToParent;
Stuff::Scalar min_seed =
m_specification->m_minimumChildSeed.ComputeValue(m_age, m_seed);
Stuff::Scalar seed_range =
m_specification->m_maximumChildSeed.ComputeValue(m_age, m_seed) - min_seed;
Stuff::Scalar seed =
Stuff::Random::GetFraction()*seed_range + min_seed;
Clamp(seed, 0.0f, 1.0f);
ExecuteInfo
local_info(
info->m_time,
&m_localToWorld,
NULL,
seed
);
effect->Start(&local_info);
}
//
//------------------------------------------------------------
// Execute all the children. If any of them finish, kill them
//------------------------------------------------------------
//
Stuff::ChainIteratorOf<gosFX::Effect*> children(&m_children);
gosFX::Effect *child;
Stuff::OBB child_obb = Stuff::OBB::Identity;
ExecuteInfo
child_info(
info->m_time,
&m_localToWorld,
&child_obb
);
child_info.m_bounds = &child_obb;
while ((child = children.ReadAndNext()) != NULL)
{
Check_Object(child);
if (!child->Execute(&child_info))
{
Unregister_Object(child);
delete child;
}
//
//--------------------------------------------------------------
// Merge the bounding sphere of the child into the bounds of the
// parent
//--------------------------------------------------------------
//
Stuff::OBB parent_bounds;
parent_bounds.Multiply(child_obb, m_localToParent);
info->m_bounds->Union(*info->m_bounds, parent_bounds);
}
Check_Object(info->m_bounds);
//
//----------------------------------------------------------------------
// Set the new time, then if we have run the course of the effect, start
// over if we loop, otherwise wait for our children to finish before
// killing ourselves
//----------------------------------------------------------------------
//
m_lastRan = info->m_time;
m_age = age;
if (m_age >= 1.0f)
{
if (IsLooped())
Start(info);
else if (HasFinished())
Kill();
}
//
//----------------------------------
// Tell our parent if we need to die
//----------------------------------
//
gos_PopCurrentHeap();
return IsExecuted();
}
//------------------------------------------------------------------------------
//
void gosFX::Effect::Stop()
{
Check_Object(this);
//
//------------------------------------
// Stop the children then stop ourself
//------------------------------------
//
m_age = 1.0f;
m_event.Last();
m_event.Next();
}
//------------------------------------------------------------------------------
//
void gosFX::Effect::Kill()
{
Check_Object(this);
//
//------------------------------------
// Kill the children then kill ourself
//------------------------------------
//
Stuff::ChainIteratorOf<gosFX::Effect*> children(&m_children);
gosFX::Effect* child;
while ((child = children.ReadAndNext()) != NULL)
{
Check_Object(child);
child->Kill();
}
SetExecuteOff();
}
//------------------------------------------------------------------------------
//
void gosFX::Effect::Draw(DrawInfo *info)
{
Check_Object(this);
Check_Pointer(info);
//
//-------------------------------------
// Make sure all the children get drawn
//-------------------------------------
//
DrawInfo new_info;
Check_Object(m_specification);
new_info.m_state.Combine(info->m_state, m_specification->m_state);
Stuff::LinearMatrix4D local_to_world;
local_to_world.Multiply(m_localToParent, *info->m_parentToWorld);
new_info.m_parentToWorld = &local_to_world;
new_info.m_clipper = info->m_clipper;
new_info.m_clippingFlags = info->m_clippingFlags;
Stuff::ChainIteratorOf<gosFX::Effect*> children(&m_children);
gosFX::Effect *child;
while ((child = children.ReadAndNext()) != NULL)
{
Check_Object(child);
child->Draw(&new_info);
}
}
//------------------------------------------------------------------------------
//
bool gosFX::Effect::HasFinished()
{
Check_Object(this);
//
//-------------------------------------------------------------------------
// An effect is not finished if it is executing and its life hasn't expired
//-------------------------------------------------------------------------
//
if (IsExecuted() && m_age < 1.0f)
return false;
//
//-----------------------------------------------
// It is also not finished if it has any children
//-----------------------------------------------
//
Stuff::ChainIteratorOf<gosFX::Effect*> children(&m_children);
return children.GetCurrent() == NULL;
}
//#############################################################################
//########################## gosFX::Effect__ClassData ##########################
//#############################################################################
void
gosFX::Effect__ClassData::TestInstance()
{
Verify(IsDerivedFrom(gosFX::Effect::DefaultData));
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -