Add support for playing sounds at given points during the cutscene

git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@11310 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
auria 2012-06-16 23:35:51 +00:00
parent f7ce2fcd44
commit aced31cbfa
7 changed files with 81 additions and 5 deletions

View File

@ -59,6 +59,32 @@ void CutsceneWorld::init()
core::vector3df(0.0f, 0.0f, 0.0f));
m_camera->setFOV(0.61f);
m_camera->bindTargetAndRotation(true); // no "look-at"
// --- Build list of sounds to play at certain frames
PtrVector<TrackObject>& objects = m_track->getTrackObjectManager()->getObjects();
TrackObject* curr;
for_in(curr, objects)
{
if (curr->getType() == "sfx-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_sounds_to_trigger[frame / FPS].push_back(curr);
}
}
}
} // CutsceneWorld
//-----------------------------------------------------------------------------
@ -91,11 +117,12 @@ const std::string& CutsceneWorld::getIdent() const
*/
void CutsceneWorld::update(float dt)
{
m_time += dt;
World::update(dt);
World::updateTrack(dt);
const PtrVector<TrackObject>& objects = m_track->getTrackObjectManager()->getObjects();
const TrackObject* curr;
PtrVector<TrackObject>& objects = m_track->getTrackObjectManager()->getObjects();
TrackObject* curr;
for_in(curr, objects)
{
if (curr->getType() == "cutscene_camera")
@ -106,10 +133,27 @@ void CutsceneWorld::update(float dt)
Vec3 rot2(rot);
rot2.setPitch(rot2.getPitch() + 90.0f);
m_camera->setRotation(rot2.toIrrVector());
break;
//printf("Camera %f %f %f\n", curr->getNode()->getPosition().X, curr->getNode()->getPosition().Y, curr->getNode()->getPosition().Z);
}
}
for (std::map<float, std::vector<TrackObject*>>::iterator it = m_sounds_to_trigger.begin();
it != m_sounds_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]->triggerSound();
}
m_sounds_to_trigger.erase(it++);
}
else
{
it++;
}
}
} // update
//-----------------------------------------------------------------------------

View File

@ -28,6 +28,8 @@
#include <ICameraSceneNode.h>
class TrackObject;
/**
* \brief An implementation of World, to provide animated 3D cutscenes
* \ingroup modes
@ -37,6 +39,8 @@ class CutsceneWorld : public World
scene::ICameraSceneNode* m_camera;
std::map<float, std::vector<TrackObject*>> m_sounds_to_trigger;
public:
CutsceneWorld();

View File

@ -83,6 +83,8 @@ TrackObject::TrackObject(const XMLNode &xml_node)
xml_node.get("distance", &trigger_distance);
xml_node.get("conditions", &m_trigger_condition);
// first try track dir, then global dir
std::string soundfile = file_manager->getModelFile(sound);
if (!file_manager->fileExists(soundfile))
@ -100,7 +102,7 @@ TrackObject::TrackObject(const XMLNode &xml_node)
if (m_sound != NULL)
{
m_sound->position(m_init_xyz);
if (!trigger_when_near)
if (!trigger_when_near && m_trigger_condition.empty())
{
m_sound->setLoop(true);
m_sound->play();
@ -335,3 +337,11 @@ void TrackObject::onTriggerItemApproached(Item* who)
}
}
}
// ----------------------------------------------------------------------------
/** if this is a sound object, play the object */
void TrackObject::triggerSound()
{
if (m_sound != NULL) m_sound->play();
}

View File

@ -63,6 +63,9 @@ private:
/** End frame of the animation to be played. */
unsigned int m_frame_end;
/** Currently used for sound effects only, in cutscenes only atm */
std::string m_trigger_condition;
virtual void OnAnimationEnd(scene::IAnimatedMeshSceneNode* node);
protected:
@ -82,7 +85,7 @@ protected:
/** The initial scale of the object. */
core::vector3df m_init_scale;
/** If a sound is attached to this objectt and/or this is a sound emitter object */
/** If a sound is attached to this object and/or this is a sound emitter object */
SFXBase* m_sound;
/** LOD group this object is part of, if it is LOD */
@ -128,6 +131,11 @@ public:
const std::string& getType() const { return m_type; }
/** Currently used for sound effects only, in cutscenes only atm */
const std::string& getTriggerCondition() const { return m_trigger_condition; }
void triggerSound();
virtual void onTriggerItemApproached(Item* who);
}; // TrackObject

View File

@ -79,6 +79,7 @@ public:
void assingLodNodes(const std::vector<LODNode*>& lod);
PtrVector<TrackObject>& getObjects() { return m_all_objects; }
const PtrVector<TrackObject>& getObjects() const { return m_all_objects; }
}; // class TrackObjectManager

View File

@ -42,6 +42,14 @@ namespace StringUtils
rhs.c_str() )==0;
} // hasSuffix
bool startsWith(const std::string& str, const std::string& prefix)
{
if (str.length() < prefix.length())
return false;
else
return strncmp(str.c_str(), prefix.c_str(), prefix.size())==0;
}
//-------------------------------------------------------------------------
/** Returns the path of a filename, i.e. everything till the last '/'.
*/

View File

@ -29,6 +29,7 @@ namespace StringUtils
{
bool hasSuffix(const std::string& lhs, const std::string rhs);
bool startsWith(const std::string& str, const std::string& prefix);
/** Return the filename part of a path */
std::string getBasename(const std::string& filename);