1
0
forked from 0ad/0ad

#Cinematic editor

This was SVN commit r4234.
This commit is contained in:
pyrolink 2006-08-22 02:24:44 +00:00
parent 6a7ee226f0
commit b62f53620f
20 changed files with 2149 additions and 361 deletions

View File

@ -15,86 +15,95 @@
#include "lib/res/mem.h"
CCinemaPath::CCinemaPath(const CCinemaData& data, const TNSpline& spline)
: CCinemaData(data), TNSpline(spline)
: CCinemaData(data), TNSpline(spline), m_TimeElapsed(0.f)
{
DistStylePtr = &CCinemaPath::EaseDefault;
DistModePtr = &CCinemaPath::EaseIn;
}
void CCinemaPath::DrawSpline(CVector4D RGBA, int smoothness)
void CCinemaPath::DrawSpline(const CVector4D& RGBA, int smoothness, bool lines) const
{
if (NodeCount < 3 || DistModePtr == NULL)
if (NodeCount < 2 || DistModePtr == NULL)
return;
if ( NodeCount == 2 )
smoothness = 2;
float start = MaxDistance / smoothness;
CVector3D tmp;
float time=0;
glColor4f( RGBA.m_X, RGBA.m_Y, RGBA.m_Z, RGBA.m_W );
glLineWidth(2.0f);
glBegin(GL_LINE_STRIP);
for (int i=0; i<smoothness; i++)
{
//Find distorted time
time = (this->*DistModePtr)(start*i / MaxDistance);
tmp = GetPosition(time);
glVertex3f( tmp.X, tmp.Y, tmp.Z );
}
glEnd();
glLineWidth(1.0f);
if ( lines )
{
glLineWidth(1.8f);
glEnable(GL_LINE_SMOOTH);
glBegin(GL_LINE_STRIP);
glPointSize(6.0f);
//Draw spline endpoints
glBegin(GL_POINTS);
tmp = GetPosition(0);
glVertex3f( tmp.X, tmp.Y, tmp.Z );
tmp = GetPosition(1);
glVertex3f( tmp.X, tmp.Y, tmp.Z );
glEnd();
glPointSize(1.0f);
for (int i=0; i<smoothness; ++i)
{
//Find distorted time
time = start*i / MaxDistance;
CVector3D tmp = GetPosition(time);
glVertex3f( tmp.X, tmp.Y, tmp.Z );
}
glEnd();
glDisable(GL_LINE_SMOOTH);
glLineWidth(1.0f);
}
else
{
smoothness /= 2;
start = MaxDistance / smoothness;
glEnable(GL_POINT_SMOOTH);
glPointSize(3.0f);
glBegin(GL_POINTS);
for (int i=0; i<smoothness; ++i)
{
//Find distorted time
time = (this->*DistModePtr)(start*i / MaxDistance);
CVector3D tmp = GetPosition(time);
glVertex3f( tmp.X, tmp.Y, tmp.Z );
}
glColor3f(1.0f, 1.0f, 0.0f); //yellow
for ( size_t i=0; i<Node.size(); ++i )
glVertex3f(Node[i].Position.X, Node[i].Position.Y, Node[i].Position.Z);
glEnd();
glPointSize(1.0f);
glDisable(GL_POINT_SMOOTH);
}
}
void CCinemaPath::MoveToPointAt(float t, const CVector3D &startRotation)
{
CCamera *Cam=g_Game->GetView()->GetCamera();
t = (this->*DistModePtr)(t);
CVector3D rot = startRotation + m_TotalRotation * t;
Cam->m_Orientation.SetXRotation(fmodf(rot.X, 360.0f));
Cam->m_Orientation.RotateY(fmodf(rot.Y, 360.0f));
Cam->m_Orientation.RotateZ(fmodf(rot.Z, 360.0f));
Cam->m_Orientation.SetXRotation(fmodf(rot.X, DEGTORAD(360.0f)) );
Cam->m_Orientation.RotateY( fmodf(rot.Y, DEGTORAD(360.0f)) );
Cam->m_Orientation.RotateZ( fmodf(rot.Z, DEGTORAD(360.0f)) );
CVector3D pos = GetPosition(t);
Cam->m_Orientation.Translate(pos);
Cam->UpdateFrustum();
}
void CCinemaPath::ResetRotation(float t)
{
CCamera *Cam=g_Game->GetView()->GetCamera();
t = (this->*DistModePtr)(t);
CVector3D rot = m_TotalRotation * t;
//rotate in reverse order and reverse angles
Cam->m_Orientation.RotateZ(-fmodf(rot.Z, 360));
Cam->m_Orientation.RotateY(-fmodf(rot.Y, 360));
Cam->m_Orientation.RotateX(-fmodf(rot.X, 360));
}
//Distortion mode functions
float CCinemaPath::EaseIn(float t)
float CCinemaPath::EaseIn(float t) const
{
return (this->*DistStylePtr)(t);
}
float CCinemaPath::EaseOut(float t)
float CCinemaPath::EaseOut(float t) const
{
return 1.0f - EaseIn(1.0f-t);
}
float CCinemaPath::EaseInOut(float t)
float CCinemaPath::EaseInOut(float t) const
{
if (t < m_Switch)
return EaseIn(1.0f/m_Switch * t) * m_Switch;
return EaseOut(1.0f/m_Switch * (t-m_Switch)) * m_Switch + m_Switch;
}
float CCinemaPath::EaseOutIn(float t)
float CCinemaPath::EaseOutIn(float t) const
{
if (t < m_Switch)
return EaseOut(1.0f/m_Switch * t) * m_Switch;
@ -103,22 +112,22 @@ float CCinemaPath::EaseOutIn(float t)
//Distortion style functions
float CCinemaPath::EaseDefault(float t)
float CCinemaPath::EaseDefault(float t) const
{
return t;
}
float CCinemaPath::EaseGrowth(float t)
float CCinemaPath::EaseGrowth(float t) const
{
return pow(t, m_Growth);
}
float CCinemaPath::EaseExpo(float t)
float CCinemaPath::EaseExpo(float t) const
{
if(t == 0)
return t;
return powf(m_Growth, 10*(t-1.0f));
}
float CCinemaPath::EaseCircle(float t)
float CCinemaPath::EaseCircle(float t) const
{
t = -(sqrt(1.0f - t*t) - 1.0f);
if(m_GrowthCount > 1.0f)
@ -129,7 +138,7 @@ float CCinemaPath::EaseCircle(float t)
return t;
}
float CCinemaPath::EaseSine(float t)
float CCinemaPath::EaseSine(float t) const
{
t = 1.0f - cos(t * PI/2);
if(m_GrowthCount > 1.0f)
@ -140,10 +149,14 @@ float CCinemaPath::EaseSine(float t)
return t;
}
//-------CinemaTrack functions------
//AddPath-For building tracks from loaded file
void CCinemaTrack::AddPath(CCinemaData& data, TNSpline& spline)
CCinemaTrack::CCinemaTrack() : m_AbsoluteTime(0), m_Timescale(1),
m_TotalDuration(0)
{
m_CPA = m_Paths.end();
}
void CCinemaTrack::AddPath(const CCinemaData& data, const TNSpline& spline)
{
CCinemaPath path(data, spline);
path.m_TimeElapsed=0;
@ -156,16 +169,16 @@ void CCinemaTrack::AddPath(CCinemaData& data, TNSpline& spline)
//Set distortion mode and style
switch(data.m_Mode)
{
case EM_IN:
case CCinemaPath::EM_IN:
SetTemp->DistModePtr = &CCinemaPath::EaseIn;
break;
case EM_OUT:
case CCinemaPath::EM_OUT:
SetTemp->DistModePtr = &CCinemaPath::EaseOut;
break;
case EM_INOUT:
case CCinemaPath::EM_INOUT:
SetTemp->DistModePtr = &CCinemaPath::EaseInOut;
break;
case EM_OUTIN:
case CCinemaPath::EM_OUTIN:
SetTemp->DistModePtr = &CCinemaPath::EaseOutIn;
break;
default:
@ -175,19 +188,19 @@ void CCinemaTrack::AddPath(CCinemaData& data, TNSpline& spline)
switch (data.m_Style)
{
case ES_DEFAULT:
case CCinemaPath::ES_DEFAULT:
SetTemp->DistStylePtr = &CCinemaPath::EaseDefault;
break;
case ES_GROWTH:
case CCinemaPath::ES_GROWTH:
SetTemp->DistStylePtr = &CCinemaPath::EaseGrowth;
break;
case ES_EXPO:
case CCinemaPath::ES_EXPO:
SetTemp->DistStylePtr = &CCinemaPath::EaseExpo;
break;
case ES_CIRCLE:
case CCinemaPath::ES_CIRCLE:
SetTemp->DistStylePtr = &CCinemaPath::EaseCircle;
break;
case ES_SINE:
case CCinemaPath::ES_SINE:
SetTemp->DistStylePtr = &CCinemaPath::EaseSine;
break;
default:
@ -195,8 +208,16 @@ void CCinemaTrack::AddPath(CCinemaData& data, TNSpline& spline)
break;
}
UpdateDuration();
}
void CCinemaTrack::AddPath(const CCinemaPath& path)
{
m_Paths.push_back(path);
m_Paths.back().BuildSpline();
m_Paths.back().m_TimeElapsed = 0;
UpdateDuration();
}
void CCinemaTrack::UpdateDuration()
{
m_TotalDuration=0;
@ -257,6 +278,7 @@ bool CCinemaTrack::ValidateForward()
{
if (m_CPA == m_Paths.end() - 1)
{
m_CPA->MoveToPointAt(1.f, CalculateRotation());
return false;
}
//Make sure it's within limits of path
@ -281,7 +303,7 @@ bool CCinemaTrack::ValidateForward()
}
else
{
m_CPA->m_TimeElapsed+=Pos;
m_CPA->m_TimeElapsed = Pos;
break;
}
}
@ -289,46 +311,31 @@ bool CCinemaTrack::ValidateForward()
}
return true;
}
CVector3D CCinemaTrack::CalculateRotation()
{
if ( m_CPA == m_Paths.begin() )
return m_StartRotation;
CVector3D startRotation(0.f, 0.f, 0.f);
for ( std::vector<CCinemaPath>::iterator it=m_Paths.begin(); it!=m_CPA; ++it )
startRotation += it->GetData()->m_TotalRotation;
return startRotation + m_StartRotation;
}
bool CCinemaTrack::Play(float DeltaTime)
{
if (m_CPA->m_TimeElapsed == 0)
{
if (m_CPA == m_Paths.begin())
{
//Set camera to start at starting rotations
CCamera *Cam=g_Game->GetView()->GetCamera();
Cam->m_Orientation.SetIdentity();
Cam->SetProjection (1, 5000, DEGTORAD(20));
Cam->m_Orientation.SetXRotation(m_StartRotation.X);
Cam->m_Orientation.RotateY(m_StartRotation.Y);
Cam->m_Orientation.RotateZ(m_StartRotation.Z);
}
}
m_CPA->m_TimeElapsed += m_TimeScale*DeltaTime;
m_AbsoluteTime += m_TimeScale*DeltaTime;
m_CPA->m_TimeElapsed += m_Timescale*DeltaTime;
m_AbsoluteTime += m_Timescale*DeltaTime;
if (!Validate())
return false;
m_CPA->MoveToPointAt( m_CPA->GetElapsedTime() / m_CPA->GetDuration(), m_StartRotation);
CVector3D rotation = CalculateRotation();
m_CPA->MoveToPointAt( m_CPA->GetElapsedTime() / m_CPA->GetDuration(), rotation);
return true;
}
void CCinemaTrack::MoveToPointAt(float t)
CCinemaManager::CCinemaManager() : m_DrawCurrentSpline(false),
m_DrawAllSplines(false), m_Active(true), m_CurrentTrack(false)
{
m_CPA->m_TimeElapsed = t;
if ( !Validate() )
return;
MoveToPointAt(m_CPA->m_TimeElapsed / m_CPA->GetDuration());
}
void CCinemaTrack::MoveToPointAbsolute(float time)
{
m_CPA = m_Paths.begin();
m_AbsoluteTime = m_CPA->m_TimeElapsed = time;
if (!ValidateForward())
return;
else
m_CPA->MoveToPointAt(m_CPA->m_TimeElapsed, m_StartRotation);
}
void CCinemaManager::AddTrack(CCinemaTrack track, const CStrW& name)
@ -346,6 +353,8 @@ void CCinemaManager::QueueTrack(const CStrW& name, bool queue )
else
{
debug_assert(HasTrack(name));
if ( m_Tracks[name].m_Paths.empty() )
return;
m_TrackQueue.push_back(m_Tracks[name]);
m_TrackQueue.back().m_CPA = m_TrackQueue.back().m_Paths.begin();
}
@ -354,7 +363,96 @@ void CCinemaManager::OverrideTrack(const CStrW& name)
{
m_TrackQueue.clear();
debug_assert(HasTrack(name));
if ( m_Tracks[name].m_Paths.empty() )
return;
m_TrackQueue.push_back( m_Tracks[name] );
m_TrackQueue.back().m_CPA = m_TrackQueue.back().m_Paths.begin();
}
void CCinemaManager::SetAllTracks( const std::map<CStrW, CCinemaTrack>& tracks)
{
m_Tracks = tracks;
for ( std::map<CStrW, CCinemaTrack>::iterator it=m_Tracks.begin();
it != m_Tracks.end(); ++it )
{
it->second.m_CPA = it->second.m_Paths.begin();
}
}
void CCinemaManager::SetCurrentTrack(const CStrW& name, bool all, bool current, bool drawLines)
{
debug_assert(HasTrack(name));
m_CurrentTrack = &m_Tracks[name];
m_DrawAllSplines = all;
m_DrawCurrentSpline = current;
m_DrawLines = drawLines;
DrawAllSplines();
}
void CCinemaManager::SetCurrentPath(const int path)
{
debug_assert(m_CurrentTrack);
m_CurrentPath = path;
m_CurrentTrack->m_CPA = m_CurrentTrack->m_Paths.begin() + path;
}
bool CCinemaManager::HasTrack(const CStrW& name) const
{
return m_Tracks.find(name) != m_Tracks.end();
}
void CCinemaManager::DrawAllSplines() const
{
if ( !(m_DrawAllSplines || m_DrawCurrentSpline) )
return;
static const int smoothness = 200;
if ( m_DrawAllSplines )
{
for ( std::vector<CCinemaPath>::iterator it = m_CurrentTrack->m_Paths.begin();
it != m_CurrentTrack->m_Paths.end(); ++it )
{
it->DrawSpline(CVector4D(0.f, 0.f, 1.f, 1.f), smoothness, m_DrawLines);
}
}
if ( m_DrawCurrentSpline && m_CurrentTrack->m_CPA !=
m_CurrentTrack->m_Paths.end() )
{
if ( m_DrawAllSplines )
{
m_CurrentTrack->m_CPA->DrawSpline(CVector4D(1.f, 0.f, 0.f, 1.f),
smoothness, m_DrawLines);
}
else
{
m_CurrentTrack->m_CPA->DrawSpline(CVector4D(0.f, 0.f, 1.f, 1.f),
smoothness, m_DrawLines);
}
}
}
void CCinemaManager::MoveToPointAt(float time)
{
debug_assert(m_CurrentTrack);
StopPlaying();
if ( m_CurrentTrack->m_Paths.empty() )
return;
m_CurrentTrack->m_CPA->m_TimeElapsed = time;
if ( !m_CurrentTrack->Validate() )
return;
m_CurrentTrack->m_CPA->MoveToPointAt(m_CurrentTrack->m_CPA->m_TimeElapsed /
m_CurrentTrack->m_CPA->GetDuration(), m_CurrentTrack->CalculateRotation());
}
void CCinemaManager::MoveToPointAbsolute(float time)
{
debug_assert(m_CurrentTrack);
g_Game->GetView()->GetCinema()->StopPlaying();
if ( m_CurrentTrack->m_Paths.empty() )
return;
m_CurrentTrack->m_CPA = m_CurrentTrack->m_Paths.begin();
m_CurrentTrack->m_AbsoluteTime = m_CurrentTrack->m_CPA->m_TimeElapsed = time;
if (!m_CurrentTrack->ValidateForward())
return;
m_CurrentTrack->m_CPA->MoveToPointAt(m_CurrentTrack->m_CPA->m_TimeElapsed /
m_CurrentTrack->m_CPA->GetDuration(), m_CurrentTrack->CalculateRotation());
}
bool CCinemaManager::Update(float DeltaTime)
{
@ -365,70 +463,3 @@ bool CCinemaManager::Update(float DeltaTime)
}
return true;
}
int CCinemaManager::LoadTracks()
{
unsigned int fileID;
int numTracks;
//NOTE: How do you find the current scenario's cinematics?
FileIOBuf buf; size_t size;
RETURN_ERR(vfs_load("FILENAME", buf, size));
std::istringstream Stream(std::string((const char*)buf, (int)size), std::istringstream::binary);
(void)file_buf_free(buf);
//Read in lone data
Stream >> fileID;
Stream >> numTracks;
if (fileID != 0x0ADC)
{
debug_printf("Cinematic file not found for (FILENAME)!");
return 0;
}
for (int i=0; i < numTracks; i++)
{
CCinemaTrack tmpTrack;
CVector3D tmpPos;
float tmpTime;
int numPaths;
CStr Name;
Stream >> Name;
Stream >> numPaths;
Stream >> tmpTrack.m_StartRotation.X;
Stream >> tmpTrack.m_StartRotation.Y;
Stream >> tmpTrack.m_StartRotation.Z;
for (int j=0; j < numPaths; j++)
{
CCinemaData tmpData;
TNSpline tmpSpline;
int numNodes;
//load main data
Stream >> numNodes;
Stream >> tmpData.m_TotalRotation.X;
Stream >> tmpData.m_TotalRotation.Y;
Stream >> tmpData.m_TotalRotation.Z;
Stream >> tmpData.m_Growth;
tmpData.m_GrowthCount = tmpData.m_Growth;
Stream >> tmpData.m_Switch;
Stream >> tmpData.m_Mode;
Stream >> tmpData.m_Style;
//Get point data for path
for (int x=0; x<numNodes; x++)
{
Stream >> tmpPos.X;
Stream >> tmpPos.Y;
Stream >> tmpPos.Z;
Stream >> tmpTime;
tmpSpline.AddNode( tmpPos, tmpTime );
}
tmpTrack.AddPath(tmpData, tmpSpline);
}
AddTrack(tmpTrack, Name);
}
return 0;
}

