Core Classes Reorganization:

- g_Terrain and g_Camera totally eradicated as globals, is now m_Terrain
of CWorld and m_Camera of CGameView
- terrainMain.cpp is almost completely empty with functionality moved
into the relevant core classes
- Miscellaneous global functions moved into Core Classes (mostly
GameView)

This was SVN commit r865.
This commit is contained in:
Simon Brenner 2004-07-31 15:57:18 +00:00
parent aff7bd83e6
commit 09f47d6820
22 changed files with 705 additions and 650 deletions

View File

@ -6,29 +6,100 @@
#include "Game.h"
#include "Camera.h"
extern CCamera g_Camera;
#include "Matrix3D.h"
#include "Renderer.h"
#include "Terrain.h"
#include "LightEnv.h"
#include "HFTracer.h"
#include "TextureManager.h"
#include "ObjectManager.h"
#include "Prometheus.h"
#include "Hotkey.h"
#include "ConfigDB.h"
#include "sdl.h"
#include "input.h"
#include "lib.h"
extern int g_xres, g_yres;
extern bool g_active;
extern CLightEnv g_LightEnv;
CGameView::CGameView(CGame *pGame):
m_pGame(pGame),
m_pWorld(pGame->GetWorld()),
m_pCamera(&g_Camera)
{}
m_Camera(),
m_ViewScrollSpeed(60),
m_ViewRotateSensitivity(0.002f),
m_ViewRotateAboutTargetSensitivity(0.010f),
m_ViewDragSensitivity(0.5f),
m_ViewZoomSensitivityWheel(16.0f),
m_ViewZoomSensitivity(256.0f),
m_ViewZoomSmoothness(0.02f),
m_ViewSnapSmoothness(0.02f),
m_CameraPivot(),
m_CameraDelta()//,
// m_CameraZoom(10)
{
InitResources();
}
void CGameView::Initialize(CGameAttributes *pAttribs)
{}
{
SViewPort vp;
vp.m_X=0;
vp.m_Y=0;
vp.m_Width=g_xres;
vp.m_Height=g_yres;
m_Camera.SetViewPort(&vp);
CConfigValue* cfg;
#define getViewParameter( name, value ) STMT( \
cfg = g_ConfigDB.GetValue( CFG_SYSTEM, name );\
if( cfg ) cfg->GetFloat( value ); )
getViewParameter( "view.scroll.speed", m_ViewScrollSpeed );
getViewParameter( "view.rotate.speed", m_ViewRotateSensitivity );
getViewParameter( "view.rotate.abouttarget.speed", m_ViewRotateAboutTargetSensitivity );
getViewParameter( "view.drag.speed", m_ViewDragSensitivity );
getViewParameter( "view.zoom.speed", m_ViewZoomSensitivity );
getViewParameter( "view.zoom.wheel.speed", m_ViewZoomSensitivityWheel );
getViewParameter( "view.zoom.smoothness", m_ViewZoomSmoothness );
getViewParameter( "view.snap.smoothness", m_ViewSnapSmoothness );
if( ( m_ViewZoomSmoothness < 0.0f ) || ( m_ViewZoomSmoothness > 1.0f ) ) m_ViewZoomSmoothness = 0.02f;
if( ( m_ViewSnapSmoothness < 0.0f ) || ( m_ViewSnapSmoothness > 1.0f ) ) m_ViewSnapSmoothness = 0.02f;
#undef getViewParameter
// setup default lighting environment
g_LightEnv.m_SunColor=RGBColor(1,1,1);
g_LightEnv.m_Rotation=DEGTORAD(270);
g_LightEnv.m_Elevation=DEGTORAD(45);
g_LightEnv.m_TerrainAmbientColor=RGBColor(0,0,0);
g_LightEnv.m_UnitsAmbientColor=RGBColor(0.4f,0.4f,0.4f);
g_Renderer.SetLightEnv(&g_LightEnv);
m_Camera.SetProjection (1, 5000, DEGTORAD(20));
m_Camera.m_Orientation.SetXRotation(DEGTORAD(30));
m_Camera.m_Orientation.RotateY(DEGTORAD(-45));
m_Camera.m_Orientation.Translate (100, 150, -100);
}
void CGameView::Render()
{
g_Renderer.SetCamera(m_Camera);
MICROLOG(L"render terrain");
RenderTerrain(m_pWorld->GetTerrain());
MICROLOG(L"render models");
RenderModels(m_pWorld->GetUnitManager());
MICROLOG(L"flush frame");
}
void CGameView::RenderTerrain(CTerrain *pTerrain)
{
CFrustum frustum=m_pCamera->GetFrustum();
CFrustum frustum=m_Camera.GetFrustum();
u32 patchesPerSide=pTerrain->GetPatchesPerSide();
for (uint j=0; j<patchesPerSide; j++) {
for (uint i=0; i<patchesPerSide; i++) {
@ -42,7 +113,7 @@ void CGameView::RenderTerrain(CTerrain *pTerrain)
void CGameView::RenderModels(CUnitManager *pUnitMan)
{
CFrustum frustum=m_pCamera->GetFrustum();
CFrustum frustum=m_Camera.GetFrustum();
const std::vector<CUnit*>& units=pUnitMan->GetUnits();
for (uint i=0;i<units.size();++i) {
@ -67,6 +138,8 @@ void CGameView::RenderNoCull()
CUnitManager *pUnitMan=m_pWorld->GetUnitManager();
CTerrain *pTerrain=m_pWorld->GetTerrain();
g_Renderer.SetCamera(m_Camera);
uint i,j;
const std::vector<CUnit*>& units=pUnitMan->GetUnits();
for (i=0;i<units.size();++i) {
@ -81,3 +154,386 @@ void CGameView::RenderNoCull()
}
}
}
void CGameView::InitResources()
{
g_TexMan.LoadTerrainTextures();
g_ObjMan.LoadObjects();
const char* fns[CRenderer::NumAlphaMaps] = {
"art/textures/terrain/alphamaps/special/blendcircle.png",
"art/textures/terrain/alphamaps/special/blendlshape.png",
"art/textures/terrain/alphamaps/special/blendedge.png",
"art/textures/terrain/alphamaps/special/blendedgecorner.png",
"art/textures/terrain/alphamaps/special/blendedgetwocorners.png",
"art/textures/terrain/alphamaps/special/blendfourcorners.png",
"art/textures/terrain/alphamaps/special/blendtwooppositecorners.png",
"art/textures/terrain/alphamaps/special/blendlshapecorner.png",
"art/textures/terrain/alphamaps/special/blendtwocorners.png",
"art/textures/terrain/alphamaps/special/blendcorner.png",
"art/textures/terrain/alphamaps/special/blendtwoedges.png",
"art/textures/terrain/alphamaps/special/blendthreecorners.png",
"art/textures/terrain/alphamaps/special/blendushape.png",
"art/textures/terrain/alphamaps/special/blendbad.png"
};
g_Renderer.LoadAlphaMaps(fns);
}
void CGameView::ResetCamera()
{
// quick hack to return camera home, for screenshots (after alt+tabbing)
m_Camera.SetProjection (1, 5000, DEGTORAD(20));
m_Camera.m_Orientation.SetXRotation(DEGTORAD(30));
m_Camera.m_Orientation.RotateY(DEGTORAD(-45));
m_Camera.m_Orientation.Translate (100, 150, -100);
}
void CGameView::RotateAboutTarget()
{
CTerrain *pTerrain=m_pWorld->GetTerrain();
int x, z;
CHFTracer tracer( pTerrain );
CVector3D origin, dir;
origin = m_Camera.m_Orientation.GetTranslation();
dir = m_Camera.m_Orientation.GetIn();
m_Camera.BuildCameraRay( origin, dir );
if( !tracer.RayIntersect( origin, dir, x, z, m_CameraPivot ) )
m_CameraPivot = origin - dir * ( origin.Y / dir.Y );
}
void CGameView::Update(float DeltaTime)
{
if (!g_active)
return;
float delta = powf( m_ViewSnapSmoothness, DeltaTime );
m_Camera.m_Orientation.Translate( m_CameraDelta * ( 1.0f - delta ) );
m_CameraDelta *= delta;
#define CAMERASTYLE 2 // 0 = old style, 1 = relatively new style, 2 = newest style
#if CAMERASTYLE == 2
// This could be rewritten much more reliably, so it doesn't e.g. accidentally tilt
// the camera, assuming we know exactly what limits the camera should have.
// Calculate mouse movement
static int mouse_last_x = 0;
static int mouse_last_y = 0;
int mouse_dx = mouse_x - mouse_last_x;
int mouse_dy = mouse_y - mouse_last_y;
mouse_last_x = mouse_x;
mouse_last_y = mouse_y;
// Miscellaneous vectors
CVector3D forwards = m_Camera.m_Orientation.GetIn();
CVector3D rightwards = m_Camera.m_Orientation.GetLeft() * -1.0f; // upwards.Cross(forwards);
CVector3D upwards( 0.0f, 1.0f, 0.0f );
// rightwards.Normalize();
CVector3D forwards_horizontal = forwards;
forwards_horizontal.Y = 0.0f;
forwards_horizontal.Normalize();
/*
if ((mouseButtons[SDL_BUTTON_MIDDLE] && (keys[SDLK_LCTRL] || keys[SDLK_RCTRL]))
|| (mouseButtons[SDL_BUTTON_LEFT] && mouseButtons[SDL_BUTTON_RIGHT]) )
*/
if( hotkeys[HOTKEY_CAMERA_ROTATE] )
{
// Ctrl + middle-drag or left-and-right-drag to rotate view
// Untranslate the camera, so it rotates around the correct point
CVector3D position = m_Camera.m_Orientation.GetTranslation();
m_Camera.m_Orientation.Translate(position*-1);
// Sideways rotation
m_Camera.m_Orientation.RotateY(m_ViewRotateSensitivity * (float)(mouse_dx));
// Up/down rotation
CQuaternion temp;
temp.FromAxisAngle(rightwards, m_ViewRotateSensitivity * (float)(mouse_dy));
m_Camera.m_Orientation.Rotate(temp);
// Retranslate back to the right position
m_Camera.m_Orientation.Translate(position);
}
else if( hotkeys[HOTKEY_CAMERA_ROTATE_ABOUT_TARGET] )
{
CVector3D origin = m_Camera.m_Orientation.GetTranslation();
CVector3D delta = origin - m_CameraPivot;
CQuaternion rotateH, rotateV; CMatrix3D rotateM;
// Side-to-side rotation
rotateH.FromAxisAngle( upwards, m_ViewRotateAboutTargetSensitivity * (float)mouse_dx );
// Up-down rotation
rotateV.FromAxisAngle( rightwards, m_ViewRotateAboutTargetSensitivity * (float)mouse_dy );
rotateH *= rotateV;
rotateH.ToMatrix( rotateM );
delta = rotateM.Rotate( delta );
// Lock the inclination to a rather arbitrary values (for the sake of graphical decency)
float scan = sqrt( delta.X * delta.X + delta.Z * delta.Z ) / delta.Y;
if( ( scan >= 0.5f ) )
{
// Move the camera to the origin (in preparation for rotation )
m_Camera.m_Orientation.Translate( origin * -1.0f );
m_Camera.m_Orientation.Rotate( rotateH );
// Move the camera back to where it belongs
m_Camera.m_Orientation.Translate( m_CameraPivot + delta );
}
}
else if( hotkeys[HOTKEY_CAMERA_PAN] )
{
// Middle-drag to pan
m_Camera.m_Orientation.Translate(rightwards * (m_ViewDragSensitivity * mouse_dx));
m_Camera.m_Orientation.Translate(forwards_horizontal * (-m_ViewDragSensitivity * mouse_dy));
}
// Mouse movement
if( !hotkeys[HOTKEY_CAMERA_ROTATE] && !hotkeys[HOTKEY_CAMERA_ROTATE_ABOUT_TARGET] )
{
if (mouse_x >= g_xres-2)
m_Camera.m_Orientation.Translate(rightwards * (m_ViewScrollSpeed * DeltaTime));
else if (mouse_x <= 3)
m_Camera.m_Orientation.Translate(-rightwards * (m_ViewScrollSpeed * DeltaTime));
if (mouse_y >= g_yres-2)
m_Camera.m_Orientation.Translate(-forwards_horizontal * (m_ViewScrollSpeed * DeltaTime));
else if (mouse_y <= 3)
m_Camera.m_Orientation.Translate(forwards_horizontal * (m_ViewScrollSpeed * DeltaTime));
}
// Keyboard movement (added to mouse movement, so you can go faster if you want)
if( hotkeys[HOTKEY_CAMERA_PAN_RIGHT] )
m_Camera.m_Orientation.Translate(rightwards * (m_ViewScrollSpeed * DeltaTime));
if( hotkeys[HOTKEY_CAMERA_PAN_LEFT] )
m_Camera.m_Orientation.Translate(-rightwards * (m_ViewScrollSpeed * DeltaTime));
if( hotkeys[HOTKEY_CAMERA_PAN_BACKWARD] )
m_Camera.m_Orientation.Translate(-forwards_horizontal * (m_ViewScrollSpeed * DeltaTime));
if( hotkeys[HOTKEY_CAMERA_PAN_FORWARD] )
m_Camera.m_Orientation.Translate(forwards_horizontal * (m_ViewScrollSpeed * DeltaTime));
// Smoothed zooming (move a certain percentage towards the desired zoom distance every frame)
static float zoom_delta = 0.0f;
if( hotkeys[HOTKEY_CAMERA_ZOOM_WHEEL_IN] )
zoom_delta += m_ViewZoomSensitivityWheel;
else if( hotkeys[HOTKEY_CAMERA_ZOOM_WHEEL_OUT] )
zoom_delta -= m_ViewZoomSensitivityWheel;
if( hotkeys[HOTKEY_CAMERA_ZOOM_IN] )
zoom_delta += m_ViewZoomSensitivity*DeltaTime;
else if( hotkeys[HOTKEY_CAMERA_ZOOM_OUT] )
zoom_delta -= m_ViewZoomSensitivity*DeltaTime;
if (zoom_delta)
{
float zoom_proportion = powf(m_ViewZoomSmoothness, DeltaTime);
m_Camera.m_Orientation.Translate(forwards * (zoom_delta * (1.0f-zoom_proportion)));
zoom_delta *= zoom_proportion;
}
#elif CAMERASTYLE == 1
// Remember previous mouse position, to calculate changes
static mouse_last_x = 0;
static mouse_last_y = 0;
// Miscellaneous vectors
CVector3D forwards = m_Camera.m_Orientation.GetIn();
CVector3D upwards (0.0f, 1.0f, 0.0f);
CVector3D rightwards = upwards.Cross(forwards);
// Click and drag to look around
if (mouseButtons[0])
{
// Untranslate the camera, so it rotates around the correct point
CVector3D position = m_Camera.m_Orientation.GetTranslation();
m_Camera.m_Orientation.Translate(position*-1);
// Sideways rotation
m_Camera.m_Orientation.RotateY(m_ViewRotateSpeed*(float)(mouse_x-mouse_last_x));
// Up/down rotation
CQuaternion temp;
temp.FromAxisAngle(rightwards, m_ViewRotateSpeed*(float)(mouse_y-mouse_last_y));
m_Camera.m_Orientation.Rotate(temp);
// Retranslate back to the right position
m_Camera.m_Orientation.Translate(position);
}
mouse_last_x = mouse_x;
mouse_last_y = mouse_y;
// Calculate the necessary vectors for movement
rightwards.Normalize();
CVector3D forwards_horizontal = upwards.Cross(rightwards);
forwards_horizontal.Normalize();
// Move when desirable
if (mouse_x >= g_xres-2)
m_Camera.m_Orientation.Translate(rightwards);
else if (mouse_x <= 3)
m_Camera.m_Orientation.Translate(-rightwards);
if (mouse_y >= g_yres-2)
m_Camera.m_Orientation.Translate(forwards_horizontal);
else if (mouse_y <= 3)
m_Camera.m_Orientation.Translate(-forwards_horizontal);
// Smoothed height-changing (move a certain percentage towards the desired height every frame)
static float height_delta = 0.0f;
if (mouseButtons[SDL_BUTTON_WHEELUP])
height_delta -= 4.0f;
else if (mouseButtons[SDL_BUTTON_WHEELDOWN])
height_delta += 4.0f;
const float height_speed = 0.2f;
m_Camera.m_Orientation.Translate(0.0f, height_delta*height_speed, 0.0f);
height_delta *= (1.0f - height_speed);
#else // CAMERASTYLE == 0
const float dx = m_ViewScrollSpeed * DeltaTime;
const CVector3D Right(dx,0, dx);
const CVector3D Up (dx,0,-dx);
if (mouse_x >= g_xres-2)
m_Camera.m_Orientation.Translate(Right);
if (mouse_x <= 3)
m_Camera.m_Orientation.Translate(Right*-1);
if (mouse_y >= g_yres-2)
m_Camera.m_Orientation.Translate(Up);
if (mouse_y <= 3)
m_Camera.m_Orientation.Translate(Up*-1);
/*
janwas: grr, plotted the zoom vector on paper twice, but it appears
to be completely wrong. sticking with the FOV hack for now.
if anyone sees what's wrong, or knows how to correctly implement zoom,
please put this code out of its misery :)
*/
// RC - added ScEd style zoom in and out (actually moving camera, rather than fudging fov)
float dir=0;
if (mouseButtons[SDL_BUTTON_WHEELUP]) dir=-1;
else if (mouseButtons[SDL_BUTTON_WHEELDOWN]) dir=1;
float factor=dir*dir;
if (factor) {
if (dir<0) factor=-factor;
CVector3D forward=m_Camera.m_Orientation.GetIn();
// check we're not going to zoom into the terrain, or too far out into space
float h=m_Camera.m_Orientation.GetTranslation().Y+forward.Y*factor*m_Camera.Zoom;
float minh=65536*HEIGHT_SCALE*1.05f;
if (h<minh || h>1500) {
// yup, we will; don't move anywhere (do clamped move instead, at some point)
} else {
// do a full move
m_Camera.Zoom-=(factor)*0.1f;
if (m_Camera.Zoom<0.01f) m_Camera.Zoom=0.01f;
m_Camera.m_Orientation.Translate(forward*(factor*m_Camera.Zoom));
}
}
#endif // CAMERASTYLE
m_Camera.UpdateFrustum ();
}
void CGameView::PushCameraTarget( const CVector3D& target )
{
// Save the current position
m_CameraTargets.push_back( m_Camera.m_Orientation.GetTranslation() );
// And set the camera
SetCameraTarget( target );
}
void CGameView::SetCameraTarget( const CVector3D& target )
{
// Maintain the same orientation and level of zoom, if we can
// (do this by working out the point the camera is looking at, saving
// the difference beteen that position and the camera point, and restoring
// that difference to our new target)
CHFTracer tracer( m_pWorld->GetTerrain() );
int x, z;
CVector3D origin, dir, currentTarget;
origin = m_Camera.m_Orientation.GetTranslation();
dir = m_Camera.m_Orientation.GetIn();
if( tracer.RayIntersect( origin, dir, x, z, currentTarget ) )
{
m_CameraDelta = target - currentTarget;
}
else
m_CameraDelta = ( target - dir * 160.0f ) - origin;
}
void CGameView::PopCameraTarget()
{
m_CameraDelta = m_CameraTargets.back() - m_Camera.m_Orientation.GetTranslation();
m_CameraTargets.pop_back();
}
int game_view_handler(const SDL_Event* ev)
{
CGameView *pView=g_Game->GetView();
// put any events that must be processed even if inactive here
if(!g_active)
return EV_PASS;
switch(ev->type)
{
case SDL_HOTKEYDOWN:
switch(ev->user.code)
{
case HOTKEY_WIREFRAME:
if (g_Renderer.GetTerrainRenderMode()==WIREFRAME) {
g_Renderer.SetTerrainRenderMode(SOLID);
} else {
g_Renderer.SetTerrainRenderMode(WIREFRAME);
}
return( EV_HANDLED );
case HOTKEY_CAMERA_RESET:
pView->ResetCamera();
return( EV_HANDLED );
case HOTKEY_CAMERA_ROTATE_ABOUT_TARGET:
pView->RotateAboutTarget();
return( EV_HANDLED );
}
}
return EV_PASS;
}

View File

@ -1,22 +1,40 @@
#ifndef _GameView_H
#define _GameView_H
#include "Camera.h"
#include "Vector3D.h"
class CGame;
class CGameAttributes;
class CWorld;
class CTerrain;
class CUnitManager;
class CModel;
class CCamera;
extern CCamera g_Camera;
class CGameView
{
CGame *m_pGame;
CWorld *m_pWorld;
CCamera *m_pCamera;
CCamera m_Camera;
////////////////////////////////////////
// Settings
float m_ViewScrollSpeed;
float m_ViewRotateSensitivity;
float m_ViewRotateAboutTargetSensitivity;
float m_ViewDragSensitivity;
float m_ViewZoomSensitivityWheel;
float m_ViewZoomSensitivity;
float m_ViewZoomSmoothness; // 0.0 = instantaneous zooming, 1.0 = so slow it never moves
float m_ViewSnapSmoothness; // Just the same.
////////////////////////////////////////
// Camera Controls State
CVector3D m_CameraDelta;
CVector3D m_CameraPivot;
//float m_CameraZoom;
std::vector<CVector3D> m_CameraTargets;
// RenderTerrain: iterate through all terrain patches and submit all patches
// in viewing frustum to the renderer
void RenderTerrain(CTerrain *pTerrain);
@ -28,22 +46,37 @@ class CGameView
// SubmitModelRecursive: recurse down given model, submitting it and all its
// descendents to the renderer
void SubmitModelRecursive(CModel *pModel);
// InitResources(): Load all graphics resources (textures, actor objects and
// alpha maps) required by the game
void InitResources();
public:
CGameView(CGame *pGame);
void Initialize(CGameAttributes *pGameAttributes);
/*
Render the World
*/
// Update: Update all the view information (i.e. rotate camera, scroll,
// whatever). This will *not* change any World information - only the
// *presentation*
void Update(float DeltaTime);
// Render: Render the World
void Render();
// RenderNoCull: render absolutely everything to a blank frame to force
// renderer to load required assets
void RenderNoCull();
// Camera Control Functions (used by input handler)
void ResetCamera();
void RotateAboutTarget();
void PushCameraTarget( const CVector3D& target );
void SetCameraTarget( const CVector3D& target );
void PopCameraTarget();
inline CCamera *GetCamera()
{ return m_pCamera; }
{ return &m_Camera; }
};
#endif

View File

@ -13,13 +13,14 @@
#include "Bound.h"
#include "Vector3D.h"
extern CTerrain g_Terrain;
///////////////////////////////////////////////////////////////////////////////
// CHFTracer constructor
CHFTracer::CHFTracer(const u16* hf,u32 mapsize,float cellsize,float heightscale)
: m_Heightfield(hf), m_MapSize(mapsize), m_CellSize(cellsize),
m_HeightScale(heightscale)
CHFTracer::CHFTracer(CTerrain *pTerrain):
m_pTerrain(pTerrain),
m_Heightfield(m_pTerrain->GetHeightMap()),
m_MapSize(m_pTerrain->GetVerticesPerSide()),
m_CellSize(CELL_SIZE),
m_HeightScale(HEIGHT_SCALE)
{
}
@ -82,10 +83,10 @@ bool CHFTracer::CellIntersect(int cx,int cz,CVector3D& origin,CVector3D& dir,flo
// get vertices for this cell
CVector3D vpos[4];
g_Terrain.CalcPosition(cx,cz,vpos[0]);
g_Terrain.CalcPosition(cx+1,cz,vpos[1]);
g_Terrain.CalcPosition(cx+1,cz+1,vpos[2]);
g_Terrain.CalcPosition(cx,cz+1,vpos[3]);
m_pTerrain->CalcPosition(cx,cz,vpos[0]);
m_pTerrain->CalcPosition(cx+1,cz,vpos[1]);
m_pTerrain->CalcPosition(cx+1,cz+1,vpos[2]);
m_pTerrain->CalcPosition(cx,cz+1,vpos[3]);
dist=1.0e30f;
if (RayTriIntersect(vpos[0],vpos[1],vpos[2],origin,dir,dist)) {

View File

@ -10,6 +10,7 @@
#define _HFTRACER_H
class CVector3D;
class CTerrain;
#include "res/res.h"
@ -19,7 +20,7 @@ class CHFTracer
{
public:
// constructor; setup data
CHFTracer(const u16* hf,u32 mapsize,float cellsize,float heightscale);
CHFTracer(CTerrain *pTerrain);
// intersect ray with this heightfield; return true if intersection
// occurs (and fill in grid coordinates and point of intersection), or false otherwise
@ -35,6 +36,8 @@ private:
// test if ray intersects either of the triangles in the given
bool CellIntersect(int cx,int cz,CVector3D& origin,CVector3D& dir,float& dist) const;
// The terrain we're operating on
CTerrain *m_pTerrain;
// the heightfield were tracing
const u16* m_Heightfield;
// size of the heightfield

View File

@ -12,18 +12,13 @@
#include "Terrain.h"
#include "TextureManager.h"
extern CTerrain g_Terrain;
extern CLightEnv g_LightEnv;
// CMapReader constructor: nothing to do at the minute
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)
void CMapReader::LoadMap(const char* filename, CTerrain *pTerrain, CUnitManager *pUnitMan, CLightEnv *pLightEnv)
{
CFileUnpacker unpacker;
unpacker.Read(filename,"PSMP");
@ -37,7 +32,7 @@ void CMapReader::LoadMap(const char* filename)
UnpackMap(unpacker);
// finally, apply data to the world
ApplyData(unpacker);
ApplyData(unpacker, pTerrain, pUnitMan, pLightEnv);
}
// UnpackMap: unpack the given data from the raw data stream into local variables
@ -122,10 +117,10 @@ void CMapReader::UnpackTerrain(CFileUnpacker& unpacker)
}
// ApplyData: take all the input data, and rebuild the scene from it
void CMapReader::ApplyData(CFileUnpacker& unpacker)
void CMapReader::ApplyData(CFileUnpacker& unpacker, CTerrain *pTerrain, CUnitManager *pUnitMan, CLightEnv *pLightEnv)
{
// initialise the terrain
g_Terrain.Initialize(m_MapSize,&m_Heightmap[0]);
pTerrain->Initialize(m_MapSize,&m_Heightmap[0]);
// setup the textures on the minipatches
STileDesc* tileptr=&m_Tiles[0];
@ -133,7 +128,7 @@ void CMapReader::ApplyData(CFileUnpacker& unpacker)
for (u32 i=0;i<m_MapSize;i++) {
for (u32 m=0;m<PATCH_SIZE;m++) {
for (u32 k=0;k<PATCH_SIZE;k++) {
CMiniPatch& mp=g_Terrain.GetPatch(i,j)->m_MiniPatches[m][k];
CMiniPatch& mp=pTerrain->GetPatch(i,j)->m_MiniPatches[m][k];
mp.Tex1=m_TerrainTextures[tileptr->m_Tex1Index];
mp.Tex1Priority=tileptr->m_Priority;
@ -145,7 +140,7 @@ void CMapReader::ApplyData(CFileUnpacker& unpacker)
}
// empty out existing units
g_UnitMan.DeleteAll();
pUnitMan->DeleteAll();
// add new objects
for (u32 i=0;i<m_Objects.size();i++) {
@ -155,6 +150,7 @@ void CMapReader::ApplyData(CFileUnpacker& unpacker)
// Not an ideal solution; we'll have to figure out a map format that can define entities seperately or somesuch.
CBaseEntity* templateObject = g_EntityTemplateCollection.getTemplateByActor( objentry );
if( templateObject )
{
CVector3D orient = ((CMatrix3D*)m_Objects[i].m_Transform)->GetIn();
@ -171,13 +167,13 @@ void CMapReader::ApplyData(CFileUnpacker& unpacker)
unit->GetModel()->SetTransform(transform);
// add this unit to list of units stored in unit manager
g_UnitMan.AddUnit(unit);
pUnitMan->AddUnit(unit);
}
}
}
if (unpacker.GetVersion()>=2) {
// copy over the lighting parameters
g_LightEnv=m_LightEnv;
*pLightEnv=m_LightEnv;
}
}

View File

@ -7,6 +7,9 @@
#include "FileUnpacker.h"
class CObjectEntry;
class CTerrain;
class CUnitManager;
class CLightEnv;
class CMapReader : public CMapIO
{
@ -14,7 +17,7 @@ public:
// constructor
CMapReader();
// LoadMap: try to load the map from given file; reinitialise the scene to new data if successful
void LoadMap(const char* filename);
void LoadMap(const char* filename, CTerrain *pTerrain, CUnitManager *pUnitMan, CLightEnv *pLightEnv);
private:
// UnpackMap: unpack the given data from the raw data stream into local variables
@ -27,7 +30,7 @@ private:
void UnpackLightEnv(CFileUnpacker& unpacker);
// ApplyData: take all the input data, and rebuild the scene from it
void ApplyData(CFileUnpacker& unpacker);
void ApplyData(CFileUnpacker& unpacker, CTerrain *pTerrain, CUnitManager *pUnitMan, CLightEnv *pLightEnv);
// size of map
u32 m_MapSize;

View File

@ -9,9 +9,6 @@
#include "LightEnv.h"
#include "TextureManager.h"
extern CTerrain g_Terrain;
extern CLightEnv g_LightEnv;
///////////////////////////////////////////////////////////////////////////////////////////////////
// CMapWriter constructor: nothing to do at the minute
CMapWriter::CMapWriter()
@ -20,12 +17,12 @@ CMapWriter::CMapWriter()
///////////////////////////////////////////////////////////////////////////////////////////////////
// SaveMap: try to save the current map to the given file
void CMapWriter::SaveMap(const char* filename)
void CMapWriter::SaveMap(const char* filename, CTerrain *pTerrain, CLightEnv *pLightEnv, CUnitManager *pUnitMan)
{
CFilePacker packer;
// build necessary data
PackMap(packer);
PackMap(packer, pTerrain, pLightEnv, pUnitMan);
// write it out
packer.Write(filename,FILE_VERSION,"PSMP");
@ -62,23 +59,24 @@ static u16 GetObjectIndex(const CObjectEntry* object,const std::vector<CObjectEn
///////////////////////////////////////////////////////////////////////////////////////////////////
// EnumTerrainTextures: build lists of textures used by map, and tile descriptions for
// each tile on the terrain
void CMapWriter::EnumTerrainTextures(std::vector<CStr>& textures,
void CMapWriter::EnumTerrainTextures(CTerrain *pTerrain,
std::vector<CStr>& textures,
std::vector<STileDesc>& tiles)
{
// the list of all handles in use
std::vector<Handle> handles;
// resize tile array to required size
tiles.resize(SQR(g_Terrain.GetVerticesPerSide()-1));
tiles.resize(SQR(pTerrain->GetVerticesPerSide()-1));
STileDesc* tileptr=&tiles[0];
// now iterate through all the tiles
u32 mapsize=g_Terrain.GetPatchesPerSide();
u32 mapsize=pTerrain->GetPatchesPerSide();
for (u32 j=0;j<mapsize;j++) {
for (u32 i=0;i<mapsize;i++) {
for (u32 m=0;m<PATCH_SIZE;m++) {
for (u32 k=0;k<PATCH_SIZE;k++) {
CMiniPatch& mp=g_Terrain.GetPatch(i,j)->m_MiniPatches[m][k];
CMiniPatch& mp=pTerrain->GetPatch(i,j)->m_MiniPatches[m][k];
u16 index=u16(GetHandleIndex(mp.Tex1,handles));
if (index==0xffff) {
index=(u16)handles.size();
@ -111,13 +109,14 @@ void CMapWriter::EnumTerrainTextures(std::vector<CStr>& textures,
///////////////////////////////////////////////////////////////////////////////////////////////////
// EnumObjects: build lists of object types used by map, and object descriptions for
// each object in the world
void CMapWriter::EnumObjects(std::vector<CStr>& objectTypes,std::vector<SObjectDesc>& objects)
void CMapWriter::EnumObjects(CUnitManager *pUnitMan,
std::vector<CStr>& objectTypes, std::vector<SObjectDesc>& objects)
{
// the list of all object entries in use
std::vector<CObjectEntry*> objectsInUse;
// resize object array to required size
const std::vector<CUnit*>& units=g_UnitMan.GetUnits();
const std::vector<CUnit*>& units=pUnitMan->GetUnits();
objects.resize(units.size());
SObjectDesc* objptr=&objects[0];
@ -144,29 +143,29 @@ void CMapWriter::EnumObjects(std::vector<CStr>& objectTypes,std::vector<SObjectD
///////////////////////////////////////////////////////////////////////////////////////////////////
// PackMap: pack the current world into a raw data stream
void CMapWriter::PackMap(CFilePacker& packer)
void CMapWriter::PackMap(CFilePacker& packer, CTerrain *pTerrain, CLightEnv *pLightEnv, CUnitManager *pUnitMan)
{
// now pack everything up
PackTerrain(packer);
PackObjects(packer);
PackLightEnv(packer);
PackTerrain(packer, pTerrain);
PackObjects(packer, pUnitMan);
PackLightEnv(packer, pLightEnv);
}
///////////////////////////////////////////////////////////////////////////////////////////////////
// PackLightEnv: pack lighting parameters onto the end of the output data stream
void CMapWriter::PackLightEnv(CFilePacker& packer)
void CMapWriter::PackLightEnv(CFilePacker& packer, CLightEnv *pLightEnv)
{
packer.PackRaw(&g_LightEnv.m_SunColor,sizeof(g_LightEnv.m_SunColor));
packer.PackRaw(&g_LightEnv.m_Elevation,sizeof(g_LightEnv.m_Elevation));
packer.PackRaw(&g_LightEnv.m_Rotation,sizeof(g_LightEnv.m_Rotation));
packer.PackRaw(&g_LightEnv.m_TerrainAmbientColor,sizeof(g_LightEnv.m_TerrainAmbientColor));
packer.PackRaw(&g_LightEnv.m_UnitsAmbientColor,sizeof(g_LightEnv.m_UnitsAmbientColor));
packer.PackRaw(&pLightEnv->m_SunColor,sizeof(pLightEnv->m_SunColor));
packer.PackRaw(&pLightEnv->m_Elevation,sizeof(pLightEnv->m_Elevation));
packer.PackRaw(&pLightEnv->m_Rotation,sizeof(pLightEnv->m_Rotation));
packer.PackRaw(&pLightEnv->m_TerrainAmbientColor,sizeof(pLightEnv->m_TerrainAmbientColor));
packer.PackRaw(&pLightEnv->m_UnitsAmbientColor,sizeof(pLightEnv->m_UnitsAmbientColor));
}
///////////////////////////////////////////////////////////////////////////////////////////////////
// PackObjects: pack world objects onto the end of the output data stream
// - data: list of objects types used by map, list of object descriptions
void CMapWriter::PackObjects(CFilePacker& packer)
void CMapWriter::PackObjects(CFilePacker& packer, CUnitManager *pUnitMan)
{
// the list of object types used by map
std::vector<CStr> objectTypes;
@ -174,7 +173,7 @@ void CMapWriter::PackObjects(CFilePacker& packer)
std::vector<SObjectDesc> objects;
// build lists by scanning through the world
EnumObjects(objectTypes,objects);
EnumObjects(pUnitMan, objectTypes, objects);
// pack object types
u32 numObjTypes=(u32)objectTypes.size();
@ -192,14 +191,14 @@ void CMapWriter::PackObjects(CFilePacker& packer)
///////////////////////////////////////////////////////////////////////////////////////////////////
// PackTerrain: pack the terrain onto the end of the output data stream
// - data: map size, heightmap, list of textures used by map, texture tile assignments
void CMapWriter::PackTerrain(CFilePacker& packer)
void CMapWriter::PackTerrain(CFilePacker& packer, CTerrain *pTerrain)
{
// pack map size
u32 mapsize=g_Terrain.GetPatchesPerSide();
u32 mapsize=pTerrain->GetPatchesPerSide();
packer.PackRaw(&mapsize,sizeof(mapsize));
// pack heightmap
packer.PackRaw(g_Terrain.GetHeightMap(),sizeof(u16)*SQR(g_Terrain.GetVerticesPerSide()));
packer.PackRaw(pTerrain->GetHeightMap(),sizeof(u16)*SQR(pTerrain->GetVerticesPerSide()));
// the list of textures used by map
std::vector<CStr> terrainTextures;
@ -207,7 +206,7 @@ void CMapWriter::PackTerrain(CFilePacker& packer)
std::vector<STileDesc> tiles;
// build lists by scanning through the terrain
EnumTerrainTextures(terrainTextures,tiles);
EnumTerrainTextures(pTerrain, terrainTextures, tiles);
// pack texture names
u32 numTextures=(u32)terrainTextures.size();

View File

@ -6,31 +6,37 @@
#include "CStr.h"
#include "FilePacker.h"
class CLightEnv;
class CTerrain;
class CUnitManager;
class CMapWriter : public CMapIO
{
public:
// constructor
CMapWriter();
// SaveMap: try to save the current map to the given file
void SaveMap(const char* filename);
void SaveMap(const char* filename, CTerrain *pTerr, CLightEnv *pLightEnv, CUnitManager *pUnitMan);
private:
// PackMap: pack the current world into a raw data stream
void PackMap(CFilePacker& packer);
void PackMap(CFilePacker& packer, CTerrain *pTerr, CLightEnv *pLightEnv, CUnitManager *pUnitMan);
// PackTerrain: pack the terrain onto the end of the data stream
void PackTerrain(CFilePacker& packer);
void PackTerrain(CFilePacker& packer, CTerrain *pTerrain);
// PackObjects: pack world objects onto the end of the output data stream
void PackObjects(CFilePacker& packer);
void PackObjects(CFilePacker& packer, CUnitManager *pUnitMan);
// PackLightEnv: pack lighting parameters onto the end of the output data stream
void PackLightEnv(CFilePacker& packer);
void PackLightEnv(CFilePacker& packer, CLightEnv *pLightEnv);
// EnumTerrainTextures: build lists of textures used by map, and indices into this list
// for each tile on the terrain
void EnumTerrainTextures(std::vector<CStr>& textures,std::vector<STileDesc>& tileIndices);
void EnumTerrainTextures(CTerrain *pTerrain, std::vector<CStr>& textures,
std::vector<STileDesc>& tileIndices);
// EnumObjects: build lists of object types used by map, and object descriptions for
// each object in the world
void EnumObjects(std::vector<CStr>& objectTypes,std::vector<SObjectDesc>& objects);
void EnumObjects(CUnitManager *pUnitMan, std::vector<CStr>& objectTypes,
std::vector<SObjectDesc>& objects);
};
#endif

View File

@ -77,9 +77,4 @@ private:
u16* m_Heightmap;
};
extern CTerrain* g_Terrain_ptr;
#ifndef g_Terrain
#define g_Terrain (*g_Terrain_ptr)
#endif
#endif

View File

@ -91,21 +91,15 @@ static bool g_EntGraph = false;
static float g_Gamma = 1.0f;
CGameAttributes g_GameAttributes;
CGame *g_Game=NULL;
extern int game_view_handler(const SDL_Event* ev);
static Handle g_Font_Console; // for the console
static Handle g_Font_Misc; // random font for miscellaneous things
extern CCamera g_Camera;
static CMusicPlayer MusicPlayer;
CStr g_CursorName = "test";
extern void terr_init();
extern void terr_update(float time);
extern int terr_handler(const SDL_Event* ev);
extern int allow_reload();
extern int dir_add_watch(const char* const dir, bool watch_subdirs);
@ -371,8 +365,7 @@ static int handler(const SDL_Event* ev)
void RenderNoCull()
{
g_Renderer.BeginFrame();
g_Renderer.SetCamera(g_Camera);
g_Game->GetView()->RenderNoCull();
g_Renderer.FlushFrame();
@ -387,13 +380,13 @@ static void Render()
// start new frame
g_Renderer.BeginFrame();
g_Renderer.SetCamera(g_Camera);
// switch on wireframe for terrain if we want it
//g_Renderer.SetTerrainRenderMode( SOLID ); // (PT: If this is done here, the W key doesn't work)
g_Game->Render();
g_Game->GetView()->Render();
MICROLOG(L"flush frame");
g_Renderer.FlushFrame();
glPushAttrib( GL_ENABLE_BIT );
@ -681,7 +674,6 @@ static void Shutdown()
// destroy terrain related stuff
delete &g_TexMan;
delete &g_Terrain;
// destroy renderer
delete &g_Renderer;
@ -831,12 +823,6 @@ PREVTSC=CURTSC;
MICROLOG(L"init renderer");
g_Renderer.Open(g_xres,g_yres,g_bpp);
g_Terrain_ptr = new CTerrain;
// terr_init loads a bunch of resources as well as setting up the terrain
terr_init();
// This needs to be done after the renderer has loaded all its actors...
new CBaseEntityCollection;
new CEntityManager;
@ -844,8 +830,6 @@ PREVTSC=CURTSC;
new CSelectedEntities;
new CMouseoverEntities;
g_EntityTemplateCollection.loadTemplates();
// if no map name specified, load test01.pmp (for convenience during
// development. that means loading no map at all is currently impossible.
// is that a problem?
@ -867,11 +851,8 @@ PREVTSC=CURTSC;
// Initialize entities
CMessage init_msg (CMessage::EMSG_INIT);
g_EntityManager.dispatchAll(&init_msg);
in_add_handler(handler);
in_add_handler(terr_handler);
in_add_handler(game_view_handler);
in_add_handler(interactInputHandler);
@ -888,6 +869,7 @@ PREVTSC=CURTSC;
RenderNoCull();
if (g_FixedFrameTiming) {
CCamera &g_Camera=*g_Game->GetView()->GetCamera();
#if 0 // TOPDOWN
g_Camera.SetProjection(1.0f,10000.0f,DEGTORAD(90));
g_Camera.m_Orientation.SetIdentity();
@ -1005,8 +987,9 @@ static void Frame()
g_Game->Update(TimeSinceLastFrame);
if (!g_FixedFrameTiming)
terr_update(float(TimeSinceLastFrame));
g_Game->GetView()->Update(float(TimeSinceLastFrame));
// TODO Where does GameView end and other things begin?
g_Mouseover.update( TimeSinceLastFrame );
g_Selection.update();

View File

@ -2,16 +2,21 @@
#include "Game.h"
void CGame::Initialize(CGameAttributes *pAttribs)
{
m_World.Initialize(pAttribs);
m_Simulation.Initialize(pAttribs);
m_GameView.Initialize(pAttribs);
}
CGame *g_Game=NULL;
void CGame::Render()
PSRETURN CGame::Initialize(CGameAttributes *pAttribs)
{
m_GameView.Render();
try
{
m_World.Initialize(pAttribs);
m_Simulation.Initialize(pAttribs);
m_GameView.Initialize(pAttribs);
}
catch (PSERROR_Game e)
{
return e.code;
}
return 0;
}
void CGame::Update(double deltaTime)

View File

@ -47,23 +47,22 @@ public:
/*
Initialize all local state and members for playing a game described by
the attribute class.
Return: 0 on OK - a PSRETURN code otherwise
*/
void Initialize(CGameAttributes *pGameAttributes);
PSRETURN Initialize(CGameAttributes *pGameAttributes);
/*
Perform all per-frame updates
*/
void Update(double deltaTime);
/*
Render the game
*/
void Render();
inline CWorld *GetWorld()
{ return &m_World; }
inline CGameView *GetView()
{ return &m_GameView; }
};
extern CGame *g_Game;
#endif

View File

@ -6,8 +6,9 @@
#include "HFTracer.h"
#include "Hotkey.h"
#include "timer.h"
#include "Game.h"
extern CCamera g_Camera;
extern CGame *g_Game;
extern CConsole* g_Console;
extern int mouse_x, mouse_y;
extern bool keys[SDLK_LAST];
@ -15,6 +16,10 @@ extern bool keys[SDLK_LAST];
static const float SELECT_DBLCLICK_RATE = 0.5f;
static const int ORDER_DELAY = 5;
CVector3D cameraBookmarks[10];
bool bookmarkInUse[10] = { false, false, false, false, false, false, false, false, false, false };
u8 currentBookmark = 255;
void CSelectedEntities::addSelection( CEntity* entity )
{
m_group = 255;
@ -60,6 +65,9 @@ void CSelectedEntities::renderSelectionOutlines()
void CSelectedEntities::renderOverlays()
{
CTerrain *pTerrain=g_Game->GetWorld()->GetTerrain();
CCamera *pCamera=g_Game->GetView()->GetCamera();
glPushMatrix();
glEnable( GL_TEXTURE_2D );
std::vector<CEntity*>::iterator it;
@ -71,11 +79,11 @@ void CSelectedEntities::renderOverlays()
glLoadIdentity();
float x, y;
CVector3D labelpos = (*it)->m_graphics_position - g_Camera.m_Orientation.GetLeft() * (*it)->m_bounds->m_radius;
CVector3D labelpos = (*it)->m_graphics_position - pCamera->m_Orientation.GetLeft() * (*it)->m_bounds->m_radius;
#ifdef SELECTION_TERRAIN_CONFORMANCE
labelpos.Y = g_Terrain.getExactGroundLevel( labelpos.X, labelpos.Z );
labelpos.Y = pTerrain->getExactGroundLevel( labelpos.X, labelpos.Z );
#endif
g_Camera.GetScreenCoordinates( labelpos, x, y );
pCamera->GetScreenCoordinates( labelpos, x, y );
glColor4f( 1.0f, 1.0f, 1.0f, 1.0f );
glTranslatef( x, g_Renderer.GetHeight() - y, 0.0f );
glScalef( 1.0f, -1.0f, 1.0f );
@ -95,11 +103,11 @@ void CSelectedEntities::renderOverlays()
glLoadIdentity();
float x, y;
CVector3D labelpos = (*it)->m_graphics_position - g_Camera.m_Orientation.GetLeft() * (*it)->m_bounds->m_radius;
CVector3D labelpos = (*it)->m_graphics_position - pCamera->m_Orientation.GetLeft() * (*it)->m_bounds->m_radius;
#ifdef SELECTION_TERRAIN_CONFORMANCE
labelpos.Y = g_Terrain.getExactGroundLevel( labelpos.X, labelpos.Z );
labelpos.Y = pTerrain->getExactGroundLevel( labelpos.X, labelpos.Z );
#endif
g_Camera.GetScreenCoordinates( labelpos, x, y );
pCamera->GetScreenCoordinates( labelpos, x, y );
glColor4f( 1.0f, 1.0f, 1.0f, 0.5f );
glTranslatef( x, g_Renderer.GetHeight() - y, 0.0f );
glScalef( 1.0f, -1.0f, 1.0f );
@ -275,13 +283,13 @@ void CSelectedEntities::highlightGroup( u8 groupid )
if( !getGroupCount( groupid ) )
return;
m_group_highlight = groupid;
pushCameraTarget( getGroupPosition( groupid ) );
g_Game->GetView()->PushCameraTarget( getGroupPosition( groupid ) );
}
void CSelectedEntities::highlightNone()
{
if( m_group_highlight != 255 )
popCameraTarget();
g_Game->GetView()->PopCameraTarget();
m_group_highlight = 255;
}
@ -312,7 +320,7 @@ void CSelectedEntities::update()
m_contextOrder = -1;
}
if( ( m_group_highlight != 255 ) && getGroupCount( m_group_highlight ) )
setCameraTarget( getGroupPosition( m_group_highlight ) );
g_Game->GetView()->SetCameraTarget( getGroupPosition( m_group_highlight ) );
}
void CSelectedEntities::setContext( int contextOrder )
@ -369,18 +377,21 @@ bool CSelectedEntities::isContextValid( int contextOrder )
void CSelectedEntities::contextOrder( bool pushQueue )
{
CCamera *pCamera=g_Game->GetView()->GetCamera();
CTerrain *pTerrain=g_Game->GetWorld()->GetTerrain();
std::vector<CEntity*>::iterator it;
CEntityOrder context, contextRandomized;
(int&)context.m_type = m_contextOrder;
CVector3D origin, dir;
g_Camera.BuildCameraRay( origin, dir );
pCamera->BuildCameraRay( origin, dir );
switch( m_contextOrder )
{
case CEntityOrder::ORDER_GOTO:
case CEntityOrder::ORDER_PATROL:
{
CHFTracer maptracer( g_Terrain.GetHeightMap(), g_Terrain.GetVerticesPerSide(), (float)CELL_SIZE, HEIGHT_SCALE );
CHFTracer maptracer( pTerrain );
int x, y; CVector3D ipt;
maptracer.RayIntersect( origin, dir, x, y, ipt );
context.m_data[0].location.x = ipt.X;
@ -423,8 +434,11 @@ void CSelectedEntities::contextOrder( bool pushQueue )
void CMouseoverEntities::update( float timestep )
{
CCamera *pCamera=g_Game->GetView()->GetCamera();
CTerrain *pTerrain=g_Game->GetWorld()->GetTerrain();
CVector3D origin, dir;
g_Camera.BuildCameraRay( origin, dir );
pCamera->BuildCameraRay( origin, dir );
CUnit* hit = g_UnitMan.PickUnit( origin, dir );
@ -473,7 +487,7 @@ void CMouseoverEntities::update( float timestep )
float x, y;
g_Camera.GetScreenCoordinates( worldspace, x, y );
pCamera->GetScreenCoordinates( worldspace, x, y );
bool inBox;
if( m_x1 < m_x2 )
@ -616,6 +630,9 @@ void CMouseoverEntities::renderSelectionOutlines()
void CMouseoverEntities::renderOverlays()
{
CCamera *pCamera=g_Game->GetView()->GetCamera();
CTerrain *pTerrain=g_Game->GetWorld()->GetTerrain();
glLoadIdentity();
glDisable( GL_TEXTURE_2D );
if( m_bandbox )
@ -642,11 +659,11 @@ void CMouseoverEntities::renderOverlays()
glEnable( GL_TEXTURE_2D );
glLoadIdentity();
float x, y;
CVector3D labelpos = it->entity->m_graphics_position - g_Camera.m_Orientation.GetLeft() * it->entity->m_bounds->m_radius;
CVector3D labelpos = it->entity->m_graphics_position - pCamera->m_Orientation.GetLeft() * it->entity->m_bounds->m_radius;
#ifdef SELECTION_TERRAIN_CONFORMANCE
labelpos.Y = g_Terrain.getExactGroundLevel( labelpos.X, labelpos.Z );
labelpos.Y = pTerrain->getExactGroundLevel( labelpos.X, labelpos.Z );
#endif
g_Camera.GetScreenCoordinates( labelpos, x, y );
pCamera->GetScreenCoordinates( labelpos, x, y );
glColor4f( 1.0f, 1.0f, 1.0f, it->fade );
glTranslatef( x, g_Renderer.GetHeight() - y, 0.0f );
glScalef( 1.0f, -1.0f, 1.0f );
@ -670,7 +687,10 @@ void CMouseoverEntities::stopBandbox()
int interactInputHandler( const SDL_Event* ev )
{
CGameView *pView=g_Game->GetView();
CCamera *pCamera=pView->GetCamera();
CTerrain *pTerrain=g_Game->GetWorld()->GetTerrain();
static float lastclicktime = 0.0f;
static CEntity* lastclickobject = NULL;
static u8 clicks = 0;
@ -688,7 +708,7 @@ int interactInputHandler( const SDL_Event* ev )
break;
case HOTKEY_SELECTION_SNAP:
if( g_Selection.m_selected.size() )
setCameraTarget( g_Selection.getSelectionPosition() );
pView->SetCameraTarget( g_Selection.getSelectionPosition() );
break;
case HOTKEY_CONTEXTORDER_NEXT:
g_Selection.nextContext();
@ -697,7 +717,7 @@ int interactInputHandler( const SDL_Event* ev )
g_Selection.previousContext();
break;
default:
if( ( ev->user.code >= HOTKEY_SELECTION_GROUP_0 ) && ( ev->key.keysym.sym <= HOTKEY_SELECTION_GROUP_19 ) )
if( ( ev->user.code >= HOTKEY_SELECTION_GROUP_0 ) && ( ev->user.code <= HOTKEY_SELECTION_GROUP_19 ) )
{
// The above test limits it to 20 groups, so don't worry about overflowing
u8 id = (u8)( ev->user.code - HOTKEY_SELECTION_GROUP_0 );
@ -718,7 +738,7 @@ int interactInputHandler( const SDL_Event* ev )
{
if( ( g_Selection.m_group == id ) && g_Selection.getGroupCount( id ) )
{
setCameraTarget( g_Selection.getGroupPosition( id ) );
pView->SetCameraTarget( g_Selection.getGroupPosition( id ) );
}
else
g_Selection.loadGroup( id );
@ -732,10 +752,11 @@ int interactInputHandler( const SDL_Event* ev )
if( hotkeys[HOTKEY_CAMERA_BOOKMARK_SAVE] )
{
// Attempt to track the ground we're looking at
CHFTracer tracer( g_Terrain.GetHeightMap(), g_Terrain.GetVerticesPerSide(), (float)CELL_SIZE, (float)HEIGHT_SCALE ); int x, z;
CHFTracer tracer( pTerrain );
int x, z;
CVector3D origin, dir, delta, currentTarget;
origin = g_Camera.m_Orientation.GetTranslation();
dir = g_Camera.m_Orientation.GetIn();
origin = pCamera->m_Orientation.GetTranslation();
dir = pCamera->m_Orientation.GetIn();
if( tracer.RayIntersect( origin, dir, x, z, currentTarget ) )
{
cameraBookmarks[id] = currentTarget;
@ -743,7 +764,7 @@ int interactInputHandler( const SDL_Event* ev )
else
{
// Placing a bookmark off the map? If you say so, guv'nor.
cameraBookmarks[id] = g_Camera.m_Orientation.GetTranslation() + g_Camera.m_Orientation.GetIn() * 160.0f;
cameraBookmarks[id] = pCamera->m_Orientation.GetTranslation() + pCamera->m_Orientation.GetIn() * 160.0f;
}
bookmarkInUse[id] = true;
}
@ -751,14 +772,14 @@ int interactInputHandler( const SDL_Event* ev )
{
if( bookmarkInUse[id] && ( currentBookmark == 255 ) )
{
pushCameraTarget( cameraBookmarks[id] );
pView->PushCameraTarget( cameraBookmarks[id] );
currentBookmark = id;
}
}
else
{
if( bookmarkInUse[id] )
setCameraTarget( cameraBookmarks[id] );
pView->SetCameraTarget( cameraBookmarks[id] );
}
return( EV_HANDLED );
}
@ -774,7 +795,7 @@ int interactInputHandler( const SDL_Event* ev )
break;
case HOTKEY_CAMERA_BOOKMARK_SNAP:
if( currentBookmark != 255 )
popCameraTarget();
pView->PopCameraTarget();
currentBookmark = 255;
break;
case HOTKEY_HIGHLIGHTALL:
@ -855,7 +876,9 @@ int interactInputHandler( const SDL_Event* ev )
bool isOnScreen( CEntity* ev )
{
CFrustum frustum = g_Camera.GetFrustum();
CCamera *pCamera=g_Game->GetView()->GetCamera();
CFrustum frustum = pCamera->GetFrustum();
return( frustum.IsBoxVisible( CVector3D(), ev->m_actor->GetModel()->GetBounds() ) );
}
@ -869,36 +892,3 @@ bool isMouseoverType( CEntity* ev )
}
return( false );
}
void pushCameraTarget( const CVector3D& target )
{
// Save the current position
cameraTargets.push_back( g_Camera.m_Orientation.GetTranslation() );
// And set the camera
setCameraTarget( target );
}
void setCameraTarget( const CVector3D& target )
{
// Maintain the same orientation and level of zoom, if we can
// (do this by working out the point the camera is looking at, saving
// the difference beteen that position and the camera point, and restoring
// that difference to our new target)
CHFTracer tracer( g_Terrain.GetHeightMap(), g_Terrain.GetVerticesPerSide(), (float)CELL_SIZE, (float)HEIGHT_SCALE ); int x, z;
CVector3D origin, dir, currentTarget;
origin = g_Camera.m_Orientation.GetTranslation();
dir = g_Camera.m_Orientation.GetIn();
if( tracer.RayIntersect( origin, dir, x, z, currentTarget ) )
{
cameraDelta = target - currentTarget;
}
else
cameraDelta = ( target - dir * 160.0f ) - origin;
}
void popCameraTarget()
{
cameraDelta = cameraTargets.back() - g_Camera.m_Orientation.GetTranslation();
cameraTargets.pop_back();
}

View File

@ -103,18 +103,8 @@ struct CMouseoverEntities : public Singleton<CMouseoverEntities>
bool isMouseoverType( CEntity* ev );
bool isOnScreen( CEntity* ev );
void pushCameraTarget( const CVector3D& target );
void setCameraTarget( const CVector3D& target );
void popCameraTarget();
int interactInputHandler( const SDL_Event* ev );
extern std::vector<CVector3D> cameraTargets;
extern CVector3D cameraBookmarks[10];
extern bool bookmarkInUse[10];
extern u8 currentBookmark;
extern CVector3D cameraDelta;
#define g_Selection CSelectedEntities::GetSingleton()
#define g_Mouseover CMouseoverEntities::GetSingleton()

View File

@ -8,21 +8,22 @@
#include "MapReader.h"
#include "Game.h"
#include "Terrain.h"
#include "LightEnv.h"
#include "BaseEntityCollection.h"
CTerrain* g_Terrain_ptr = NULL;
extern CLightEnv g_LightEnv;
void CWorld::Initialize(CGameAttributes *pAttribs)
{
// load a map if we were given one
if (pAttribs->m_MapFile) {
CStr mapfilename("mods/official/maps/scenarios/");
mapfilename+=pAttribs->m_MapFile;
try {
CMapReader reader;
reader.LoadMap(mapfilename);
} catch (...) {
LOG(ERROR, "Failed to load map %s", mapfilename.c_str());
throw PSERROR_Game_World_MapLoadFailed();
}
g_EntityTemplateCollection.loadTemplates();
CStr mapfilename("mods/official/maps/scenarios/");
mapfilename+=pAttribs->m_MapFile;
try {
CMapReader reader;
reader.LoadMap(mapfilename, &m_Terrain, &m_UnitManager, &g_LightEnv);
} catch (...) {
LOG(ERROR, "Failed to load map %s", mapfilename.c_str());
throw PSERROR_Game_World_MapLoadFailed();
}
}

View File

@ -1,15 +1,12 @@
#ifndef _ps_World_H
#define _ps_World_H
#include "Terrain.h"
#include "UnitManager.h"
class CGame;
class CGameAttributes;
class CTerrain;
extern CTerrain* g_Terrain_ptr;
#define g_Terrain (*g_Terrain_ptr)
#include "UnitManager.h"
class CWorld
{
CGame *m_pGame;
@ -17,13 +14,13 @@ class CWorld
// These both point to the respective g_* globals - the plan is to remove
// the globals and move them into CWorld members as soon as all code has
// been converted
CTerrain *m_pTerrain;
CUnitManager *m_pUnitManager;
CTerrain m_Terrain;
CUnitManager &m_UnitManager;
public:
inline CWorld(CGame *pGame):
m_pGame(pGame),
m_pTerrain(&g_Terrain),
m_pUnitManager(&g_UnitMan)
m_Terrain(),
m_UnitManager(g_UnitMan)
{}
/*
@ -32,9 +29,9 @@ public:
void Initialize(CGameAttributes *pGameAttributes);
inline CTerrain *GetTerrain()
{ return m_pTerrain; }
{ return &m_Terrain; }
inline CUnitManager *GetUnitManager()
{ return m_pUnitManager; }
{ return &m_UnitManager; }
};
#include "Game.h"

View File

@ -12,6 +12,8 @@
# endif
#endif
#include "Errors.h"
ERROR_GROUP(Scripting);
ERROR_TYPE(Scripting, RuntimeCreationFailed);
ERROR_TYPE(Scripting, ContextCreationFailed);

View File

@ -14,7 +14,7 @@
#include "Collision.h"
#include "PathfindEngine.h"
extern CCamera g_Camera;
#include "Game.h"
CEntity::CEntity( CBaseEntity* base, CVector3D position, float orientation )
{
@ -155,7 +155,9 @@ void CEntity::updateActorTransforms()
void CEntity::snapToGround()
{
m_graphics_position.Y = g_Terrain.getExactGroundLevel( m_graphics_position.X, m_graphics_position.Z );
CTerrain *pTerrain = g_Game->GetWorld()->GetTerrain();
m_graphics_position.Y = pTerrain->getExactGroundLevel( m_graphics_position.X, m_graphics_position.Z );
}
void CEntity::update( size_t timestep )
@ -340,6 +342,8 @@ void CEntity::interpolate( float relativeoffset )
void CEntity::render()
{
CTerrain *pTerrain = g_Game->GetWorld()->GetTerrain();
if( !m_orderQueue.empty() )
{
std::deque<CEntityOrder>::iterator it;
@ -384,11 +388,11 @@ void CEntity::render()
glEnd();
glBegin( GL_LINES );
glColor3f( 1.0f, 0.0f, 0.0f );
glVertex3f( x0 + fwd.x * r.distance, g_Terrain.getExactGroundLevel( x0 + fwd.x * r.distance, y0 + fwd.y * r.distance ) + 0.25f, y0 + fwd.y * r.distance );
glVertex3f( r.position.x, g_Terrain.getExactGroundLevel( r.position.x, r.position.y ) + 0.25f, r.position.y );
glVertex3f( x0 + fwd.x * r.distance, pTerrain->getExactGroundLevel( x0 + fwd.x * r.distance, y0 + fwd.y * r.distance ) + 0.25f, y0 + fwd.y * r.distance );
glVertex3f( r.position.x, pTerrain->getExactGroundLevel( r.position.x, r.position.y ) + 0.25f, r.position.y );
glEnd();
glBegin( GL_LINE_STRIP );
glVertex3f( x0, g_Terrain.getExactGroundLevel( x0, y0 ), y0 );
glVertex3f( x0, pTerrain->getExactGroundLevel( x0, y0 ), y0 );
}
switch( it->m_type )
{
@ -405,7 +409,7 @@ void CEntity::render()
continue;
}
glVertex3f( x, g_Terrain.getExactGroundLevel( x, y ) + 0.25f, y );
glVertex3f( x, pTerrain->getExactGroundLevel( x, y ) + 0.25f, y );
}
glEnd();
@ -414,11 +418,13 @@ void CEntity::render()
glColor3f( 1.0f, 1.0f, 1.0f );
if( getCollisionObject( this ) ) glColor3f( 0.5f, 0.5f, 1.0f );
m_bounds->render( g_Terrain.getExactGroundLevel( m_position.X, m_position.Z ) + 0.25f ); //m_position.Y + 0.25f );
m_bounds->render( pTerrain->getExactGroundLevel( m_position.X, m_position.Z ) + 0.25f ); //m_position.Y + 0.25f );
}
void CEntity::renderSelectionOutline( float alpha )
{
CTerrain *pTerrain = g_Game->GetWorld()->GetTerrain();
if( !m_bounds ) return;
glColor4f( 1.0f, 1.0f, 1.0f, alpha );
@ -439,7 +445,7 @@ void CEntity::renderSelectionOutline( float alpha )
float x = pos.X + radius * sin( ang );
float y = pos.Z + radius * cos( ang );
#ifdef SELECTION_TERRAIN_CONFORMANCE
glVertex3f( x, g_Terrain.getExactGroundLevel( x, y ) + 0.25f, y );
glVertex3f( x, pTerrain->getExactGroundLevel( x, y ) + 0.25f, y );
#else
glVertex3f( x, pos.Y + 0.25f, y );
#endif
@ -463,29 +469,29 @@ void CEntity::renderSelectionOutline( float alpha )
for( int i = SELECTION_BOX_POINTS; i > -SELECTION_BOX_POINTS; i-- )
{
p = q + u * h + v * ( w * (float)i / (float)SELECTION_BOX_POINTS );
glVertex3f( p.x, g_Terrain.getExactGroundLevel( p.x, p.y ) + 0.25f, p.y );
glVertex3f( p.x, pTerrain->getExactGroundLevel( p.x, p.y ) + 0.25f, p.y );
}
for( int i = SELECTION_BOX_POINTS; i > -SELECTION_BOX_POINTS; i-- )
{
p = q + u * ( h * (float)i / (float)SELECTION_BOX_POINTS ) - v * w;
glVertex3f( p.x, g_Terrain.getExactGroundLevel( p.x, p.y ) + 0.25f, p.y );
glVertex3f( p.x, pTerrain->getExactGroundLevel( p.x, p.y ) + 0.25f, p.y );
}
for( int i = -SELECTION_BOX_POINTS; i < SELECTION_BOX_POINTS; i++ )
{
p = q - u * h + v * ( w * (float)i / (float)SELECTION_BOX_POINTS );
glVertex3f( p.x, g_Terrain.getExactGroundLevel( p.x, p.y ) + 0.25f, p.y );
glVertex3f( p.x, pTerrain->getExactGroundLevel( p.x, p.y ) + 0.25f, p.y );
}
for( int i = -SELECTION_BOX_POINTS; i < SELECTION_BOX_POINTS; i++ )
{
p = q + u * ( h * (float)i / (float)SELECTION_BOX_POINTS ) + v * w;
glVertex3f( p.x, g_Terrain.getExactGroundLevel( p.x, p.y ) + 0.25f, p.y );
glVertex3f( p.x, pTerrain->getExactGroundLevel( p.x, p.y ) + 0.25f, p.y );
}
#else
p = q + u * h + v * w;
glVertex3f( p.x, g_Terrain.getExactGroundLevel( p.x, p.y ) + 0.25f, p.y );
glVertex3f( p.x, pTerrain->getExactGroundLevel( p.x, p.y ) + 0.25f, p.y );
p = q + u * h - v * w;
glVertex3f( p.x, getExactGroundLevel( p.x, p.y ) + 0.25f, p.y );

View File

@ -9,7 +9,7 @@
#include "PathfindEngine.h"
#include "Terrain.h"
extern CTerrain g_Terrain;
#include "Game.h"
bool CEntity::processGotoNoPathing( CEntityOrder* current, size_t timestep_millis )
{
@ -192,7 +192,7 @@ bool CEntity::processGotoNoPathing( CEntityOrder* current, size_t timestep_milli
}
// Will we step off the map?
if( !g_Terrain.isOnMap( m_position.X, m_position.Z ) )
if( !g_Game->GetWorld()->GetTerrain()->isOnMap( m_position.X, m_position.Z ) )
{
// Yes. That's not a particularly good idea, either.

View File

@ -2,6 +2,7 @@
#include "PathfindSparse.h"
#include "Terrain.h"
#include "Game.h"
int SPF_RECURSION_DEPTH = 10;
@ -28,6 +29,8 @@ sparsePathTree::~sparsePathTree()
bool sparsePathTree::slice()
{
CTerrain *pTerrain = g_Game->GetWorld()->GetTerrain();
if( type == SPF_OPEN_UNVISITED )
{
if( !recursionDepth )
@ -104,14 +107,14 @@ bool sparsePathTree::slice()
// Let me know.
// Check that the subwaypoints are on the map...
if( !g_Terrain.isOnMap( left ) )
if( !pTerrain->isOnMap( left ) )
{
// Shut that path down
leftPre->type = SPF_IMPOSSIBLE;
leftPost->type = SPF_IMPOSSIBLE;
}
if( !g_Terrain.isOnMap( right ) )
if( !pTerrain->isOnMap( right ) )
{
// Shut that path down
rightPre->type = SPF_IMPOSSIBLE;

View File

@ -16,7 +16,10 @@ CSimulation::CSimulation(CGame *pGame):
{}
void CSimulation::Initialize(CGameAttributes *pAttribs)
{}
{
CMessage init_msg (CMessage::EMSG_INIT);
g_EntityManager.dispatchAll(&init_msg);
}
void CSimulation::Update(double frameTime)
{

View File

@ -27,398 +27,11 @@ extern bool g_active;
CMatrix3D g_WorldMat;
CCamera g_Camera;
CLightEnv g_LightEnv;
float g_CameraZoom = 10;
std::vector<CVector3D> cameraTargets;
CVector3D cameraBookmarks[10];
bool bookmarkInUse[10] = { false, false, false, false, false, false, false, false, false, false };
u8 currentBookmark = 255;
CVector3D cameraDelta;
CVector3D cameraPivot;
// These were 'const'; loaded from config now.
float ViewScrollSpeed = 60;
float ViewRotateSensitivity = 0.002f;
float ViewRotateAboutTargetSensitivity = 0.010f;
float ViewDragSensitivity = 0.5f;
float ViewZoomSensitivityWheel = 16.0f;
float ViewZoomSensitivity = 256.0f;
float ViewZoomSmoothness = 0.02f; // 0.0 = instantaneous zooming, 1.0 = so slow it never moves
float ViewSnapSmoothness = 0.02f; // Just the same.
float ViewFOV;
extern int g_xres, g_yres;
void terr_init()
/*void InitScene ()
{
SViewPort vp;
vp.m_X=0;
vp.m_Y=0;
vp.m_Width=g_xres;
vp.m_Height=g_yres;
g_Camera.SetViewPort(&vp);
CConfigValue* cfg;
#define getViewParameter( name, value ) STMT( \
cfg = g_ConfigDB.GetValue( CFG_SYSTEM, name );\
if( cfg ) cfg->GetFloat( value ); )
getViewParameter( "view.scroll.speed", ViewScrollSpeed );
getViewParameter( "view.rotate.speed", ViewRotateSensitivity );
getViewParameter( "view.rotate.abouttarget.speed", ViewRotateAboutTargetSensitivity );
getViewParameter( "view.drag.speed", ViewDragSensitivity );
getViewParameter( "view.zoom.speed", ViewZoomSensitivity );
getViewParameter( "view.zoom.wheel.speed", ViewZoomSensitivityWheel );
getViewParameter( "view.zoom.smoothness", ViewZoomSmoothness );
getViewParameter( "view.snap.smoothness", ViewSnapSmoothness );
if( ( ViewZoomSmoothness < 0.0f ) || ( ViewZoomSmoothness > 1.0f ) ) ViewZoomSmoothness = 0.02f;
if( ( ViewSnapSmoothness < 0.0f ) || ( ViewSnapSmoothness > 1.0f ) ) ViewSnapSmoothness = 0.02f;
#undef getViewParameter
InitResources ();
InitScene ();
}
static void move_camera(float DeltaTime)
{
float delta = powf( ViewSnapSmoothness, DeltaTime );
g_Camera.m_Orientation.Translate( cameraDelta * ( 1.0f - delta ) );
cameraDelta *= delta;
#define CAMERASTYLE 2 // 0 = old style, 1 = relatively new style, 2 = newest style
#if CAMERASTYLE == 2
// This could be rewritten much more reliably, so it doesn't e.g. accidentally tilt
// the camera, assuming we know exactly what limits the camera should have.
// Calculate mouse movement
static int mouse_last_x = 0;
static int mouse_last_y = 0;
int mouse_dx = mouse_x - mouse_last_x;
int mouse_dy = mouse_y - mouse_last_y;
mouse_last_x = mouse_x;
mouse_last_y = mouse_y;
// Miscellaneous vectors
CVector3D forwards = g_Camera.m_Orientation.GetIn();
CVector3D rightwards = g_Camera.m_Orientation.GetLeft() * -1.0f; // upwards.Cross(forwards);
CVector3D upwards( 0.0f, 1.0f, 0.0f );
// rightwards.Normalize();
CVector3D forwards_horizontal = forwards;
forwards_horizontal.Y = 0.0f;
forwards_horizontal.Normalize();
/*
if ((mouseButtons[SDL_BUTTON_MIDDLE] && (keys[SDLK_LCTRL] || keys[SDLK_RCTRL]))
|| (mouseButtons[SDL_BUTTON_LEFT] && mouseButtons[SDL_BUTTON_RIGHT]) )
*/
if( hotkeys[HOTKEY_CAMERA_ROTATE] )
{
// Ctrl + middle-drag or left-and-right-drag to rotate view
// Untranslate the camera, so it rotates around the correct point
CVector3D position = g_Camera.m_Orientation.GetTranslation();
g_Camera.m_Orientation.Translate(position*-1);
// Sideways rotation
g_Camera.m_Orientation.RotateY(ViewRotateSensitivity * (float)(mouse_dx));
// Up/down rotation
CQuaternion temp;
temp.FromAxisAngle(rightwards, ViewRotateSensitivity * (float)(mouse_dy));
g_Camera.m_Orientation.Rotate(temp);
// Retranslate back to the right position
g_Camera.m_Orientation.Translate(position);
}
else if( hotkeys[HOTKEY_CAMERA_ROTATE_ABOUT_TARGET] )
{
CVector3D origin = g_Camera.m_Orientation.GetTranslation();
CVector3D delta = origin - cameraPivot;
CQuaternion rotateH, rotateV; CMatrix3D rotateM;
// Side-to-side rotation
rotateH.FromAxisAngle( upwards, ViewRotateAboutTargetSensitivity * (float)mouse_dx );
// Up-down rotation
rotateV.FromAxisAngle( rightwards, ViewRotateAboutTargetSensitivity * (float)mouse_dy );
rotateH *= rotateV;
rotateH.ToMatrix( rotateM );
delta = rotateM.Rotate( delta );
// Lock the inclination to a rather arbitrary values (for the sake of graphical decency)
float scan = sqrt( delta.X * delta.X + delta.Z * delta.Z ) / delta.Y;
if( ( scan >= 0.5f ) )
{
// Move the camera to the origin (in preparation for rotation )
g_Camera.m_Orientation.Translate( origin * -1.0f );
g_Camera.m_Orientation.Rotate( rotateH );
// Move the camera back to where it belongs
g_Camera.m_Orientation.Translate( cameraPivot + delta );
}
}
else if( hotkeys[HOTKEY_CAMERA_PAN] )
{
// Middle-drag to pan
g_Camera.m_Orientation.Translate(rightwards * (ViewDragSensitivity * mouse_dx));
g_Camera.m_Orientation.Translate(forwards_horizontal * (-ViewDragSensitivity * mouse_dy));
}
// Mouse movement
if( !hotkeys[HOTKEY_CAMERA_ROTATE] && !hotkeys[HOTKEY_CAMERA_ROTATE_ABOUT_TARGET] )
{
if (mouse_x >= g_xres-2)
g_Camera.m_Orientation.Translate(rightwards * (ViewScrollSpeed * DeltaTime));
else if (mouse_x <= 3)
g_Camera.m_Orientation.Translate(-rightwards * (ViewScrollSpeed * DeltaTime));
if (mouse_y >= g_yres-2)
g_Camera.m_Orientation.Translate(-forwards_horizontal * (ViewScrollSpeed * DeltaTime));
else if (mouse_y <= 3)
g_Camera.m_Orientation.Translate(forwards_horizontal * (ViewScrollSpeed * DeltaTime));
}
// Keyboard movement (added to mouse movement, so you can go faster if you want)
if( hotkeys[HOTKEY_CAMERA_PAN_RIGHT] )
g_Camera.m_Orientation.Translate(rightwards * (ViewScrollSpeed * DeltaTime));
if( hotkeys[HOTKEY_CAMERA_PAN_LEFT] )
g_Camera.m_Orientation.Translate(-rightwards * (ViewScrollSpeed * DeltaTime));
if( hotkeys[HOTKEY_CAMERA_PAN_BACKWARD] )
g_Camera.m_Orientation.Translate(-forwards_horizontal * (ViewScrollSpeed * DeltaTime));
if( hotkeys[HOTKEY_CAMERA_PAN_FORWARD] )
g_Camera.m_Orientation.Translate(forwards_horizontal * (ViewScrollSpeed * DeltaTime));
// Smoothed zooming (move a certain percentage towards the desired zoom distance every frame)
static float zoom_delta = 0.0f;
if( hotkeys[HOTKEY_CAMERA_ZOOM_WHEEL_IN] )
zoom_delta += ViewZoomSensitivityWheel;
else if( hotkeys[HOTKEY_CAMERA_ZOOM_WHEEL_OUT] )
zoom_delta -= ViewZoomSensitivityWheel;
if( hotkeys[HOTKEY_CAMERA_ZOOM_IN] )
zoom_delta += ViewZoomSensitivity*DeltaTime;
else if( hotkeys[HOTKEY_CAMERA_ZOOM_OUT] )
zoom_delta -= ViewZoomSensitivity*DeltaTime;
if (zoom_delta)
{
float zoom_proportion = powf(ViewZoomSmoothness, DeltaTime);
g_Camera.m_Orientation.Translate(forwards * (zoom_delta * (1.0f-zoom_proportion)));
zoom_delta *= zoom_proportion;
}
#elif CAMERASTYLE == 1
// Remember previous mouse position, to calculate changes
static mouse_last_x = 0;
static mouse_last_y = 0;
// Miscellaneous vectors
CVector3D forwards = g_Camera.m_Orientation.GetIn();
CVector3D upwards (0.0f, 1.0f, 0.0f);
CVector3D rightwards = upwards.Cross(forwards);
// Click and drag to look around
if (mouseButtons[0])
{
// Untranslate the camera, so it rotates around the correct point
CVector3D position = g_Camera.m_Orientation.GetTranslation();
g_Camera.m_Orientation.Translate(position*-1);
// Sideways rotation
g_Camera.m_Orientation.RotateY(ViewRotateSpeed*(float)(mouse_x-mouse_last_x));
// Up/down rotation
CQuaternion temp;
temp.FromAxisAngle(rightwards, ViewRotateSpeed*(float)(mouse_y-mouse_last_y));
g_Camera.m_Orientation.Rotate(temp);
// Retranslate back to the right position
g_Camera.m_Orientation.Translate(position);
}
mouse_last_x = mouse_x;
mouse_last_y = mouse_y;
// Calculate the necessary vectors for movement
rightwards.Normalize();
CVector3D forwards_horizontal = upwards.Cross(rightwards);
forwards_horizontal.Normalize();
// Move when desirable
if (mouse_x >= g_xres-2)
g_Camera.m_Orientation.Translate(rightwards);
else if (mouse_x <= 3)
g_Camera.m_Orientation.Translate(-rightwards);
if (mouse_y >= g_yres-2)
g_Camera.m_Orientation.Translate(forwards_horizontal);
else if (mouse_y <= 3)
g_Camera.m_Orientation.Translate(-forwards_horizontal);
// Smoothed height-changing (move a certain percentage towards the desired height every frame)
static float height_delta = 0.0f;
if (mouseButtons[SDL_BUTTON_WHEELUP])
height_delta -= 4.0f;
else if (mouseButtons[SDL_BUTTON_WHEELDOWN])
height_delta += 4.0f;
const float height_speed = 0.2f;
g_Camera.m_Orientation.Translate(0.0f, height_delta*height_speed, 0.0f);
height_delta *= (1.0f - height_speed);
#else // CAMERASTYLE == 0
const float dx = ViewScrollSpeed * DeltaTime;
const CVector3D Right(dx,0, dx);
const CVector3D Up (dx,0,-dx);
if (mouse_x >= g_xres-2)
g_Camera.m_Orientation.Translate(Right);
if (mouse_x <= 3)
g_Camera.m_Orientation.Translate(Right*-1);
if (mouse_y >= g_yres-2)
g_Camera.m_Orientation.Translate(Up);
if (mouse_y <= 3)
g_Camera.m_Orientation.Translate(Up*-1);
/*
janwas: grr, plotted the zoom vector on paper twice, but it appears
to be completely wrong. sticking with the FOV hack for now.
if anyone sees what's wrong, or knows how to correctly implement zoom,
please put this code out of its misery :)
*/
// RC - added ScEd style zoom in and out (actually moving camera, rather than fudging fov)
float dir=0;
if (mouseButtons[SDL_BUTTON_WHEELUP]) dir=-1;
else if (mouseButtons[SDL_BUTTON_WHEELDOWN]) dir=1;
float factor=dir*dir;
if (factor) {
if (dir<0) factor=-factor;
CVector3D forward=g_Camera.m_Orientation.GetIn();
// check we're not going to zoom into the terrain, or too far out into space
float h=g_Camera.m_Orientation.GetTranslation().Y+forward.Y*factor*g_CameraZoom;
float minh=65536*HEIGHT_SCALE*1.05f;
if (h<minh || h>1500) {
// yup, we will; don't move anywhere (do clamped move instead, at some point)
} else {
// do a full move
g_CameraZoom-=(factor)*0.1f;
if (g_CameraZoom<0.01f) g_CameraZoom=0.01f;
g_Camera.m_Orientation.Translate(forward*(factor*g_CameraZoom));
}
}
#endif // CAMERASTYLE
g_Camera.UpdateFrustum ();
}
void terr_update(const float DeltaTime)
{
if(g_active)
move_camera(DeltaTime);
}
int terr_handler(const SDL_Event* ev)
{
// put any events that must be processed even if inactive here
if(!g_active)
return EV_PASS;
switch(ev->type)
{
case SDL_HOTKEYDOWN:
switch(ev->user.code)
{
case HOTKEY_WIREFRAME:
if (g_Renderer.GetTerrainRenderMode()==WIREFRAME) {
g_Renderer.SetTerrainRenderMode(SOLID);
} else {
g_Renderer.SetTerrainRenderMode(WIREFRAME);
}
return( EV_HANDLED );
case HOTKEY_CAMERA_RESET:
// quick hack to return camera home, for screenshots (after alt+tabbing)
g_Camera.SetProjection (1, 5000, DEGTORAD(20));
g_Camera.m_Orientation.SetXRotation(DEGTORAD(30));
g_Camera.m_Orientation.RotateY(DEGTORAD(-45));
g_Camera.m_Orientation.Translate (100, 150, -100);
return( EV_HANDLED );
case HOTKEY_CAMERA_ROTATE_ABOUT_TARGET:
{
int x, z;
CHFTracer tracer( g_Terrain.GetHeightMap(), g_Terrain.GetVerticesPerSide(), (float)CELL_SIZE, HEIGHT_SCALE );
CVector3D origin, dir;
origin = g_Camera.m_Orientation.GetTranslation();
dir = g_Camera.m_Orientation.GetIn();
g_Camera.BuildCameraRay( origin, dir );
if( !tracer.RayIntersect( origin, dir, x, z, cameraPivot ) )
cameraPivot = origin - dir * ( origin.Y / dir.Y );
}
return( EV_HANDLED );
}
}
return EV_PASS;
}
void InitScene ()
{
// setup default lighting environment
g_LightEnv.m_SunColor=RGBColor(1,1,1);
g_LightEnv.m_Rotation=DEGTORAD(270);
g_LightEnv.m_Elevation=DEGTORAD(45);
g_LightEnv.m_TerrainAmbientColor=RGBColor(0,0,0);
g_LightEnv.m_UnitsAmbientColor=RGBColor(0.4f,0.4f,0.4f);
g_Renderer.SetLightEnv(&g_LightEnv);
// load terrain
TexInfo ti;
int err = tex_load("terrain.raw", &ti);
@ -466,35 +79,6 @@ void InitScene ()
}
}
g_Camera.SetProjection (1, 5000, DEGTORAD(20));
g_Camera.m_Orientation.SetXRotation(DEGTORAD(30));
g_Camera.m_Orientation.RotateY(DEGTORAD(-45));
g_Camera.m_Orientation.Translate (100, 150, -100);
}
void InitResources()
{
g_TexMan.LoadTerrainTextures();
g_ObjMan.LoadObjects();
const char* fns[CRenderer::NumAlphaMaps] = {
"art/textures/terrain/alphamaps/special/blendcircle.png",
"art/textures/terrain/alphamaps/special/blendlshape.png",
"art/textures/terrain/alphamaps/special/blendedge.png",
"art/textures/terrain/alphamaps/special/blendedgecorner.png",
"art/textures/terrain/alphamaps/special/blendedgetwocorners.png",
"art/textures/terrain/alphamaps/special/blendfourcorners.png",
"art/textures/terrain/alphamaps/special/blendtwooppositecorners.png",
"art/textures/terrain/alphamaps/special/blendlshapecorner.png",
"art/textures/terrain/alphamaps/special/blendtwocorners.png",
"art/textures/terrain/alphamaps/special/blendcorner.png",
"art/textures/terrain/alphamaps/special/blendtwoedges.png",
"art/textures/terrain/alphamaps/special/blendthreecorners.png",
"art/textures/terrain/alphamaps/special/blendushape.png",
"art/textures/terrain/alphamaps/special/blendbad.png"
};
g_Renderer.LoadAlphaMaps(fns);
}
*/