forked from 0ad/0ad
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:
parent
aff7bd83e6
commit
09f47d6820
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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)) {
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
|
@ -77,9 +77,4 @@ private:
|
||||
u16* m_Heightmap;
|
||||
};
|
||||
|
||||
extern CTerrain* g_Terrain_ptr;
|
||||
#ifndef g_Terrain
|
||||
#define g_Terrain (*g_Terrain_ptr)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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()
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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"
|
||||
|
@ -12,6 +12,8 @@
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#include "Errors.h"
|
||||
|
||||
ERROR_GROUP(Scripting);
|
||||
ERROR_TYPE(Scripting, RuntimeCreationFailed);
|
||||
ERROR_TYPE(Scripting, ContextCreationFailed);
|
||||
|
@ -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 );
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user