View File

@ -2,17 +2,6 @@
#ifndef H_CinemaTracks_H
#define H_CinemaTracks_H
#define EM_IN 0
#define EM_OUT 1
#define EM_INOUT 2
#define EM_OUTIN 3
#define ES_DEFAULT 0
#define ES_GROWTH 1
#define ES_EXPO 2
#define ES_CIRCLE 3
#define ES_SINE 4
#include <list>
#include <map>
#include "ps/CStr.h"
@ -22,6 +11,7 @@
Andrew (aka pyrolink)
Contact: ajdecker1022@msn.com
desc: contains various functions used for cinematic camera tracks
See also: CinemaHandler.cpp, Cinematic.h/.cpp
*/
class CVector3D;
@ -32,15 +22,16 @@ class CCamera;
class CCinemaData
{
public:
CCinemaData() {}
~CCinemaData() {}
CCinemaData() : m_GrowthCount(0), m_Growth(0), m_Switch(0),
m_Mode(0), m_Style(0) {}
virtual ~CCinemaData() {}
const CCinemaData* GetData() const { return this; }
CVector3D m_TotalRotation;
//Distortion variables
float m_GrowthCount;
mutable float m_GrowthCount;
float m_Growth;
float m_Switch;
int m_Mode;
@ -51,112 +42,120 @@ public:
//Once the data is part of the path, it shouldn't be changeable
class CCinemaPath : private CCinemaData, public TNSpline
{
friend class CCinemaTrack;
//friend class CCinemaTrack;
public:
CCinemaPath(const CCinemaData& data, const TNSpline& spline);
~CCinemaPath() { DistStylePtr = NULL; DistModePtr = NULL; }
void ResetRotation(float t);
enum { EM_IN, EM_OUT, EM_INOUT, EM_OUTIN };
enum { ES_DEFAULT, ES_GROWTH, ES_EXPO, ES_CIRCLE, ES_SINE };
//sets camera position to calculated point on spline
void MoveToPointAt(float t, const CVector3D &startRotation);
//void MoveToPointAt(float t);
//Distortion mode functions-change how ratio is passed to distortion style functions
float EaseIn(float t);
float EaseOut(float t);
float EaseInOut(float t);
float EaseOutIn(float t);
float EaseIn(float t) const;
float EaseOut(float t) const;
float EaseInOut(float t) const;
float EaseOutIn(float t) const;
//Distortion style functions
float EaseDefault(float t);
float EaseGrowth(float t);
float EaseExpo(float t);
float EaseCircle(float t);
float EaseSine(float t);
float EaseDefault(float t) const;
float EaseGrowth(float t) const;
float EaseExpo(float t) const;
float EaseCircle(float t) const;
float EaseSine(float t) const;
float (CCinemaPath::*DistStylePtr)(float ratio);
float (CCinemaPath::*DistModePtr)(float ratio);
float (CCinemaPath::*DistStylePtr)(float ratio) const;
float (CCinemaPath::*DistModePtr)(float ratio) const;
const CCinemaData* GetData() const { return CCinemaData::GetData(); }
public:
void DrawSpline(CVector4D RGBA, int smoothness);
void DrawSpline(const CVector4D& RGBA, int smoothness, bool lines) const;
inline CVector3D GetNodePosition(const int index) const { return Node[index].Position; }
inline float GetNodeDuration(const int index) const { return Node[index].Distance; }
inline float GetDuration() const { return MaxDistance; }
inline float GetElapsedTime() const { return m_TimeElapsed; }
const std::vector<SplineData>& GetAllNodes() const { return Node; }
// inline void SetElapsedTime(float time) { m_TimeElapsed = time; }
private:
float m_TimeElapsed;
};
class CCinemaTrack
{
friend class CCinemaManager;
public:
CCinemaTrack() {}
CCinemaTrack();
~CCinemaTrack() {}
void AddPath(CCinemaData& data, TNSpline& spline);
inline void SetTimeScale(float scale) { m_TimeScale = scale; }
void AddPath(const CCinemaData& data, const TNSpline& spline);
void AddPath(const CCinemaPath& path);
inline void SetTimescale(float scale) { m_Timescale = scale; }
inline void SetStartRotation(CVector3D rotation) { m_StartRotation = rotation; }
void UpdateDuration();
//DOES NOT set CPA to Paths.begin(). Returns-false indicates it's finished,
//true means it's still playing.
//Returns false if finished
bool Play(float DeltaTime);
bool Validate();
void MoveToPointAt(float t);
void MoveToPointAbsolute(float time); //Time, not ratio, in terms of track
inline const CVector3D& GetRotation() const { return m_StartRotation; }
inline float GetTimeScale() const { return m_TimeScale; }
inline float GetTimescale() const { return m_Timescale; }
inline float GetTotalDuration() const { return m_TotalDuration; }
inline const std::vector<CCinemaPath>& GetAllPaths() const { return m_Paths; }
private:
std::vector<CCinemaPath> m_Paths;
std::vector<CCinemaPath>::iterator m_CPA; //current path
CVector3D m_StartRotation;
float m_TimeScale; //a negative timescale results in backwards play
float m_Timescale; //a negative timescale results in backwards play
float m_AbsoluteTime; //Current time of track, in absolute terms (not path)
float m_TotalDuration;
bool ValidateForward();
bool ValidateRewind();
CVector3D CalculateRotation();
};
//Class for in game playing of cinematics
//Class for in game playing of cinematics. Should only be instantiated
//in CGameView.
class CCinemaManager
{
public:
CCinemaManager() { m_Active=false; }
CCinemaManager();
~CCinemaManager() {}
void AddTrack(CCinemaTrack track, const CStrW& name);
int LoadTracks(); //Loads tracks from file
//Adds track to list of being played. (Called by triggers?)
//Adds track to list of being played.
void QueueTrack(const CStrW& name, bool queue);
void OverrideTrack(const CStrW& name); //clears track queue and replaces with 'name'
bool Update(float DeltaTime);
//These stop track play, and accept time, not ratio of time
void MoveToPointAt(float time);
void MoveToPointAbsolute(float time); //Time in terms of track
inline void StopPlaying() { m_TrackQueue.clear(); }
void DrawAllSplines() const;
inline bool IsPlaying() const { return !m_TrackQueue.empty(); }
bool HasTrack(const CStrW& name) const { return m_Tracks.find(name) != m_Tracks.end(); }
bool HasTrack(const CStrW& name) const;
inline bool IsActive() const { return m_Active; }
inline void SetActive(bool active) { m_Active=active; }
CCinemaTrack* GetTrack(const CStrW& name) { debug_assert(HasTrack(name)); return &m_Tracks[name]; }
inline const std::map<CStrW, CCinemaTrack>& GetAllTracks() { return m_Tracks; }
inline void SetAllTracks( const std::map<CStrW, CCinemaTrack>& tracks) { m_Tracks = tracks; }
void SetAllTracks( const std::map<CStrW, CCinemaTrack>& tracks);
void SetCurrentTrack(const CStrW& name, bool all, bool current, bool lines);
void SetCurrentPath(int path);
private:
bool m_Active;
bool m_Active, m_DrawCurrentSpline, m_DrawAllSplines, m_DrawLines;
int m_CurrentPath;
CCinemaTrack* m_CurrentTrack;
std::map<CStrW, CCinemaTrack> m_Tracks;
std::list<CCinemaTrack> m_TrackQueue;
};

View File

@ -431,7 +431,6 @@ void CGameView::Update(float DeltaTime)
if(!m_TrackManager.Update(DeltaTime))
ResetCamera();
}
m_ViewCamera.UpdateFrustum();
return;
}

