2016-03-27 11:49:47 +02:00
|
|
|
/*
|
|
|
|
===========================================================================
|
|
|
|
Copyright (C) 2015 the OpenMoHAA team
|
|
|
|
|
|
|
|
This file is part of OpenMoHAA source code.
|
|
|
|
|
|
|
|
OpenMoHAA source code is free software; you can redistribute it
|
|
|
|
and/or modify it under the terms of the GNU General Public License as
|
|
|
|
published by the Free Software Foundation; either version 2 of the License,
|
|
|
|
or (at your option) any later version.
|
|
|
|
|
|
|
|
OpenMoHAA source code is distributed in the hope that it will be
|
|
|
|
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with OpenMoHAA source code; if not, write to the Free Software
|
|
|
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
|
|
===========================================================================
|
|
|
|
*/
|
|
|
|
|
|
|
|
// camera.h: Camera. Duh.
|
2023-10-13 19:11:51 +02:00
|
|
|
//
|
2016-03-27 11:49:47 +02:00
|
|
|
|
2023-10-13 19:11:51 +02:00
|
|
|
#pragma once
|
2016-03-27 11:49:47 +02:00
|
|
|
|
|
|
|
#include "g_local.h"
|
|
|
|
#include "entity.h"
|
|
|
|
#include "bspline.h"
|
|
|
|
#include "container.h"
|
2023-01-29 20:59:31 +01:00
|
|
|
#include "level.h"
|
2016-03-27 11:49:47 +02:00
|
|
|
|
|
|
|
#define CAMERA_SWITCHTIME 0.5f
|
|
|
|
|
2023-10-13 19:11:51 +02:00
|
|
|
#define ORBIT (1 << 0)
|
|
|
|
#define START_ON (1 << 1)
|
|
|
|
#define AUTOMATIC (1 << 2)
|
|
|
|
#define NO_TRACE (1 << 3)
|
|
|
|
#define NO_WATCH (1 << 4)
|
|
|
|
#define LEVEL_EXIT (1 << 5)
|
2016-03-27 11:49:47 +02:00
|
|
|
|
|
|
|
extern Event EV_Camera_CameraThink;
|
|
|
|
extern Event EV_Camera_StartMoving;
|
|
|
|
extern Event EV_Camera_Pause;
|
|
|
|
extern Event EV_Camera_Continue;
|
|
|
|
extern Event EV_Camera_StopMoving;
|
|
|
|
extern Event EV_Camera_SetSpeed;
|
|
|
|
extern Event EV_Camera_SetFollowDistance;
|
|
|
|
extern Event EV_Camera_SetOrbitHeight;
|
|
|
|
extern Event EV_Camera_SetYaw;
|
|
|
|
extern Event EV_Camera_AbsoluteYaw;
|
|
|
|
extern Event EV_Camera_RelativeYaw;
|
|
|
|
extern Event EV_Camera_SetFOV;
|
|
|
|
extern Event EV_Camera_Orbit;
|
|
|
|
extern Event EV_Camera_Follow;
|
|
|
|
extern Event EV_Camera_Watch;
|
|
|
|
extern Event EV_Camera_WatchPath;
|
|
|
|
extern Event EV_Camera_LookAt;
|
|
|
|
extern Event EV_Camera_TurnTo;
|
|
|
|
extern Event EV_Camera_MoveToEntity;
|
|
|
|
extern Event EV_Camera_MoveToPos;
|
|
|
|
extern Event EV_Camera_NoWatch;
|
|
|
|
extern Event EV_Camera_FadeTime;
|
|
|
|
extern Event EV_Camera_Cut;
|
|
|
|
|
|
|
|
class Camera;
|
|
|
|
|
|
|
|
class CameraMoveState : public Class
|
2023-10-13 19:11:51 +02:00
|
|
|
{
|
|
|
|
public:
|
|
|
|
Vector pos;
|
|
|
|
Vector movedir; // direction of travel
|
|
|
|
Vector angles; // angles from spline camera
|
|
|
|
|
|
|
|
BSpline cameraPath;
|
|
|
|
SplinePathPtr splinePath;
|
|
|
|
SplinePathPtr currentNode;
|
|
|
|
SplinePathPtr loopNode;
|
|
|
|
|
|
|
|
float cameraTime;
|
|
|
|
int lastTime;
|
|
|
|
int newTime;
|
|
|
|
|
|
|
|
qboolean followingpath;
|
|
|
|
EntityPtr followEnt;
|
|
|
|
EntityPtr orbitEnt;
|
|
|
|
|
|
|
|
void operator=(CameraMoveState& newstate);
|
|
|
|
void Evaluate(Camera *camera);
|
|
|
|
void Initialize(Camera *camera);
|
|
|
|
void DoNodeEvents(Camera *camera);
|
|
|
|
void Archive(Archiver& arc) override;
|
|
|
|
};
|
|
|
|
|
|
|
|
inline void CameraMoveState::operator=(CameraMoveState& newstate)
|
|
|
|
|
|
|
|
{
|
|
|
|
movedir = newstate.movedir;
|
|
|
|
pos = newstate.pos;
|
|
|
|
angles = newstate.angles;
|
|
|
|
|
|
|
|
cameraPath = newstate.cameraPath;
|
|
|
|
splinePath = newstate.splinePath;
|
|
|
|
currentNode = newstate.currentNode;
|
|
|
|
loopNode = newstate.loopNode;
|
|
|
|
|
|
|
|
cameraTime = newstate.cameraTime;
|
|
|
|
lastTime = newstate.lastTime;
|
|
|
|
newTime = newstate.newTime;
|
|
|
|
|
|
|
|
followEnt = newstate.followEnt;
|
|
|
|
orbitEnt = newstate.orbitEnt;
|
|
|
|
|
|
|
|
followingpath = newstate.followingpath;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline void CameraMoveState::Archive(Archiver& arc)
|
|
|
|
{
|
|
|
|
arc.ArchiveVector(&movedir);
|
|
|
|
arc.ArchiveVector(&pos);
|
|
|
|
arc.ArchiveVector(&angles);
|
|
|
|
|
|
|
|
cameraPath.Archive(arc);
|
|
|
|
|
|
|
|
arc.ArchiveSafePointer(&splinePath);
|
|
|
|
arc.ArchiveSafePointer(¤tNode);
|
|
|
|
arc.ArchiveSafePointer(&loopNode);
|
|
|
|
|
|
|
|
arc.ArchiveFloat(&cameraTime);
|
|
|
|
arc.ArchiveInteger(&lastTime);
|
|
|
|
arc.ArchiveInteger(&newTime);
|
|
|
|
|
|
|
|
arc.ArchiveSafePointer(&followEnt);
|
|
|
|
arc.ArchiveSafePointer(&orbitEnt);
|
|
|
|
|
|
|
|
arc.ArchiveBoolean(&followingpath);
|
|
|
|
}
|
|
|
|
|
|
|
|
class CameraWatchState : public Class
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
Vector watchAngles;
|
|
|
|
|
|
|
|
EntityPtr watchEnt;
|
|
|
|
qboolean watchNodes;
|
|
|
|
qboolean watchPath;
|
|
|
|
|
|
|
|
void Evaluate(Camera *camera, CameraMoveState *move);
|
|
|
|
void Initialize(Camera *camera);
|
|
|
|
void Archive(Archiver& arc) override;
|
|
|
|
};
|
|
|
|
|
|
|
|
inline void CameraWatchState::Archive(Archiver& arc)
|
|
|
|
{
|
|
|
|
arc.ArchiveVector(&watchAngles);
|
|
|
|
arc.ArchiveSafePointer(&watchEnt);
|
|
|
|
arc.ArchiveBoolean(&watchNodes);
|
|
|
|
arc.ArchiveBoolean(&watchPath);
|
|
|
|
}
|
|
|
|
|
|
|
|
class CameraState : public Class
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
CameraMoveState move;
|
|
|
|
CameraWatchState watch;
|
|
|
|
float fov;
|
|
|
|
|
|
|
|
void Evaluate(Camera *camera);
|
|
|
|
void Initialize(Camera *camera);
|
|
|
|
void Archive(Archiver& arc) override;
|
|
|
|
};
|
|
|
|
|
|
|
|
inline void CameraState::Archive(Archiver& arc)
|
|
|
|
{
|
|
|
|
move.Archive(arc);
|
|
|
|
watch.Archive(arc);
|
|
|
|
arc.ArchiveFloat(&fov);
|
|
|
|
}
|
2016-03-27 11:49:47 +02:00
|
|
|
|
|
|
|
class Camera : public Entity
|
|
|
|
{
|
2023-10-13 19:11:51 +02:00
|
|
|
private:
|
|
|
|
friend class CameraState;
|
|
|
|
friend class CameraWatchState;
|
|
|
|
friend class CameraMoveState;
|
|
|
|
//
|
|
|
|
// follow parameters
|
|
|
|
//
|
|
|
|
float follow_yaw;
|
|
|
|
qboolean follow_yaw_fixed;
|
|
|
|
float follow_dist;
|
|
|
|
int follow_mask;
|
|
|
|
|
|
|
|
// camera speed
|
|
|
|
float camera_speed;
|
|
|
|
// current camera fov
|
|
|
|
float camera_fov;
|
|
|
|
// orbit height
|
|
|
|
float orbit_height;
|
|
|
|
// orbit_dotrace
|
|
|
|
qboolean orbit_dotrace;
|
|
|
|
// whether or not auto calculate fov, a non-zero value means yes
|
|
|
|
float auto_fov;
|
|
|
|
|
|
|
|
// automatic variables
|
|
|
|
float automatic_startTime;
|
|
|
|
float automatic_stopTime;
|
|
|
|
float automatic_radius;
|
|
|
|
float automatic_maxFOV;
|
|
|
|
qboolean automatic_active;
|
|
|
|
Container<str> automatic_states;
|
|
|
|
|
|
|
|
// Miscellaneous
|
|
|
|
Vector m_vPosOffset;
|
|
|
|
|
|
|
|
protected:
|
|
|
|
CameraState currentstate;
|
|
|
|
CameraState newstate;
|
|
|
|
|
|
|
|
float watchTime; // if non-zero, camera view is transitioning
|
|
|
|
float followTime; // if non-zero, camera position is tranisitioning
|
|
|
|
float fovTime; // if non-zero, fov is being lerped
|
|
|
|
|
|
|
|
float fadeTime; // time to transition over
|
|
|
|
float fovFadeTime; // time for fov transition
|
|
|
|
float followFadeTime; // time for fov transition
|
|
|
|
float watchFadeTime; // time for fov transition
|
|
|
|
|
|
|
|
bool m_bShowquakes;
|
|
|
|
|
|
|
|
str nextCamera;
|
|
|
|
|
|
|
|
qboolean showcamera;
|
|
|
|
|
|
|
|
void SetupCamera(Event *ev);
|
|
|
|
void CameraThink(Event *ev);
|
|
|
|
void CreateOrbit(Vector pos, float radius, Vector &forward, Vector &left);
|
|
|
|
void CreatePath(SplinePath *path, splinetype_t type);
|
|
|
|
void UpdateStates(void);
|
|
|
|
Vector CalculatePosition(void);
|
|
|
|
Vector CalculateOrientation(void);
|
|
|
|
float CalculateFov(void);
|
2024-04-11 00:30:00 +02:00
|
|
|
virtual void bind(Entity *master, qboolean use_my_angles = false) override;
|
2023-10-13 19:11:51 +02:00
|
|
|
void unbind(void) override;
|
|
|
|
|
|
|
|
public:
|
|
|
|
CLASS_PROTOTYPE(Camera);
|
|
|
|
|
|
|
|
Camera();
|
|
|
|
void Stop(void);
|
|
|
|
void FollowPath(SplinePath *path, qboolean loop, Entity *watch);
|
|
|
|
void Orbit(Entity *ent, float dist, Entity *watch, float yaw_offset = 0, qboolean dotrace = qtrue);
|
|
|
|
void FollowEntity(Entity *ent, float dist, int mask, Entity *watch = NULL);
|
|
|
|
void Watch(str watch, float time);
|
|
|
|
void Watch(Entity *ent, float time);
|
|
|
|
void SetFOV(float fov, float time);
|
|
|
|
|
|
|
|
void StartMoving(Event *ev);
|
|
|
|
void StopMoving(Event *ev);
|
|
|
|
void Pause(Event *ev);
|
|
|
|
void Continue(Event *ev);
|
|
|
|
void SetAnglesEvent(Event *ev);
|
|
|
|
void SetSpeed(Event *ev);
|
|
|
|
void SetFollowDistance(Event *ev);
|
|
|
|
void SetOrbitHeight(float height);
|
|
|
|
void SetOrbitHeight(Event *ev);
|
|
|
|
void SetFollowYaw(Event *ev);
|
|
|
|
void AbsoluteYaw(Event *ev);
|
|
|
|
void RelativeYaw(Event *ev);
|
|
|
|
void SetFOV(Event *ev);
|
|
|
|
void OrbitEvent(Event *ev);
|
|
|
|
void FollowEvent(Event *ev);
|
|
|
|
void WatchEvent(Event *ev);
|
|
|
|
void WatchStringEvent(Event *ev);
|
|
|
|
void WatchPathEvent(Event *ev);
|
|
|
|
void WatchNodesEvent(Event *ev);
|
|
|
|
void NoWatchEvent(Event *ev);
|
|
|
|
void EventShowQuakes(Event *ev);
|
|
|
|
void LookAt(Event *ev);
|
|
|
|
void MoveToEntity(Event *ev);
|
|
|
|
void MoveToPos(Event *ev);
|
|
|
|
void Cut(Event *ev);
|
|
|
|
void FadeTime(Event *ev);
|
|
|
|
void TurnTo(Event *ev);
|
|
|
|
void SetNextCamera(Event *ev);
|
|
|
|
float CalculateScore(Entity *player, str state);
|
|
|
|
float AutomaticStart(Entity *player);
|
|
|
|
float AutomaticStop(Entity *player);
|
|
|
|
qboolean IsAutomatic(void);
|
|
|
|
qboolean IsLevelExit(void);
|
|
|
|
void SetAutoStateEvent(Event *ev);
|
|
|
|
void SetAutoRadiusEvent(Event *ev);
|
|
|
|
void SetAutoStartTimeEvent(Event *ev);
|
|
|
|
void SetAutoStopTimeEvent(Event *ev);
|
|
|
|
void SetMaximumAutoFOVEvent(Event *ev);
|
|
|
|
void SetAutoActiveEvent(Event *ev);
|
|
|
|
|
|
|
|
str & NextCamera(void);
|
|
|
|
float Fov(void);
|
|
|
|
|
|
|
|
void Reset(Vector org, Vector ang);
|
|
|
|
|
2023-10-13 19:14:37 +02:00
|
|
|
bool ShowQuakes(void) const;
|
2023-10-13 19:11:51 +02:00
|
|
|
Vector GetPositionOffset(void);
|
|
|
|
void SetPositionOffset(Vector vNewOfs);
|
|
|
|
|
|
|
|
void Archive(Archiver& arc) override;
|
|
|
|
};
|
|
|
|
|
2023-10-13 19:14:37 +02:00
|
|
|
inline bool Camera::ShowQuakes(void) const
|
|
|
|
{
|
|
|
|
return m_bShowquakes;
|
|
|
|
}
|
|
|
|
|
2023-10-13 19:11:51 +02:00
|
|
|
inline Vector Camera::GetPositionOffset(void)
|
|
|
|
{
|
|
|
|
return m_vPosOffset;
|
2016-03-27 11:49:47 +02:00
|
|
|
}
|
|
|
|
|
2023-10-13 19:11:51 +02:00
|
|
|
inline void Camera::SetPositionOffset(Vector vNewOfs)
|
2016-03-27 11:49:47 +02:00
|
|
|
{
|
2023-10-13 19:11:51 +02:00
|
|
|
m_vPosOffset = vNewOfs;
|
2016-03-27 11:49:47 +02:00
|
|
|
}
|
|
|
|
|
2023-10-13 19:11:51 +02:00
|
|
|
inline void Camera::Archive(Archiver& arc)
|
|
|
|
{
|
|
|
|
Entity::Archive(arc);
|
|
|
|
|
|
|
|
arc.ArchiveFloat(&follow_yaw);
|
|
|
|
arc.ArchiveBoolean(&follow_yaw_fixed);
|
|
|
|
arc.ArchiveFloat(&follow_dist);
|
|
|
|
arc.ArchiveInteger(&follow_mask);
|
|
|
|
|
|
|
|
arc.ArchiveFloat(&camera_speed);
|
|
|
|
arc.ArchiveFloat(&camera_fov);
|
|
|
|
arc.ArchiveFloat(&orbit_height);
|
|
|
|
arc.ArchiveBoolean(&orbit_dotrace);
|
|
|
|
arc.ArchiveFloat(&auto_fov);
|
|
|
|
|
|
|
|
arc.ArchiveFloat(&automatic_startTime);
|
|
|
|
arc.ArchiveFloat(&automatic_stopTime);
|
|
|
|
arc.ArchiveFloat(&automatic_radius);
|
|
|
|
arc.ArchiveFloat(&automatic_maxFOV);
|
|
|
|
arc.ArchiveBoolean(&automatic_active);
|
|
|
|
|
|
|
|
automatic_states.Archive(arc);
|
|
|
|
|
|
|
|
// currentstate
|
|
|
|
currentstate.Archive(arc);
|
|
|
|
// newstate
|
|
|
|
newstate.Archive(arc);
|
|
|
|
|
|
|
|
arc.ArchiveFloat(&watchTime);
|
|
|
|
arc.ArchiveFloat(&followTime);
|
|
|
|
arc.ArchiveFloat(&fovTime);
|
|
|
|
arc.ArchiveFloat(&fadeTime);
|
|
|
|
arc.ArchiveFloat(&fovFadeTime);
|
|
|
|
arc.ArchiveFloat(&followFadeTime);
|
|
|
|
arc.ArchiveFloat(&watchFadeTime);
|
|
|
|
|
|
|
|
arc.ArchiveString(&nextCamera);
|
|
|
|
|
|
|
|
arc.ArchiveBoolean(&showcamera);
|
|
|
|
|
|
|
|
if (arc.Loading()) {
|
|
|
|
if (spawnflags & AUTOMATIC) {
|
|
|
|
level.AddAutomaticCamera(this);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void SetCamera(Entity *ent, float switchTime);
|
|
|
|
Entity *GetWatchEntity(str watch);
|
2016-03-27 11:49:47 +02:00
|
|
|
|
|
|
|
typedef SafePtr<Camera> CameraPtr;
|
|
|
|
|
|
|
|
class CameraManager : public Listener
|
2023-10-13 19:11:51 +02:00
|
|
|
{
|
|
|
|
protected:
|
|
|
|
Container<str> pathList;
|
|
|
|
BSpline cameraPath;
|
|
|
|
SplinePathPtr path;
|
|
|
|
SplinePathPtr current;
|
|
|
|
float speed;
|
|
|
|
int watch;
|
|
|
|
str pathName;
|
|
|
|
CameraPtr cam;
|
|
|
|
qboolean cameraPath_dirty;
|
|
|
|
|
|
|
|
void NewPath(Event *ev);
|
|
|
|
void SetPath(Event *ev);
|
|
|
|
void SetTargetName(Event *ev);
|
|
|
|
void SetTarget(Event *ev);
|
|
|
|
void AddPoint(Event *ev);
|
|
|
|
void ReplacePoint(Event *ev);
|
|
|
|
void DeletePoint(Event *ev);
|
|
|
|
void MovePlayer(Event *ev);
|
|
|
|
void NextPoint(Event *ev);
|
|
|
|
void PreviousPoint(Event *ev);
|
|
|
|
void ShowingPath(Event *ev);
|
|
|
|
void ShowPath(Event *ev);
|
|
|
|
void HidePath(Event *ev);
|
|
|
|
void StopPlayback(Event *ev);
|
|
|
|
void PlayPath(Event *ev);
|
|
|
|
void LoopPath(Event *ev);
|
|
|
|
void Watch(Event *ev);
|
|
|
|
void NoWatch(Event *ev);
|
|
|
|
void Fov(Event *ev);
|
|
|
|
void FadeTime(Event *ev);
|
|
|
|
void Speed(Event *ev);
|
|
|
|
void Save(Event *ev);
|
|
|
|
void Load(Event *ev);
|
|
|
|
void SaveMap(Event *ev);
|
|
|
|
void UpdateEvent(Event *ev);
|
|
|
|
void NextPath(Event *ev);
|
|
|
|
void PreviousPath(Event *ev);
|
|
|
|
void RenamePath(Event *ev);
|
|
|
|
|
|
|
|
void ShowPath(void);
|
|
|
|
void UpdateUI(void);
|
|
|
|
void SetPathName(str name);
|
|
|
|
void SavePath(str pathName);
|
|
|
|
|
|
|
|
public:
|
|
|
|
CLASS_PROTOTYPE(CameraManager);
|
|
|
|
|
|
|
|
CameraManager();
|
|
|
|
void SetPath(str pathName);
|
|
|
|
void Archive(Archiver& arc) override;
|
|
|
|
};
|
|
|
|
|
|
|
|
inline void CameraManager::Archive(Archiver& arc)
|
2016-03-27 11:49:47 +02:00
|
|
|
|
2023-10-13 19:11:51 +02:00
|
|
|
{
|
|
|
|
Listener::Archive(arc);
|
2016-03-27 11:49:47 +02:00
|
|
|
|
2023-10-13 19:11:51 +02:00
|
|
|
pathList.Archive(arc);
|
|
|
|
|
|
|
|
// no need to archive the cameraPath
|
|
|
|
arc.ArchiveSafePointer(&path);
|
|
|
|
arc.ArchiveSafePointer(¤t);
|
|
|
|
arc.ArchiveFloat(&speed);
|
|
|
|
arc.ArchiveInteger(&watch);
|
|
|
|
arc.ArchiveString(&pathName);
|
|
|
|
arc.ArchiveSafePointer(&cam);
|
|
|
|
|
|
|
|
// make sure the cameraPath gets rebuilt
|
|
|
|
cameraPath_dirty = qtrue;
|
|
|
|
}
|
|
|
|
|
|
|
|
extern CameraManager CameraMan;
|