Work on end cutscene. Code to start particles based on a condition

git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@11516 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
auria 2012-08-23 01:52:55 +00:00
parent 6f88c78753
commit fe65f46035
6 changed files with 110 additions and 5 deletions

View File

@ -0,0 +1,31 @@
<?xml version="1.0"?>
<particles emitter="point">
<spreading angle="360" />
<velocity x="0.002"
y="0.002"
z="0.002" />
<material file="smoke_black.png" />
<!-- Amount of particles emitted per second -->
<rate min="20"
max="30"
decay_rate="40" />
<!-- Minimal and maximal lifetime of a particle, in milliseconds. -->
<lifetime min="800"
max="999" />
<!-- Size of the particles -->
<size min="1.5"
max="3.5" />
<color min="255 255 255"
max="255 255 255" />
<!-- How much time in milliseconds before the particle is fully faded out -->
<fadeout time="500" />
</particles>

View File

@ -93,6 +93,8 @@ void AnimationBase::reset()
*/
void AnimationBase::update(float dt, Vec3 *xyz, Vec3 *hpr, Vec3 *scale)
{
TrackObject::update(dt);
// Don't do anything if the animation is disabled
if(!m_playing) return;
m_current_time += dt;

View File

@ -76,7 +76,26 @@ void CutsceneWorld::init()
TrackObject* curr;
for_in(curr, objects)
{
if (curr->getType() == "sfx-emitter" && !curr->getTriggerCondition().empty())
if (curr->getType() == "particle-emitter" && !curr->getTriggerCondition().empty())
{
const std::string& condition = curr->getTriggerCondition();
if (StringUtils::startsWith(condition, "frame "))
{
std::string frameStr = condition.substr(6); // remove 'frame ' prefix
int frame;
if (!StringUtils::fromString(frameStr, frame))
{
fprintf(stderr, "[CutsceneWorld] Invalid condition '%s'\n", condition.c_str());
continue;
}
float FPS = 25.0f; // for now we assume the cutscene is saved at 25 FPS
m_particles_to_trigger[frame / FPS].push_back(curr);
}
}
else if (curr->getType() == "sfx-emitter" && !curr->getTriggerCondition().empty())
{
const std::string& condition = curr->getTriggerCondition();
@ -153,6 +172,17 @@ const std::string& CutsceneWorld::getIdent() const
*/
void CutsceneWorld::update(float dt)
{
/*
{
PtrVector<TrackObject>& objects = m_track->getTrackObjectManager()->getObjects();
TrackObject* curr;
for_in(curr, objects)
{
printf("* %s\n", curr->getType().c_str());
}
}
**/
m_time += dt;
if (m_time < 2.0f)
@ -168,7 +198,6 @@ void CutsceneWorld::update(float dt)
dynamic_cast<CutsceneGUI*>(m_race_gui)->setFadeLevel(0.0f);
}
float currFrame = m_time * 25.0f; // We assume 25 FPS
const std::vector<Subtitle>& subtitles = m_track->getSubtitles();
@ -232,9 +261,27 @@ void CutsceneWorld::update(float dt)
}
}
for (std::map<float, std::vector<TrackObject*> >::iterator it = m_particles_to_trigger.begin();
it != m_particles_to_trigger.end(); )
{
if (m_time >= it->first)
{
std::vector<TrackObject*> objects = it->second;
for (unsigned int i = 0; i < objects.size(); i++)
{
objects[i]->triggerParticles();
}
m_particles_to_trigger.erase(it++);
}
else
{
it++;
}
}
for (std::map<float, std::vector<TrackObject*> >::iterator it = m_sounds_to_stop.begin();
it != m_sounds_to_stop.end(); )
{
{
if (m_time >= it->first)
{
std::vector<TrackObject*> objects = it->second;
@ -248,7 +295,7 @@ void CutsceneWorld::update(float dt)
{
it++;
}
}
}
} // update
//-----------------------------------------------------------------------------

View File

@ -40,6 +40,7 @@ class CutsceneWorld : public World
std::map<float, std::vector<TrackObject*> > m_sounds_to_trigger;
std::map<float, std::vector<TrackObject*> > m_sounds_to_stop;
std::map<float, std::vector<TrackObject*> > m_particles_to_trigger;
float m_duration;
bool m_aborted;

View File

@ -81,6 +81,7 @@ TrackObject::TrackObject(const XMLNode &xml_node)
if (xml_node.getName() == "particle-emitter")
{
m_type = "particle-emitter";
std::string path;
irr::core::vector3df emitter_origin;
xml_node.get("kind", &path);
@ -89,6 +90,8 @@ TrackObject::TrackObject(const XMLNode &xml_node)
int clip_distance = -1;
xml_node.get("clip_distance", &clip_distance);
xml_node.get("conditions", &m_trigger_condition);
try
{
ParticleKind* kind = ParticleKindManager::get()->getParticles( path.c_str() );
@ -114,6 +117,11 @@ TrackObject::TrackObject(const XMLNode &xml_node)
m_node = emitter->getNode(); // FIXME: this leaks
m_emitter = emitter;
}
if (m_trigger_condition.size() > 0)
{
m_emitter->setCreationRateAbsolute(0.0f);
}
}
catch (std::runtime_error& e)
{
@ -423,7 +431,6 @@ void TrackObject::OnAnimationEnd(scene::IAnimatedMeshSceneNode* node)
// ----------------------------------------------------------------------------
void TrackObject::update(float dt)
{
if (m_sound != NULL)
{
// muting when too far is implemented manually since not supported by OpenAL
@ -431,6 +438,11 @@ void TrackObject::update(float dt)
// moved
m_sound->position(m_init_xyz);
}
if (m_emitter != NULL)
{
m_emitter->update(dt);
}
} // update
// ----------------------------------------------------------------------------
@ -477,3 +489,14 @@ void TrackObject::stopSound()
// ----------------------------------------------------------------------------
void TrackObject::triggerParticles()
{
if (m_emitter != NULL)
{
m_emitter->setCreationRateAbsolute(1.0f);
m_emitter->setParticleType(m_emitter->getParticlesInfo());
}
}
// ----------------------------------------------------------------------------

View File

@ -156,6 +156,7 @@ public:
void triggerSound(bool loop=false);
void stopSound();
void triggerParticles();
virtual void onTriggerItemApproached(Item* who);