Incomplete cinematic functions. (Are committed to keep CGameView compatible, which uses an instance of CCinemaManager). Atlas components will be committed once Atlas is up and running.

This was SVN commit r3198.
This commit is contained in:
pyrolink 2005-12-06 06:52:24 +00:00
parent 483917fbc8
commit 8199091425
2 changed files with 503 additions and 0 deletions

View File

@ -0,0 +1,368 @@
#include "precompiled.h"
#include <string>
#include <sstream>
#include "CinemaTrack.h"
#include "Game.h"
#include "GameView.h"
#include "MathUtil.h"
#include "lib/res/file/vfs.h"
#include "lib/res/mem.h"
CCinemaPath::CCinemaPath(CCinemaData data)
{
m_TotalDuration = data.m_TotalDuration;
m_TotalRotation = data.m_TotalRotation;
m_StartRotation = data.m_StartRotation;
m_GrowthCount = data.m_GrowthCount;
m_Growth = data.m_Growth;
m_Switch = data.m_Switch;
}
void CCinemaPath::UpdateSplineEq()
{
Cx = 3 *(m_Points[1].X - m_Points[0].X);
Bx = 3 *(m_Points[2].X - m_Points[1].X) - Cx;
Ax = m_Points[3].X - m_Points[0].X - Cx - Bx;
Cy = 3 *(m_Points[1].Y - m_Points[0].Y);
By = 3 *(m_Points[2].Y - m_Points[1].Y) - Cy;
Ay = m_Points[3].Y - m_Points[0].Y - Cy - By;
Cz = 3 *(m_Points[1].Z - m_Points[0].Z);
Bz = 3 *(m_Points[2].Z - m_Points[1].Z) - Cz;
Az = m_Points[3].Z - m_Points[0].Z - Cz - Bz;
}
CVector3D CCinemaPath::RetrievePointAt(float t)
{
float x= Ax * powf(t, 3) + Bx * powf(t, 2) + Cx*t + m_Points[0].X;
float y= Ay * powf(t, 3) + By * powf(t, 2) + Cy*t + m_Points[0].Y;
float z= Az * powf(t, 3) + Bz * powf(t, 2) + Cz*t + m_Points[0].Z;
return CVector3D(x, y, z);
}
void CCinemaPath::MoveToPointAt(float t)
{
CCamera *Cam=g_Game->GetView()->GetCamera();
t = (this->*DistModePtr)(t);
CVector3D pos = RetrievePointAt(t);
Cam->m_Orientation.SetTranslation(pos);
CVector3D rot = m_TotalRotation * t;
if (rot.X >= 360)
Cam->m_Orientation.RotateX(DEGTORAD(fmodf(rot.X, 360)));
else
Cam->m_Orientation.RotateX(DEGTORAD(rot.X));
if (rot.Y >= 360)
Cam->m_Orientation.RotateY(DEGTORAD(fmodf(rot.Y, 360)));
else
Cam->m_Orientation.RotateY(DEGTORAD(rot.Y));
if (rot.Z >= 360)
Cam->m_Orientation.RotateZ(DEGTORAD(fmodf(rot.Z, 360)));
else
Cam->m_Orientation.RotateZ(DEGTORAD(rot.Z));
}
void CCinemaPath::ResetRotation(float t)
{
CCamera *Cam=g_Game->GetView()->GetCamera();
t = (this->*DistModePtr)(t);
CVector3D rot = m_TotalRotation * t;
if (rot.X >= 360)
Cam->m_Orientation.RotateX(DEGTORAD(-fmodf(rot.X, 360)));
else
Cam->m_Orientation.RotateX(DEGTORAD(-rot.X));
if (rot.Y >= 360)
Cam->m_Orientation.RotateY(DEGTORAD(-fmodf(rot.Y, 360)));
else
Cam->m_Orientation.RotateY(DEGTORAD(-rot.Y));
if (rot.Z >= 360)
Cam->m_Orientation.RotateZ(DEGTORAD(-fmodf(rot.Z, 360)));
else
Cam->m_Orientation.RotateZ(DEGTORAD(-rot.Z));
}
//Distortion mode functions
float CCinemaPath::EaseIn(float t)
{
return (this->*DistStylePtr)(t);
}
float CCinemaPath::EaseOut(float t)
{
return 1.0f - EaseIn(1.0f-t);
}
float CCinemaPath::EaseInOut(float t)
{
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)
{
if (t < m_Switch)
return EaseOut(1.0f/m_Switch * t) * m_Switch;
return EaseIn(1.0f/m_Switch * (t-m_Switch)) * m_Switch + m_Switch;
}
//Distortion style functions
float CCinemaPath::EaseDefault(float t)
{
return t;
}
float CCinemaPath::EaseQuad(float t)
{
return pow(t, m_GrowthCount);
}
float CCinemaPath::EaseExpo(float t)
{
if(t == 0)
return t;
return powf(m_GrowthCount, 10*(t-1.0f));
}
float CCinemaPath::EaseCircle(float t)
{
t = -(sqrt(1.0f - t*t) - 1.0f);
if(m_GrowthCount > 1.0f)
{
m_GrowthCount--;
return (this->*DistStylePtr)(t);
}
return t;
}
float CCinemaPath::EaseSine(float t)
{
t = 1.0f - cos(t * PI/2);
if(m_GrowthCount > 1.0f)
{
m_GrowthCount--;
return (this->*DistStylePtr)(t);
}
return t;
}
//-------CinemaTrack functions------
//AddPath-For building tracks from loaded file
void CCinemaTrack::AddPath(CCinemaData data, CVector3D points[4])
{
CCinemaPath path(data);
path.m_TimeElapsed=0;
for (int i=0; i<4; i++)
{
path.SetPoint(i, points[i]);
}
path.UpdateSplineEq();
m_Paths.push_back(path);
std::vector<CCinemaPath>::iterator SetTemp;
SetTemp=m_Paths.end() - 1;
//Set distortion mode and style
switch(data.m_mode)
{
case EM_IN:
SetTemp->DistModePtr = &CCinemaPath::EaseIn;
break;
case EM_OUT:
SetTemp->DistModePtr = &CCinemaPath::EaseOut;
break;
case EM_INOUT:
SetTemp->DistModePtr = &CCinemaPath::EaseInOut;
break;
case EM_OUTIN:
SetTemp->DistModePtr = &CCinemaPath::EaseOutIn;
break;
default:
debug_printf("Cinematic mode not found for %d !", data.m_mode);
break;
}
switch (data.m_style)
{
case ES_DEFAULT:
SetTemp->DistStylePtr = &CCinemaPath::EaseDefault;
break;
case ES_QUAD:
SetTemp->DistStylePtr = &CCinemaPath::EaseQuad;
break;
case ES_EXPO:
SetTemp->DistStylePtr = &CCinemaPath::EaseExpo;
break;
case ES_CIRCLE:
SetTemp->DistStylePtr = &CCinemaPath::EaseCircle;
break;
case ES_SINE:
SetTemp->DistStylePtr = &CCinemaPath::EaseSine;
break;
default:
debug_printf("Cinematic mode not found for %d !", data.m_style);
break;
}
}
bool CCinemaTrack::Validate()
{
if (m_CPA->m_TimeElapsed >= m_CPA->m_TotalDuration)
{
if (m_CPA == m_Paths.end() - 1)
{
return false;
}
//Make sure it's within limits of path
else
{
float Pos=m_CPA->m_TimeElapsed - m_CPA->m_TotalDuration;
m_CPA++;
while (1)
{
if (Pos > m_CPA->m_TotalDuration)
{
if (m_CPA == m_Paths.end() -1)
{
return false;
}
Pos-=m_CPA->m_TotalDuration;
m_CPA++;
}
else
{
m_CPA->m_TimeElapsed+=Pos;
break;
}
}
} //main if statement
}
return true;
}
bool CCinemaTrack::Play(float DeltaTime)
{
if (m_CPA->m_TimeElapsed == 0)
{
if (m_CPA == m_Paths.begin())
{
//Set camera to start at set position
CCamera *Cam=g_Game->GetView()->GetCamera();
Cam->m_Orientation.SetIdentity();
Cam->m_Orientation.SetXRotation(DEGTORAD(m_CPA->m_StartRotation.X));
Cam->m_Orientation.RotateY(DEGTORAD(m_CPA->m_StartRotation.Y));
Cam->m_Orientation.RotateZ(DEGTORAD(m_CPA->m_StartRotation.Z));
Cam->SetProjection (1, 5000, DEGTORAD(20));
}
}
m_CPA->ResetRotation(m_CPA->m_TimeElapsed / m_CPA->m_TotalDuration);
m_CPA->m_TimeElapsed += DeltaTime;
if (!Validate())
{
m_CPA->MoveToPointAt(1);
return false;
}
m_CPA->MoveToPointAt(m_CPA->m_TimeElapsed / m_CPA->m_TotalDuration);
return true;
}
void CCinemaManager::AddTrack(bool queue, CStr Track)
{
if (!m_TrackQueue.empty() && queue == false)
{
return;
}
else
{
m_TrackQueue.push_back(m_Tracks[Track]);
m_TrackQueue.back().m_CPA = m_TrackQueue.back().m_Paths.begin();
}
}
bool CCinemaManager::Update(float DeltaTime)
{
if (!m_TrackQueue.front().Play(DeltaTime))
{
m_TrackQueue.pop_front();
return false;
}
return true;
}
int CCinemaManager::LoadTracks()
{
unsigned int fileID;
int numTracks;
CCinemaData tmpData;
CVector3D Points[4];
//NOTE: How do you find the current scenario's cinematics?
void* fData;
size_t fSize;
Handle hm = vfs_load("FILENAME", fData, fSize);
RETURN_ERR(hm);
std::istringstream Stream(std::string((const char*)fData, (int)fSize), std::istringstream::binary);
Stream >> fileID;
Stream >> numTracks;
if (fileID != 0x0ADC)
{
debug_printf("Cinematic file not found for (FILENAME)!");
mem_free_h(hm);
return 0;
}
for (int i=0; i < numTracks; i++)
{
CCinemaTrack tmpTrack;
int numPaths;
CStr Name;
Stream >> Name;
Stream >> numPaths;
for (int j=0; j < numPaths; j++)
{
//load main data
Stream >> tmpData.m_TotalDuration;
Stream >> tmpData.m_TotalRotation.X;
Stream >> tmpData.m_TotalRotation.Y;
Stream >> tmpData.m_TotalRotation.Z;
Stream >> tmpData.m_StartRotation.X;
Stream >> tmpData.m_StartRotation.Y;
Stream >> tmpData.m_StartRotation.Z;
Stream >> tmpData.m_GrowthCount;
Stream >> 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<4; x++)
{
Stream >> Points[x].X;
Stream >> Points[x].Y;
Stream >> Points[x].Z;
}
tmpTrack.AddPath(tmpData, Points);
}
m_Tracks[Name]=tmpTrack;
}
mem_free_h(hm);
return 0;
}