View File

@ -14,6 +14,7 @@
#include "maths/MathUtil.h"
#include "Camera.h"
#include "graphics/Patch.h"
#include "graphics/GameView.h"
#include "renderer/WaterManager.h"
#include "renderer/SkyManager.h"
@ -38,7 +39,7 @@ CMapReader::CMapReader()
// LoadMap: try to load the map from given file; reinitialise the scene to new data if successful
void CMapReader::LoadMap(const char* filename, CTerrain *pTerrain_,
CUnitManager *pUnitMan_, WaterManager* pWaterMan_, SkyManager* pSkyMan_,
CLightEnv *pLightEnv_, CCamera *pCamera_)
CLightEnv *pLightEnv_, CCamera *pCamera_, CCinemaManager* pCinema_)
{
// latch parameters (held until DelayedLoadFinished)
pTerrain = pTerrain_;
@ -47,6 +48,7 @@ void CMapReader::LoadMap(const char* filename, CTerrain *pTerrain_,
pCamera = pCamera_;
pWaterMan = pWaterMan_;
pSkyMan = pSkyMan_;
pCinema = pCinema_;
// [25ms]
unpacker.Read(filename, "PSMP");
@ -180,6 +182,57 @@ int CMapReader::UnpackTerrain()
return 0;
}
int CMapReader::UnpackCinema()
{
size_t numTracks;
unpacker.UnpackRaw(&numTracks, (u32)sizeof(size_t));
for ( size_t track=0; track < numTracks; ++track )
{
CCinemaTrack trackObj;
std::vector<CCinemaPath> paths;
CStr name;
size_t numPaths;
CVector3D startRotation;
float timescale;
unpacker.UnpackString(name);
unpacker.UnpackRaw(&timescale, sizeof(float));
unpacker.UnpackRaw(&numPaths, sizeof(size_t));
unpacker.UnpackRaw(&startRotation, sizeof(CVector3D));
trackObj.SetStartRotation(startRotation);
trackObj.SetTimescale(timescale);
for ( size_t i=0; i<numPaths; ++i )
{
TNSpline spline;
size_t numNodes;
CCinemaData data;
if ( i != 0 )
unpacker.UnpackRaw(&data.m_TotalRotation, sizeof(CVector3D));
unpacker.UnpackRaw(&data.m_Mode, sizeof(data.m_Mode));
unpacker.UnpackRaw(&data.m_Style, sizeof(data.m_Style));
unpacker.UnpackRaw(&data.m_Growth, sizeof(data.m_Growth));
unpacker.UnpackRaw(&data.m_Switch, sizeof(data.m_Switch));
unpacker.UnpackRaw(&numNodes, sizeof(size_t));
data.m_GrowthCount = data.m_Growth;
for ( size_t j=0; j < numNodes; ++j )
{
CVector3D position;
float distance;
unpacker.UnpackRaw(&position, sizeof(position));
unpacker.UnpackRaw(&distance, sizeof(distance));
spline.AddNode(position, distance);
}
trackObj.AddPath(data, spline);
}
m_Tracks[CStrW(name)] = trackObj;
}
return 0;
}
// ApplyData: take all the input data, and rebuild the scene from it
int CMapReader::ApplyData()
@ -258,6 +311,7 @@ private:
CMapReader& m_MapReader;
int el_entity;
int el_tracks;
int el_template, el_player;
int el_position, el_orientation;
int el_nonentity;
@ -279,6 +333,7 @@ private:
void ReadEnvironment(XMBElement parent);
void ReadCamera(XMBElement parent);
void ReadCinema(XMBElement parent);
int ReadEntities(XMBElement parent, double end_time);
int ReadNonEntities(XMBElement parent, double end_time);
@ -301,6 +356,7 @@ void CXMLReader::Init(const CStr& xml_filename)
#define EL(x) el_##x = xmb_file.getElementID(#x)
#define AT(x) at_##x = xmb_file.getAttributeID(#x)
EL(entity);
EL(tracks);
EL(template);
EL(player);
EL(position);
@ -480,7 +536,118 @@ void CXMLReader::ReadCamera(XMBElement parent)
m_MapReader.pCamera->m_Orientation.Translate(translation);
m_MapReader.pCamera->UpdateFrustum();
}
void CXMLReader::ReadCinema(XMBElement parent)
{
#define EL(x) int el_##x = xmb_file.getElementID(#x)
#define AT(x) int at_##x = xmb_file.getAttributeID(#x)
EL(track);
EL(startrotation);
EL(path);
EL(rotation);
EL(distortion);
EL(node);
AT(name);
AT(timescale);
AT(mode);
AT(style);
AT(growth);
AT(switch);
AT(x);
AT(y);
AT(z);
AT(t);
#undef EL
#undef AT
std::map<CStrW, CCinemaTrack> trackList;
XERO_ITER_EL(parent, element)
{
int elementName = element.getNodeName();
if ( elementName == el_track )
{
CCinemaTrack track;
XMBAttributeList attrs = element.getAttributes();
CStrW name( CStr(attrs.getNamedItem(at_name)) );
float timescale = CStr(attrs.getNamedItem(at_timescale)).ToFloat();
track.SetTimescale(timescale);
XERO_ITER_EL(element, trackChild)
{
elementName = trackChild.getNodeName();
if ( elementName == el_startrotation )
{
attrs = trackChild.getAttributes();
float x = CStr(attrs.getNamedItem(at_x)).ToFloat();
float y = CStr(attrs.getNamedItem(at_y)).ToFloat();
float z = CStr(attrs.getNamedItem(at_z)).ToFloat();
track.SetStartRotation(CVector3D(x, y, z));
}
else if ( elementName == el_path )
{
CCinemaData pathData;
TNSpline spline, backwardSpline;
XERO_ITER_EL(trackChild, pathChild)
{
elementName = pathChild.getNodeName();
attrs = pathChild.getAttributes();
if ( elementName == el_rotation )
{
float x = CStr(attrs.getNamedItem(at_x)).ToFloat();
float y = CStr(attrs.getNamedItem(at_y)).ToFloat();
float z = CStr(attrs.getNamedItem(at_z)).ToFloat();
pathData.m_TotalRotation = CVector3D(x, y, z);
}
else if ( elementName == el_distortion )
{
pathData.m_Mode = CStr(attrs.getNamedItem(at_mode)).ToInt();
pathData.m_Style = CStr(attrs.getNamedItem(at_style)).ToInt();
pathData.m_Growth = CStr(attrs.getNamedItem(at_growth)).ToInt();
pathData.m_Switch = CStr(attrs.getNamedItem(at_switch)).ToInt();
}
else if ( elementName == el_node )
{
SplineData data;
data.Position.X = CStr(attrs.getNamedItem(at_x)).ToFloat();
data.Position.Y = CStr(attrs.getNamedItem(at_y)).ToFloat();
data.Position.Z = CStr(attrs.getNamedItem(at_z)).ToFloat();
data.Distance = CStr(attrs.getNamedItem(at_t)).ToFloat();
backwardSpline.AddNode(data.Position, data.Distance);
}
else
debug_warn("Invalid cinematic element for path child");
} //node loop
CCinemaPath temp(pathData, backwardSpline);
const std::vector<SplineData>& nodes = temp.GetAllNodes();
if ( nodes.empty() )
{
debug_warn("Failure loading cinematics");
return;
}
for ( std::vector<SplineData>::const_reverse_iterator
it=nodes.rbegin(); it != nodes.rend(); ++it )
{
spline.AddNode(it->Position, it->Distance);
}
track.AddPath(pathData, spline);
} // == el_path
else
debug_warn("Invalid cinematic element for track child");
}
trackList[name] = track;
}
else
debug_warn("Invalid cinematic element for root track child");
}
g_Game->GetView()->GetCinema()->SetAllTracks(trackList);
}
int CXMLReader::ReadEntities(XMBElement parent, double end_time)
{
@ -663,6 +830,10 @@ int CXMLReader::ProgressiveRead()
if (ret != 0) // error or timed out
return ret;
}
else if (name == "Tracks")
{
ReadCinema(node);
}
else
debug_warn("Invalid map XML data");

