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:
parent
f7ce2fcd44
commit
aced31cbfa
@ -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
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
}
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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 '/'.
|
||||
*/
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user