View File

@ -0,0 +1,135 @@
#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_QUAD 1
#define ES_EXPO 2
#define ES_CIRCLE 3
#define ES_SINE 4
#include <stdlib.h>
#include "Camera.h"
#include "CStr.h"
#include "Vector3D.h"
/*
Andrew (aka pyrolink)
Contact: ajdecker1022@msn.com
desc: contains various functions used for cinematic camera tracks
Note: There are some differences between the common 'things' of this and the Atlas
version.
The Play functions for both are essentially the same, but Atlas does not support queued tracks.
The difference between the Track Manager and Cinema Manager is the track manager
is for adding and deleting tracks to the list, in the editor. The Cinema Manager is
for taking care of the queued up Tracks, i.e. when they are to be destroyed/added.
*/
//For loading data
class CCinemaData
{
public:
CCinemaData() {}
~CCinemaData() {}
float m_TotalDuration;
//X=x rotation in degrees...etc
CVector3D m_TotalRotation;
CVector3D m_StartRotation;
//Distortion variables
float m_GrowthCount;
float m_Growth;
float m_Switch;
int m_mode;
int m_style;
};
class CCinemaPath : public CCinemaData
{
public:
CCinemaPath(CCinemaData data);
CCinemaPath() { DistStylePtr = NULL; DistModePtr = NULL; }
~CCinemaPath() { DistStylePtr = NULL; DistModePtr = NULL; }
float m_TimeElapsed;
void UpdateSplineEq();
//Resets Rotation-Must call before MoveToPointAt()!!!
void ResetRotation(float t);
//sets camera position to calculated point on spline
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);
//Distortion style functions
float EaseDefault(float t);
float EaseQuad(float t);
float EaseExpo(float t);
float EaseCircle(float t);
float EaseSine(float t);
float (CCinemaPath::*DistStylePtr)(float ratio);
float (CCinemaPath::*DistModePtr)(float ratio);
//returns point on spline
CVector3D RetrievePointAt(float t);
CVector3D getPoint(int point){ return m_Points[point]; }
void SetPoint(int point, CVector3D value) { m_Points[point]=value; }
private:
CVector3D m_Points[4];
//coefficents used in equation
float Ax, Bx, Cx, Ay, By, Cy, Az, Bz, Cz;
};
class CCinemaTrack
{
public:
CCinemaTrack() {}
~CCinemaTrack() {}
std::vector<CCinemaPath> m_Paths;
std::vector<CCinemaPath>::iterator m_CPA; //current path selected (in listbox?)
void AddPath(CCinemaData path, CVector3D points[4]);
bool Validate();
//DOES NOT set CPA to Paths.begin(). Returns-false indicates it's finished,
//true means it's still playing.
bool Play(float DeltaTime);
};
//Class for in game playing of cinematics
class CCinemaManager
{
public:
CCinemaManager() {}
~CCinemaManager() {}
std::list<CCinemaTrack> m_TrackQueue;
std::map<CStr, CCinemaTrack> m_Tracks;
int LoadTracks(); //Loads tracks from file
//Adds track to list of being played. (Called by triggers?)
void AddTrack(bool queue, CStr Track);
bool Update(float DeltaTime);
};
#endif