View File

@ -5,6 +5,7 @@
#include "lib/res/handle.h"
#include "ps/CStr.h"
#include "LightEnv.h"
#include "CinemaTrack.h"
#include "ps/FileUnpacker.h"
class CObjectEntry;
@ -14,6 +15,7 @@ class WaterManager;
class SkyManager;
class CLightEnv;
class CCamera;
class CCinemaManager;
class CXMLReader;
@ -26,11 +28,13 @@ public:
CMapReader();
// LoadMap: try to load the map from given file; reinitialise the scene to new data if successful
void LoadMap(const char* filename, CTerrain *pTerrain, CUnitManager *pUnitMan,
WaterManager* pWaterMan, SkyManager* pSkyMan, CLightEnv *pLightEnv, CCamera *pCamera);
WaterManager* pWaterMan, SkyManager* pSkyMan, CLightEnv *pLightEnv, CCamera *pCamera, CCinemaManager* pCinema);
private:
// UnpackTerrain: unpack the terrain from the input stream
int UnpackTerrain();
//UnpackCinema: unpack the cinematic tracks from the input stream
int UnpackCinema();
// UnpackObjects: unpack world objects from the input stream
void UnpackObjects();
// UnpackObjects: unpack lighting parameters from the input stream
@ -56,6 +60,8 @@ private:
std::vector<Handle> m_TerrainTextures;
// tile descriptions for each tile
std::vector<STileDesc> m_Tiles;
// cinematic tracks used by cinema manager
std::map<CStrW, CCinemaTrack> m_Tracks;
// list of object types used by map
std::vector<CStr> m_ObjectTypes;
// descriptions for each objects
@ -71,6 +77,7 @@ private:
SkyManager* pSkyMan;
CLightEnv* pLightEnv;
CCamera* pCamera;
CCinemaManager* pCinema;
CStr filename_xml;
// UnpackTerrain generator state

View File

@ -4,6 +4,7 @@
#include "lib/res/file/vfs.h"
#include "Camera.h"
#include "CinemaTrack.h"
#include "LightEnv.h"
#include "MapReader.h"
#include "MapWriter.h"
@ -18,6 +19,7 @@
#include "UnitManager.h"
#include "maths/MathUtil.h"
#include "maths/NUSpline.h"
#include "ps/Loader.h"
#include "ps/Player.h"
#include "ps/VFSUtil.h"
@ -38,7 +40,7 @@ CMapWriter::CMapWriter()
// SaveMap: try to save the current map to the given file
void CMapWriter::SaveMap(const char* filename, CTerrain* pTerrain,
CUnitManager* pUnitMan, WaterManager* pWaterMan, SkyManager* pSkyMan,
CLightEnv* pLightEnv, CCamera* pCamera)
CLightEnv* pLightEnv, CCamera* pCamera, CCinemaManager* pCinema)
{
CFilePacker packer(FILE_VERSION, "PSMP");
@ -50,7 +52,7 @@ void CMapWriter::SaveMap(const char* filename, CTerrain* pTerrain,
CStr filename_xml (filename);
filename_xml = filename_xml.Left(filename_xml.Length()-4) + ".xml";
WriteXML(filename_xml, pUnitMan, pWaterMan, pSkyMan, pLightEnv, pCamera);
WriteXML(filename_xml, pUnitMan, pWaterMan, pSkyMan, pLightEnv, pCamera, pCinema);
}
///////////////////////////////////////////////////////////////////////////////////////////////////
@ -156,12 +158,9 @@ void CMapWriter::PackTerrain(CFilePacker& packer, CTerrain* pTerrain)
// pack tile data
packer.PackRaw(&tiles[0],(u32)(sizeof(STileDesc)*tiles.size()));
}
void CMapWriter::WriteXML(const char* filename,
CUnitManager* pUnitMan, WaterManager* pWaterMan, SkyManager* pSkyMan,
CLightEnv* pLightEnv, CCamera* pCamera)
CLightEnv* pLightEnv, CCamera* pCamera, CCinemaManager* pCinema)
{
Handle h = vfs_open(filename, FILE_WRITE_TO_TARGET|FILE_NO_AIO);
if (h <= 0)
@ -318,6 +317,71 @@ void CMapWriter::WriteXML(const char* filename,
}
}
}
const std::map<CStrW, CCinemaTrack>& tracks = pCinema->GetAllTracks();
std::map<CStrW, CCinemaTrack>::const_iterator it = tracks.begin();
{
XML_Element("Tracks");
for ( ; it != tracks.end(); it++ )
{
const std::vector<CCinemaPath>& paths = it->second.GetAllPaths();
CStrW name = it->first;
size_t numPaths = paths.size();
CVector3D startRotation = it->second.GetRotation();
float timescale = it->second.GetTimescale();
{
XML_Element("Track");
XML_Attribute("name", name);
XML_Attribute("timescale", timescale);
{
XML_Element("StartRotation");
XML_Attribute("x", startRotation.X);
XML_Attribute("y", startRotation.Y);
XML_Attribute("z", startRotation.Z);
}
for ( size_t i=0; i<numPaths; ++i )
{
const std::vector<SplineData>& nodes =
paths[i].GetAllNodes();
const CCinemaData* data = paths[i].GetData();
{
XML_Element("Path");
{
CVector3D rot = data->m_TotalRotation;
XML_Element("Rotation");
XML_Attribute("x", rot.X);
XML_Attribute("y", rot.Y);
XML_Attribute("z", rot.Z);
}
{
XML_Element("Distortion");
XML_Attribute("mode", data->m_Mode);
XML_Attribute("style", data->m_Style);
XML_Attribute("growth", data->m_Growth);
XML_Attribute("switch", data->m_Switch);
}
for ( int j=(int)nodes.size()-1; j >= 0; --j )
{
{
XML_Element("Node");
XML_Attribute("x", nodes[j].Position.X);
XML_Attribute("y", nodes[j].Position.Y);
XML_Attribute("z", nodes[j].Position.Z);
XML_Attribute("t", nodes[j].Distance);
}
}
} //path data
}
} //track data
}
} //(Did this really happen) - I blame XML
}
if (! XML_StoreVFS(h))
@ -331,7 +395,7 @@ void CMapWriter::WriteXML(const char* filename,
// RewriteAllMaps
void CMapWriter::RewriteAllMaps(CTerrain* pTerrain, CUnitManager* pUnitMan,
WaterManager* pWaterMan, SkyManager* pSkyMan,
CLightEnv* pLightEnv, CCamera* pCamera)
CLightEnv* pLightEnv, CCamera* pCamera, CCinemaManager* pCinema)
{
VFSUtil::FileList files;
VFSUtil::FindFiles("maps/scenarios", "*.pmp", files);
@ -340,13 +404,13 @@ void CMapWriter::RewriteAllMaps(CTerrain* pTerrain, CUnitManager* pUnitMan,
{
CMapReader* reader = new CMapReader;
LDR_BeginRegistering();
reader->LoadMap(*it, pTerrain, pUnitMan, pWaterMan, pSkyMan, pLightEnv, pCamera);
reader->LoadMap(*it, pTerrain, pUnitMan, pWaterMan, pSkyMan, pLightEnv, pCamera, pCinema);
LDR_EndRegistering();
LDR_NonprogressiveLoad();
CStr n (*it);
n.Replace("scenarios/", "scenarios/new/");
CMapWriter writer;
writer.SaveMap(n, pTerrain, pUnitMan, pWaterMan, pSkyMan, pLightEnv, pCamera);
writer.SaveMap(n, pTerrain, pUnitMan, pWaterMan, pSkyMan, pLightEnv, pCamera, pCinema);
}
}

View File

@ -10,6 +10,7 @@ class CLightEnv;
class CTerrain;
class CUnitManager;
class CCamera;
class CCinemaManager;
class WaterManager;
class SkyManager;
@ -19,11 +20,11 @@ public:
// constructor
CMapWriter();
// SaveMap: try to save the current map to the given file
void SaveMap(const char* filename, CTerrain* pTerr, CUnitManager* pUnitMan, WaterManager* pWaterMan, SkyManager* pSkyMan, CLightEnv* pLightEnv, CCamera* pCamera);
void SaveMap(const char* filename, CTerrain* pTerr, CUnitManager* pUnitMan, WaterManager* pWaterMan, SkyManager* pSkyMan, CLightEnv* pLightEnv, CCamera* pCamera, CCinemaManager* pCinema);
// RewriteAllMaps: for use during development: load/save all maps, to
// update them to the newest format.
static void RewriteAllMaps(CTerrain* pTerrain, CUnitManager* pUnitMan, WaterManager* pWaterMan, SkyManager* pSkyMan, CLightEnv* pLightEnv, CCamera* pCamera);
static void RewriteAllMaps(CTerrain* pTerrain, CUnitManager* pUnitMan, WaterManager* pWaterMan, SkyManager* pSkyMan, CLightEnv* pLightEnv, CCamera* pCamera, CCinemaManager* pCinema);
private:
// PackMap: pack the current world into a raw data stream
@ -37,7 +38,7 @@ private:
std::vector<STileDesc>& tileIndices);
// WriteXML: output some other data (entities, etc) in XML format
void WriteXML(const char* filename, CUnitManager* pUnitMan, WaterManager* pWaterMan, SkyManager* pSkyMan, CLightEnv* pLightEnv, CCamera* pCamera);
void WriteXML(const char* filename, CUnitManager* pUnitMan, WaterManager* pWaterMan, SkyManager* pSkyMan, CLightEnv* pLightEnv, CCamera* pCamera, CCinemaManager* pCinema);
};
#endif

View File

@ -76,7 +76,7 @@ void RNSpline::BuildSpline()
}
// spline access function. time is 0 -> 1
CVector3D RNSpline::GetPosition(float time)
CVector3D RNSpline::GetPosition(float time) const
{
if ( NodeCount < 2 )
return CVector3D(0.0f, 0.0f, 0.0f);

View File

@ -21,9 +21,10 @@ class RNSpline
public:
RNSpline() { NodeCount = 0; }
virtual ~RNSpline() {}
void AddNode(const CVector3D &pos);
void BuildSpline();
CVector3D GetPosition(float time);
CVector3D GetPosition(float time) const;
float MaxDistance;
int NodeCount;
@ -37,6 +38,7 @@ protected:
class SNSpline : public RNSpline
{
public:
virtual ~SNSpline() {}
void BuildSpline(){ RNSpline::BuildSpline(); Smooth(); Smooth(); Smooth(); }
void Smooth();
};
@ -44,6 +46,7 @@ public:
class TNSpline : public SNSpline
{
public:
virtual ~TNSpline() {}
void AddNode(const CVector3D &pos, float timePeriod);
void PushNode() { Node.push_back( SplineData() ); }
void InsertNode(const int index, const CVector3D &pos, float timePeriod);

View File

@ -91,6 +91,35 @@ void CQuaternion::FromEulerAngles (float x, float y, float z)
(*this) = QYaw * QPitch * QRoll;
}
CVector3D CQuaternion::ToEulerAngles()
{
float heading, attitude, bank;
float sqw = m_W * m_W;
float sqx = m_V.X*m_V.X;
float sqy = m_V.Y*m_V.Y;
float sqz = m_V.Z*m_V.Z;
float unit = sqx + sqy + sqz + sqw; // if normalised is one, otherwise is correction factor
float test = m_V.X*m_V.Y + m_V.Z*m_W;
if (test > (.5f-EPSILON)*unit)
{ // singularity at north pole
heading = 2 * atan2( m_V.X, m_W);
attitude = PI/2;
bank = 0;
}
else if (test < (-.5f+EPSILON)*unit)
{ // singularity at south pole
heading = -2 * atan2(m_V.X, m_W);
attitude = -PI/2;
bank = 0;
}
else
{
heading = atan2(2.f * (m_V.X*m_V.Y + m_V.Z*m_W),(sqx - sqy - sqz + sqw));
bank = atan2(2.f * (m_V.Y*m_V.Z + m_V.X*m_W),(-sqx - sqy + sqz + sqw));
attitude = asin(-2.f * (m_V.X*m_V.Z - m_V.Y*m_W));
}
return CVector3D(bank, attitude, heading);
}
CMatrix3D CQuaternion::ToMatrix () const
{

View File

@ -33,6 +33,7 @@ public:
CQuaternion &operator *= (const CQuaternion &quat);
void FromEulerAngles (float x, float y, float z);
CVector3D ToEulerAngles();
//convert the quaternion to matrix
CMatrix3D ToMatrix() const;

View File

@ -365,12 +365,18 @@ void Render()
PROFILE_END( "render entity bars" );
glPopAttrib();
glMatrixMode(GL_MODELVIEW);
// Depth test is now enabled
PROFILE_START( "render rally points" );
g_Selection.renderRallyPoints();
g_Mouseover.renderRallyPoints();
PROFILE_END( "render rally points" );
PROFILE_START( "render cinematic splines" );
//Sets/resets renderering properties itself
g_Game->GetView()->GetCinema()->DrawAllSplines();
PROFILE_END( "render cinematic splines" );
}
else
{

View File

@ -58,7 +58,7 @@ void CWorld::Initialize(CGameAttributes *pAttribs)
try {
reader = new CMapReader;
reader->LoadMap(mapfilename, m_Terrain, m_UnitManager, g_Renderer.GetWaterManager(),
g_Renderer.GetSkyManager(), &g_LightEnv, m_pGame->GetView()->GetCamera());
g_Renderer.GetSkyManager(), &g_LightEnv, m_pGame->GetView()->GetCamera(), m_pGame->GetView()->GetCinema());
// fails immediately, or registers for delay loading
} catch (PSERROR_File&) {
delete reader;
@ -89,5 +89,6 @@ void CWorld::RewriteMap()
{
CMapWriter::RewriteAllMaps(m_Terrain, m_UnitManager,
g_Renderer.GetWaterManager(), g_Renderer.GetSkyManager(),
&g_LightEnv, m_pGame->GetView()->GetCamera());
&g_LightEnv, m_pGame->GetView()->GetCamera(),
m_pGame->GetView()->GetCinema());
}

View File

@ -1,15 +1,75 @@
/* Andrew Decker, a.k.a pyrolink
Contact ajdecker1022@msn.com
Desc: receives user input and communicates with the engine
to perform various cinematic functions.
*/
#include "../Common/Sidebar.h"
#include "GameInterface/Messages.h"
class TrackListCtrl;
class PathListCtrl;
class NodeListCtrl;
class CinemaSliderBox;
class CinemaSpinnerBox;
class CinemaInfoBox;
class CinematicBottomBar;
class wxImage;
class CinematicSidebar : public Sidebar
{
//For ease (from lazyness)
friend class CinemaButtonBox;
friend class TrackSlider;
friend class PathSlider;
public:
CinematicSidebar(wxWindow* sidebarContainer, wxWindow* bottomBarContainer);
//The actual data is stored in bottom bar, but is controled from here
void SelectTrack(ssize_t n);
void SelectPath(ssize_t n);
void SelectSplineNode(ssize_t n);
//avoid excessive shareable->vector conversion with size paramater
void SelectSplineNode(ssize_t n, ssize_t size = -1);
void AddTrack(float x, float y, float z, std::wstring& name,
int count);
void AddPath(int x, int y, int z, int count);
void AddNode(float x, float y, float z, int count);
void UpdateTrack(std::wstring name, float timescale);
void UpdateTrack(float x, float y, float z);
void UpdatePath(int x, int y, int z, ssize_t index=-1);
void UpdateNode(float x, float y, float z, float t=-1);
void DeleteTrack();
void DeletePath();
void DeleteNode();
void SetSpinners(CinemaSpinnerBox* box) { m_SpinnerBox = box; }
const AtlasMessage::sCinemaTrack* GetCurrentTrack();
AtlasMessage::sCinemaPath GetCurrentPath();
AtlasMessage::sCinemaSplineNode GetCurrentNode();
int GetSelectedTrack() { return m_SelectedTrack; }
int GetSelectedPath() { return m_SelectedPath; }
int GetSelectedNode() { return m_SelectedSplineNode; }
void GotoNode(ssize_t index=-1);
void GetAbsoluteRotation(int& x, int& y, int& z, ssize_t index=-1);
float UpdateSelectedPath();
void UpdatePathInfo(int mode, int style, float growth, float change,
bool drawAll, bool drawCurrent, bool drawLine);
void UpdateSpinners();
void UpdateTexts();
void UpdateEngineData();
float m_TimeElapsed; //path time
float m_AbsoluteTime; //track time
bool m_RotationAbsolute; //rotation display flag in spinner box
bool m_UpdatePathEcho;
bool m_Playing;
protected:
virtual void OnFirstDisplay();
@ -18,11 +78,28 @@ private:
// Stores all cinematics data for this map. Initialised by OnFirstDisplay.
// Sent back to the game by [TODO]. (TODO: handle 'undo' correctly)
std::vector<AtlasMessage::sCinemaTrack> m_Tracks;
CinemaButtonBox* m_IconSizer;
ssize_t m_SelectedTrack; // -1 for none
ssize_t m_SelectedPath; // -1 for none
ssize_t m_SelectedSplineNode; // -1 for none
TrackListCtrl* m_TrackList;
PathListCtrl* m_PathList;
NodeListCtrl* m_NodeList;
wxListCtrl* m_TrackList;
wxListCtrl* m_PathList;
CinemaSliderBox* m_SliderBox;
CinemaSpinnerBox* m_SpinnerBox; //We must update the display
CinemaInfoBox* m_InfoBox; // ^same^
CinematicBottomBar* m_CinemaBottomBar;
struct eCinemaButton
{
enum {
previous/*, rewind, reverse*/, stop,
play, pause, /*forward,*/ next };
};
wxImage LoadIcon(const wxString& filename);
void LoadIcons();
};

View File

@ -199,8 +199,14 @@ bool BeginAtlas(int argc, char* argv[], void* dll)
// Be nice to the processor (by sleeping lots) if we're not doing anything
// useful, and nice to the user (by just yielding to other threads) if we are
if (time - last_activity > 0.5) // if there was no recent activity...
bool yield = time - last_activity > 0.5;
if ( state.worldloaded )
{
if ( g_Game->GetView()->GetCinema()->IsPlaying() )
g_Game->GetView()->GetCinema()->Update(state.frameLength);
yield = false;
}
if (yield) // if there was no recent activity...
{
double sleepUntil = time + 0.5; // only redraw at 2fps
while (time < sleepUntil)

View File

@ -16,6 +16,8 @@ namespace AtlasMessage {
MESSAGEHANDLER(ScrollConstant)
{
if ( g_Game->GetView()->GetCinema()->IsPlaying() )
return;
if (msg->dir < 0 || msg->dir > 3)
{
debug_warn("ScrollConstant: invalid direction");
@ -28,6 +30,8 @@ MESSAGEHANDLER(ScrollConstant)
MESSAGEHANDLER(Scroll)
{
if ( g_Game->GetView()->GetCinema()->IsPlaying() )
return;
static CVector3D targetPos;
static float targetDistance = 0.f;
@ -75,11 +79,15 @@ MESSAGEHANDLER(Scroll)
MESSAGEHANDLER(SmoothZoom)
{
if ( g_Game->GetView()->GetCinema()->IsPlaying() )
return;
g_GameLoop->input.zoomDelta += msg->amount;
}
MESSAGEHANDLER(RotateAround)
{
if ( g_Game->GetView()->GetCinema()->IsPlaying() )
return;
static CVector3D focusPos;
static float lastX = 0.f, lastY = 0.f;

View File

@ -7,31 +7,33 @@
#include "ps/CStr.h"
#include "ps/CLogger.h"
#include "ps/VFSUtil.h"
#include "lib/res/graphics/tex.h"
#include "maths/Quaternion.h"
#include "lib/res/graphics/ogl_tex.h"
#define LOG_CATEGORY "Cinema"
namespace AtlasMessage {
sCinemaTrack ConstructCinemaTrack(const CCinemaTrack& _track)
sCinemaTrack ConstructCinemaTrack(const CCinemaTrack& data)
{
sCinemaTrack track;
const CVector3D& rotation = _track.GetRotation();
track.x = rotation.X;
track.y = rotation.Y;
track.z = rotation.Z;
track.timescale = _track.GetTimeScale();
track.duration = _track.GetTotalDuration();
const CVector3D& rotation = data.GetRotation();
track.x = RADTODEG(rotation.X);
track.y = RADTODEG(rotation.Y);
track.z = RADTODEG(rotation.Z);
track.timescale = data.GetTimescale();
track.duration = data.GetTotalDuration();
return track;
}
sCinemaPath ConstructCinemaPath(const CCinemaData* data)
sCinemaPath ConstructCinemaPath(const CCinemaPath* source)
{
sCinemaPath path;
const CCinemaData* data = source->GetData();
path.x = data->m_TotalRotation.X;
path.y = data->m_TotalRotation.Y;
path.z = data->m_TotalRotation.Z;
path.x = RADTODEG(data->m_TotalRotation.X);
path.y = RADTODEG(data->m_TotalRotation.Y);
path.z = RADTODEG(data->m_TotalRotation.Z);
path.mode = data->m_Mode;
path.style = data->m_Style;
path.growth = data->m_Growth;
@ -42,7 +44,8 @@ sCinemaPath ConstructCinemaPath(const CCinemaData* data)
CCinemaData ConstructCinemaData(const sCinemaPath& path)
{
CCinemaData data;
data.m_TotalRotation = CVector3D(path.x, path.y, path.z);
data.m_TotalRotation = CVector3D(DEGTORAD(path.x), DEGTORAD(path.y),
DEGTORAD(path.z));
data.m_Growth = data.m_GrowthCount = path.growth;
data.m_Switch = path.change;
data.m_Mode = path.mode;
@ -77,7 +80,7 @@ std::vector<sCinemaTrack> GetCurrentTracks()
for ( std::vector<CCinemaPath>::const_iterator it2=paths.begin(); it2!=paths.end(); it2++ )
{
sCinemaPath path = ConstructCinemaPath(it2->GetData()); //Get data part of path
sCinemaPath path = ConstructCinemaPath(&*it2);
const std::vector<SplineData>& nodes = it2->GetAllNodes();
std::vector<sCinemaSplineNode> atlasNodes;
@ -86,7 +89,19 @@ std::vector<sCinemaTrack> GetCurrentTracks()
{
atlasNodes.push_back( ConstructCinemaNode(nodes[i]) );
}
if ( !atlasNodes.empty() )
{
float back = atlasNodes.back().t;
if ( atlasNodes.size() > 2 )
{
for ( size_t i=atlasNodes.size()-2; i>0; --i )
atlasNodes[i].t = atlasNodes[i-1].t;
}
atlasNodes.back().t = atlasNodes.front().t;
atlasNodes.front().t = back;
}
path.nodes = atlasNodes;
path.duration = it2->GetDuration();
atlasPaths.push_back(path);
}
atlasTrack.paths = atlasPaths;
@ -102,77 +117,65 @@ void SetCurrentTracks(const std::vector<sCinemaTrack>& atlasTracks)
{
CStrW trackName(*it->name);
tracks[trackName] = CCinemaTrack();
tracks[trackName].SetStartRotation( CVector3D(it->x, it->y, it->z) );
tracks[trackName].SetTimeScale(it->timescale);
tracks[trackName].SetStartRotation( CVector3D(DEGTORAD(it->x),
DEGTORAD(it->y), DEGTORAD(it->z)) );
tracks[trackName].SetTimescale(it->timescale);
const std::vector<sCinemaPath> paths = *it->paths;
for ( std::vector<sCinemaPath>::const_iterator it2=paths.begin(); it2!=paths.end(); it2++ )
size_t i=0;
for ( std::vector<sCinemaPath>::const_iterator it2=paths.begin();
it2!=paths.end(); it2++, ++i )
{
const sCinemaPath& atlasPath = *it2;
const std::vector<sCinemaSplineNode> nodes = *atlasPath.nodes;
TNSpline spline;
CCinemaData data = ConstructCinemaData(atlasPath);
for ( size_t i=0; i<nodes.size(); ++i )
for ( size_t j=0; j<nodes.size(); ++j )
{
spline.AddNode( CVector3D(nodes[i].x, nodes[i].y, nodes[i].z), nodes[i].t );
spline.AddNode( CVector3D(nodes[j].x, nodes[j].y, nodes[j].z), nodes[j].t );
}
tracks[trackName].AddPath(data, spline);
}
}
g_Game->GetView()->GetCinema()->SetAllTracks(tracks);
}
QUERYHANDLER(GetCinemaIcons)
QUERYHANDLER(GetCameraInfo)
{
VFSUtil::FileList files;
VFSUtil::FindFiles("art/textures/ui/session/icons/cinematic/","", files);
FileIOBuf buf;
size_t bufsize;
std::vector<sCinemaIcon> iconList;
sCameraInfo info;
CMatrix3D* cam = &g_Game->GetView()->GetCamera()->m_Orientation;
for ( VFSUtil::FileList::iterator it=files.begin(); it != files.end(); it++ )
{
if ( tex_is_known_extension(*it) )
{
const char* file = it->c_str();
if ( vfs_load(file, buf, bufsize) < 0 )
{
LOG( ERROR, LOG_CATEGORY, "Failure on loading cinematic icon %s", file );
file_buf_free(buf);
continue;
}
sCinemaIcon icon;
std::wstring name( CStrW( *it->AfterLast("/").BeforeFirst(".").c_str() ) );
std::vector<unsigned char> data;
data.resize(sizeof(data));
//Copy the buffer to the icon
for ( size_t i=0; *buf++; i++ )
{
data.push_back(*buf);
}
file_buf_free(buf);
icon.name = name;
icon.imageData = data;
iconList.push_back(icon);
}
}
msg->images = iconList;
CQuaternion quatRot = cam->GetRotation();
quatRot.Normalize();
CVector3D rotation = quatRot.ToEulerAngles();
rotation.X = RADTODEG(rotation.X);
rotation.Y = RADTODEG(rotation.Y);
rotation.Z = RADTODEG(rotation.Z);
CVector3D translation = cam->GetTranslation();
info.pX = translation.X;
info.pY = translation.Y;
info.pZ = translation.Z;
info.rX = rotation.X;
info.rY = rotation.Y;
info.rZ = rotation.Z;
msg->info = info;
}
MESSAGEHANDLER(CinemaMovement)
MESSAGEHANDLER(CinemaEvent)
{
CCinemaManager* manager = g_Game->GetView()->GetCinema();
CCinemaTrack* track = manager->GetTrack(*msg->track);
manager->SetCurrentTrack(*msg->track, msg->drawAll,
msg->drawCurrent, msg->lines);
if ( msg->mode == eCinemaMovementMode::SMOOTH )
if ( msg->mode == eCinemaEventMode::SMOOTH )
manager->OverrideTrack(*msg->track);
else if ( msg->mode == eCinemaMovementMode::IMMEDIATE_PATH )
track->MoveToPointAt(msg->t);
else if ( msg->mode == eCinemaMovementMode::IMMEDIATE_TRACK )
track->MoveToPointAbsolute(msg->t);
else if ( msg->mode == eCinemaEventMode::IMMEDIATE_PATH )
manager->MoveToPointAt(msg->t);
else if ( msg->mode == eCinemaEventMode::IMMEDIATE_TRACK )
manager->MoveToPointAbsolute(msg->t);
else
manager->SetCurrentPath((int)msg->t);
}
BEGIN_COMMAND(SetCinemaTracks)

View File

@ -110,7 +110,7 @@ MESSAGEHANDLER(SaveMap)
writer.SaveMap(CStr(L"maps/scenarios/" + *msg->filename),
g_Game->GetWorld()->GetTerrain(), g_Game->GetWorld()->GetUnitManager(),
g_Renderer.GetWaterManager(), g_Renderer.GetSkyManager(),
&g_LightEnv, g_Game->GetView()->GetCamera());
&g_LightEnv, g_Game->GetView()->GetCamera(), g_Game->GetView()->GetCinema());
}
}

View File

@ -279,6 +279,10 @@ COMMAND(SetObjectSettings, NOMERGE,
struct sCinemaSplineNode
{
Shareable<float> x, y, z, t;
public:
sCinemaSplineNode(float px, float py, float pz) : x(px), y(py), z(pz), t(0.0f){}
sCinemaSplineNode() {}
void SetTime(float _t) { t = _t; }
};
SHAREABLE_STRUCT(sCinemaSplineNode);
@ -287,6 +291,22 @@ struct sCinemaPath
Shareable<std::vector<AtlasMessage::sCinemaSplineNode> > nodes;
Shareable<float> duration, x, y, z;
Shareable<int> mode, growth, change, style; //change == switch point
sCinemaPath(float rx, float ry, float rz) : x(rx), y(ry), z(rz),
mode(0), style(0), change(0), growth(0), duration(0) {}
sCinemaPath() : x(0), y(0), z(0), mode(0), style(0),
change(0), growth(0), duration(0) {}
AtlasMessage::sCinemaPath operator-(const AtlasMessage::sCinemaPath& path)
{
return AtlasMessage::sCinemaPath(x - path.x, y - path.y,
z - path.z);
}
AtlasMessage::sCinemaPath operator+(const AtlasMessage::sCinemaPath& path)
{
return AtlasMessage::sCinemaPath(x + path.x, y + path.y,
z + path.z);
}
};
SHAREABLE_STRUCT(sCinemaPath);
@ -295,38 +315,44 @@ struct sCinemaTrack
Shareable<std::wstring> name;
Shareable<float> x, y, z, timescale, duration;
Shareable<std::vector<AtlasMessage::sCinemaPath> > paths;
public:
sCinemaTrack(float rx, float ry, float rz, std::wstring track)
: x(rx), y(ry), z(rz), timescale(1.f), duration(0)
{ name = track; }
sCinemaTrack() : x(0), y(0), z(0), timescale(1.f), duration(0) {}
};
SHAREABLE_STRUCT(sCinemaTrack);
struct eCinemaMovementMode { enum { SMOOTH, IMMEDIATE_PATH, IMMEDIATE_TRACK }; };
struct sCinemaIcon
struct eCinemaEventMode { enum { SMOOTH, SELECT, IMMEDIATE_PATH,
IMMEDIATE_TRACK }; };
struct sCameraInfo
{
Shareable<std::wstring> name;
Shareable<std::vector<unsigned char> > imageData;
Shareable<float> pX, pY, pZ, rX, rY, rZ; //position and rotation
};
SHAREABLE_STRUCT(sCinemaIcon);
SHAREABLE_STRUCT(sCameraInfo);
QUERY(GetCinemaTracks,
, //no input
((std::vector<AtlasMessage::sCinemaTrack> , tracks))
);
QUERY(GetCinemaIcons,
QUERY(GetCameraInfo,
,
((std::vector<AtlasMessage::sCinemaIcon>, images))
((AtlasMessage::sCameraInfo, info))
);
COMMAND(SetCinemaTracks, MERGE,
COMMAND(SetCinemaTracks, NOMERGE,
((std::vector<AtlasMessage::sCinemaTrack>, tracks))
((float, timescale))
);
MESSAGE(CinemaMovement,
MESSAGE(CinemaEvent,
((std::wstring, track))
((int, mode))
((float, t))
((bool, drawAll))
((bool, drawCurrent))
((bool, lines))
);
//////////////////////////////////////////////////////////////////////////