ran everything though mark's newline stomper.
This was SVN commit r322.
This commit is contained in:
parent
a929a3506b
commit
1eaadd38aa
@ -1,146 +1,146 @@
|
||||
//***********************************************************
|
||||
//
|
||||
// Name: Camera.Cpp
|
||||
// Last Update: 24/2/02
|
||||
// Author: Poya Manouchehri
|
||||
//
|
||||
// Description: CCamera holds a view and a projection matrix.
|
||||
// It also has a frustum which can be used to
|
||||
// cull objects for rendering.
|
||||
//
|
||||
//***********************************************************
|
||||
|
||||
#include "Camera.h"
|
||||
|
||||
CCamera::CCamera ()
|
||||
{
|
||||
// set viewport to something anything should handle, but should be initialised
|
||||
// to window size before use
|
||||
m_ViewPort.m_X = 0;
|
||||
m_ViewPort.m_Y = 0;
|
||||
m_ViewPort.m_Width = 800;
|
||||
m_ViewPort.m_Height = 600;
|
||||
}
|
||||
|
||||
CCamera::~CCamera ()
|
||||
{
|
||||
}
|
||||
|
||||
void CCamera::SetProjection (float nearp, float farp, float fov)
|
||||
{
|
||||
float h, w, Q;
|
||||
|
||||
m_NearPlane = nearp;
|
||||
m_FarPlane = farp;
|
||||
m_FOV = fov;
|
||||
|
||||
float Aspect = (float)m_ViewPort.m_Width/(float)m_ViewPort.m_Height;
|
||||
|
||||
w = 1/tanf (fov*0.5f*Aspect);
|
||||
h = 1/tanf (fov*0.5f);
|
||||
Q = m_FarPlane / (m_FarPlane - m_NearPlane);
|
||||
|
||||
m_ProjMat.SetZero ();
|
||||
m_ProjMat._11 = w;
|
||||
m_ProjMat._22 = h;
|
||||
m_ProjMat._33 = (m_FarPlane+m_NearPlane)/(m_FarPlane-m_NearPlane);;
|
||||
m_ProjMat._34 = -2*m_FarPlane*m_NearPlane/(m_FarPlane-m_NearPlane);
|
||||
m_ProjMat._43 = 1.0f;
|
||||
}
|
||||
|
||||
//Updates the frustum planes. Should be called
|
||||
//everytime the view or projection matrices are
|
||||
//altered.
|
||||
void CCamera::UpdateFrustum ()
|
||||
{
|
||||
CMatrix3D MatFinal;
|
||||
CMatrix3D MatView;
|
||||
|
||||
m_Orientation.GetInverse(MatView);
|
||||
|
||||
MatFinal = m_ProjMat * MatView;
|
||||
|
||||
//get the RIGHT plane
|
||||
m_ViewFrustum.SetNumPlanes (6);
|
||||
|
||||
m_ViewFrustum.m_aPlanes[0].m_Norm.X = MatFinal._41-MatFinal._11;
|
||||
m_ViewFrustum.m_aPlanes[0].m_Norm.Y = MatFinal._42-MatFinal._12;
|
||||
m_ViewFrustum.m_aPlanes[0].m_Norm.Z = MatFinal._43-MatFinal._13;
|
||||
m_ViewFrustum.m_aPlanes[0].m_Dist = MatFinal._44-MatFinal._14;
|
||||
|
||||
//get the LEFT plane
|
||||
m_ViewFrustum.m_aPlanes[1].m_Norm.X = MatFinal._41+MatFinal._11;
|
||||
m_ViewFrustum.m_aPlanes[1].m_Norm.Y = MatFinal._42+MatFinal._12;
|
||||
m_ViewFrustum.m_aPlanes[1].m_Norm.Z = MatFinal._43+MatFinal._13;
|
||||
m_ViewFrustum.m_aPlanes[1].m_Dist = MatFinal._44+MatFinal._14;
|
||||
|
||||
//get the BOTTOM plane
|
||||
m_ViewFrustum.m_aPlanes[2].m_Norm.X = MatFinal._41+MatFinal._21;
|
||||
m_ViewFrustum.m_aPlanes[2].m_Norm.Y = MatFinal._42+MatFinal._22;
|
||||
m_ViewFrustum.m_aPlanes[2].m_Norm.Z = MatFinal._43+MatFinal._23;
|
||||
m_ViewFrustum.m_aPlanes[2].m_Dist = MatFinal._44+MatFinal._24;
|
||||
|
||||
//get the TOP plane
|
||||
m_ViewFrustum.m_aPlanes[3].m_Norm.X = MatFinal._41-MatFinal._21;
|
||||
m_ViewFrustum.m_aPlanes[3].m_Norm.Y = MatFinal._42-MatFinal._22;
|
||||
m_ViewFrustum.m_aPlanes[3].m_Norm.Z = MatFinal._43-MatFinal._23;
|
||||
m_ViewFrustum.m_aPlanes[3].m_Dist = MatFinal._44-MatFinal._24;
|
||||
|
||||
//get the FAR plane
|
||||
m_ViewFrustum.m_aPlanes[4].m_Norm.X = MatFinal._41-MatFinal._31;
|
||||
m_ViewFrustum.m_aPlanes[4].m_Norm.Y = MatFinal._42-MatFinal._32;
|
||||
m_ViewFrustum.m_aPlanes[4].m_Norm.Z = MatFinal._43-MatFinal._33;
|
||||
m_ViewFrustum.m_aPlanes[4].m_Dist = MatFinal._44-MatFinal._34;
|
||||
|
||||
//get the NEAR plane
|
||||
m_ViewFrustum.m_aPlanes[5].m_Norm.X = MatFinal._41+MatFinal._31;
|
||||
m_ViewFrustum.m_aPlanes[5].m_Norm.Y = MatFinal._42+MatFinal._32;
|
||||
m_ViewFrustum.m_aPlanes[5].m_Norm.Z = MatFinal._43+MatFinal._33;
|
||||
m_ViewFrustum.m_aPlanes[5].m_Dist = MatFinal._44+MatFinal._34;
|
||||
}
|
||||
|
||||
void CCamera::SetViewPort (SViewPort *viewport)
|
||||
{
|
||||
m_ViewPort.m_X = viewport->m_X;
|
||||
m_ViewPort.m_Y = viewport->m_Y;
|
||||
m_ViewPort.m_Width = viewport->m_Width;
|
||||
m_ViewPort.m_Height = viewport->m_Height;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// GetCameraPlanePoints: return four points in camera space at given distance from camera
|
||||
void CCamera::GetCameraPlanePoints(float dist,CVector3D pts[4]) const
|
||||
{
|
||||
float aspect=float(m_ViewPort.m_Width)/float(m_ViewPort.m_Height);
|
||||
|
||||
float x=dist*float(tan(GetFOV()*aspect*0.5));
|
||||
float y=dist*float(tan(GetFOV()*0.5));
|
||||
pts[0].X=-x;
|
||||
pts[0].Y=-y;
|
||||
pts[0].Z=dist;
|
||||
pts[1].X=x;
|
||||
pts[1].Y=-y;
|
||||
pts[1].Z=dist;
|
||||
pts[2].X=x;
|
||||
pts[2].Y=y;
|
||||
pts[2].Z=dist;
|
||||
pts[3].X=-x;
|
||||
pts[3].Y=y;
|
||||
pts[3].Z=dist;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// GetFrustumPoints: calculate and return the position of the 8 points of the frustum in world space
|
||||
void CCamera::GetFrustumPoints(CVector3D pts[8]) const
|
||||
{
|
||||
// get camera space points for near and far planes
|
||||
CVector3D cpts[8];
|
||||
GetCameraPlanePoints(m_NearPlane,pts);
|
||||
GetCameraPlanePoints(m_FarPlane,pts+4);
|
||||
|
||||
// transform to world space
|
||||
for (int i=0;i<8;i++) {
|
||||
m_Orientation.Transform(cpts[i],pts[i]);
|
||||
}
|
||||
}
|
||||
//***********************************************************
|
||||
//
|
||||
// Name: Camera.Cpp
|
||||
// Last Update: 24/2/02
|
||||
// Author: Poya Manouchehri
|
||||
//
|
||||
// Description: CCamera holds a view and a projection matrix.
|
||||
// It also has a frustum which can be used to
|
||||
// cull objects for rendering.
|
||||
//
|
||||
//***********************************************************
|
||||
|
||||
#include "Camera.h"
|
||||
|
||||
CCamera::CCamera ()
|
||||
{
|
||||
// set viewport to something anything should handle, but should be initialised
|
||||
// to window size before use
|
||||
m_ViewPort.m_X = 0;
|
||||
m_ViewPort.m_Y = 0;
|
||||
m_ViewPort.m_Width = 800;
|
||||
m_ViewPort.m_Height = 600;
|
||||
}
|
||||
|
||||
CCamera::~CCamera ()
|
||||
{
|
||||
}
|
||||
|
||||
void CCamera::SetProjection (float nearp, float farp, float fov)
|
||||
{
|
||||
float h, w, Q;
|
||||
|
||||
m_NearPlane = nearp;
|
||||
m_FarPlane = farp;
|
||||
m_FOV = fov;
|
||||
|
||||
float Aspect = (float)m_ViewPort.m_Width/(float)m_ViewPort.m_Height;
|
||||
|
||||
w = 1/tanf (fov*0.5f*Aspect);
|
||||
h = 1/tanf (fov*0.5f);
|
||||
Q = m_FarPlane / (m_FarPlane - m_NearPlane);
|
||||
|
||||
m_ProjMat.SetZero ();
|
||||
m_ProjMat._11 = w;
|
||||
m_ProjMat._22 = h;
|
||||
m_ProjMat._33 = (m_FarPlane+m_NearPlane)/(m_FarPlane-m_NearPlane);;
|
||||
m_ProjMat._34 = -2*m_FarPlane*m_NearPlane/(m_FarPlane-m_NearPlane);
|
||||
m_ProjMat._43 = 1.0f;
|
||||
}
|
||||
|
||||
//Updates the frustum planes. Should be called
|
||||
//everytime the view or projection matrices are
|
||||
//altered.
|
||||
void CCamera::UpdateFrustum ()
|
||||
{
|
||||
CMatrix3D MatFinal;
|
||||
CMatrix3D MatView;
|
||||
|
||||
m_Orientation.GetInverse(MatView);
|
||||
|
||||
MatFinal = m_ProjMat * MatView;
|
||||
|
||||
//get the RIGHT plane
|
||||
m_ViewFrustum.SetNumPlanes (6);
|
||||
|
||||
m_ViewFrustum.m_aPlanes[0].m_Norm.X = MatFinal._41-MatFinal._11;
|
||||
m_ViewFrustum.m_aPlanes[0].m_Norm.Y = MatFinal._42-MatFinal._12;
|
||||
m_ViewFrustum.m_aPlanes[0].m_Norm.Z = MatFinal._43-MatFinal._13;
|
||||
m_ViewFrustum.m_aPlanes[0].m_Dist = MatFinal._44-MatFinal._14;
|
||||
|
||||
//get the LEFT plane
|
||||
m_ViewFrustum.m_aPlanes[1].m_Norm.X = MatFinal._41+MatFinal._11;
|
||||
m_ViewFrustum.m_aPlanes[1].m_Norm.Y = MatFinal._42+MatFinal._12;
|
||||
m_ViewFrustum.m_aPlanes[1].m_Norm.Z = MatFinal._43+MatFinal._13;
|
||||
m_ViewFrustum.m_aPlanes[1].m_Dist = MatFinal._44+MatFinal._14;
|
||||
|
||||
//get the BOTTOM plane
|
||||
m_ViewFrustum.m_aPlanes[2].m_Norm.X = MatFinal._41+MatFinal._21;
|
||||
m_ViewFrustum.m_aPlanes[2].m_Norm.Y = MatFinal._42+MatFinal._22;
|
||||
m_ViewFrustum.m_aPlanes[2].m_Norm.Z = MatFinal._43+MatFinal._23;
|
||||
m_ViewFrustum.m_aPlanes[2].m_Dist = MatFinal._44+MatFinal._24;
|
||||
|
||||
//get the TOP plane
|
||||
m_ViewFrustum.m_aPlanes[3].m_Norm.X = MatFinal._41-MatFinal._21;
|
||||
m_ViewFrustum.m_aPlanes[3].m_Norm.Y = MatFinal._42-MatFinal._22;
|
||||
m_ViewFrustum.m_aPlanes[3].m_Norm.Z = MatFinal._43-MatFinal._23;
|
||||
m_ViewFrustum.m_aPlanes[3].m_Dist = MatFinal._44-MatFinal._24;
|
||||
|
||||
//get the FAR plane
|
||||
m_ViewFrustum.m_aPlanes[4].m_Norm.X = MatFinal._41-MatFinal._31;
|
||||
m_ViewFrustum.m_aPlanes[4].m_Norm.Y = MatFinal._42-MatFinal._32;
|
||||
m_ViewFrustum.m_aPlanes[4].m_Norm.Z = MatFinal._43-MatFinal._33;
|
||||
m_ViewFrustum.m_aPlanes[4].m_Dist = MatFinal._44-MatFinal._34;
|
||||
|
||||
//get the NEAR plane
|
||||
m_ViewFrustum.m_aPlanes[5].m_Norm.X = MatFinal._41+MatFinal._31;
|
||||
m_ViewFrustum.m_aPlanes[5].m_Norm.Y = MatFinal._42+MatFinal._32;
|
||||
m_ViewFrustum.m_aPlanes[5].m_Norm.Z = MatFinal._43+MatFinal._33;
|
||||
m_ViewFrustum.m_aPlanes[5].m_Dist = MatFinal._44+MatFinal._34;
|
||||
}
|
||||
|
||||
void CCamera::SetViewPort (SViewPort *viewport)
|
||||
{
|
||||
m_ViewPort.m_X = viewport->m_X;
|
||||
m_ViewPort.m_Y = viewport->m_Y;
|
||||
m_ViewPort.m_Width = viewport->m_Width;
|
||||
m_ViewPort.m_Height = viewport->m_Height;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// GetCameraPlanePoints: return four points in camera space at given distance from camera
|
||||
void CCamera::GetCameraPlanePoints(float dist,CVector3D pts[4]) const
|
||||
{
|
||||
float aspect=float(m_ViewPort.m_Width)/float(m_ViewPort.m_Height);
|
||||
|
||||
float x=dist*float(tan(GetFOV()*aspect*0.5));
|
||||
float y=dist*float(tan(GetFOV()*0.5));
|
||||
pts[0].X=-x;
|
||||
pts[0].Y=-y;
|
||||
pts[0].Z=dist;
|
||||
pts[1].X=x;
|
||||
pts[1].Y=-y;
|
||||
pts[1].Z=dist;
|
||||
pts[2].X=x;
|
||||
pts[2].Y=y;
|
||||
pts[2].Z=dist;
|
||||
pts[3].X=-x;
|
||||
pts[3].Y=y;
|
||||
pts[3].Z=dist;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// GetFrustumPoints: calculate and return the position of the 8 points of the frustum in world space
|
||||
void CCamera::GetFrustumPoints(CVector3D pts[8]) const
|
||||
{
|
||||
// get camera space points for near and far planes
|
||||
CVector3D cpts[8];
|
||||
GetCameraPlanePoints(m_NearPlane,pts);
|
||||
GetCameraPlanePoints(m_FarPlane,pts+4);
|
||||
|
||||
// transform to world space
|
||||
for (int i=0;i<8;i++) {
|
||||
m_Orientation.Transform(cpts[i],pts[i]);
|
||||
}
|
||||
}
|
||||
|
@ -50,12 +50,12 @@ class CCamera
|
||||
float GetNearPlane() const { return m_NearPlane; }
|
||||
float GetFarPlane() const { return m_FarPlane; }
|
||||
float GetFOV() const { return m_FOV; }
|
||||
|
||||
// calculate and return the position of the 8 points of the frustum in world space
|
||||
void GetFrustumPoints(CVector3D pts[8]) const;
|
||||
|
||||
// return four points in camera space at given distance from camera
|
||||
void GetCameraPlanePoints(float dist,CVector3D pts[4]) const;
|
||||
|
||||
// calculate and return the position of the 8 points of the frustum in world space
|
||||
void GetFrustumPoints(CVector3D pts[8]) const;
|
||||
|
||||
// return four points in camera space at given distance from camera
|
||||
void GetCameraPlanePoints(float dist,CVector3D pts[4]) const;
|
||||
|
||||
public:
|
||||
//This is the orientation matrix. The inverse of this
|
||||
|
@ -1,177 +1,177 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Name: HFTracer.cpp
|
||||
// Author: Rich Cross
|
||||
// Contact: rich@wildfiregames.com
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "HFTracer.h"
|
||||
#include "Terrain.h"
|
||||
#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)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// RayTriIntersect: intersect a ray with triangle defined by vertices
|
||||
// v0,v1,v2; return true if ray hits triangle at distance less than dist,
|
||||
// or false otherwise
|
||||
bool CHFTracer::RayTriIntersect(const CVector3D& v0,const CVector3D& v1,const CVector3D& v2,
|
||||
const CVector3D& origin,const CVector3D& dir,float& dist) const
|
||||
{
|
||||
const float EPSILON=0.00001f;
|
||||
|
||||
// calculate edge vectors
|
||||
CVector3D edge0=v1-v0;
|
||||
CVector3D edge1=v2-v0;
|
||||
|
||||
// begin calculating determinant - also used to calculate U parameter
|
||||
CVector3D pvec=dir.Cross(edge1);
|
||||
|
||||
// if determinant is near zero, ray lies in plane of triangle
|
||||
float det = edge0.Dot(pvec);
|
||||
if (fabs(det)<EPSILON)
|
||||
return false;
|
||||
|
||||
float inv_det = 1.0f/det;
|
||||
|
||||
// calculate vector from vert0 to ray origin
|
||||
CVector3D tvec=origin-v0;
|
||||
|
||||
// calculate U parameter, test bounds
|
||||
float u=tvec.Dot(pvec)*inv_det;
|
||||
if (u<-0.01f || u>1.01f)
|
||||
return false;
|
||||
|
||||
// prepare to test V parameter
|
||||
CVector3D qvec=tvec.Cross(edge0);
|
||||
|
||||
// calculate V parameter and test bounds
|
||||
float v=dir.Dot(qvec)*inv_det;
|
||||
if (v<0.0f || u+v>1.0f)
|
||||
return false;
|
||||
|
||||
// calculate distance to intersection point from ray origin
|
||||
float d=edge1.Dot(qvec)*inv_det;
|
||||
if (d>=0 && d<dist) {
|
||||
dist=d;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// CellIntersect: test if ray intersects either of the triangles in the given
|
||||
// cell - return hit result, and distance to hit, if hit occurred
|
||||
bool CHFTracer::CellIntersect(int cx,int cz,CVector3D& origin,CVector3D& dir,float& dist) const
|
||||
{
|
||||
bool res=false;
|
||||
|
||||
// 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]);
|
||||
|
||||
dist=1.0e30f;
|
||||
if (RayTriIntersect(vpos[0],vpos[1],vpos[2],origin,dir,dist)) {
|
||||
res=true;
|
||||
}
|
||||
|
||||
if (RayTriIntersect(vpos[0],vpos[2],vpos[3],origin,dir,dist)) {
|
||||
res=true;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// RayIntersect: intersect ray with this heightfield; return true if
|
||||
// intersection occurs (and fill in grid coordinates of intersection), or false
|
||||
// otherwise
|
||||
bool CHFTracer::RayIntersect(CVector3D& origin,CVector3D& dir,int& x,int& z,CVector3D& ipt) const
|
||||
{
|
||||
// intersect first against bounding box
|
||||
CBound bound;
|
||||
bound[0]=CVector3D(0,0,0);
|
||||
bound[1]=CVector3D(m_MapSize*m_CellSize,65535*m_HeightScale,m_MapSize*m_CellSize);
|
||||
|
||||
float tmin,tmax;
|
||||
if (!bound.RayIntersect(origin,dir,tmin,tmax)) {
|
||||
// ray missed world bounds; no intersection
|
||||
return false;
|
||||
}
|
||||
|
||||
// project origin onto grid, if necessary, to get starting point for traversal
|
||||
CVector3D traversalPt;
|
||||
if (tmin>0) {
|
||||
traversalPt=origin+dir*tmin;
|
||||
} else {
|
||||
traversalPt=origin;
|
||||
}
|
||||
|
||||
// setup traversal variables
|
||||
int sx=dir.X<0 ? -1 : 1;
|
||||
int sz=dir.Z<0 ? -1 : 1;
|
||||
|
||||
float invCellSize=1.0f/float(m_CellSize);
|
||||
|
||||
float fcx=traversalPt.X*invCellSize;
|
||||
int cx=int(fcx);
|
||||
|
||||
float fcz=traversalPt.Z*invCellSize;
|
||||
int cz=int(fcz);
|
||||
|
||||
float invdx=float(1.0/fabs(dir.X));
|
||||
float invdz=float(1.0/fabs(dir.Z));
|
||||
|
||||
float dist;
|
||||
do {
|
||||
// test current cell
|
||||
if (cx>=0 && cx<int(m_MapSize-1) && cz>=0 && cz<int(m_MapSize-1)) {
|
||||
if (CellIntersect(cx,cz,origin,dir,dist)) {
|
||||
x=cx;
|
||||
z=cz;
|
||||
ipt=origin+dir*dist;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// get coords of current cell
|
||||
fcx=traversalPt.X*invCellSize;
|
||||
fcz=traversalPt.Z*invCellSize;
|
||||
|
||||
// get distance to next cell in x,z
|
||||
float dx=(sx==-1) ? fcx-float(cx) : 1-(fcx-float(cx));
|
||||
dx*=invdx;
|
||||
float dz=(sz==-1) ? fcz-float(cz) : 1-(fcz-float(cz));
|
||||
dz*=invdz;
|
||||
|
||||
// advance ..
|
||||
float dist;
|
||||
if (dx<dz) {
|
||||
cx+=sx;
|
||||
dist=dx;
|
||||
} else {
|
||||
cz+=sz;
|
||||
dist=dz;
|
||||
}
|
||||
|
||||
traversalPt+=dir*dist;
|
||||
} while (traversalPt.Y>=0);
|
||||
|
||||
// fell off end of heightmap with no intersection; return a miss
|
||||
return false;
|
||||
}
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Name: HFTracer.cpp
|
||||
// Author: Rich Cross
|
||||
// Contact: rich@wildfiregames.com
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "HFTracer.h"
|
||||
#include "Terrain.h"
|
||||
#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)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// RayTriIntersect: intersect a ray with triangle defined by vertices
|
||||
// v0,v1,v2; return true if ray hits triangle at distance less than dist,
|
||||
// or false otherwise
|
||||
bool CHFTracer::RayTriIntersect(const CVector3D& v0,const CVector3D& v1,const CVector3D& v2,
|
||||
const CVector3D& origin,const CVector3D& dir,float& dist) const
|
||||
{
|
||||
const float EPSILON=0.00001f;
|
||||
|
||||
// calculate edge vectors
|
||||
CVector3D edge0=v1-v0;
|
||||
CVector3D edge1=v2-v0;
|
||||
|
||||
// begin calculating determinant - also used to calculate U parameter
|
||||
CVector3D pvec=dir.Cross(edge1);
|
||||
|
||||
// if determinant is near zero, ray lies in plane of triangle
|
||||
float det = edge0.Dot(pvec);
|
||||
if (fabs(det)<EPSILON)
|
||||
return false;
|
||||
|
||||
float inv_det = 1.0f/det;
|
||||
|
||||
// calculate vector from vert0 to ray origin
|
||||
CVector3D tvec=origin-v0;
|
||||
|
||||
// calculate U parameter, test bounds
|
||||
float u=tvec.Dot(pvec)*inv_det;
|
||||
if (u<-0.01f || u>1.01f)
|
||||
return false;
|
||||
|
||||
// prepare to test V parameter
|
||||
CVector3D qvec=tvec.Cross(edge0);
|
||||
|
||||
// calculate V parameter and test bounds
|
||||
float v=dir.Dot(qvec)*inv_det;
|
||||
if (v<0.0f || u+v>1.0f)
|
||||
return false;
|
||||
|
||||
// calculate distance to intersection point from ray origin
|
||||
float d=edge1.Dot(qvec)*inv_det;
|
||||
if (d>=0 && d<dist) {
|
||||
dist=d;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// CellIntersect: test if ray intersects either of the triangles in the given
|
||||
// cell - return hit result, and distance to hit, if hit occurred
|
||||
bool CHFTracer::CellIntersect(int cx,int cz,CVector3D& origin,CVector3D& dir,float& dist) const
|
||||
{
|
||||
bool res=false;
|
||||
|
||||
// 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]);
|
||||
|
||||
dist=1.0e30f;
|
||||
if (RayTriIntersect(vpos[0],vpos[1],vpos[2],origin,dir,dist)) {
|
||||
res=true;
|
||||
}
|
||||
|
||||
if (RayTriIntersect(vpos[0],vpos[2],vpos[3],origin,dir,dist)) {
|
||||
res=true;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// RayIntersect: intersect ray with this heightfield; return true if
|
||||
// intersection occurs (and fill in grid coordinates of intersection), or false
|
||||
// otherwise
|
||||
bool CHFTracer::RayIntersect(CVector3D& origin,CVector3D& dir,int& x,int& z,CVector3D& ipt) const
|
||||
{
|
||||
// intersect first against bounding box
|
||||
CBound bound;
|
||||
bound[0]=CVector3D(0,0,0);
|
||||
bound[1]=CVector3D(m_MapSize*m_CellSize,65535*m_HeightScale,m_MapSize*m_CellSize);
|
||||
|
||||
float tmin,tmax;
|
||||
if (!bound.RayIntersect(origin,dir,tmin,tmax)) {
|
||||
// ray missed world bounds; no intersection
|
||||
return false;
|
||||
}
|
||||
|
||||
// project origin onto grid, if necessary, to get starting point for traversal
|
||||
CVector3D traversalPt;
|
||||
if (tmin>0) {
|
||||
traversalPt=origin+dir*tmin;
|
||||
} else {
|
||||
traversalPt=origin;
|
||||
}
|
||||
|
||||
// setup traversal variables
|
||||
int sx=dir.X<0 ? -1 : 1;
|
||||
int sz=dir.Z<0 ? -1 : 1;
|
||||
|
||||
float invCellSize=1.0f/float(m_CellSize);
|
||||
|
||||
float fcx=traversalPt.X*invCellSize;
|
||||
int cx=int(fcx);
|
||||
|
||||
float fcz=traversalPt.Z*invCellSize;
|
||||
int cz=int(fcz);
|
||||
|
||||
float invdx=float(1.0/fabs(dir.X));
|
||||
float invdz=float(1.0/fabs(dir.Z));
|
||||
|
||||
float dist;
|
||||
do {
|
||||
// test current cell
|
||||
if (cx>=0 && cx<int(m_MapSize-1) && cz>=0 && cz<int(m_MapSize-1)) {
|
||||
if (CellIntersect(cx,cz,origin,dir,dist)) {
|
||||
x=cx;
|
||||
z=cz;
|
||||
ipt=origin+dir*dist;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// get coords of current cell
|
||||
fcx=traversalPt.X*invCellSize;
|
||||
fcz=traversalPt.Z*invCellSize;
|
||||
|
||||
// get distance to next cell in x,z
|
||||
float dx=(sx==-1) ? fcx-float(cx) : 1-(fcx-float(cx));
|
||||
dx*=invdx;
|
||||
float dz=(sz==-1) ? fcz-float(cz) : 1-(fcz-float(cz));
|
||||
dz*=invdz;
|
||||
|
||||
// advance ..
|
||||
float dist;
|
||||
if (dx<dz) {
|
||||
cx+=sx;
|
||||
dist=dx;
|
||||
} else {
|
||||
cz+=sz;
|
||||
dist=dz;
|
||||
}
|
||||
|
||||
traversalPt+=dir*dist;
|
||||
} while (traversalPt.Y>=0);
|
||||
|
||||
// fell off end of heightmap with no intersection; return a miss
|
||||
return false;
|
||||
}
|
||||
|
@ -1,48 +1,48 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Name: HFTracer.h
|
||||
// Author: Rich Cross
|
||||
// Contact: rich@wildfiregames.com
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _HFTRACER_H
|
||||
#define _HFTRACER_H
|
||||
|
||||
class CVector3D;
|
||||
|
||||
#include "res/res.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// CHFTracer: a class for determining ray intersections with a heightfield
|
||||
class CHFTracer
|
||||
{
|
||||
public:
|
||||
// constructor; setup data
|
||||
CHFTracer(const u16* hf,u32 mapsize,float cellsize,float heightscale);
|
||||
|
||||
// intersect ray with this heightfield; return true if intersection
|
||||
// occurs (and fill in grid coordinates and point of intersection), or false otherwise
|
||||
bool RayIntersect(CVector3D& origin,CVector3D& dir,int& x,int& z,CVector3D& ipt) const;
|
||||
|
||||
private:
|
||||
// intersect a ray with triangle defined by vertices
|
||||
// v0,v1,v2; return true if ray hits triangle at distance less than dist,
|
||||
// or false otherwise
|
||||
bool RayTriIntersect(const CVector3D& v0,const CVector3D& v1,const CVector3D& v2,
|
||||
const CVector3D& origin,const CVector3D& dir,float& dist) const;
|
||||
|
||||
// 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 heightfield were tracing
|
||||
const u16* m_Heightfield;
|
||||
// size of the heightfield
|
||||
u32 m_MapSize;
|
||||
// cell size - size of each cell in x and z
|
||||
float m_CellSize;
|
||||
// vertical scale - size of each cell in y
|
||||
float m_HeightScale;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Name: HFTracer.h
|
||||
// Author: Rich Cross
|
||||
// Contact: rich@wildfiregames.com
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _HFTRACER_H
|
||||
#define _HFTRACER_H
|
||||
|
||||
class CVector3D;
|
||||
|
||||
#include "res/res.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// CHFTracer: a class for determining ray intersections with a heightfield
|
||||
class CHFTracer
|
||||
{
|
||||
public:
|
||||
// constructor; setup data
|
||||
CHFTracer(const u16* hf,u32 mapsize,float cellsize,float heightscale);
|
||||
|
||||
// intersect ray with this heightfield; return true if intersection
|
||||
// occurs (and fill in grid coordinates and point of intersection), or false otherwise
|
||||
bool RayIntersect(CVector3D& origin,CVector3D& dir,int& x,int& z,CVector3D& ipt) const;
|
||||
|
||||
private:
|
||||
// intersect a ray with triangle defined by vertices
|
||||
// v0,v1,v2; return true if ray hits triangle at distance less than dist,
|
||||
// or false otherwise
|
||||
bool RayTriIntersect(const CVector3D& v0,const CVector3D& v1,const CVector3D& v2,
|
||||
const CVector3D& origin,const CVector3D& dir,float& dist) const;
|
||||
|
||||
// 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 heightfield were tracing
|
||||
const u16* m_Heightfield;
|
||||
// size of the heightfield
|
||||
u32 m_MapSize;
|
||||
// cell size - size of each cell in x and z
|
||||
float m_CellSize;
|
||||
// vertical scale - size of each cell in y
|
||||
float m_HeightScale;
|
||||
};
|
||||
|
||||
#endif
|
@ -1,341 +1,336 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Name: Model.cpp
|
||||
// Author: Rich Cross
|
||||
// Contact: rich@wildfiregames.com
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "Model.h"
|
||||
#include "Quaternion.h"
|
||||
#include "Bound.h"
|
||||
#include "SkeletonAnim.h"
|
||||
#include "SkeletonAnimDef.h"
|
||||
#include "SkeletonAnimManager.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Constructor
|
||||
CModel::CModel()
|
||||
: m_pModelDef(0), m_Anim(0), m_AnimTime(0),
|
||||
m_BoneMatrices(0), m_InvBoneMatrices(0), m_BoneMatricesValid(false)
|
||||
{
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Destructor
|
||||
CModel::~CModel()
|
||||
{
|
||||
ReleaseData();
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// ReleaseData: delete anything allocated by the model
|
||||
void CModel::ReleaseData()
|
||||
{
|
||||
delete[] m_BoneMatrices;
|
||||
delete[] m_InvBoneMatrices;
|
||||
for (size_t i=0;i<m_Props.size();i++) {
|
||||
delete m_Props[i].m_Model;
|
||||
}
|
||||
m_Props.clear();
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// InitModel: setup model from given geometry
|
||||
bool CModel::InitModel(CModelDef* modeldef)
|
||||
{
|
||||
// clean up any existing data first
|
||||
ReleaseData();
|
||||
|
||||
m_pModelDef = modeldef;
|
||||
|
||||
u32 numBones=modeldef->GetNumBones();
|
||||
if (numBones>0) {
|
||||
// allocate matrices for bone transformations
|
||||
m_BoneMatrices=new CMatrix3D[numBones];
|
||||
m_InvBoneMatrices=new CMatrix3D[numBones];
|
||||
// store default pose until animation assigned
|
||||
CBoneState* defpose=modeldef->GetBones();
|
||||
for (uint i=0;i<numBones;i++) {
|
||||
CMatrix3D& m=m_BoneMatrices[i];
|
||||
m.SetIdentity();
|
||||
m.Rotate(defpose[i].m_Rotation);
|
||||
m.Translate(defpose[i].m_Translation);
|
||||
m.GetInverse(m_InvBoneMatrices[i]);
|
||||
}
|
||||
m_BoneMatricesValid=true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// SkinPoint: skin the given point using the given blend and bonestate data
|
||||
static CVector3D SkinPoint(const CVector3D& pos,const SVertexBlend& blend,
|
||||
const CBoneState* bonestates)
|
||||
{
|
||||
CVector3D result(0,0,0);
|
||||
for (int i=0;i<SVertexBlend::SIZE && blend.m_Bone[i]!=0xff;i++) {
|
||||
CMatrix3D m;
|
||||
m.SetIdentity();
|
||||
m.Rotate(bonestates[blend.m_Bone[i]].m_Rotation);
|
||||
m.Translate(bonestates[blend.m_Bone[i]].m_Translation);
|
||||
|
||||
CVector3D tmp=m.Transform(pos);
|
||||
result+=tmp*blend.m_Weight[i];
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// SkinPoint: skin the given point using the given blend and matrix data
|
||||
static CVector3D SkinPoint(const CVector3D& pos,const SVertexBlend& blend,
|
||||
const CMatrix3D* bonestates)
|
||||
{
|
||||
CVector3D result(0,0,0);
|
||||
for (int i=0;i<SVertexBlend::SIZE && blend.m_Bone[i]!=0xff;i++) {
|
||||
const CMatrix3D& m=bonestates[blend.m_Bone[i]];
|
||||
|
||||
CVector3D tmp=m.Transform(pos);
|
||||
result+=tmp*blend.m_Weight[i];
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CalcBound: calculate the world space bounds of this model
|
||||
void CModel::CalcBounds()
|
||||
{
|
||||
m_ObjectBounds.Transform(GetTransform(),m_Bounds);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CalcObjectBounds: calculate object space bounds of this model, based solely on vertex positions
|
||||
void CModel::CalcObjectBounds()
|
||||
{
|
||||
m_ObjectBounds.SetEmpty();
|
||||
|
||||
int numverts=m_pModelDef->GetNumVertices();
|
||||
SModelVertex* verts=m_pModelDef->GetVertices();
|
||||
|
||||
for (int i=0;i<numverts;i++) {
|
||||
m_ObjectBounds+=verts[i].m_Coords;
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CalcAnimatedObjectBound: calculate bounds encompassing all vertex positions for given animation
|
||||
void CModel::CalcAnimatedObjectBound(CSkeletonAnimDef* anim,CBound& result)
|
||||
{
|
||||
result.SetEmpty();
|
||||
|
||||
CSkeletonAnim dummyanim;
|
||||
dummyanim.m_AnimDef=anim;
|
||||
if (!SetAnimation(&dummyanim)) return;
|
||||
|
||||
int numverts=m_pModelDef->GetNumVertices();
|
||||
SModelVertex* verts=m_pModelDef->GetVertices();
|
||||
|
||||
// iterate through every frame of the animation
|
||||
for (uint j=0;j<anim->GetNumFrames();j++) {
|
||||
// extend bounds by vertex positions at the frame
|
||||
for (int i=0;i<numverts;i++) {
|
||||
CVector3D tmp=SkinPoint(verts[i].m_Coords,verts[i].m_Blend,GetBoneMatrices());
|
||||
result+=tmp;
|
||||
}
|
||||
// advance to next frame
|
||||
m_AnimTime+=anim->GetFrameTime();
|
||||
m_BoneMatricesValid=false;
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// BuildAnimation: load raw animation frame animation from given file, and build a
|
||||
// animation specific to this model
|
||||
CSkeletonAnim* CModel::BuildAnimation(const char* filename,float speed)
|
||||
{
|
||||
CSkeletonAnimDef* def=g_SkelAnimMan.GetAnimation(filename);
|
||||
if (!def) return 0;
|
||||
|
||||
CSkeletonAnim* anim=new CSkeletonAnim;
|
||||
anim->m_AnimDef=def;
|
||||
anim->m_Speed=speed;
|
||||
CalcAnimatedObjectBound(def,anim->m_ObjectBounds);
|
||||
|
||||
return anim;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Update: update this model by the given time, in seconds
|
||||
void CModel::Update(float time)
|
||||
{
|
||||
if (m_Anim && m_BoneMatrices) {
|
||||
// convert to ms and adjust for animation speed
|
||||
float animtime=time*1000*m_Anim->m_Speed;
|
||||
|
||||
// update animation time, but don't calculate bone matrices - do that (lazily) when
|
||||
// something requests them; that saves some calculation work for offscreen models,
|
||||
// and also assures the world space, inverted bone matrices (required for normal
|
||||
// skinning) are up to date with respect to m_Transform
|
||||
m_AnimTime+=animtime;
|
||||
|
||||
float duration=m_Anim->m_AnimDef->GetDuration();
|
||||
if (m_AnimTime>duration) {
|
||||
m_AnimTime=(float) fmod(m_AnimTime,duration);
|
||||
}
|
||||
|
||||
// mark vertices as dirty
|
||||
SetDirty(RENDERDATA_UPDATE_VERTICES);
|
||||
|
||||
// mark matrices as dirty
|
||||
m_BoneMatricesValid=false;
|
||||
}
|
||||
|
||||
// update props
|
||||
for (uint i=0;i<m_Props.size();i++) {
|
||||
m_Props[i].m_Model->Update(time);
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// GenerateBoneMatrices: calculate necessary bone transformation matrices for skinning
|
||||
void CModel::GenerateBoneMatrices()
|
||||
{
|
||||
if (!m_Anim || !m_BoneMatrices) return;
|
||||
|
||||
m_Anim->m_AnimDef->BuildBoneMatrices(m_AnimTime,m_BoneMatrices);
|
||||
|
||||
const CMatrix3D& transform=GetTransform();
|
||||
for (int i=0;i<m_pModelDef->GetNumBones();i++) {
|
||||
CMatrix3D m=m_BoneMatrices[i];
|
||||
m.Concatenate(transform);
|
||||
m.GetInverse(m_InvBoneMatrices[i]);
|
||||
}
|
||||
|
||||
// update transform of boned props
|
||||
// TODO, RC - ugh, we'll be doing this twice (for boned props, at least) - once here,
|
||||
// and once again in SetTransform; better to just do it in Update?
|
||||
for (size_t i=0;i<m_Props.size();i++) {
|
||||
const Prop& prop=m_Props[i];
|
||||
|
||||
if (prop.m_Point->m_BoneIndex!=0xff) {
|
||||
CMatrix3D proptransform=prop.m_Point->m_Transform;;
|
||||
if (prop.m_Point->m_BoneIndex!=0xff) {
|
||||
proptransform.Concatenate(m_BoneMatrices[prop.m_Point->m_BoneIndex]);
|
||||
}
|
||||
proptransform.Concatenate(transform);
|
||||
prop.m_Model->SetTransform(proptransform);
|
||||
}
|
||||
}
|
||||
|
||||
m_BoneMatricesValid=true;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// SetAnimation: set the given animation as the current animation on this model;
|
||||
// return false on error, else true
|
||||
bool CModel::SetAnimation(CSkeletonAnim* anim)
|
||||
{
|
||||
m_Anim=anim;
|
||||
if (m_Anim) {
|
||||
if (!m_BoneMatrices) {
|
||||
// not boned, can't animate
|
||||
return false;
|
||||
}
|
||||
|
||||
if (anim->m_AnimDef->GetNumKeys()!=m_pModelDef->GetNumBones()) {
|
||||
// mismatch between models skeleton and animations skeleton
|
||||
return false;
|
||||
}
|
||||
|
||||
// update object bounds to the bounds when given animation applied
|
||||
m_ObjectBounds=m_Anim->m_ObjectBounds;
|
||||
// start anim from beginning
|
||||
m_AnimTime=0;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// AddProp: add a prop to the model on the given point
|
||||
void CModel::AddProp(SPropPoint* point,CModel* model)
|
||||
{
|
||||
// position model according to prop point position
|
||||
CMatrix3D proptransform=point->m_Transform;;
|
||||
if (m_BoneMatrices && point->m_BoneIndex!=0xff) {
|
||||
proptransform.Concatenate(m_BoneMatrices[point->m_BoneIndex]);
|
||||
}
|
||||
proptransform.Concatenate(m_Transform);
|
||||
model->SetTransform(proptransform);
|
||||
|
||||
// check if we're already using this point, and replace
|
||||
// model on it if so
|
||||
uint i;
|
||||
for (i=0;i<m_Props.size();i++) {
|
||||
if (m_Props[i].m_Point==point) {
|
||||
m_Props[i].m_Model=model;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// not using point; add new prop
|
||||
Prop prop;
|
||||
prop.m_Point=point;
|
||||
prop.m_Model=model;
|
||||
m_Props.push_back(prop);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// RemoveProp: remove a prop from the given point
|
||||
void CModel::RemoveProp(SPropPoint* point)
|
||||
{
|
||||
typedef std::vector<Prop>::iterator Iter;
|
||||
for (Iter iter=m_Props.begin();iter!=m_Props.end();++iter) {
|
||||
const Prop& prop=*iter;
|
||||
if (prop.m_Point==point) {
|
||||
m_Props.erase(iter);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Clone: return a clone of this model
|
||||
CModel* CModel::Clone() const
|
||||
{
|
||||
CModel* clone=new CModel;
|
||||
clone->m_ObjectBounds=m_ObjectBounds;
|
||||
clone->InitModel(m_pModelDef);
|
||||
clone->SetTexture(m_Texture);
|
||||
clone->SetAnimation(m_Anim);
|
||||
for (uint i=0;i<m_Props.size();i++) {
|
||||
// eek! TODO, RC - need to investigate shallow clone here
|
||||
clone->AddProp(m_Props[i].m_Point,m_Props[i].m_Model->Clone());
|
||||
}
|
||||
return clone;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// SetTransform: set the transform on this object, and reorientate props accordingly
|
||||
void CModel::SetTransform(const CMatrix3D& transform)
|
||||
{
|
||||
// call base class to set transform on this object
|
||||
CRenderableObject::SetTransform(transform);
|
||||
|
||||
// now set transforms on props
|
||||
const CMatrix3D* bonematrices=GetBoneMatrices();
|
||||
for (size_t i=0;i<m_Props.size();i++) {
|
||||
const Prop& prop=m_Props[i];
|
||||
|
||||
CMatrix3D proptransform=prop.m_Point->m_Transform;;
|
||||
if (prop.m_Point->m_BoneIndex!=0xff) {
|
||||
proptransform.Concatenate(m_BoneMatrices[prop.m_Point->m_BoneIndex]);
|
||||
}
|
||||
proptransform.Concatenate(transform);
|
||||
prop.m_Model->SetTransform(proptransform);
|
||||
}
|
||||
}
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Name: Model.cpp
|
||||
// Author: Rich Cross
|
||||
// Contact: rich@wildfiregames.com
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "Model.h"
|
||||
#include "Quaternion.h"
|
||||
#include "Bound.h"
|
||||
#include "SkeletonAnim.h"
|
||||
#include "SkeletonAnimDef.h"
|
||||
#include "SkeletonAnimManager.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Constructor
|
||||
CModel::CModel()
|
||||
: m_pModelDef(0), m_Anim(0), m_AnimTime(0),
|
||||
m_BoneMatrices(0), m_InvBoneMatrices(0), m_BoneMatricesValid(false)
|
||||
{
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Destructor
|
||||
CModel::~CModel()
|
||||
{
|
||||
ReleaseData();
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// ReleaseData: delete anything allocated by the model
|
||||
void CModel::ReleaseData()
|
||||
{
|
||||
delete[] m_BoneMatrices;
|
||||
delete[] m_InvBoneMatrices;
|
||||
for (size_t i=0;i<m_Props.size();i++) {
|
||||
delete m_Props[i].m_Model;
|
||||
}
|
||||
m_Props.clear();
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// InitModel: setup model from given geometry
|
||||
bool CModel::InitModel(CModelDef* modeldef)
|
||||
{
|
||||
// clean up any existing data first
|
||||
ReleaseData();
|
||||
|
||||
m_pModelDef = modeldef;
|
||||
|
||||
u32 numBones=modeldef->GetNumBones();
|
||||
if (numBones>0) {
|
||||
// allocate matrices for bone transformations
|
||||
m_BoneMatrices=new CMatrix3D[numBones];
|
||||
m_InvBoneMatrices=new CMatrix3D[numBones];
|
||||
// store default pose until animation assigned
|
||||
CBoneState* defpose=modeldef->GetBones();
|
||||
for (uint i=0;i<numBones;i++) {
|
||||
CMatrix3D& m=m_BoneMatrices[i];
|
||||
m.SetIdentity();
|
||||
m.Rotate(defpose[i].m_Rotation);
|
||||
m.Translate(defpose[i].m_Translation);
|
||||
m.GetInverse(m_InvBoneMatrices[i]);
|
||||
}
|
||||
m_BoneMatricesValid=true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// SkinPoint: skin the given point using the given blend and bonestate data
|
||||
static CVector3D SkinPoint(const CVector3D& pos,const SVertexBlend& blend,
|
||||
const CBoneState* bonestates)
|
||||
{
|
||||
CVector3D result(0,0,0);
|
||||
for (int i=0;i<SVertexBlend::SIZE && blend.m_Bone[i]!=0xff;i++) {
|
||||
CMatrix3D m;
|
||||
m.SetIdentity();
|
||||
m.Rotate(bonestates[blend.m_Bone[i]].m_Rotation);
|
||||
m.Translate(bonestates[blend.m_Bone[i]].m_Translation);
|
||||
|
||||
CVector3D tmp=m.Transform(pos);
|
||||
result+=tmp*blend.m_Weight[i];
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// SkinPoint: skin the given point using the given blend and matrix data
|
||||
static CVector3D SkinPoint(const CVector3D& pos,const SVertexBlend& blend,
|
||||
const CMatrix3D* bonestates)
|
||||
{
|
||||
CVector3D result(0,0,0);
|
||||
for (int i=0;i<SVertexBlend::SIZE && blend.m_Bone[i]!=0xff;i++) {
|
||||
const CMatrix3D& m=bonestates[blend.m_Bone[i]];
|
||||
|
||||
CVector3D tmp=m.Transform(pos);
|
||||
result+=tmp*blend.m_Weight[i];
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CalcBound: calculate the world space bounds of this model
|
||||
void CModel::CalcBounds()
|
||||
{
|
||||
m_ObjectBounds.Transform(GetTransform(),m_Bounds);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CalcObjectBounds: calculate object space bounds of this model, based solely on vertex positions
|
||||
void CModel::CalcObjectBounds()
|
||||
{
|
||||
m_ObjectBounds.SetEmpty();
|
||||
|
||||
int numverts=m_pModelDef->GetNumVertices();
|
||||
SModelVertex* verts=m_pModelDef->GetVertices();
|
||||
|
||||
for (int i=0;i<numverts;i++) {
|
||||
m_ObjectBounds+=verts[i].m_Coords;
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CalcAnimatedObjectBound: calculate bounds encompassing all vertex positions for given animation
|
||||
void CModel::CalcAnimatedObjectBound(CSkeletonAnimDef* anim,CBound& result)
|
||||
{
|
||||
result.SetEmpty();
|
||||
|
||||
CSkeletonAnim dummyanim;
|
||||
dummyanim.m_AnimDef=anim;
|
||||
if (!SetAnimation(&dummyanim)) return;
|
||||
|
||||
int numverts=m_pModelDef->GetNumVertices();
|
||||
SModelVertex* verts=m_pModelDef->GetVertices();
|
||||
|
||||
// iterate through every frame of the animation
|
||||
for (uint j=0;j<anim->GetNumFrames();j++) {
|
||||
// extend bounds by vertex positions at the frame
|
||||
for (int i=0;i<numverts;i++) {
|
||||
CVector3D tmp=SkinPoint(verts[i].m_Coords,verts[i].m_Blend,GetBoneMatrices());
|
||||
result+=tmp;
|
||||
}
|
||||
// advance to next frame
|
||||
m_AnimTime+=anim->GetFrameTime();
|
||||
m_BoneMatricesValid=false;
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// BuildAnimation: load raw animation frame animation from given file, and build a
|
||||
// animation specific to this model
|
||||
CSkeletonAnim* CModel::BuildAnimation(const char* filename,float speed)
|
||||
{
|
||||
CSkeletonAnimDef* def=g_SkelAnimMan.GetAnimation(filename);
|
||||
if (!def) return 0;
|
||||
|
||||
CSkeletonAnim* anim=new CSkeletonAnim;
|
||||
anim->m_AnimDef=def;
|
||||
anim->m_Speed=speed;
|
||||
CalcAnimatedObjectBound(def,anim->m_ObjectBounds);
|
||||
|
||||
return anim;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Update: update this model by the given time, in seconds
|
||||
void CModel::Update(float time)
|
||||
{
|
||||
if (m_Anim && m_BoneMatrices) {
|
||||
// convert to ms and adjust for animation speed
|
||||
float animtime=time*1000*m_Anim->m_Speed;
|
||||
|
||||
// update animation time, but don't calculate bone matrices - do that (lazily) when
|
||||
// something requests them; that saves some calculation work for offscreen models,
|
||||
// and also assures the world space, inverted bone matrices (required for normal
|
||||
// skinning) are up to date with respect to m_Transform
|
||||
m_AnimTime+=animtime;
|
||||
|
||||
float duration=m_Anim->m_AnimDef->GetDuration();
|
||||
if (m_AnimTime>duration) {
|
||||
m_AnimTime=(float) fmod(m_AnimTime,duration);
|
||||
}
|
||||
|
||||
// mark vertices as dirty
|
||||
SetDirty(RENDERDATA_UPDATE_VERTICES);
|
||||
|
||||
// mark matrices as dirty
|
||||
m_BoneMatricesValid=false;
|
||||
}
|
||||
|
||||
// update props
|
||||
for (uint i=0;i<m_Props.size();i++) {
|
||||
m_Props[i].m_Model->Update(time);
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// GenerateBoneMatrices: calculate necessary bone transformation matrices for skinning
|
||||
void CModel::GenerateBoneMatrices()
|
||||
{
|
||||
if (!m_Anim || !m_BoneMatrices) return;
|
||||
|
||||
m_Anim->m_AnimDef->BuildBoneMatrices(m_AnimTime,m_BoneMatrices);
|
||||
|
||||
const CMatrix3D& transform=GetTransform();
|
||||
for (int i=0;i<m_pModelDef->GetNumBones();i++) {
|
||||
CMatrix3D m=m_BoneMatrices[i];
|
||||
m.Concatenate(transform);
|
||||
m.GetInverse(m_InvBoneMatrices[i]);
|
||||
}
|
||||
|
||||
// update transform of boned props
|
||||
// TODO, RC - ugh, we'll be doing this twice (for boned props, at least) - once here,
|
||||
// and once again in SetTransform; better to just do it in Update?
|
||||
for (size_t i=0;i<m_Props.size();i++) {
|
||||
const Prop& prop=m_Props[i];
|
||||
|
||||
if (prop.m_Point->m_BoneIndex!=0xff) {
|
||||
CMatrix3D proptransform=prop.m_Point->m_Transform;;
|
||||
if (prop.m_Point->m_BoneIndex!=0xff) {
|
||||
proptransform.Concatenate(m_BoneMatrices[prop.m_Point->m_BoneIndex]);
|
||||
}
|
||||
proptransform.Concatenate(transform);
|
||||
prop.m_Model->SetTransform(proptransform);
|
||||
}
|
||||
}
|
||||
|
||||
m_BoneMatricesValid=true;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// SetAnimation: set the given animation as the current animation on this model;
|
||||
// return false on error, else true
|
||||
bool CModel::SetAnimation(CSkeletonAnim* anim)
|
||||
{
|
||||
m_Anim=anim;
|
||||
if (m_Anim) {
|
||||
if (!m_BoneMatrices) {
|
||||
// not boned, can't animate
|
||||
return false;
|
||||
}
|
||||
|
||||
if (anim->m_AnimDef->GetNumKeys()!=m_pModelDef->GetNumBones()) {
|
||||
// mismatch between models skeleton and animations skeleton
|
||||
return false;
|
||||
}
|
||||
|
||||
// update object bounds to the bounds when given animation applied
|
||||
m_ObjectBounds=m_Anim->m_ObjectBounds;
|
||||
// start anim from beginning
|
||||
m_AnimTime=0;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// AddProp: add a prop to the model on the given point
|
||||
void CModel::AddProp(SPropPoint* point,CModel* model)
|
||||
{
|
||||
// position model according to prop point position
|
||||
model->SetTransform(point->m_Transform);
|
||||
|
||||
// check if we're already using this point, and replace
|
||||
// model on it if so
|
||||
uint i;
|
||||
for (i=0;i<m_Props.size();i++) {
|
||||
if (m_Props[i].m_Point==point) {
|
||||
m_Props[i].m_Model=model;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// not using point; add new prop
|
||||
Prop prop;
|
||||
prop.m_Point=point;
|
||||
prop.m_Model=model;
|
||||
m_Props.push_back(prop);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// RemoveProp: remove a prop from the given point
|
||||
void CModel::RemoveProp(SPropPoint* point)
|
||||
{
|
||||
typedef std::vector<Prop>::iterator Iter;
|
||||
for (Iter iter=m_Props.begin();iter!=m_Props.end();++iter) {
|
||||
const Prop& prop=*iter;
|
||||
if (prop.m_Point==point) {
|
||||
m_Props.erase(iter);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Clone: return a clone of this model
|
||||
CModel* CModel::Clone() const
|
||||
{
|
||||
CModel* clone=new CModel;
|
||||
clone->m_ObjectBounds=m_ObjectBounds;
|
||||
clone->InitModel(m_pModelDef);
|
||||
clone->SetTexture(m_Texture);
|
||||
clone->SetAnimation(m_Anim);
|
||||
for (uint i=0;i<m_Props.size();i++) {
|
||||
// eek! TODO, RC - need to investigate shallow clone here
|
||||
clone->AddProp(m_Props[i].m_Point,m_Props[i].m_Model->Clone());
|
||||
}
|
||||
return clone;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// SetTransform: set the transform on this object, and reorientate props accordingly
|
||||
void CModel::SetTransform(const CMatrix3D& transform)
|
||||
{
|
||||
// call base class to set transform on this object
|
||||
CRenderableObject::SetTransform(transform);
|
||||
|
||||
// now set transforms on props
|
||||
const CMatrix3D* bonematrices=GetBoneMatrices();
|
||||
for (size_t i=0;i<m_Props.size();i++) {
|
||||
const Prop& prop=m_Props[i];
|
||||
|
||||
CMatrix3D proptransform=prop.m_Point->m_Transform;;
|
||||
if (prop.m_Point->m_BoneIndex!=0xff) {
|
||||
proptransform.Concatenate(m_BoneMatrices[prop.m_Point->m_BoneIndex]);
|
||||
}
|
||||
proptransform.Concatenate(transform);
|
||||
prop.m_Model->SetTransform(proptransform);
|
||||
}
|
||||
}
|
||||
|
@ -1,117 +1,117 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Name: Model.h
|
||||
// Author: Rich Cross
|
||||
// Contact: rich@wildfiregames.com
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _MODEL_H
|
||||
#define _MODEL_H
|
||||
|
||||
#include "Texture.h"
|
||||
#include "ModelDef.h"
|
||||
#include "RenderableObject.h"
|
||||
#include "SkeletonAnim.h"
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// CModel: basically, a mesh object - holds the texturing and skinning
|
||||
// information for a model in game
|
||||
class CModel : public CRenderableObject
|
||||
{
|
||||
public:
|
||||
struct Prop {
|
||||
SPropPoint* m_Point;
|
||||
CModel* m_Model;
|
||||
};
|
||||
|
||||
public:
|
||||
// constructor
|
||||
CModel();
|
||||
// destructor
|
||||
~CModel();
|
||||
|
||||
// setup model from given geometry
|
||||
bool InitModel(CModelDef *modeldef);
|
||||
// calculate the world space bounds of this model
|
||||
void CalcBounds();
|
||||
// update this model's state; 'time' is the time since the last update, in MS
|
||||
void Update(float time);
|
||||
|
||||
// get the model's geometry data
|
||||
CModelDef *GetModelDef() { return m_pModelDef; }
|
||||
|
||||
// set the model's texture
|
||||
void SetTexture(const CTexture& tex) { m_Texture=tex; }
|
||||
// get the model's texture
|
||||
CTexture* GetTexture() { return &m_Texture; }
|
||||
|
||||
// set the given animation as the current animation on this model
|
||||
bool SetAnimation(CSkeletonAnim* anim);
|
||||
// get the currently playing animation, if any
|
||||
CSkeletonAnim* GetAnimation() { return m_Anim; }
|
||||
|
||||
// calculate object space bounds of this model, based solely on vertex positions
|
||||
void CalcObjectBounds();
|
||||
// calculate bounds encompassing all vertex positions for given animation
|
||||
void CalcAnimatedObjectBound(CSkeletonAnimDef* anim,CBound& result);
|
||||
// return object space bounds
|
||||
const CBound& GetObjectBounds() const { return m_ObjectBounds; }
|
||||
|
||||
// set transform of this object, and recurse down into props to update their world space transform
|
||||
void SetTransform(const CMatrix3D& transform);
|
||||
|
||||
// return the models bone matrices
|
||||
const CMatrix3D* GetBoneMatrices() {
|
||||
if (!m_BoneMatricesValid) GenerateBoneMatrices();
|
||||
return m_BoneMatrices;
|
||||
}
|
||||
// return the models inverted bone matrices
|
||||
const CMatrix3D* GetInvBoneMatrices() {
|
||||
if (!m_BoneMatricesValid) GenerateBoneMatrices();
|
||||
return m_InvBoneMatrices;
|
||||
}
|
||||
|
||||
// load raw animation frame animation from given file, and build a
|
||||
// animation specific to this model
|
||||
CSkeletonAnim* BuildAnimation(const char* filename,float speed);
|
||||
|
||||
// add a prop to the model on the given point
|
||||
void AddProp(SPropPoint* point,CModel* model);
|
||||
// remove a prop from the given point
|
||||
void RemoveProp(SPropPoint* point);
|
||||
// return prop list
|
||||
const std::vector<Prop>& GetProps() { return m_Props; }
|
||||
|
||||
// return a clone of this model
|
||||
CModel* Clone() const;
|
||||
|
||||
private:
|
||||
// delete anything allocated by the model
|
||||
void ReleaseData();
|
||||
// calculate necessary bone transformation matrices for skinning
|
||||
void GenerateBoneMatrices();
|
||||
|
||||
// texture used by model
|
||||
CTexture m_Texture;
|
||||
// pointer to the model's raw 3d data
|
||||
CModelDef* m_pModelDef;
|
||||
// object space bounds of model - accounts for bounds of all possible animations
|
||||
// that can play on a model
|
||||
CBound m_ObjectBounds;
|
||||
// animation currently playing on this model, if any
|
||||
CSkeletonAnim* m_Anim;
|
||||
// time (in MS) into the current animation
|
||||
float m_AnimTime;
|
||||
// flag stating whether bone matrices are currently valid
|
||||
bool m_BoneMatricesValid;
|
||||
// current state of all bones on this model; null if associated modeldef isn't skeletal
|
||||
CMatrix3D* m_BoneMatrices;
|
||||
// inverse of the above world space transform of the above matrices
|
||||
CMatrix3D* m_InvBoneMatrices;
|
||||
// list of current props on model
|
||||
std::vector<Prop> m_Props;
|
||||
};
|
||||
|
||||
#endif
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Name: Model.h
|
||||
// Author: Rich Cross
|
||||
// Contact: rich@wildfiregames.com
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _MODEL_H
|
||||
#define _MODEL_H
|
||||
|
||||
#include "Texture.h"
|
||||
#include "ModelDef.h"
|
||||
#include "RenderableObject.h"
|
||||
#include "SkeletonAnim.h"
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// CModel: basically, a mesh object - holds the texturing and skinning
|
||||
// information for a model in game
|
||||
class CModel : public CRenderableObject
|
||||
{
|
||||
public:
|
||||
struct Prop {
|
||||
SPropPoint* m_Point;
|
||||
CModel* m_Model;
|
||||
};
|
||||
|
||||
public:
|
||||
// constructor
|
||||
CModel();
|
||||
// destructor
|
||||
~CModel();
|
||||
|
||||
// setup model from given geometry
|
||||
bool InitModel(CModelDef *modeldef);
|
||||
// calculate the world space bounds of this model
|
||||
void CalcBounds();
|
||||
// update this model's state; 'time' is the time since the last update, in MS
|
||||
void Update(float time);
|
||||
|
||||
// get the model's geometry data
|
||||
CModelDef *GetModelDef() { return m_pModelDef; }
|
||||
|
||||
// set the model's texture
|
||||
void SetTexture(const CTexture& tex) { m_Texture=tex; }
|
||||
// get the model's texture
|
||||
CTexture* GetTexture() { return &m_Texture; }
|
||||
|
||||
// set the given animation as the current animation on this model
|
||||
bool SetAnimation(CSkeletonAnim* anim);
|
||||
// get the currently playing animation, if any
|
||||
CSkeletonAnim* GetAnimation() { return m_Anim; }
|
||||
|
||||
// calculate object space bounds of this model, based solely on vertex positions
|
||||
void CalcObjectBounds();
|
||||
// calculate bounds encompassing all vertex positions for given animation
|
||||
void CalcAnimatedObjectBound(CSkeletonAnimDef* anim,CBound& result);
|
||||
// return object space bounds
|
||||
const CBound& GetObjectBounds() const { return m_ObjectBounds; }
|
||||
|
||||
// set transform of this object, and recurse down into props to update their world space transform
|
||||
void SetTransform(const CMatrix3D& transform);
|
||||
|
||||
// return the models bone matrices
|
||||
const CMatrix3D* GetBoneMatrices() {
|
||||
if (!m_BoneMatricesValid) GenerateBoneMatrices();
|
||||
return m_BoneMatrices;
|
||||
}
|
||||
// return the models inverted bone matrices
|
||||
const CMatrix3D* GetInvBoneMatrices() {
|
||||
if (!m_BoneMatricesValid) GenerateBoneMatrices();
|
||||
return m_InvBoneMatrices;
|
||||
}
|
||||
|
||||
// load raw animation frame animation from given file, and build a
|
||||
// animation specific to this model
|
||||
CSkeletonAnim* BuildAnimation(const char* filename,float speed);
|
||||
|
||||
// add a prop to the model on the given point
|
||||
void AddProp(SPropPoint* point,CModel* model);
|
||||
// remove a prop from the given point
|
||||
void RemoveProp(SPropPoint* point);
|
||||
// return prop list
|
||||
const std::vector<Prop>& GetProps() { return m_Props; }
|
||||
|
||||
// return a clone of this model
|
||||
CModel* Clone() const;
|
||||
|
||||
private:
|
||||
// delete anything allocated by the model
|
||||
void ReleaseData();
|
||||
// calculate necessary bone transformation matrices for skinning
|
||||
void GenerateBoneMatrices();
|
||||
|
||||
// texture used by model
|
||||
CTexture m_Texture;
|
||||
// pointer to the model's raw 3d data
|
||||
CModelDef* m_pModelDef;
|
||||
// object space bounds of model - accounts for bounds of all possible animations
|
||||
// that can play on a model
|
||||
CBound m_ObjectBounds;
|
||||
// animation currently playing on this model, if any
|
||||
CSkeletonAnim* m_Anim;
|
||||
// time (in MS) into the current animation
|
||||
float m_AnimTime;
|
||||
// flag stating whether bone matrices are currently valid
|
||||
bool m_BoneMatricesValid;
|
||||
// current state of all bones on this model; null if associated modeldef isn't skeletal
|
||||
CMatrix3D* m_BoneMatrices;
|
||||
// inverse of the above world space transform of the above matrices
|
||||
CMatrix3D* m_InvBoneMatrices;
|
||||
// list of current props on model
|
||||
std::vector<Prop> m_Props;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -13,7 +13,7 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// CModelDef Constructor
|
||||
CModelDef::CModelDef()
|
||||
: m_pVertices(0), m_NumVertices(0), m_pFaces(0), m_NumFaces(0), m_Bones(0), m_NumBones(0),
|
||||
: m_pVertices(0), m_NumVertices(0), m_pFaces(0), m_NumFaces(0), m_Bones(0), m_NumBones(0),
|
||||
m_NumPropPoints(0), m_PropPoints(0)
|
||||
{
|
||||
}
|
||||
@ -24,23 +24,23 @@ CModelDef::~CModelDef()
|
||||
{
|
||||
delete[] m_pVertices;
|
||||
delete[] m_pFaces;
|
||||
delete[] m_Bones;
|
||||
delete[] m_Bones;
|
||||
delete[] m_PropPoints;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// FindPropPoint: find and return pointer to prop point matching given name;
|
||||
// return null if no match (case insensitive search)
|
||||
SPropPoint* CModelDef::FindPropPoint(const char* name) const
|
||||
{
|
||||
for (uint i=0;i<m_NumPropPoints;i++) {
|
||||
if (stricmp(name,m_PropPoints[i].m_Name)==0) {
|
||||
return &m_PropPoints[i];
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// FindPropPoint: find and return pointer to prop point matching given name;
|
||||
// return null if no match (case insensitive search)
|
||||
SPropPoint* CModelDef::FindPropPoint(const char* name) const
|
||||
{
|
||||
for (uint i=0;i<m_NumPropPoints;i++) {
|
||||
if (stricmp(name,m_PropPoints[i].m_Name)==0) {
|
||||
return &m_PropPoints[i];
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Load: read and return a new CModelDef initialised with data from given file
|
||||
@ -71,26 +71,26 @@ CModelDef* CModelDef::Load(const char* filename)
|
||||
if (mdef->m_NumBones) {
|
||||
mdef->m_Bones=new CBoneState[mdef->m_NumBones];
|
||||
unpacker.UnpackRaw(mdef->m_Bones,mdef->m_NumBones*sizeof(CBoneState));
|
||||
}
|
||||
|
||||
if (unpacker.GetVersion()>=2) {
|
||||
}
|
||||
|
||||
if (unpacker.GetVersion()>=2) {
|
||||
// versions >=2 also have prop point data
|
||||
unpacker.UnpackRaw(&mdef->m_NumPropPoints,sizeof(mdef->m_NumPropPoints));
|
||||
if (mdef->m_NumPropPoints) {
|
||||
mdef->m_PropPoints=new SPropPoint[mdef->m_NumPropPoints];
|
||||
for (u32 i=0;i<mdef->m_NumPropPoints;i++) {
|
||||
unpacker.UnpackString(mdef->m_PropPoints[i].m_Name);
|
||||
unpacker.UnpackRaw(&mdef->m_PropPoints[i].m_Position.X,sizeof(mdef->m_PropPoints[i].m_Position));
|
||||
unpacker.UnpackRaw(&mdef->m_PropPoints[i].m_Rotation.m_V.X,sizeof(mdef->m_PropPoints[i].m_Rotation));
|
||||
unpacker.UnpackRaw(&mdef->m_PropPoints[i].m_BoneIndex,sizeof(mdef->m_PropPoints[i].m_BoneIndex));
|
||||
|
||||
// build prop point transform
|
||||
mdef->m_PropPoints[i].m_Transform.SetIdentity();
|
||||
mdef->m_PropPoints[i].m_Transform.Rotate(mdef->m_PropPoints[i].m_Rotation);
|
||||
mdef->m_PropPoints[i].m_Transform.Translate(mdef->m_PropPoints[i].m_Position);
|
||||
}
|
||||
}
|
||||
}
|
||||
unpacker.UnpackRaw(&mdef->m_NumPropPoints,sizeof(mdef->m_NumPropPoints));
|
||||
if (mdef->m_NumPropPoints) {
|
||||
mdef->m_PropPoints=new SPropPoint[mdef->m_NumPropPoints];
|
||||
for (u32 i=0;i<mdef->m_NumPropPoints;i++) {
|
||||
unpacker.UnpackString(mdef->m_PropPoints[i].m_Name);
|
||||
unpacker.UnpackRaw(&mdef->m_PropPoints[i].m_Position.X,sizeof(mdef->m_PropPoints[i].m_Position));
|
||||
unpacker.UnpackRaw(&mdef->m_PropPoints[i].m_Rotation.m_V.X,sizeof(mdef->m_PropPoints[i].m_Rotation));
|
||||
unpacker.UnpackRaw(&mdef->m_PropPoints[i].m_BoneIndex,sizeof(mdef->m_PropPoints[i].m_BoneIndex));
|
||||
|
||||
// build prop point transform
|
||||
mdef->m_PropPoints[i].m_Transform.SetIdentity();
|
||||
mdef->m_PropPoints[i].m_Transform.Rotate(mdef->m_PropPoints[i].m_Rotation);
|
||||
mdef->m_PropPoints[i].m_Transform.Translate(mdef->m_PropPoints[i].m_Position);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (...) {
|
||||
delete mdef;
|
||||
throw CFileUnpacker::CFileEOFError();
|
||||
@ -118,17 +118,17 @@ void CModelDef::Save(const char* filename,const CModelDef* mdef)
|
||||
if (mdef->m_NumBones) {
|
||||
packer.PackRaw(mdef->m_Bones,sizeof(CBoneState)*mdef->m_NumBones);
|
||||
}
|
||||
|
||||
packer.PackRaw(&mdef->m_NumPropPoints,sizeof(mdef->m_NumPropPoints));
|
||||
for (u32 i=0;i<mdef->m_NumPropPoints;i++) {
|
||||
packer.PackString(mdef->m_PropPoints[i].m_Name);
|
||||
packer.PackRaw(&mdef->m_PropPoints[i].m_Position.X,sizeof(mdef->m_PropPoints[i].m_Position));
|
||||
packer.PackRaw(&mdef->m_PropPoints[i].m_Rotation.m_V.X,sizeof(mdef->m_PropPoints[i].m_Rotation));
|
||||
packer.PackRaw(&mdef->m_PropPoints[i].m_BoneIndex,sizeof(mdef->m_PropPoints[i].m_BoneIndex));
|
||||
}
|
||||
|
||||
|
||||
packer.PackRaw(&mdef->m_NumPropPoints,sizeof(mdef->m_NumPropPoints));
|
||||
for (u32 i=0;i<mdef->m_NumPropPoints;i++) {
|
||||
packer.PackString(mdef->m_PropPoints[i].m_Name);
|
||||
packer.PackRaw(&mdef->m_PropPoints[i].m_Position.X,sizeof(mdef->m_PropPoints[i].m_Position));
|
||||
packer.PackRaw(&mdef->m_PropPoints[i].m_Rotation.m_V.X,sizeof(mdef->m_PropPoints[i].m_Rotation));
|
||||
packer.PackRaw(&mdef->m_PropPoints[i].m_BoneIndex,sizeof(mdef->m_PropPoints[i].m_BoneIndex));
|
||||
}
|
||||
|
||||
|
||||
// flush everything out to file
|
||||
packer.Write(filename,FILE_VERSION,"PSMD");
|
||||
}
|
||||
|
||||
|
||||
|
@ -10,25 +10,25 @@
|
||||
#define _MODELDEF_H
|
||||
|
||||
#include "res/res.h"
|
||||
#include "CStr.h"
|
||||
#include "CStr.h"
|
||||
#include "Vector3D.h"
|
||||
#include "SkeletonAnimDef.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// SPropPoint: structure describing a prop point
|
||||
struct SPropPoint
|
||||
{
|
||||
// name of the prop point
|
||||
CStr m_Name;
|
||||
// position of the point
|
||||
CVector3D m_Position;
|
||||
// rotation of the point
|
||||
CQuaternion m_Rotation;
|
||||
// object to parent space transformation
|
||||
CMatrix3D m_Transform;
|
||||
// index of parent bone; 0xff if unboned
|
||||
u8 m_BoneIndex;
|
||||
};
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// SPropPoint: structure describing a prop point
|
||||
struct SPropPoint
|
||||
{
|
||||
// name of the prop point
|
||||
CStr m_Name;
|
||||
// position of the point
|
||||
CVector3D m_Position;
|
||||
// rotation of the point
|
||||
CQuaternion m_Rotation;
|
||||
// object to parent space transformation
|
||||
CMatrix3D m_Transform;
|
||||
// index of parent bone; 0xff if unboned
|
||||
u8 m_BoneIndex;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// SVertexBlend: structure containing the necessary data for blending vertices
|
||||
@ -100,10 +100,10 @@ public:
|
||||
// accessor: get bone data
|
||||
int GetNumBones() const { return m_NumBones; }
|
||||
CBoneState *GetBones() const { return m_Bones; }
|
||||
|
||||
// find and return pointer to prop point matching given name; return
|
||||
// null if no match (case insensitive search)
|
||||
SPropPoint* FindPropPoint(const char* name) const;
|
||||
|
||||
// find and return pointer to prop point matching given name; return
|
||||
// null if no match (case insensitive search)
|
||||
SPropPoint* FindPropPoint(const char* name) const;
|
||||
|
||||
public:
|
||||
// vertex data
|
||||
@ -114,9 +114,9 @@ public:
|
||||
SModelFace* m_pFaces;
|
||||
// bone data - default model pose
|
||||
u32 m_NumBones;
|
||||
CBoneState* m_Bones;
|
||||
// prop point data
|
||||
u32 m_NumPropPoints;
|
||||
CBoneState* m_Bones;
|
||||
// prop point data
|
||||
u32 m_NumPropPoints;
|
||||
SPropPoint* m_PropPoints;
|
||||
};
|
||||
|
||||
|
@ -1,321 +1,321 @@
|
||||
#include "ObjectEntry.h"
|
||||
#include "ObjectManager.h"
|
||||
#include "Model.h"
|
||||
#include "ModelDef.h"
|
||||
|
||||
#include "UnitManager.h"
|
||||
|
||||
// xerces XML stuff
|
||||
#include <xercesc/dom/DOM.hpp>
|
||||
#include <xercesc/parsers/XercesDOMParser.hpp>
|
||||
#include <xercesc/framework/LocalFileInputSource.hpp>
|
||||
#include <xercesc/util/XMLString.hpp>
|
||||
#include <xercesc/util/PlatformUtils.hpp>
|
||||
|
||||
// Gee's custom error handler
|
||||
#include <ps/XercesErrorHandler.h>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma comment(lib, "xerces-c_2.lib")
|
||||
#endif
|
||||
|
||||
// automatically use namespace ..
|
||||
XERCES_CPP_NAMESPACE_USE
|
||||
|
||||
|
||||
CObjectEntry::CObjectEntry(int type) : m_Model(0), m_Type(type)
|
||||
{
|
||||
m_IdleAnim=0;
|
||||
m_WalkAnim=0;
|
||||
m_DeathAnim=0;
|
||||
m_MeleeAnim=0;
|
||||
m_RangedAnim=0;
|
||||
}
|
||||
|
||||
CObjectEntry::~CObjectEntry()
|
||||
{
|
||||
for (size_t i=0;i<m_Animations.size();i++) {
|
||||
CSkeletonAnim* anim=m_Animations[i].m_AnimData;
|
||||
delete anim;
|
||||
}
|
||||
|
||||
delete m_Model;
|
||||
}
|
||||
|
||||
bool CObjectEntry::BuildModel()
|
||||
{
|
||||
debug_out("Building model %s\n",(const char*) m_Name);
|
||||
|
||||
// check we've enough data to consider building the object
|
||||
if (m_ModelName.Length()==0 || m_TextureName.Length()==0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// get the root directory of this object
|
||||
CStr dirname=g_ObjMan.m_ObjectTypes[m_Type].m_Name;
|
||||
|
||||
// remember the old model so we can replace any models using it later on
|
||||
CModelDef* oldmodel=m_Model ? m_Model->GetModelDef() : 0;
|
||||
|
||||
// build filename
|
||||
CStr modelfilename("mods\\official\\");
|
||||
modelfilename+=m_ModelName;
|
||||
|
||||
// try and create a model
|
||||
CModelDef* modeldef;
|
||||
|
||||
try {
|
||||
modeldef=CModelDef::Load((const char*) modelfilename);
|
||||
} catch (...) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// create new Model
|
||||
m_Model=new CModel;
|
||||
m_Model->SetTexture((const char*) m_TextureName);
|
||||
m_Model->InitModel(modeldef);
|
||||
|
||||
// calculate initial object space bounds, based on vertex positions
|
||||
m_Model->CalcObjectBounds();
|
||||
|
||||
// load animations
|
||||
for( uint t = 0; t < m_Animations.size(); t++ )
|
||||
{
|
||||
if( m_Animations[t].m_FileName.Length() > 0 )
|
||||
{
|
||||
CStr animfilename( "mods\\official\\" );
|
||||
animfilename += m_Animations[t].m_FileName;
|
||||
m_Animations[t].m_AnimData = m_Model->BuildAnimation((const char*) animfilename,m_Animations[t].m_Speed);
|
||||
|
||||
if( m_Animations[t].m_AnimName.LowerCase() == CStr( "idle" ) )
|
||||
m_IdleAnim = m_Animations[t].m_AnimData;
|
||||
if( m_Animations[t].m_AnimName.LowerCase() == CStr( "walk" ) )
|
||||
m_WalkAnim = m_Animations[t].m_AnimData;
|
||||
}
|
||||
else
|
||||
{
|
||||
// FIXME, RC - don't store invalid animations
|
||||
m_Animations[t].m_AnimData=0;
|
||||
}
|
||||
}
|
||||
// start up idling
|
||||
m_Model->SetAnimation( m_IdleAnim );
|
||||
|
||||
// build props - TODO, RC - need to fix up bounds here
|
||||
for (uint p=0;p<m_Props.size();p++) {
|
||||
const Prop& prop=m_Props[p];
|
||||
SPropPoint* proppoint=modeldef->FindPropPoint((const char*) prop.m_PropPointName);
|
||||
if (proppoint) {
|
||||
CObjectEntry* oe=g_ObjMan.FindObject(prop.m_ModelName);
|
||||
if (oe) {
|
||||
// try and build model if we haven't already got it
|
||||
if (!oe->m_Model) oe->BuildModel();
|
||||
if (oe->m_Model) {
|
||||
CModel* propmodel=oe->m_Model->Clone();
|
||||
m_Model->AddProp(proppoint,propmodel);
|
||||
if (oe->m_WalkAnim) propmodel->SetAnimation(oe->m_WalkAnim);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// build world space bounds
|
||||
m_Model->CalcBounds();
|
||||
|
||||
// replace any units using old model to now use new model; also reprop models, if necessary
|
||||
const std::vector<CUnit*>& units=g_UnitMan.GetUnits();
|
||||
for (uint i=0;i<units.size();++i) {
|
||||
CModel* unitmodel=units[i]->GetModel();
|
||||
if (unitmodel->GetModelDef()==oldmodel) {
|
||||
unitmodel->InitModel(m_Model->GetModelDef());
|
||||
|
||||
const std::vector<CModel::Prop>& newprops=m_Model->GetProps();
|
||||
for (uint j=0;j<newprops.size();j++) {
|
||||
unitmodel->AddProp(newprops[j].m_Point,newprops[j].m_Model->Clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// and were done with the old model ..
|
||||
delete oldmodel;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
CSkeletonAnim* CObjectEntry::GetNamedAnimation( CStr animationName )
|
||||
{
|
||||
for( uint t = 0; t < m_Animations.size(); t++ )
|
||||
{
|
||||
if( m_Animations[t].m_AnimName == animationName )
|
||||
return( m_Animations[t].m_AnimData );
|
||||
}
|
||||
return( NULL );
|
||||
}
|
||||
|
||||
CStr Transcode(const XMLCh* xmltext)
|
||||
{
|
||||
char* str=XMLString::transcode(xmltext);
|
||||
CStr result(str);
|
||||
XMLString::release(&str);
|
||||
return result;
|
||||
}
|
||||
|
||||
bool CObjectEntry::Load(const char* filename)
|
||||
{
|
||||
bool parseOK = false;
|
||||
|
||||
|
||||
// Initialize XML library
|
||||
XMLPlatformUtils::Initialize();
|
||||
{
|
||||
XMLCh* attachpointtext=XMLString::transcode("attachpoint");
|
||||
XMLCh* modeltext=XMLString::transcode("model");
|
||||
XMLCh* nametext=XMLString::transcode("name");
|
||||
XMLCh* filetext=XMLString::transcode("file");
|
||||
XMLCh* speedtext=XMLString::transcode("speed");
|
||||
|
||||
// Create parser instance
|
||||
XercesDOMParser *parser = new XercesDOMParser();
|
||||
|
||||
// Setup parser
|
||||
parser->setValidationScheme(XercesDOMParser::Val_Auto);
|
||||
parser->setDoNamespaces(false);
|
||||
parser->setDoSchema(false);
|
||||
parser->setCreateEntityReferenceNodes(false);
|
||||
|
||||
// Set customized error handler
|
||||
CXercesErrorHandler *errorHandler = new CXercesErrorHandler();
|
||||
parser->setErrorHandler(errorHandler);
|
||||
|
||||
// Push the CLogger to mark it's reading this file.
|
||||
|
||||
// Get main node
|
||||
XMLCh* xfilename=XMLString::transcode(filename);
|
||||
LocalFileInputSource source(xfilename);
|
||||
XMLString::release(&xfilename);
|
||||
|
||||
// Parse file
|
||||
parser->parse(source);
|
||||
|
||||
// Check how many errors
|
||||
parseOK = parser->getErrorCount() == 0;
|
||||
|
||||
if (parseOK) {
|
||||
// parsed successfully - grab our data
|
||||
DOMDocument *doc = parser->getDocument();
|
||||
DOMElement *element = doc->getDocumentElement();
|
||||
|
||||
// root_name should be Object
|
||||
CStr root_name = Transcode( element->getNodeName() );
|
||||
|
||||
// should have at least 3 children - Name, ModelName and TextureName
|
||||
DOMNodeList *children = element->getChildNodes();
|
||||
int numChildren=children->getLength();
|
||||
for (int i=0; i<numChildren; ++i) {
|
||||
// Get node
|
||||
DOMNode *child = children->item(i);
|
||||
|
||||
// A child element
|
||||
if (child->getNodeType() == DOMNode::ELEMENT_NODE)
|
||||
{
|
||||
// First get element and not node
|
||||
DOMElement *child_element = (DOMElement*)child;
|
||||
|
||||
CStr element_name = Transcode( child_element->getNodeName() );
|
||||
DOMNode *value_node= child_element->getChildNodes()->item(0);
|
||||
CStr element_value=value_node ? Transcode(value_node->getNodeValue()) : "";
|
||||
|
||||
if (element_name==CStr("Name")) {
|
||||
m_Name=element_value;
|
||||
} else if (element_name==CStr("ModelName")) {
|
||||
m_ModelName=element_value;
|
||||
} else if (element_name==CStr("TextureName")) {
|
||||
m_TextureName=element_value;
|
||||
} else if (element_name==CStr("Animations")) {
|
||||
DOMNodeList* animations=(DOMNodeList*) child_element->getChildNodes();
|
||||
|
||||
for (uint j=0; j<animations->getLength(); ++j) {
|
||||
DOMElement *anim_element = (DOMElement*) animations->item(j);
|
||||
CStr element_name = Transcode( anim_element->getNodeName() );
|
||||
DOMNamedNodeMap* attributes=anim_element->getAttributes();
|
||||
if (attributes) {
|
||||
Anim anim;
|
||||
|
||||
DOMNode *nameattr=attributes->getNamedItem(nametext);
|
||||
anim.m_AnimName=Transcode(nameattr->getChildNodes()->item(0)->getNodeValue());
|
||||
DOMNode *fileattr=attributes->getNamedItem(filetext);
|
||||
anim.m_FileName=Transcode(fileattr->getChildNodes()->item(0)->getNodeValue());
|
||||
|
||||
DOMNode *speedattr=attributes->getNamedItem(speedtext);
|
||||
CStr speedstr=Transcode(speedattr->getChildNodes()->item(0)->getNodeValue());
|
||||
|
||||
anim.m_Speed=float(atoi((const char*) speedstr))/100.0f;
|
||||
if (anim.m_Speed<=0) anim.m_Speed=1.0f;
|
||||
|
||||
m_Animations.push_back(anim);
|
||||
}
|
||||
}
|
||||
} else if (element_name==CStr("Props")) {
|
||||
DOMNodeList* props=(DOMNodeList*) child_element->getChildNodes();
|
||||
|
||||
for (uint j=0; j<props->getLength(); ++j) {
|
||||
DOMElement *prop_element = (DOMElement*) props->item(j);
|
||||
CStr element_name = Transcode( prop_element->getNodeName() );
|
||||
DOMNamedNodeMap* attributes=prop_element->getAttributes();
|
||||
if (attributes) {
|
||||
Prop prop;
|
||||
|
||||
DOMNode *nameattr=attributes->getNamedItem(attachpointtext);
|
||||
prop.m_PropPointName=Transcode(nameattr->getChildNodes()->item(0)->getNodeValue());
|
||||
DOMNode *modelattr=attributes->getNamedItem(modeltext);
|
||||
prop.m_ModelName=XMLString::transcode(modelattr->getChildNodes()->item(0)->getNodeValue());
|
||||
|
||||
m_Props.push_back(prop);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
XMLString::release(&attachpointtext);
|
||||
XMLString::release(&modeltext);
|
||||
XMLString::release(&nametext);
|
||||
XMLString::release(&filetext);
|
||||
XMLString::release(&speedtext);
|
||||
|
||||
delete parser;
|
||||
delete errorHandler;
|
||||
}
|
||||
XMLPlatformUtils::Terminate();
|
||||
|
||||
return parseOK;
|
||||
}
|
||||
|
||||
bool CObjectEntry::Save(const char* filename)
|
||||
{
|
||||
FILE* fp=fopen(filename,"w");
|
||||
if (!fp) return false;
|
||||
|
||||
// write XML header
|
||||
fprintf(fp,"<?xml version=\"1.0\" encoding=\"iso-8859-1\" standalone=\"no\"?>\n\n");
|
||||
fprintf(fp,"<!DOCTYPE Object SYSTEM \"..\\object.dtd\">\n\n");
|
||||
|
||||
// write the object itself
|
||||
fprintf(fp,"<!-- File automatically generated by ScEd -->\n");
|
||||
fprintf(fp,"<Object>\n");
|
||||
fprintf(fp,"\t<Name>%s</Name>\n",(const char*) m_Name);
|
||||
fprintf(fp,"\t<ModelName>%s</ModelName>\n",(const char*) m_ModelName);
|
||||
fprintf(fp,"\t<TextureName>%s</TextureName>\n",(const char*) m_TextureName);
|
||||
if (m_Animations.size()>0) {
|
||||
fprintf(fp,"\t<Animations>\n");
|
||||
for (uint i=0;i<m_Animations.size();i++) {
|
||||
fprintf(fp,"\t\t<Animation name=\"%s\" file=\"%s\"> </Animation>\n",(const char*) m_Animations[i].m_AnimName,(const char*) m_Animations[i].m_FileName);
|
||||
}
|
||||
fprintf(fp,"\t</Animations>\n");
|
||||
}
|
||||
fprintf(fp,"</Object>\n");
|
||||
fclose(fp);
|
||||
|
||||
return true;
|
||||
}
|
||||
#include "ObjectEntry.h"
|
||||
#include "ObjectManager.h"
|
||||
#include "Model.h"
|
||||
#include "ModelDef.h"
|
||||
|
||||
#include "UnitManager.h"
|
||||
|
||||
// xerces XML stuff
|
||||
#include <xercesc/dom/DOM.hpp>
|
||||
#include <xercesc/parsers/XercesDOMParser.hpp>
|
||||
#include <xercesc/framework/LocalFileInputSource.hpp>
|
||||
#include <xercesc/util/XMLString.hpp>
|
||||
#include <xercesc/util/PlatformUtils.hpp>
|
||||
|
||||
// Gee's custom error handler
|
||||
#include <ps/XercesErrorHandler.h>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma comment(lib, "xerces-c_2.lib")
|
||||
#endif
|
||||
|
||||
// automatically use namespace ..
|
||||
XERCES_CPP_NAMESPACE_USE
|
||||
|
||||
|
||||
CObjectEntry::CObjectEntry(int type) : m_Model(0), m_Type(type)
|
||||
{
|
||||
m_IdleAnim=0;
|
||||
m_WalkAnim=0;
|
||||
m_DeathAnim=0;
|
||||
m_MeleeAnim=0;
|
||||
m_RangedAnim=0;
|
||||
}
|
||||
|
||||
CObjectEntry::~CObjectEntry()
|
||||
{
|
||||
for (size_t i=0;i<m_Animations.size();i++) {
|
||||
CSkeletonAnim* anim=m_Animations[i].m_AnimData;
|
||||
delete anim;
|
||||
}
|
||||
|
||||
delete m_Model;
|
||||
}
|
||||
|
||||
bool CObjectEntry::BuildModel()
|
||||
{
|
||||
debug_out("Building model %s\n",(const char*) m_Name);
|
||||
|
||||
// check we've enough data to consider building the object
|
||||
if (m_ModelName.Length()==0 || m_TextureName.Length()==0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// get the root directory of this object
|
||||
CStr dirname=g_ObjMan.m_ObjectTypes[m_Type].m_Name;
|
||||
|
||||
// remember the old model so we can replace any models using it later on
|
||||
CModelDef* oldmodel=m_Model ? m_Model->GetModelDef() : 0;
|
||||
|
||||
// build filename
|
||||
CStr modelfilename("mods\\official\\");
|
||||
modelfilename+=m_ModelName;
|
||||
|
||||
// try and create a model
|
||||
CModelDef* modeldef;
|
||||
|
||||
try {
|
||||
modeldef=CModelDef::Load((const char*) modelfilename);
|
||||
} catch (...) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// create new Model
|
||||
m_Model=new CModel;
|
||||
m_Model->SetTexture((const char*) m_TextureName);
|
||||
m_Model->InitModel(modeldef);
|
||||
|
||||
// calculate initial object space bounds, based on vertex positions
|
||||
m_Model->CalcObjectBounds();
|
||||
|
||||
// load animations
|
||||
for( uint t = 0; t < m_Animations.size(); t++ )
|
||||
{
|
||||
if( m_Animations[t].m_FileName.Length() > 0 )
|
||||
{
|
||||
CStr animfilename( "mods\\official\\" );
|
||||
animfilename += m_Animations[t].m_FileName;
|
||||
m_Animations[t].m_AnimData = m_Model->BuildAnimation((const char*) animfilename,m_Animations[t].m_Speed);
|
||||
|
||||
if( m_Animations[t].m_AnimName.LowerCase() == CStr( "idle" ) )
|
||||
m_IdleAnim = m_Animations[t].m_AnimData;
|
||||
if( m_Animations[t].m_AnimName.LowerCase() == CStr( "walk" ) )
|
||||
m_WalkAnim = m_Animations[t].m_AnimData;
|
||||
}
|
||||
else
|
||||
{
|
||||
// FIXME, RC - don't store invalid animations
|
||||
m_Animations[t].m_AnimData=0;
|
||||
}
|
||||
}
|
||||
// start up idling
|
||||
m_Model->SetAnimation( m_IdleAnim );
|
||||
|
||||
// build props - TODO, RC - need to fix up bounds here
|
||||
for (uint p=0;p<m_Props.size();p++) {
|
||||
const Prop& prop=m_Props[p];
|
||||
SPropPoint* proppoint=modeldef->FindPropPoint((const char*) prop.m_PropPointName);
|
||||
if (proppoint) {
|
||||
CObjectEntry* oe=g_ObjMan.FindObject(prop.m_ModelName);
|
||||
if (oe) {
|
||||
// try and build model if we haven't already got it
|
||||
if (!oe->m_Model) oe->BuildModel();
|
||||
if (oe->m_Model) {
|
||||
CModel* propmodel=oe->m_Model->Clone();
|
||||
m_Model->AddProp(proppoint,propmodel);
|
||||
if (oe->m_WalkAnim) propmodel->SetAnimation(oe->m_WalkAnim);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// build world space bounds
|
||||
m_Model->CalcBounds();
|
||||
|
||||
// replace any units using old model to now use new model; also reprop models, if necessary
|
||||
const std::vector<CUnit*>& units=g_UnitMan.GetUnits();
|
||||
for (uint i=0;i<units.size();++i) {
|
||||
CModel* unitmodel=units[i]->GetModel();
|
||||
if (unitmodel->GetModelDef()==oldmodel) {
|
||||
unitmodel->InitModel(m_Model->GetModelDef());
|
||||
|
||||
const std::vector<CModel::Prop>& newprops=m_Model->GetProps();
|
||||
for (uint j=0;j<newprops.size();j++) {
|
||||
unitmodel->AddProp(newprops[j].m_Point,newprops[j].m_Model->Clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// and were done with the old model ..
|
||||
delete oldmodel;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
CSkeletonAnim* CObjectEntry::GetNamedAnimation( CStr animationName )
|
||||
{
|
||||
for( uint t = 0; t < m_Animations.size(); t++ )
|
||||
{
|
||||
if( m_Animations[t].m_AnimName == animationName )
|
||||
return( m_Animations[t].m_AnimData );
|
||||
}
|
||||
return( NULL );
|
||||
}
|
||||
|
||||
CStr Transcode(const XMLCh* xmltext)
|
||||
{
|
||||
char* str=XMLString::transcode(xmltext);
|
||||
CStr result(str);
|
||||
XMLString::release(&str);
|
||||
return result;
|
||||
}
|
||||
|
||||
bool CObjectEntry::Load(const char* filename)
|
||||
{
|
||||
bool parseOK = false;
|
||||
|
||||
|
||||
// Initialize XML library
|
||||
XMLPlatformUtils::Initialize();
|
||||
{
|
||||
XMLCh* attachpointtext=XMLString::transcode("attachpoint");
|
||||
XMLCh* modeltext=XMLString::transcode("model");
|
||||
XMLCh* nametext=XMLString::transcode("name");
|
||||
XMLCh* filetext=XMLString::transcode("file");
|
||||
XMLCh* speedtext=XMLString::transcode("speed");
|
||||
|
||||
// Create parser instance
|
||||
XercesDOMParser *parser = new XercesDOMParser();
|
||||
|
||||
// Setup parser
|
||||
parser->setValidationScheme(XercesDOMParser::Val_Auto);
|
||||
parser->setDoNamespaces(false);
|
||||
parser->setDoSchema(false);
|
||||
parser->setCreateEntityReferenceNodes(false);
|
||||
|
||||
// Set customized error handler
|
||||
CXercesErrorHandler *errorHandler = new CXercesErrorHandler();
|
||||
parser->setErrorHandler(errorHandler);
|
||||
|
||||
// Push the CLogger to mark it's reading this file.
|
||||
|
||||
// Get main node
|
||||
XMLCh* xfilename=XMLString::transcode(filename);
|
||||
LocalFileInputSource source(xfilename);
|
||||
XMLString::release(&xfilename);
|
||||
|
||||
// Parse file
|
||||
parser->parse(source);
|
||||
|
||||
// Check how many errors
|
||||
parseOK = parser->getErrorCount() == 0;
|
||||
|
||||
if (parseOK) {
|
||||
// parsed successfully - grab our data
|
||||
DOMDocument *doc = parser->getDocument();
|
||||
DOMElement *element = doc->getDocumentElement();
|
||||
|
||||
// root_name should be Object
|
||||
CStr root_name = Transcode( element->getNodeName() );
|
||||
|
||||
// should have at least 3 children - Name, ModelName and TextureName
|
||||
DOMNodeList *children = element->getChildNodes();
|
||||
int numChildren=children->getLength();
|
||||
for (int i=0; i<numChildren; ++i) {
|
||||
// Get node
|
||||
DOMNode *child = children->item(i);
|
||||
|
||||
// A child element
|
||||
if (child->getNodeType() == DOMNode::ELEMENT_NODE)
|
||||
{
|
||||
// First get element and not node
|
||||
DOMElement *child_element = (DOMElement*)child;
|
||||
|
||||
CStr element_name = Transcode( child_element->getNodeName() );
|
||||
DOMNode *value_node= child_element->getChildNodes()->item(0);
|
||||
CStr element_value=value_node ? Transcode(value_node->getNodeValue()) : "";
|
||||
|
||||
if (element_name==CStr("Name")) {
|
||||
m_Name=element_value;
|
||||
} else if (element_name==CStr("ModelName")) {
|
||||
m_ModelName=element_value;
|
||||
} else if (element_name==CStr("TextureName")) {
|
||||
m_TextureName=element_value;
|
||||
} else if (element_name==CStr("Animations")) {
|
||||
DOMNodeList* animations=(DOMNodeList*) child_element->getChildNodes();
|
||||
|
||||
for (uint j=0; j<animations->getLength(); ++j) {
|
||||
DOMElement *anim_element = (DOMElement*) animations->item(j);
|
||||
CStr element_name = Transcode( anim_element->getNodeName() );
|
||||
DOMNamedNodeMap* attributes=anim_element->getAttributes();
|
||||
if (attributes) {
|
||||
Anim anim;
|
||||
|
||||
DOMNode *nameattr=attributes->getNamedItem(nametext);
|
||||
anim.m_AnimName=Transcode(nameattr->getChildNodes()->item(0)->getNodeValue());
|
||||
DOMNode *fileattr=attributes->getNamedItem(filetext);
|
||||
anim.m_FileName=Transcode(fileattr->getChildNodes()->item(0)->getNodeValue());
|
||||
|
||||
DOMNode *speedattr=attributes->getNamedItem(speedtext);
|
||||
CStr speedstr=Transcode(speedattr->getChildNodes()->item(0)->getNodeValue());
|
||||
|
||||
anim.m_Speed=float(atoi((const char*) speedstr))/100.0f;
|
||||
if (anim.m_Speed<=0) anim.m_Speed=1.0f;
|
||||
|
||||
m_Animations.push_back(anim);
|
||||
}
|
||||
}
|
||||
} else if (element_name==CStr("Props")) {
|
||||
DOMNodeList* props=(DOMNodeList*) child_element->getChildNodes();
|
||||
|
||||
for (uint j=0; j<props->getLength(); ++j) {
|
||||
DOMElement *prop_element = (DOMElement*) props->item(j);
|
||||
CStr element_name = Transcode( prop_element->getNodeName() );
|
||||
DOMNamedNodeMap* attributes=prop_element->getAttributes();
|
||||
if (attributes) {
|
||||
Prop prop;
|
||||
|
||||
DOMNode *nameattr=attributes->getNamedItem(attachpointtext);
|
||||
prop.m_PropPointName=Transcode(nameattr->getChildNodes()->item(0)->getNodeValue());
|
||||
DOMNode *modelattr=attributes->getNamedItem(modeltext);
|
||||
prop.m_ModelName=XMLString::transcode(modelattr->getChildNodes()->item(0)->getNodeValue());
|
||||
|
||||
m_Props.push_back(prop);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
XMLString::release(&attachpointtext);
|
||||
XMLString::release(&modeltext);
|
||||
XMLString::release(&nametext);
|
||||
XMLString::release(&filetext);
|
||||
XMLString::release(&speedtext);
|
||||
|
||||
delete parser;
|
||||
delete errorHandler;
|
||||
}
|
||||
XMLPlatformUtils::Terminate();
|
||||
|
||||
return parseOK;
|
||||
}
|
||||
|
||||
bool CObjectEntry::Save(const char* filename)
|
||||
{
|
||||
FILE* fp=fopen(filename,"w");
|
||||
if (!fp) return false;
|
||||
|
||||
// write XML header
|
||||
fprintf(fp,"<?xml version=\"1.0\" encoding=\"iso-8859-1\" standalone=\"no\"?>\n\n");
|
||||
fprintf(fp,"<!DOCTYPE Object SYSTEM \"..\\object.dtd\">\n\n");
|
||||
|
||||
// write the object itself
|
||||
fprintf(fp,"<!-- File automatically generated by ScEd -->\n");
|
||||
fprintf(fp,"<Object>\n");
|
||||
fprintf(fp,"\t<Name>%s</Name>\n",(const char*) m_Name);
|
||||
fprintf(fp,"\t<ModelName>%s</ModelName>\n",(const char*) m_ModelName);
|
||||
fprintf(fp,"\t<TextureName>%s</TextureName>\n",(const char*) m_TextureName);
|
||||
if (m_Animations.size()>0) {
|
||||
fprintf(fp,"\t<Animations>\n");
|
||||
for (uint i=0;i<m_Animations.size();i++) {
|
||||
fprintf(fp,"\t\t<Animation name=\"%s\" file=\"%s\"> </Animation>\n",(const char*) m_Animations[i].m_AnimName,(const char*) m_Animations[i].m_FileName);
|
||||
}
|
||||
fprintf(fp,"\t</Animations>\n");
|
||||
}
|
||||
fprintf(fp,"</Object>\n");
|
||||
fclose(fp);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -1,65 +1,65 @@
|
||||
#ifndef _OBJECTENTRY_H
|
||||
#define _OBJECTENTRY_H
|
||||
|
||||
class CModel;
|
||||
class CSkeletonAnim;
|
||||
|
||||
#include <vector>
|
||||
#include "CStr.h"
|
||||
#include "Bound.h"
|
||||
#include "ModelDef.h"
|
||||
|
||||
class CObjectEntry
|
||||
{
|
||||
public:
|
||||
struct Anim {
|
||||
// name of the animation - "Idle", "Run", etc
|
||||
CStr m_AnimName;
|
||||
// filename of the animation - manidle.psa, manrun.psa, etc
|
||||
CStr m_FileName;
|
||||
// animation speed, as specified in XML actor file
|
||||
float m_Speed;
|
||||
// the animation data, specific to the this model
|
||||
CSkeletonAnim* m_AnimData;
|
||||
};
|
||||
|
||||
struct Prop {
|
||||
// name of the prop point to attach to - "Prop01", "Prop02", "Head", "LeftHand", etc ..
|
||||
CStr m_PropPointName;
|
||||
// name of the model file - art/actors/props/sword.xml or whatever
|
||||
CStr m_ModelName;
|
||||
};
|
||||
|
||||
public:
|
||||
CObjectEntry(int type);
|
||||
~CObjectEntry();
|
||||
|
||||
bool BuildModel();
|
||||
|
||||
bool Load(const char* filename);
|
||||
bool Save(const char* filename);
|
||||
|
||||
// object name
|
||||
CStr m_Name;
|
||||
// texture name
|
||||
CStr m_TextureName;
|
||||
// model name
|
||||
CStr m_ModelName;
|
||||
// list of valid animations for this object
|
||||
std::vector<Anim> m_Animations;
|
||||
CSkeletonAnim* m_IdleAnim;
|
||||
CSkeletonAnim* m_WalkAnim;
|
||||
CSkeletonAnim* m_DeathAnim;
|
||||
CSkeletonAnim* m_MeleeAnim;
|
||||
CSkeletonAnim* m_RangedAnim;
|
||||
CSkeletonAnim* GetNamedAnimation( CStr animationName );
|
||||
// list of props attached to object
|
||||
std::vector<Prop> m_Props;
|
||||
// corresponding model
|
||||
CModel* m_Model;
|
||||
// type of object; index into object managers types array
|
||||
int m_Type;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
#ifndef _OBJECTENTRY_H
|
||||
#define _OBJECTENTRY_H
|
||||
|
||||
class CModel;
|
||||
class CSkeletonAnim;
|
||||
|
||||
#include <vector>
|
||||
#include "CStr.h"
|
||||
#include "Bound.h"
|
||||
#include "ModelDef.h"
|
||||
|
||||
class CObjectEntry
|
||||
{
|
||||
public:
|
||||
struct Anim {
|
||||
// name of the animation - "Idle", "Run", etc
|
||||
CStr m_AnimName;
|
||||
// filename of the animation - manidle.psa, manrun.psa, etc
|
||||
CStr m_FileName;
|
||||
// animation speed, as specified in XML actor file
|
||||
float m_Speed;
|
||||
// the animation data, specific to the this model
|
||||
CSkeletonAnim* m_AnimData;
|
||||
};
|
||||
|
||||
struct Prop {
|
||||
// name of the prop point to attach to - "Prop01", "Prop02", "Head", "LeftHand", etc ..
|
||||
CStr m_PropPointName;
|
||||
// name of the model file - art/actors/props/sword.xml or whatever
|
||||
CStr m_ModelName;
|
||||
};
|
||||
|
||||
public:
|
||||
CObjectEntry(int type);
|
||||
~CObjectEntry();
|
||||
|
||||
bool BuildModel();
|
||||
|
||||
bool Load(const char* filename);
|
||||
bool Save(const char* filename);
|
||||
|
||||
// object name
|
||||
CStr m_Name;
|
||||
// texture name
|
||||
CStr m_TextureName;
|
||||
// model name
|
||||
CStr m_ModelName;
|
||||
// list of valid animations for this object
|
||||
std::vector<Anim> m_Animations;
|
||||
CSkeletonAnim* m_IdleAnim;
|
||||
CSkeletonAnim* m_WalkAnim;
|
||||
CSkeletonAnim* m_DeathAnim;
|
||||
CSkeletonAnim* m_MeleeAnim;
|
||||
CSkeletonAnim* m_RangedAnim;
|
||||
CSkeletonAnim* GetNamedAnimation( CStr animationName );
|
||||
// list of props attached to object
|
||||
std::vector<Prop> m_Props;
|
||||
// corresponding model
|
||||
CModel* m_Model;
|
||||
// type of object; index into object managers types array
|
||||
int m_Type;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -8,15 +8,15 @@ CObjectManager::CObjectManager() : m_SelectedObject(0)
|
||||
m_ObjectTypes.reserve(32);
|
||||
}
|
||||
|
||||
CObjectManager::~CObjectManager()
|
||||
{
|
||||
m_SelectedObject=0;
|
||||
for (size_t i=0;i<m_ObjectTypes.size();i++) {
|
||||
for (size_t j=0;j<m_ObjectTypes[i].m_Objects.size();j++) {
|
||||
delete m_ObjectTypes[i].m_Objects[j];
|
||||
}
|
||||
}
|
||||
}
|
||||
CObjectManager::~CObjectManager()
|
||||
{
|
||||
m_SelectedObject=0;
|
||||
for (size_t i=0;i<m_ObjectTypes.size();i++) {
|
||||
for (size_t j=0;j<m_ObjectTypes[i].m_Objects.size();j++) {
|
||||
delete m_ObjectTypes[i].m_Objects[j];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CObjectEntry* CObjectManager::FindObject(const char* objectname)
|
||||
{
|
||||
@ -65,25 +65,25 @@ void CObjectManager::LoadObjects()
|
||||
BuildObjectTypes();
|
||||
|
||||
// now iterate through terrain types loading all textures of that type
|
||||
uint i;
|
||||
uint i;
|
||||
for (i=0;i<m_ObjectTypes.size();i++) {
|
||||
LoadObjects(i);
|
||||
}
|
||||
|
||||
// now build all the models
|
||||
for (i=0;i<m_ObjectTypes.size();i++) {
|
||||
std::vector<CObjectEntry*>& objects=m_ObjectTypes[i].m_Objects;
|
||||
|
||||
for (uint j=0;j<objects.size();j++) {
|
||||
// object might have already been built (eg if it's a prop);
|
||||
// and only build if we haven't a model
|
||||
if (!objects[j]->m_Model) {
|
||||
if (!objects[j]->BuildModel()) {
|
||||
DeleteObject(objects[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// now build all the models
|
||||
for (i=0;i<m_ObjectTypes.size();i++) {
|
||||
std::vector<CObjectEntry*>& objects=m_ObjectTypes[i].m_Objects;
|
||||
|
||||
for (uint j=0;j<objects.size();j++) {
|
||||
// object might have already been built (eg if it's a prop);
|
||||
// and only build if we haven't a model
|
||||
if (!objects[j]->m_Model) {
|
||||
if (!objects[j]->BuildModel()) {
|
||||
DeleteObject(objects[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CObjectManager::BuildObjectTypes()
|
||||
|
@ -1,15 +1,15 @@
|
||||
#ifndef _OBJECTMANAGER_H
|
||||
#define _OBJECTMANAGER_H
|
||||
|
||||
#include <vector>
|
||||
#include <vector>
|
||||
#include "Singleton.h"
|
||||
#include "ObjectEntry.h"
|
||||
|
||||
// access to sole CObjectManager object
|
||||
#define g_ObjMan CObjectManager::GetSingleton()
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CObjectManager: manager class for all possible actor types
|
||||
|
||||
// access to sole CObjectManager object
|
||||
#define g_ObjMan CObjectManager::GetSingleton()
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CObjectManager: manager class for all possible actor types
|
||||
class CObjectManager : public Singleton<CObjectManager>
|
||||
{
|
||||
public:
|
||||
@ -23,10 +23,10 @@ public:
|
||||
std::vector<CObjectEntry*> m_Objects;
|
||||
};
|
||||
|
||||
public:
|
||||
public:
|
||||
// constructor, destructor
|
||||
CObjectManager();
|
||||
~CObjectManager();
|
||||
~CObjectManager();
|
||||
|
||||
void LoadObjects();
|
||||
|
||||
|
@ -1,104 +1,104 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Name: RenderableObject.h
|
||||
// Author: Rich Cross
|
||||
// Contact: rich@wildfiregames.com
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _RENDERABLEOBJECT_H
|
||||
#define _RENDERABLEOBJECT_H
|
||||
|
||||
#include <assert.h>
|
||||
#include "res/res.h"
|
||||
#include "Bound.h"
|
||||
#include "Matrix3D.h"
|
||||
|
||||
|
||||
// dirty flags - used as notification to the renderer that some bit of data
|
||||
// need updating
|
||||
#define RENDERDATA_UPDATE_VERTICES (1<<1)
|
||||
#define RENDERDATA_UPDATE_INDICES (1<<2)
|
||||
#define RENDERDATA_UPDATE_TRANSFORM (1<<3)
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// CRenderData: base class of all the renderer's renderdata classes - the
|
||||
// derived class stores necessary information for rendering an object of a
|
||||
// particular type
|
||||
class CRenderData
|
||||
{
|
||||
public:
|
||||
CRenderData() : m_UpdateFlags(0) {}
|
||||
virtual ~CRenderData() {}
|
||||
|
||||
u32 m_UpdateFlags;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// CRenderableObject: base class of all renderable objects - patches, models,
|
||||
// sprites, etc; stores position and bound information, and a pointer to
|
||||
// some renderdata necessary for the renderer to actually render it
|
||||
class CRenderableObject
|
||||
{
|
||||
public:
|
||||
// constructor
|
||||
CRenderableObject() : m_RenderData(0) {
|
||||
m_Transform.SetIdentity();
|
||||
}
|
||||
// destructor
|
||||
virtual ~CRenderableObject() { delete m_RenderData; }
|
||||
|
||||
// set object transform
|
||||
virtual void SetTransform(const CMatrix3D& transform) {
|
||||
// store transform, calculate inverse
|
||||
m_Transform=transform;
|
||||
m_Transform.GetInverse(m_InvTransform);
|
||||
// normal recalculation likely required on transform change; flag it
|
||||
SetDirty(RENDERDATA_UPDATE_VERTICES);
|
||||
// rebuild world space bounds
|
||||
CalcBounds();
|
||||
}
|
||||
// get object to world space transform
|
||||
const CMatrix3D& GetTransform() const { return m_Transform; }
|
||||
// get world to object space transform
|
||||
const CMatrix3D& GetInvTransform() const { return m_InvTransform; }
|
||||
|
||||
// mark some part of the renderdata as dirty, and requiring
|
||||
// an update on next render
|
||||
void SetDirty(u32 dirtyflags) {
|
||||
if (m_RenderData) m_RenderData->m_UpdateFlags|=dirtyflags;
|
||||
}
|
||||
|
||||
// calculate (and store in m_Bounds) the world space bounds of this object
|
||||
// - must be implemented by all concrete subclasses
|
||||
virtual void CalcBounds() = 0;
|
||||
|
||||
// return world space bounds of this object
|
||||
const CBound& GetBounds() const { return m_Bounds; }
|
||||
|
||||
// set the object renderdata
|
||||
// TODO,RC 10/04/04 - need to delete existing renderdata here, or can we
|
||||
// assume the renderer won't set renderdata when an object already has it?
|
||||
// - just assert we've no renderdata at the minute
|
||||
void SetRenderData(CRenderData* renderdata) {
|
||||
assert(m_RenderData==0);
|
||||
m_RenderData=renderdata;
|
||||
}
|
||||
|
||||
// return object renderdata - can be null if renderer hasn't yet
|
||||
// created the renderdata
|
||||
CRenderData* GetRenderData() { return m_RenderData; }
|
||||
|
||||
protected:
|
||||
// object bounds
|
||||
CBound m_Bounds;
|
||||
// local->world space transform
|
||||
CMatrix3D m_Transform;
|
||||
// world->local space transform
|
||||
CMatrix3D m_InvTransform;
|
||||
// object renderdata
|
||||
CRenderData* m_RenderData;
|
||||
};
|
||||
|
||||
#endif
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Name: RenderableObject.h
|
||||
// Author: Rich Cross
|
||||
// Contact: rich@wildfiregames.com
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _RENDERABLEOBJECT_H
|
||||
#define _RENDERABLEOBJECT_H
|
||||
|
||||
#include <assert.h>
|
||||
#include "res/res.h"
|
||||
#include "Bound.h"
|
||||
#include "Matrix3D.h"
|
||||
|
||||
|
||||
// dirty flags - used as notification to the renderer that some bit of data
|
||||
// need updating
|
||||
#define RENDERDATA_UPDATE_VERTICES (1<<1)
|
||||
#define RENDERDATA_UPDATE_INDICES (1<<2)
|
||||
#define RENDERDATA_UPDATE_TRANSFORM (1<<3)
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// CRenderData: base class of all the renderer's renderdata classes - the
|
||||
// derived class stores necessary information for rendering an object of a
|
||||
// particular type
|
||||
class CRenderData
|
||||
{
|
||||
public:
|
||||
CRenderData() : m_UpdateFlags(0) {}
|
||||
virtual ~CRenderData() {}
|
||||
|
||||
u32 m_UpdateFlags;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// CRenderableObject: base class of all renderable objects - patches, models,
|
||||
// sprites, etc; stores position and bound information, and a pointer to
|
||||
// some renderdata necessary for the renderer to actually render it
|
||||
class CRenderableObject
|
||||
{
|
||||
public:
|
||||
// constructor
|
||||
CRenderableObject() : m_RenderData(0) {
|
||||
m_Transform.SetIdentity();
|
||||
}
|
||||
// destructor
|
||||
virtual ~CRenderableObject() { delete m_RenderData; }
|
||||
|
||||
// set object transform
|
||||
virtual void SetTransform(const CMatrix3D& transform) {
|
||||
// store transform, calculate inverse
|
||||
m_Transform=transform;
|
||||
m_Transform.GetInverse(m_InvTransform);
|
||||
// normal recalculation likely required on transform change; flag it
|
||||
SetDirty(RENDERDATA_UPDATE_VERTICES);
|
||||
// rebuild world space bounds
|
||||
CalcBounds();
|
||||
}
|
||||
// get object to world space transform
|
||||
const CMatrix3D& GetTransform() const { return m_Transform; }
|
||||
// get world to object space transform
|
||||
const CMatrix3D& GetInvTransform() const { return m_InvTransform; }
|
||||
|
||||
// mark some part of the renderdata as dirty, and requiring
|
||||
// an update on next render
|
||||
void SetDirty(u32 dirtyflags) {
|
||||
if (m_RenderData) m_RenderData->m_UpdateFlags|=dirtyflags;
|
||||
}
|
||||
|
||||
// calculate (and store in m_Bounds) the world space bounds of this object
|
||||
// - must be implemented by all concrete subclasses
|
||||
virtual void CalcBounds() = 0;
|
||||
|
||||
// return world space bounds of this object
|
||||
const CBound& GetBounds() const { return m_Bounds; }
|
||||
|
||||
// set the object renderdata
|
||||
// TODO,RC 10/04/04 - need to delete existing renderdata here, or can we
|
||||
// assume the renderer won't set renderdata when an object already has it?
|
||||
// - just assert we've no renderdata at the minute
|
||||
void SetRenderData(CRenderData* renderdata) {
|
||||
assert(m_RenderData==0);
|
||||
m_RenderData=renderdata;
|
||||
}
|
||||
|
||||
// return object renderdata - can be null if renderer hasn't yet
|
||||
// created the renderdata
|
||||
CRenderData* GetRenderData() { return m_RenderData; }
|
||||
|
||||
protected:
|
||||
// object bounds
|
||||
CBound m_Bounds;
|
||||
// local->world space transform
|
||||
CMatrix3D m_Transform;
|
||||
// world->local space transform
|
||||
CMatrix3D m_InvTransform;
|
||||
// object renderdata
|
||||
CRenderData* m_RenderData;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -1,30 +1,30 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Name: SkeletonAnim.h
|
||||
// Author: Rich Cross
|
||||
// Contact: rich@wildfiregames.com
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _SKELETONANIM_H
|
||||
#define _SKELETONANIM_H
|
||||
|
||||
#include "Bound.h"
|
||||
|
||||
class CSkeletonAnimDef;
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CSkeletonAnim: an instance of a CSkeletonAnimDef, for application onto a model
|
||||
class CSkeletonAnim
|
||||
{
|
||||
public:
|
||||
// the raw animation frame data
|
||||
CSkeletonAnimDef* m_AnimDef;
|
||||
// speed at which this animation runs
|
||||
float m_Speed;
|
||||
// object space bounds of the model when this animation is applied to it
|
||||
CBound m_ObjectBounds;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Name: SkeletonAnim.h
|
||||
// Author: Rich Cross
|
||||
// Contact: rich@wildfiregames.com
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _SKELETONANIM_H
|
||||
#define _SKELETONANIM_H
|
||||
|
||||
#include "Bound.h"
|
||||
|
||||
class CSkeletonAnimDef;
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CSkeletonAnim: an instance of a CSkeletonAnimDef, for application onto a model
|
||||
class CSkeletonAnim
|
||||
{
|
||||
public:
|
||||
// the raw animation frame data
|
||||
CSkeletonAnimDef* m_AnimDef;
|
||||
// speed at which this animation runs
|
||||
float m_Speed;
|
||||
// object space bounds of the model when this animation is applied to it
|
||||
CBound m_ObjectBounds;
|
||||
};
|
||||
|
||||
#endif
|
@ -1,85 +1,85 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Name: SkeletonAnimDef.h
|
||||
// Author: Rich Cross
|
||||
// Contact: rich@wildfiregames.com
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _SKELETONANIMDEF_H
|
||||
#define _SKELETONANIMDEF_H
|
||||
|
||||
#include "res/res.h"
|
||||
#include "CStr.h"
|
||||
#include "Vector3D.h"
|
||||
#include "Quaternion.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CBoneState: structure describing state of a bone at some point
|
||||
class CBoneState
|
||||
{
|
||||
public:
|
||||
// translation of bone relative to root
|
||||
CVector3D m_Translation;
|
||||
// rotation of bone relative to root
|
||||
CQuaternion m_Rotation;
|
||||
};
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CSkeletonAnimDef: raw description - eg bonestates - of an animation that plays upon
|
||||
// a skeleton
|
||||
class CSkeletonAnimDef
|
||||
{
|
||||
public:
|
||||
// current file version given to saved animations
|
||||
enum { FILE_VERSION = 1 };
|
||||
// supported file read version - files with a version less than this will be rejected
|
||||
enum { FILE_READ_VERSION = 1 };
|
||||
|
||||
|
||||
public:
|
||||
// Key: description of a single key in a skeleton animation
|
||||
typedef CBoneState Key;
|
||||
|
||||
public:
|
||||
// CSkeletonAnimDef constructor + destructor
|
||||
CSkeletonAnimDef();
|
||||
~CSkeletonAnimDef();
|
||||
|
||||
// return the number of keys in this animation
|
||||
u32 GetNumKeys() const { return m_NumKeys; }
|
||||
|
||||
// accessors: get a key for given bone at given time
|
||||
Key& GetKey(u32 frame,u32 bone) { return m_Keys[frame*m_NumKeys+bone]; }
|
||||
const Key& GetKey(u32 frame,u32 bone) const { return m_Keys[frame*m_NumKeys+bone]; }
|
||||
|
||||
// get duration of this anim, in ms
|
||||
float GetDuration() const { return m_NumFrames*m_FrameTime; }
|
||||
|
||||
// return length of each frame, in ms
|
||||
float GetFrameTime() const { return m_FrameTime; }
|
||||
// return number of frames in animation
|
||||
u32 GetNumFrames() const { return m_NumFrames; }
|
||||
|
||||
// build matrices for all bones at the given time (in MS) in this animation
|
||||
void BuildBoneMatrices(float time,CMatrix3D* matrices) const;
|
||||
|
||||
// anim I/O functions
|
||||
static CSkeletonAnimDef* Load(const char* filename);
|
||||
static void Save(const char* filename,const CSkeletonAnimDef* anim);
|
||||
|
||||
public:
|
||||
// name of the animation
|
||||
CStr m_Name;
|
||||
// frame time - time between successive frames, in ms
|
||||
float m_FrameTime;
|
||||
// number of keys in each frame - should match number of bones in the skeleton
|
||||
u32 m_NumKeys;
|
||||
// number of frames in the animation
|
||||
u32 m_NumFrames;
|
||||
// animation data - m_NumKeys*m_NumFrames total keys
|
||||
Key* m_Keys;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Name: SkeletonAnimDef.h
|
||||
// Author: Rich Cross
|
||||
// Contact: rich@wildfiregames.com
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _SKELETONANIMDEF_H
|
||||
#define _SKELETONANIMDEF_H
|
||||
|
||||
#include "res/res.h"
|
||||
#include "CStr.h"
|
||||
#include "Vector3D.h"
|
||||
#include "Quaternion.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CBoneState: structure describing state of a bone at some point
|
||||
class CBoneState
|
||||
{
|
||||
public:
|
||||
// translation of bone relative to root
|
||||
CVector3D m_Translation;
|
||||
// rotation of bone relative to root
|
||||
CQuaternion m_Rotation;
|
||||
};
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CSkeletonAnimDef: raw description - eg bonestates - of an animation that plays upon
|
||||
// a skeleton
|
||||
class CSkeletonAnimDef
|
||||
{
|
||||
public:
|
||||
// current file version given to saved animations
|
||||
enum { FILE_VERSION = 1 };
|
||||
// supported file read version - files with a version less than this will be rejected
|
||||
enum { FILE_READ_VERSION = 1 };
|
||||
|
||||
|
||||
public:
|
||||
// Key: description of a single key in a skeleton animation
|
||||
typedef CBoneState Key;
|
||||
|
||||
public:
|
||||
// CSkeletonAnimDef constructor + destructor
|
||||
CSkeletonAnimDef();
|
||||
~CSkeletonAnimDef();
|
||||
|
||||
// return the number of keys in this animation
|
||||
u32 GetNumKeys() const { return m_NumKeys; }
|
||||
|
||||
// accessors: get a key for given bone at given time
|
||||
Key& GetKey(u32 frame,u32 bone) { return m_Keys[frame*m_NumKeys+bone]; }
|
||||
const Key& GetKey(u32 frame,u32 bone) const { return m_Keys[frame*m_NumKeys+bone]; }
|
||||
|
||||
// get duration of this anim, in ms
|
||||
float GetDuration() const { return m_NumFrames*m_FrameTime; }
|
||||
|
||||
// return length of each frame, in ms
|
||||
float GetFrameTime() const { return m_FrameTime; }
|
||||
// return number of frames in animation
|
||||
u32 GetNumFrames() const { return m_NumFrames; }
|
||||
|
||||
// build matrices for all bones at the given time (in MS) in this animation
|
||||
void BuildBoneMatrices(float time,CMatrix3D* matrices) const;
|
||||
|
||||
// anim I/O functions
|
||||
static CSkeletonAnimDef* Load(const char* filename);
|
||||
static void Save(const char* filename,const CSkeletonAnimDef* anim);
|
||||
|
||||
public:
|
||||
// name of the animation
|
||||
CStr m_Name;
|
||||
// frame time - time between successive frames, in ms
|
||||
float m_FrameTime;
|
||||
// number of keys in each frame - should match number of bones in the skeleton
|
||||
u32 m_NumKeys;
|
||||
// number of frames in the animation
|
||||
u32 m_NumFrames;
|
||||
// animation data - m_NumKeys*m_NumFrames total keys
|
||||
Key* m_Keys;
|
||||
};
|
||||
|
||||
#endif
|
@ -1,67 +1,67 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Name: SkeletonAnimManager.cpp
|
||||
// Author: Rich Cross
|
||||
// Contact: rich@wildfiregames.com
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "res/res.h"
|
||||
#include "Model.h"
|
||||
#include "SkeletonAnimManager.h"
|
||||
#include <algorithm>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// CSkeletonAnimManager constructor
|
||||
CSkeletonAnimManager::CSkeletonAnimManager()
|
||||
{
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// CSkeletonAnimManager destructor
|
||||
CSkeletonAnimManager::~CSkeletonAnimManager()
|
||||
{
|
||||
typedef std::map<CStr,CSkeletonAnimDef*>::iterator Iter;
|
||||
for (Iter i=m_Animations.begin();i!=m_Animations.end();++i) {
|
||||
delete i->second;
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// GetAnimation: return a given animation by filename; return null if filename
|
||||
// doesn't refer to valid animation file
|
||||
CSkeletonAnimDef* CSkeletonAnimManager::GetAnimation(const char* filename)
|
||||
{
|
||||
// already loaded?
|
||||
CStr fname(filename);
|
||||
std::map<CStr,CSkeletonAnimDef*>::iterator iter=m_Animations.find(fname);
|
||||
if (iter!=m_Animations.end()) {
|
||||
// yes - return it
|
||||
return iter->second;
|
||||
}
|
||||
|
||||
// already failed to load?
|
||||
std::set<CStr>::iterator setiter=m_BadAnimationFiles.find(fname);
|
||||
if (setiter!=m_BadAnimationFiles.end()) {
|
||||
// yes - return null
|
||||
return 0;
|
||||
}
|
||||
|
||||
// try and load it now
|
||||
CSkeletonAnimDef* def;
|
||||
try {
|
||||
def=CSkeletonAnimDef::Load(filename);
|
||||
} catch (...) {
|
||||
def=0;
|
||||
}
|
||||
|
||||
if (!def) {
|
||||
// add this file as bad
|
||||
m_BadAnimationFiles.insert(fname);
|
||||
return 0;
|
||||
} else {
|
||||
// add mapping for this file
|
||||
m_Animations[fname]=def;
|
||||
return def;
|
||||
}
|
||||
}
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Name: SkeletonAnimManager.cpp
|
||||
// Author: Rich Cross
|
||||
// Contact: rich@wildfiregames.com
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "res/res.h"
|
||||
#include "Model.h"
|
||||
#include "SkeletonAnimManager.h"
|
||||
#include <algorithm>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// CSkeletonAnimManager constructor
|
||||
CSkeletonAnimManager::CSkeletonAnimManager()
|
||||
{
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// CSkeletonAnimManager destructor
|
||||
CSkeletonAnimManager::~CSkeletonAnimManager()
|
||||
{
|
||||
typedef std::map<CStr,CSkeletonAnimDef*>::iterator Iter;
|
||||
for (Iter i=m_Animations.begin();i!=m_Animations.end();++i) {
|
||||
delete i->second;
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// GetAnimation: return a given animation by filename; return null if filename
|
||||
// doesn't refer to valid animation file
|
||||
CSkeletonAnimDef* CSkeletonAnimManager::GetAnimation(const char* filename)
|
||||
{
|
||||
// already loaded?
|
||||
CStr fname(filename);
|
||||
std::map<CStr,CSkeletonAnimDef*>::iterator iter=m_Animations.find(fname);
|
||||
if (iter!=m_Animations.end()) {
|
||||
// yes - return it
|
||||
return iter->second;
|
||||
}
|
||||
|
||||
// already failed to load?
|
||||
std::set<CStr>::iterator setiter=m_BadAnimationFiles.find(fname);
|
||||
if (setiter!=m_BadAnimationFiles.end()) {
|
||||
// yes - return null
|
||||
return 0;
|
||||
}
|
||||
|
||||
// try and load it now
|
||||
CSkeletonAnimDef* def;
|
||||
try {
|
||||
def=CSkeletonAnimDef::Load(filename);
|
||||
} catch (...) {
|
||||
def=0;
|
||||
}
|
||||
|
||||
if (!def) {
|
||||
// add this file as bad
|
||||
m_BadAnimationFiles.insert(fname);
|
||||
return 0;
|
||||
} else {
|
||||
// add mapping for this file
|
||||
m_Animations[fname]=def;
|
||||
return def;
|
||||
}
|
||||
}
|
||||
|
@ -1,44 +1,44 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Name: SkeletonAnimManager.h
|
||||
// Author: Rich Cross
|
||||
// Contact: rich@wildfiregames.com
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _SKELETONANIMMANAGER_H
|
||||
#define _SKELETONANIMMANAGER_H
|
||||
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include "SkeletonAnimDef.h"
|
||||
#include "Singleton.h"
|
||||
|
||||
|
||||
// access to sole CSkeletonAnimManager object
|
||||
#define g_SkelAnimMan CSkeletonAnimManager::GetSingleton()
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// CSkeletonAnimManager : owner class of all skeleton anims - manages creation,
|
||||
// loading and destruction of animation data
|
||||
class CSkeletonAnimManager : public Singleton<CSkeletonAnimManager>
|
||||
{
|
||||
public:
|
||||
// constructor, destructor
|
||||
CSkeletonAnimManager();
|
||||
~CSkeletonAnimManager();
|
||||
|
||||
// return a given animation by filename; return null if filename doesn't
|
||||
// refer to valid animation file
|
||||
CSkeletonAnimDef* GetAnimation(const char* filename);
|
||||
|
||||
private:
|
||||
CSkeletonAnimDef* LoadAnimation(const char* filename);
|
||||
|
||||
// map of all known animations
|
||||
std::map<CStr,CSkeletonAnimDef*> m_Animations;
|
||||
// set of bad animation names - prevents multiple reloads of bad files
|
||||
std::set<CStr> m_BadAnimationFiles;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Name: SkeletonAnimManager.h
|
||||
// Author: Rich Cross
|
||||
// Contact: rich@wildfiregames.com
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _SKELETONANIMMANAGER_H
|
||||
#define _SKELETONANIMMANAGER_H
|
||||
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include "SkeletonAnimDef.h"
|
||||
#include "Singleton.h"
|
||||
|
||||
|
||||
// access to sole CSkeletonAnimManager object
|
||||
#define g_SkelAnimMan CSkeletonAnimManager::GetSingleton()
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// CSkeletonAnimManager : owner class of all skeleton anims - manages creation,
|
||||
// loading and destruction of animation data
|
||||
class CSkeletonAnimManager : public Singleton<CSkeletonAnimManager>
|
||||
{
|
||||
public:
|
||||
// constructor, destructor
|
||||
CSkeletonAnimManager();
|
||||
~CSkeletonAnimManager();
|
||||
|
||||
// return a given animation by filename; return null if filename doesn't
|
||||
// refer to valid animation file
|
||||
CSkeletonAnimDef* GetAnimation(const char* filename);
|
||||
|
||||
private:
|
||||
CSkeletonAnimDef* LoadAnimation(const char* filename);
|
||||
|
||||
// map of all known animations
|
||||
std::map<CStr,CSkeletonAnimDef*> m_Animations;
|
||||
// set of bad animation names - prevents multiple reloads of bad files
|
||||
std::set<CStr> m_BadAnimationFiles;
|
||||
};
|
||||
|
||||
#endif
|
@ -25,7 +25,7 @@
|
||||
==================================================================*/
|
||||
|
||||
#include "Sprite.h"
|
||||
#include "Renderer.h"
|
||||
#include "Renderer.h"
|
||||
#include "ogl.h"
|
||||
#include "res/tex.h"
|
||||
|
||||
|
@ -16,15 +16,15 @@ CTextureManager::CTextureManager()
|
||||
{
|
||||
m_TerrainTextures.reserve(32);
|
||||
}
|
||||
|
||||
CTextureManager::~CTextureManager()
|
||||
{
|
||||
for (size_t i=0;i<m_TerrainTextures.size();i++) {
|
||||
for (size_t j=0;j<m_TerrainTextures[i].m_Textures.size();j++) {
|
||||
delete m_TerrainTextures[i].m_Textures[j];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CTextureManager::~CTextureManager()
|
||||
{
|
||||
for (size_t i=0;i<m_TerrainTextures.size();i++) {
|
||||
for (size_t j=0;j<m_TerrainTextures[i].m_Textures.size();j++) {
|
||||
delete m_TerrainTextures[i].m_Textures[j];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CTextureManager::AddTextureType(const char* name)
|
||||
{
|
||||
|
@ -2,15 +2,15 @@
|
||||
#define _TEXTUREMANAGER_H
|
||||
|
||||
#include <vector>
|
||||
#include "CStr.h"
|
||||
#include "Singleton.h"
|
||||
#include "CStr.h"
|
||||
#include "Singleton.h"
|
||||
#include "TextureEntry.h"
|
||||
|
||||
// access to sole CTextureManager object
|
||||
#define g_TexMan CTextureManager ::GetSingleton()
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CTextureManager : manager class for all terrain texture objects
|
||||
// access to sole CTextureManager object
|
||||
#define g_TexMan CTextureManager ::GetSingleton()
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CTextureManager : manager class for all terrain texture objects
|
||||
class CTextureManager : public Singleton<CTextureManager>
|
||||
{
|
||||
public:
|
||||
@ -24,10 +24,10 @@ public:
|
||||
std::vector<CTextureEntry*> m_Textures;
|
||||
};
|
||||
|
||||
public:
|
||||
public:
|
||||
// constructor, destructor
|
||||
CTextureManager();
|
||||
~CTextureManager();
|
||||
~CTextureManager();
|
||||
|
||||
void LoadTerrainTextures();
|
||||
|
||||
|
@ -1,31 +1,31 @@
|
||||
#ifndef _UNIT_H
|
||||
#define _UNIT_H
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include "Model.h"
|
||||
|
||||
class CObjectEntry;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CUnit: simple "actor" definition - defines a sole object within the world
|
||||
class CUnit
|
||||
{
|
||||
public:
|
||||
// sole constructor - unit invalid without a model and object
|
||||
CUnit(CObjectEntry* object,CModel* model) : m_Object(object), m_Model(model) {
|
||||
assert(object && model);
|
||||
}
|
||||
// destructor
|
||||
~CUnit() {
|
||||
delete m_Model;
|
||||
}
|
||||
|
||||
|
||||
// get unit's template object
|
||||
CObjectEntry* GetObject() { return m_Object; }
|
||||
// get unit's model data
|
||||
CModel* GetModel() { return m_Model; }
|
||||
|
||||
public:
|
||||
// sole constructor - unit invalid without a model and object
|
||||
CUnit(CObjectEntry* object,CModel* model) : m_Object(object), m_Model(model) {
|
||||
assert(object && model);
|
||||
}
|
||||
// destructor
|
||||
~CUnit() {
|
||||
delete m_Model;
|
||||
}
|
||||
|
||||
|
||||
// get unit's template object
|
||||
CObjectEntry* GetObject() { return m_Object; }
|
||||
// get unit's model data
|
||||
CModel* GetModel() { return m_Model; }
|
||||
|
||||
private:
|
||||
// object from which unit was created
|
||||
CObjectEntry* m_Object;
|
||||
|
@ -1,77 +1,77 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Name: UnitManager.cpp
|
||||
// Author: Rich Cross
|
||||
// Contact: rich@wildfiregames.com
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "res/res.h"
|
||||
#include "Model.h"
|
||||
#include "UnitManager.h"
|
||||
#include <algorithm>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// CUnitManager constructor
|
||||
CUnitManager::CUnitManager()
|
||||
{
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// CUnitManager destructor
|
||||
CUnitManager::~CUnitManager()
|
||||
{
|
||||
DeleteAll();
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// AddUnit: add given unit to world
|
||||
void CUnitManager::AddUnit(CUnit* unit)
|
||||
{
|
||||
m_Units.push_back(unit);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// RemoveUnit: remove given unit from world, but don't delete it
|
||||
void CUnitManager::RemoveUnit(CUnit* unit)
|
||||
{
|
||||
// find entry in list
|
||||
typedef std::vector<CUnit*>::iterator Iter;
|
||||
Iter i=std::find(m_Units.begin(),m_Units.end(),unit);
|
||||
if (i!=m_Units.end()) {
|
||||
m_Units.erase(i);
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// DeleteAll: remove and delete all units
|
||||
void CUnitManager::DeleteAll()
|
||||
{
|
||||
for (uint i=0;i<m_Units.size();i++) {
|
||||
delete m_Units[i];
|
||||
}
|
||||
m_Units.clear();
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// PickUnit: iterate through units testing given ray against bounds of each
|
||||
// unit; return the closest unit, or null if everything missed
|
||||
CUnit* CUnitManager::PickUnit(const CVector3D& origin,const CVector3D& dir) const
|
||||
{
|
||||
// closest object found so far
|
||||
CUnit* hit=0;
|
||||
// distance to closest object found so far
|
||||
float dist=1.0e30f;
|
||||
for (uint i=0;i<m_Units.size();i++) {
|
||||
CUnit* unit=m_Units[i];
|
||||
float tmin,tmax;
|
||||
if (unit->GetModel()->GetBounds().RayIntersect(origin,dir,tmin,tmax)) {
|
||||
if (!hit || tmin<dist) {
|
||||
hit=unit;
|
||||
dist=tmin;
|
||||
}
|
||||
}
|
||||
}
|
||||
return hit;
|
||||
}
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Name: UnitManager.cpp
|
||||
// Author: Rich Cross
|
||||
// Contact: rich@wildfiregames.com
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "res/res.h"
|
||||
#include "Model.h"
|
||||
#include "UnitManager.h"
|
||||
#include <algorithm>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// CUnitManager constructor
|
||||
CUnitManager::CUnitManager()
|
||||
{
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// CUnitManager destructor
|
||||
CUnitManager::~CUnitManager()
|
||||
{
|
||||
DeleteAll();
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// AddUnit: add given unit to world
|
||||
void CUnitManager::AddUnit(CUnit* unit)
|
||||
{
|
||||
m_Units.push_back(unit);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// RemoveUnit: remove given unit from world, but don't delete it
|
||||
void CUnitManager::RemoveUnit(CUnit* unit)
|
||||
{
|
||||
// find entry in list
|
||||
typedef std::vector<CUnit*>::iterator Iter;
|
||||
Iter i=std::find(m_Units.begin(),m_Units.end(),unit);
|
||||
if (i!=m_Units.end()) {
|
||||
m_Units.erase(i);
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// DeleteAll: remove and delete all units
|
||||
void CUnitManager::DeleteAll()
|
||||
{
|
||||
for (uint i=0;i<m_Units.size();i++) {
|
||||
delete m_Units[i];
|
||||
}
|
||||
m_Units.clear();
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// PickUnit: iterate through units testing given ray against bounds of each
|
||||
// unit; return the closest unit, or null if everything missed
|
||||
CUnit* CUnitManager::PickUnit(const CVector3D& origin,const CVector3D& dir) const
|
||||
{
|
||||
// closest object found so far
|
||||
CUnit* hit=0;
|
||||
// distance to closest object found so far
|
||||
float dist=1.0e30f;
|
||||
for (uint i=0;i<m_Units.size();i++) {
|
||||
CUnit* unit=m_Units[i];
|
||||
float tmin,tmax;
|
||||
if (unit->GetModel()->GetBounds().RayIntersect(origin,dir,tmin,tmax)) {
|
||||
if (!hit || tmin<dist) {
|
||||
hit=unit;
|
||||
dist=tmin;
|
||||
}
|
||||
}
|
||||
}
|
||||
return hit;
|
||||
}
|
||||
|
@ -1,49 +1,49 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Name: UnitManager.h
|
||||
// Author: Rich Cross
|
||||
// Contact: rich@wildfiregames.com
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _UNITMANAGER_H
|
||||
#define _UNITMANAGER_H
|
||||
|
||||
#include <vector>
|
||||
#include "Unit.h"
|
||||
#include "Singleton.h"
|
||||
|
||||
class CVector3D;
|
||||
|
||||
// access to sole CUnitManager object
|
||||
#define g_UnitMan CUnitManager::GetSingleton()
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// CUnitManager: simple container class holding all units within the world
|
||||
class CUnitManager : public Singleton<CUnitManager>
|
||||
{
|
||||
public:
|
||||
// constructor, destructor
|
||||
CUnitManager();
|
||||
~CUnitManager();
|
||||
|
||||
// add given unit to world
|
||||
void AddUnit(CUnit* unit);
|
||||
// remove given unit from world, but don't delete it
|
||||
void RemoveUnit(CUnit* unit);
|
||||
// remove and delete all units
|
||||
void DeleteAll();
|
||||
|
||||
// return the units
|
||||
const std::vector<CUnit*>& GetUnits() const { return m_Units; }
|
||||
|
||||
// iterate through units testing given ray against bounds of each unit;
|
||||
// return the closest unit, or null if everything missed
|
||||
CUnit* PickUnit(const CVector3D& origin,const CVector3D& dir) const;
|
||||
|
||||
private:
|
||||
// list of all known units
|
||||
std::vector<CUnit*> m_Units;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Name: UnitManager.h
|
||||
// Author: Rich Cross
|
||||
// Contact: rich@wildfiregames.com
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _UNITMANAGER_H
|
||||
#define _UNITMANAGER_H
|
||||
|
||||
#include <vector>
|
||||
#include "Unit.h"
|
||||
#include "Singleton.h"
|
||||
|
||||
class CVector3D;
|
||||
|
||||
// access to sole CUnitManager object
|
||||
#define g_UnitMan CUnitManager::GetSingleton()
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// CUnitManager: simple container class holding all units within the world
|
||||
class CUnitManager : public Singleton<CUnitManager>
|
||||
{
|
||||
public:
|
||||
// constructor, destructor
|
||||
CUnitManager();
|
||||
~CUnitManager();
|
||||
|
||||
// add given unit to world
|
||||
void AddUnit(CUnit* unit);
|
||||
// remove given unit from world, but don't delete it
|
||||
void RemoveUnit(CUnit* unit);
|
||||
// remove and delete all units
|
||||
void DeleteAll();
|
||||
|
||||
// return the units
|
||||
const std::vector<CUnit*>& GetUnits() const { return m_Units; }
|
||||
|
||||
// iterate through units testing given ray against bounds of each unit;
|
||||
// return the closest unit, or null if everything missed
|
||||
CUnit* PickUnit(const CVector3D& origin,const CVector3D& dir) const;
|
||||
|
||||
private:
|
||||
// list of all known units
|
||||
std::vector<CUnit*> m_Units;
|
||||
};
|
||||
|
||||
#endif
|
@ -1004,12 +1004,12 @@ int tex_bind(const Handle h)
|
||||
glBindTexture(GL_TEXTURE_2D, t->id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tex_id(const Handle h)
|
||||
{
|
||||
Tex* t = H_USER_DATA(h, Tex);
|
||||
return t ? t->id : 0;
|
||||
}
|
||||
|
||||
int tex_id(const Handle h)
|
||||
{
|
||||
Tex* t = H_USER_DATA(h, Tex);
|
||||
return t ? t->id : 0;
|
||||
}
|
||||
|
||||
|
||||
int tex_filter = GL_LINEAR;
|
||||
|
@ -28,7 +28,7 @@
|
||||
extern Handle tex_load(const char* const fn, int scope = 0);
|
||||
|
||||
extern int tex_bind(Handle ht);
|
||||
extern int tex_id(Handle ht);
|
||||
extern int tex_id(Handle ht);
|
||||
|
||||
extern int tex_info(Handle ht, int* w, int* h, int *fmt, int *bpp, void** p);
|
||||
|
||||
|
@ -262,7 +262,7 @@ int poll(struct pollfd /* fds */[], int /* nfds */, int /* timeout */)
|
||||
|
||||
|
||||
__declspec(naked) pthread_t pthread_self(void)
|
||||
{ __asm jmp dword ptr [GetCurrentThreadId] }
|
||||
{ __asm jmp dword ptr [GetCurrentThread] }
|
||||
|
||||
|
||||
int pthread_getschedparam(pthread_t thread, int* policy, struct sched_param* param)
|
||||
|
@ -226,19 +226,19 @@ void RenderTerrain()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// SubmitModelRecursive: recurse down given model, submitting it and all it's descendents to the
|
||||
// renderer
|
||||
void SubmitModelRecursive(CModel* model)
|
||||
{
|
||||
g_Renderer.Submit(model);
|
||||
|
||||
const std::vector<CModel::Prop>& props=model->GetProps();
|
||||
for (uint i=0;i<props.size();i++) {
|
||||
SubmitModelRecursive(props[i].m_Model);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// SubmitModelRecursive: recurse down given model, submitting it and all it's descendents to the
|
||||
// renderer
|
||||
void SubmitModelRecursive(CModel* model)
|
||||
{
|
||||
g_Renderer.Submit(model);
|
||||
|
||||
const std::vector<CModel::Prop>& props=model->GetProps();
|
||||
for (uint i=0;i<props.size();i++) {
|
||||
SubmitModelRecursive(props[i].m_Model);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// RenderModels: iterate through model list and submit all models in viewing frustum to the
|
||||
@ -249,7 +249,7 @@ void RenderModels()
|
||||
|
||||
const std::vector<CUnit*>& units=g_UnitMan.GetUnits();
|
||||
for (uint i=0;i<units.size();++i) {
|
||||
if (frustum.IsBoxVisible(CVector3D(0,0,0),units[i]->GetModel()->GetBounds())) {
|
||||
if (frustum.IsBoxVisible(CVector3D(0,0,0),units[i]->GetModel()->GetBounds())) {
|
||||
SubmitModelRecursive(units[i]->GetModel());
|
||||
}
|
||||
}
|
||||
@ -420,17 +420,12 @@ void ParseArgs(int argc, char* argv[])
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" char* _getcwd(char*, int);
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
const int ERR_MSG_SIZE = 1000;
|
||||
wchar_t err_msg[ERR_MSG_SIZE];
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
lib_init();
|
||||
|
||||
// set 24 bit (float) FPU precision for faster divides / sqrts
|
||||
@ -440,8 +435,6 @@ int main(int argc, char* argv[])
|
||||
|
||||
detect();
|
||||
|
||||
|
||||
|
||||
// init SDL
|
||||
if(SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER|SDL_INIT_NOPARACHUTE) < 0)
|
||||
{
|
||||
@ -514,12 +507,16 @@ int main(int argc, char* argv[])
|
||||
debug_warn("SDL_SetGamma failed");
|
||||
}
|
||||
|
||||
|
||||
new CConfig;
|
||||
|
||||
// vfs_mount("gui", "gui", 0);
|
||||
vfs_mount("", "mods/official/", 0);
|
||||
//// dir_add_watch("mods\\official", false);
|
||||
|
||||
|
||||
//Handle xx = tex_load("art/textures/skins/structural/null.png");
|
||||
|
||||
#ifndef NO_GUI
|
||||
// GUI uses VFS, so this must come after VFS init.
|
||||
g_GUI.Initialize();
|
||||
@ -560,8 +557,6 @@ int main(int argc, char* argv[])
|
||||
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?
|
||||
|
@ -1,162 +1,162 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Name: Bound.cpp
|
||||
// Author: Rich Cross
|
||||
// Contact: rich@wildfiregames.com
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
// necessary includes
|
||||
#include <assert.h>
|
||||
#include <float.h>
|
||||
#include "Bound.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// operator+=: extend this bound to include given bound
|
||||
CBound& CBound::operator+=(const CBound& b)
|
||||
{
|
||||
for (int i=0;i<3;++i) {
|
||||
if (b[0][i]<m_Data[0][i])
|
||||
m_Data[0][i]=b[0][i];
|
||||
if (b[1][i]>m_Data[1][i])
|
||||
m_Data[1][i]=b[1][i];
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// operator+=: extend this bound to include given point
|
||||
CBound& CBound::operator+=(const CVector3D& pt)
|
||||
{
|
||||
for (int i=0;i<3;++i) {
|
||||
if (pt[i]<m_Data[0][i])
|
||||
m_Data[0][i]=pt[i];
|
||||
else if (pt[i]>m_Data[1][i])
|
||||
m_Data[1][i]=pt[i];
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// RayIntersect: intersect ray with this bound; return true
|
||||
// if ray hits (and store entry and exit times), or false
|
||||
// otherwise
|
||||
// note: incoming ray direction must be normalised
|
||||
bool CBound::RayIntersect(const CVector3D& origin,const CVector3D& dir,
|
||||
float& tmin,float& tmax) const
|
||||
{
|
||||
float t1,t2;
|
||||
float tnear,tfar;
|
||||
|
||||
if (dir[0]==0) {
|
||||
if (origin[0]<m_Data[0][0] || origin[0]>m_Data[1][0])
|
||||
return false;
|
||||
else {
|
||||
tnear=(float) FLT_MIN;
|
||||
tfar=(float) FLT_MAX;
|
||||
}
|
||||
} else {
|
||||
t1=(m_Data[0][0]-origin[0])/dir[0];
|
||||
t2=(m_Data[1][0]-origin[0])/dir[0];
|
||||
|
||||
if (dir[0]<0) {
|
||||
tnear = t2;
|
||||
tfar = t1;
|
||||
} else {
|
||||
tnear = t1;
|
||||
tfar = t2;
|
||||
}
|
||||
|
||||
if (tfar<0)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (dir[1]==0 && (origin[1]<m_Data[0][1] || origin[1]>m_Data[1][1]))
|
||||
return false;
|
||||
else {
|
||||
t1=(m_Data[0][1]-origin[1])/dir[1];
|
||||
t2=(m_Data[1][1]-origin[1])/dir[1];
|
||||
|
||||
if (dir[1]<0) {
|
||||
if (t2>tnear)
|
||||
tnear = t2;
|
||||
if (t1<tfar)
|
||||
tfar = t1;
|
||||
} else {
|
||||
if (t1>tnear)
|
||||
tnear = t1;
|
||||
if (t2<tfar)
|
||||
tfar = t2;
|
||||
}
|
||||
|
||||
if (tnear>tfar || tfar<0)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (dir[2]==0 && (origin[2]<m_Data[0][2] || origin[2]>m_Data[1][2]))
|
||||
return false;
|
||||
else {
|
||||
t1=(m_Data[0][2]-origin[2])/dir[2];
|
||||
t2=(m_Data[1][2]-origin[2])/dir[2];
|
||||
|
||||
if (dir[2]<0) {
|
||||
if (t2>tnear)
|
||||
tnear = t2;
|
||||
if (t1<tfar)
|
||||
tfar = t1;
|
||||
} else {
|
||||
if (t1>tnear)
|
||||
tnear = t1;
|
||||
if (t2<tfar)
|
||||
tfar = t2;
|
||||
}
|
||||
|
||||
if (tnear>tfar || tfar<0)
|
||||
return false;
|
||||
}
|
||||
|
||||
tmin=tnear;
|
||||
tmax=tfar;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// SetEmpty: initialise this bound as empty
|
||||
void CBound::SetEmpty()
|
||||
{
|
||||
m_Data[0]=CVector3D(FLT_MAX,FLT_MAX,FLT_MAX);
|
||||
m_Data[1]=CVector3D(FLT_MIN,FLT_MIN,FLT_MIN);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Transform: transform this bound by given matrix; return transformed bound
|
||||
// in 'result' parameter - slightly modified version of code in Graphic Gems
|
||||
// (can't remember which one it was, though)
|
||||
void CBound::Transform(const CMatrix3D& m,CBound& result) const
|
||||
{
|
||||
assert(this!=&result);
|
||||
|
||||
for (int i=0;i<3;++i) {
|
||||
// handle translation
|
||||
result[0][i]=result[1][i]=m(i,3);
|
||||
|
||||
// Now find the extreme points by considering the product of the
|
||||
// min and max with each component of matrix
|
||||
for(int j=0;j<3;j++) {
|
||||
float a=m(j,i)*m_Data[0][j];
|
||||
float b=m(j,i)*m_Data[1][j];
|
||||
|
||||
if (a<b) {
|
||||
result[0][i]+=a;
|
||||
result[1][i]+=b;
|
||||
} else {
|
||||
result[0][i]+=b;
|
||||
result[1][i]+=a;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Name: Bound.cpp
|
||||
// Author: Rich Cross
|
||||
// Contact: rich@wildfiregames.com
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
// necessary includes
|
||||
#include <assert.h>
|
||||
#include <float.h>
|
||||
#include "Bound.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// operator+=: extend this bound to include given bound
|
||||
CBound& CBound::operator+=(const CBound& b)
|
||||
{
|
||||
for (int i=0;i<3;++i) {
|
||||
if (b[0][i]<m_Data[0][i])
|
||||
m_Data[0][i]=b[0][i];
|
||||
if (b[1][i]>m_Data[1][i])
|
||||
m_Data[1][i]=b[1][i];
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// operator+=: extend this bound to include given point
|
||||
CBound& CBound::operator+=(const CVector3D& pt)
|
||||
{
|
||||
for (int i=0;i<3;++i) {
|
||||
if (pt[i]<m_Data[0][i])
|
||||
m_Data[0][i]=pt[i];
|
||||
else if (pt[i]>m_Data[1][i])
|
||||
m_Data[1][i]=pt[i];
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// RayIntersect: intersect ray with this bound; return true
|
||||
// if ray hits (and store entry and exit times), or false
|
||||
// otherwise
|
||||
// note: incoming ray direction must be normalised
|
||||
bool CBound::RayIntersect(const CVector3D& origin,const CVector3D& dir,
|
||||
float& tmin,float& tmax) const
|
||||
{
|
||||
float t1,t2;
|
||||
float tnear,tfar;
|
||||
|
||||
if (dir[0]==0) {
|
||||
if (origin[0]<m_Data[0][0] || origin[0]>m_Data[1][0])
|
||||
return false;
|
||||
else {
|
||||
tnear=(float) FLT_MIN;
|
||||
tfar=(float) FLT_MAX;
|
||||
}
|
||||
} else {
|
||||
t1=(m_Data[0][0]-origin[0])/dir[0];
|
||||
t2=(m_Data[1][0]-origin[0])/dir[0];
|
||||
|
||||
if (dir[0]<0) {
|
||||
tnear = t2;
|
||||
tfar = t1;
|
||||
} else {
|
||||
tnear = t1;
|
||||
tfar = t2;
|
||||
}
|
||||
|
||||
if (tfar<0)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (dir[1]==0 && (origin[1]<m_Data[0][1] || origin[1]>m_Data[1][1]))
|
||||
return false;
|
||||
else {
|
||||
t1=(m_Data[0][1]-origin[1])/dir[1];
|
||||
t2=(m_Data[1][1]-origin[1])/dir[1];
|
||||
|
||||
if (dir[1]<0) {
|
||||
if (t2>tnear)
|
||||
tnear = t2;
|
||||
if (t1<tfar)
|
||||
tfar = t1;
|
||||
} else {
|
||||
if (t1>tnear)
|
||||
tnear = t1;
|
||||
if (t2<tfar)
|
||||
tfar = t2;
|
||||
}
|
||||
|
||||
if (tnear>tfar || tfar<0)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (dir[2]==0 && (origin[2]<m_Data[0][2] || origin[2]>m_Data[1][2]))
|
||||
return false;
|
||||
else {
|
||||
t1=(m_Data[0][2]-origin[2])/dir[2];
|
||||
t2=(m_Data[1][2]-origin[2])/dir[2];
|
||||
|
||||
if (dir[2]<0) {
|
||||
if (t2>tnear)
|
||||
tnear = t2;
|
||||
if (t1<tfar)
|
||||
tfar = t1;
|
||||
} else {
|
||||
if (t1>tnear)
|
||||
tnear = t1;
|
||||
if (t2<tfar)
|
||||
tfar = t2;
|
||||
}
|
||||
|
||||
if (tnear>tfar || tfar<0)
|
||||
return false;
|
||||
}
|
||||
|
||||
tmin=tnear;
|
||||
tmax=tfar;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// SetEmpty: initialise this bound as empty
|
||||
void CBound::SetEmpty()
|
||||
{
|
||||
m_Data[0]=CVector3D(FLT_MAX,FLT_MAX,FLT_MAX);
|
||||
m_Data[1]=CVector3D(FLT_MIN,FLT_MIN,FLT_MIN);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Transform: transform this bound by given matrix; return transformed bound
|
||||
// in 'result' parameter - slightly modified version of code in Graphic Gems
|
||||
// (can't remember which one it was, though)
|
||||
void CBound::Transform(const CMatrix3D& m,CBound& result) const
|
||||
{
|
||||
assert(this!=&result);
|
||||
|
||||
for (int i=0;i<3;++i) {
|
||||
// handle translation
|
||||
result[0][i]=result[1][i]=m(i,3);
|
||||
|
||||
// Now find the extreme points by considering the product of the
|
||||
// min and max with each component of matrix
|
||||
for(int j=0;j<3;j++) {
|
||||
float a=m(j,i)*m_Data[0][j];
|
||||
float b=m(j,i)*m_Data[1][j];
|
||||
|
||||
if (a<b) {
|
||||
result[0][i]+=a;
|
||||
result[1][i]+=b;
|
||||
} else {
|
||||
result[0][i]+=b;
|
||||
result[1][i]+=a;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,55 +1,55 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Name: Bound.h
|
||||
// Author: Rich Cross
|
||||
// Contact: rich@wildfiregames.com
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _BOUND_H
|
||||
#define _BOUND_H
|
||||
|
||||
// necessary includes
|
||||
#include "Vector3D.h"
|
||||
#include "Matrix3D.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// CBound: basic axis aligned bounding box class
|
||||
class CBound
|
||||
{
|
||||
public:
|
||||
CBound() {}
|
||||
CBound(const CVector3D& min,const CVector3D& max) {
|
||||
m_Data[0]=min; m_Data[1]=max;
|
||||
}
|
||||
|
||||
void Transform(const CMatrix3D& m,CBound& result) const;
|
||||
|
||||
CVector3D& operator[](int index) { return m_Data[index]; }
|
||||
const CVector3D& operator[](int index) const { return m_Data[index]; }
|
||||
|
||||
void SetEmpty();
|
||||
|
||||
CBound& operator+=(const CBound& b);
|
||||
CBound& operator+=(const CVector3D& pt);
|
||||
|
||||
bool RayIntersect(const CVector3D& origin,const CVector3D& dir,float& tmin,float& tmax) const;
|
||||
|
||||
// return the volume of this bounding box
|
||||
float GetVolume() const {
|
||||
CVector3D v=m_Data[1]-m_Data[0];
|
||||
return v.X*v.Y*v.Z;
|
||||
}
|
||||
|
||||
// return the centre of this bounding box
|
||||
void GetCentre(CVector3D& centre) const {
|
||||
centre=(m_Data[0]+m_Data[1])*0.5f;
|
||||
}
|
||||
|
||||
private:
|
||||
CVector3D m_Data[2];
|
||||
};
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#endif
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Name: Bound.h
|
||||
// Author: Rich Cross
|
||||
// Contact: rich@wildfiregames.com
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _BOUND_H
|
||||
#define _BOUND_H
|
||||
|
||||
// necessary includes
|
||||
#include "Vector3D.h"
|
||||
#include "Matrix3D.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// CBound: basic axis aligned bounding box class
|
||||
class CBound
|
||||
{
|
||||
public:
|
||||
CBound() {}
|
||||
CBound(const CVector3D& min,const CVector3D& max) {
|
||||
m_Data[0]=min; m_Data[1]=max;
|
||||
}
|
||||
|
||||
void Transform(const CMatrix3D& m,CBound& result) const;
|
||||
|
||||
CVector3D& operator[](int index) { return m_Data[index]; }
|
||||
const CVector3D& operator[](int index) const { return m_Data[index]; }
|
||||
|
||||
void SetEmpty();
|
||||
|
||||
CBound& operator+=(const CBound& b);
|
||||
CBound& operator+=(const CVector3D& pt);
|
||||
|
||||
bool RayIntersect(const CVector3D& origin,const CVector3D& dir,float& tmin,float& tmax) const;
|
||||
|
||||
// return the volume of this bounding box
|
||||
float GetVolume() const {
|
||||
CVector3D v=m_Data[1]-m_Data[0];
|
||||
return v.X*v.Y*v.Z;
|
||||
}
|
||||
|
||||
// return the centre of this bounding box
|
||||
void GetCentre(CVector3D& centre) const {
|
||||
centre=(m_Data[0]+m_Data[1])*0.5f;
|
||||
}
|
||||
|
||||
private:
|
||||
CVector3D m_Data[2];
|
||||
};
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -1,4 +1,4 @@
|
||||
#if 0
|
||||
#if 0
|
||||
// last modified Thursday, May 08, 2003
|
||||
|
||||
#include <time.h>
|
||||
|
@ -1,18 +1,18 @@
|
||||
#ifndef MATH_UTIL_H
|
||||
#define MATH_UTIL_H
|
||||
|
||||
#ifndef PI
|
||||
#define PI 3.14159265358979323846f
|
||||
#endif
|
||||
|
||||
#define DEGTORAD(a) ((a) * (PI/180.0f))
|
||||
#define RADTODEG(a) ((a) * (180.0f/PI))
|
||||
#define SQR(x) ((x) * (x))
|
||||
#define MAX3(a,b,c) ( MAX (MAX(a,b), c) )
|
||||
#define ABS(a) ((a > 0) ? (a) : (-a))
|
||||
|
||||
#if 0
|
||||
|
||||
#ifndef MATH_UTIL_H
|
||||
#define MATH_UTIL_H
|
||||
|
||||
#ifndef PI
|
||||
#define PI 3.14159265358979323846f
|
||||
#endif
|
||||
|
||||
#define DEGTORAD(a) ((a) * (PI/180.0f))
|
||||
#define RADTODEG(a) ((a) * (180.0f/PI))
|
||||
#define SQR(x) ((x) * (x))
|
||||
#define MAX3(a,b,c) ( MAX (MAX(a,b), c) )
|
||||
#define ABS(a) ((a > 0) ? (a) : (-a))
|
||||
|
||||
#if 0
|
||||
|
||||
/*
|
||||
Math utility functions
|
||||
by Michael Reiland
|
||||
@ -213,8 +213,8 @@ namespace MathUtil
|
||||
_float SignedModulus(const _float &num, const _float &n);
|
||||
_double SignedModulus(const _double &num, const _double &n);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,123 +1,123 @@
|
||||
#ifndef __MATRIX3D_H
|
||||
#define __MATRIX3D_H
|
||||
|
||||
#include <math.h>
|
||||
#include "Vector3D.h"
|
||||
#include "Vector4D.h"
|
||||
|
||||
class CQuaternion;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// CMatrix3D: a 4x4 matrix class for common operations in 3D
|
||||
class CMatrix3D
|
||||
{
|
||||
public:
|
||||
// the matrix data itself - accessible as either longhand names
|
||||
// or via a flat array
|
||||
union {
|
||||
struct {
|
||||
float _11, _21, _31, _41;
|
||||
float _12, _22, _32, _42;
|
||||
float _13, _23, _33, _43;
|
||||
float _14, _24, _34, _44;
|
||||
};
|
||||
float _data[16];
|
||||
};
|
||||
|
||||
public:
|
||||
// constructors
|
||||
CMatrix3D();
|
||||
CMatrix3D(float a11,float a12,float a13,float a14,float a21,float a22,float a23,float a24,
|
||||
float a31,float a32,float a33,float a34,float a41,float a42,float a43,float a44);
|
||||
|
||||
// accessors to individual elements of matrix
|
||||
float& operator()(int col,int row) {
|
||||
return _data[row*4+col];
|
||||
}
|
||||
const float& operator()(int col,int row) const {
|
||||
return _data[row*4+col];
|
||||
}
|
||||
|
||||
// matrix multiplication
|
||||
CMatrix3D operator*(const CMatrix3D &matrix) const;
|
||||
// matrix multiplication/assignment
|
||||
CMatrix3D& operator*=(const CMatrix3D &matrix);
|
||||
// matrix scaling
|
||||
CMatrix3D operator*(float f) const;
|
||||
// matrix scaling/assignment
|
||||
CMatrix3D& operator*=(float f);
|
||||
// matrix addition
|
||||
CMatrix3D operator+(const CMatrix3D &matrix) const;
|
||||
// matrix addition/assignment
|
||||
CMatrix3D& operator+=(const CMatrix3D &matrix);
|
||||
|
||||
// set this matrix to the identity matrix
|
||||
void SetIdentity();
|
||||
// set this matrix to the zero matrix
|
||||
void SetZero();
|
||||
|
||||
// concatenate arbitrary matrix onto this matrix
|
||||
void Concatenate(const CMatrix3D& m);
|
||||
|
||||
// set this matrix to a rotation matrix for a rotation about X axis of given angle
|
||||
void SetXRotation(float angle);
|
||||
// set this matrix to a rotation matrix for a rotation about Y axis of given angle
|
||||
void SetYRotation(float angle);
|
||||
// set this matrix to a rotation matrix for a rotation about Z axis of given angle
|
||||
void SetZRotation(float angle);
|
||||
// set this matrix to a rotation described by given quaternion
|
||||
void SetRotation(const CQuaternion& quat);
|
||||
|
||||
// concatentate a rotation about the X axis onto this matrix
|
||||
void RotateX(float angle);
|
||||
// concatentate a rotation about the Y axis onto this matrix
|
||||
void RotateY(float angle);
|
||||
// concatentate a rotation about the Z axis onto this matrix
|
||||
void RotateZ(float angle);
|
||||
// concatentate a rotation described by given quaternion
|
||||
void Rotate(const CQuaternion& quat);
|
||||
|
||||
// set this matrix to given translation
|
||||
void SetTranslation(float x, float y, float z);
|
||||
void SetTranslation(const CVector3D& vector);
|
||||
|
||||
// concatenate given translation onto this matrix
|
||||
void Translate(float x, float y, float z);
|
||||
void Translate(const CVector3D& vector);
|
||||
|
||||
// set this matrix to the given scaling matrix
|
||||
void SetScaling(float x_scale, float y_scale, float z_scale);
|
||||
|
||||
// concatentate given scaling matrix onto this matrix
|
||||
void Scale(float x_scale, float y_scale, float z_scale);
|
||||
|
||||
// calculate the inverse of this matrix, store in dst
|
||||
void GetInverse(CMatrix3D& dst) const;
|
||||
|
||||
// calculate the transpose of this matrix, store in dst
|
||||
void GetTranspose(CMatrix3D& dst) const;
|
||||
|
||||
// return the translation component of this matrix
|
||||
CVector3D GetTranslation() const;
|
||||
// return left vector, derived from rotation
|
||||
CVector3D GetLeft() const;
|
||||
// return up vector, derived from rotation
|
||||
CVector3D GetUp() const;
|
||||
// return forward vector, derived from rotation
|
||||
CVector3D GetIn() const;
|
||||
|
||||
// transform a 3D vector by this matrix
|
||||
void Transform(const CVector3D &vector,CVector3D& result) const;
|
||||
CVector3D Transform(const CVector3D &vector) const;
|
||||
// transform a 4D vector by this matrix
|
||||
void Transform(const CVector4D &vector,CVector4D& result) const;
|
||||
CVector4D Transform(const CVector4D &vector) const;
|
||||
// rotate a vector by this matrix
|
||||
void Rotate(const CVector3D& vector,CVector3D& result) const;
|
||||
CVector3D Rotate(const CVector3D& vector) const;
|
||||
// rotate a vector by the transpose of this matrix
|
||||
void RotateTransposed(const CVector3D& vector,CVector3D& result) const;
|
||||
CVector3D RotateTransposed(const CVector3D& vector) const;
|
||||
};
|
||||
|
||||
#endif
|
||||
#ifndef __MATRIX3D_H
|
||||
#define __MATRIX3D_H
|
||||
|
||||
#include <math.h>
|
||||
#include "Vector3D.h"
|
||||
#include "Vector4D.h"
|
||||
|
||||
class CQuaternion;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// CMatrix3D: a 4x4 matrix class for common operations in 3D
|
||||
class CMatrix3D
|
||||
{
|
||||
public:
|
||||
// the matrix data itself - accessible as either longhand names
|
||||
// or via a flat array
|
||||
union {
|
||||
struct {
|
||||
float _11, _21, _31, _41;
|
||||
float _12, _22, _32, _42;
|
||||
float _13, _23, _33, _43;
|
||||
float _14, _24, _34, _44;
|
||||
};
|
||||
float _data[16];
|
||||
};
|
||||
|
||||
public:
|
||||
// constructors
|
||||
CMatrix3D();
|
||||
CMatrix3D(float a11,float a12,float a13,float a14,float a21,float a22,float a23,float a24,
|
||||
float a31,float a32,float a33,float a34,float a41,float a42,float a43,float a44);
|
||||
|
||||
// accessors to individual elements of matrix
|
||||
float& operator()(int col,int row) {
|
||||
return _data[row*4+col];
|
||||
}
|
||||
const float& operator()(int col,int row) const {
|
||||
return _data[row*4+col];
|
||||
}
|
||||
|
||||
// matrix multiplication
|
||||
CMatrix3D operator*(const CMatrix3D &matrix) const;
|
||||
// matrix multiplication/assignment
|
||||
CMatrix3D& operator*=(const CMatrix3D &matrix);
|
||||
// matrix scaling
|
||||
CMatrix3D operator*(float f) const;
|
||||
// matrix scaling/assignment
|
||||
CMatrix3D& operator*=(float f);
|
||||
// matrix addition
|
||||
CMatrix3D operator+(const CMatrix3D &matrix) const;
|
||||
// matrix addition/assignment
|
||||
CMatrix3D& operator+=(const CMatrix3D &matrix);
|
||||
|
||||
// set this matrix to the identity matrix
|
||||
void SetIdentity();
|
||||
// set this matrix to the zero matrix
|
||||
void SetZero();
|
||||
|
||||
// concatenate arbitrary matrix onto this matrix
|
||||
void Concatenate(const CMatrix3D& m);
|
||||
|
||||
// set this matrix to a rotation matrix for a rotation about X axis of given angle
|
||||
void SetXRotation(float angle);
|
||||
// set this matrix to a rotation matrix for a rotation about Y axis of given angle
|
||||
void SetYRotation(float angle);
|
||||
// set this matrix to a rotation matrix for a rotation about Z axis of given angle
|
||||
void SetZRotation(float angle);
|
||||
// set this matrix to a rotation described by given quaternion
|
||||
void SetRotation(const CQuaternion& quat);
|
||||
|
||||
// concatentate a rotation about the X axis onto this matrix
|
||||
void RotateX(float angle);
|
||||
// concatentate a rotation about the Y axis onto this matrix
|
||||
void RotateY(float angle);
|
||||
// concatentate a rotation about the Z axis onto this matrix
|
||||
void RotateZ(float angle);
|
||||
// concatentate a rotation described by given quaternion
|
||||
void Rotate(const CQuaternion& quat);
|
||||
|
||||
// set this matrix to given translation
|
||||
void SetTranslation(float x, float y, float z);
|
||||
void SetTranslation(const CVector3D& vector);
|
||||
|
||||
// concatenate given translation onto this matrix
|
||||
void Translate(float x, float y, float z);
|
||||
void Translate(const CVector3D& vector);
|
||||
|
||||
// set this matrix to the given scaling matrix
|
||||
void SetScaling(float x_scale, float y_scale, float z_scale);
|
||||
|
||||
// concatentate given scaling matrix onto this matrix
|
||||
void Scale(float x_scale, float y_scale, float z_scale);
|
||||
|
||||
// calculate the inverse of this matrix, store in dst
|
||||
void GetInverse(CMatrix3D& dst) const;
|
||||
|
||||
// calculate the transpose of this matrix, store in dst
|
||||
void GetTranspose(CMatrix3D& dst) const;
|
||||
|
||||
// return the translation component of this matrix
|
||||
CVector3D GetTranslation() const;
|
||||
// return left vector, derived from rotation
|
||||
CVector3D GetLeft() const;
|
||||
// return up vector, derived from rotation
|
||||
CVector3D GetUp() const;
|
||||
// return forward vector, derived from rotation
|
||||
CVector3D GetIn() const;
|
||||
|
||||
// transform a 3D vector by this matrix
|
||||
void Transform(const CVector3D &vector,CVector3D& result) const;
|
||||
CVector3D Transform(const CVector3D &vector) const;
|
||||
// transform a 4D vector by this matrix
|
||||
void Transform(const CVector4D &vector,CVector4D& result) const;
|
||||
CVector4D Transform(const CVector4D &vector) const;
|
||||
// rotate a vector by this matrix
|
||||
void Rotate(const CVector3D& vector,CVector3D& result) const;
|
||||
CVector3D Rotate(const CVector3D& vector) const;
|
||||
// rotate a vector by the transpose of this matrix
|
||||
void RotateTransposed(const CVector3D& vector,CVector3D& result) const;
|
||||
CVector3D RotateTransposed(const CVector3D& vector) const;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -187,16 +187,16 @@ void CQuaternion::Slerp(const CQuaternion& from,const CQuaternion& to, float rat
|
||||
m_V.Z = scale0 * from.m_V.Z + scale1 * to1[2];
|
||||
m_W = scale0 * from.m_W + scale1 * to1[3];
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// FromAxisAngle: create a quaternion from axis/angle representation of a rotation
|
||||
void CQuaternion::FromAxisAngle(const CVector3D& axis,float angle)
|
||||
{
|
||||
float sinHalfTheta=(float) sin(angle/2);
|
||||
float cosHalfTheta=(float) cos(angle/2);
|
||||
|
||||
m_V.X=axis.X*sinHalfTheta;
|
||||
m_V.Y=axis.Y*sinHalfTheta;
|
||||
m_V.Z=axis.Z*sinHalfTheta;
|
||||
m_W=cosHalfTheta;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// FromAxisAngle: create a quaternion from axis/angle representation of a rotation
|
||||
void CQuaternion::FromAxisAngle(const CVector3D& axis,float angle)
|
||||
{
|
||||
float sinHalfTheta=(float) sin(angle/2);
|
||||
float cosHalfTheta=(float) cos(angle/2);
|
||||
|
||||
m_V.X=axis.X*sinHalfTheta;
|
||||
m_V.Y=axis.Y*sinHalfTheta;
|
||||
m_V.Z=axis.Z*sinHalfTheta;
|
||||
m_W=cosHalfTheta;
|
||||
}
|
||||
|
@ -37,10 +37,10 @@ public:
|
||||
void ToMatrix(CMatrix3D& result) const;
|
||||
|
||||
//sphere interpolation
|
||||
void Slerp(const CQuaternion& from,const CQuaternion& to, float ratio);
|
||||
|
||||
// create a quaternion from axis/angle representation of a rotation
|
||||
void FromAxisAngle(const CVector3D& axis,float angle);
|
||||
void Slerp(const CQuaternion& from,const CQuaternion& to, float ratio);
|
||||
|
||||
// create a quaternion from axis/angle representation of a rotation
|
||||
void FromAxisAngle(const CVector3D& axis,float angle);
|
||||
|
||||
};
|
||||
|
||||
|
@ -35,10 +35,10 @@ struct CColor
|
||||
float r, g, b, a;
|
||||
};
|
||||
|
||||
// yuck - MFC already defines CRect/CSize classes ...
|
||||
#define CRect PS_CRect
|
||||
#define CSize PS_CSize
|
||||
|
||||
// yuck - MFC already defines CRect/CSize classes ...
|
||||
#define CRect PS_CRect
|
||||
#define CSize PS_CSize
|
||||
|
||||
class CPos;
|
||||
class CSize;
|
||||
|
||||
|
@ -1,261 +1,261 @@
|
||||
#include <assert.h>
|
||||
#include <algorithm>
|
||||
#include "res/tex.h"
|
||||
#include "Renderer.h"
|
||||
#include "TransparencyRenderer.h"
|
||||
#include "ModelRData.h"
|
||||
#include "Model.h"
|
||||
|
||||
|
||||
CModelRData::CModelRData(CModel* model)
|
||||
: m_Model(model), m_Vertices(0), m_Normals(0), m_Indices(0), m_VB(0), m_Flags(0)
|
||||
{
|
||||
assert(model);
|
||||
// build all data now
|
||||
Build();
|
||||
}
|
||||
|
||||
CModelRData::~CModelRData()
|
||||
{
|
||||
delete[] m_Indices;
|
||||
delete[] m_Vertices;
|
||||
delete[] m_Normals;
|
||||
if (m_VB) {
|
||||
glGenBuffersARB(1,(GLuint*) &m_VB);
|
||||
}
|
||||
}
|
||||
|
||||
void CModelRData::Build()
|
||||
{
|
||||
// build data
|
||||
BuildVertices();
|
||||
BuildIndices();
|
||||
// force a texture load on models texture
|
||||
g_Renderer.LoadTexture(m_Model->GetTexture(),GL_CLAMP_TO_EDGE);
|
||||
// setup model render flags
|
||||
if (g_Renderer.IsTextureTransparent(m_Model->GetTexture())) {
|
||||
m_Flags|=MODELRDATA_FLAG_TRANSPARENT;
|
||||
}
|
||||
}
|
||||
|
||||
void CModelRData::BuildIndices()
|
||||
{
|
||||
CModelDef* mdef=m_Model->GetModelDef();
|
||||
|
||||
// allocate indices if we haven't got any already
|
||||
if (!m_Indices) {
|
||||
m_Indices=new u16[mdef->GetNumFaces()*3];
|
||||
}
|
||||
|
||||
// build indices
|
||||
u32 indices=0;
|
||||
SModelFace* faces=mdef->GetFaces();
|
||||
for (int j=0; j<mdef->GetNumFaces(); j++) {
|
||||
SModelFace& face=faces[j];
|
||||
m_Indices[indices++]=face.m_Verts[0];
|
||||
m_Indices[indices++]=face.m_Verts[1];
|
||||
m_Indices[indices++]=face.m_Verts[2];
|
||||
}
|
||||
}
|
||||
|
||||
inline int clamp(int x,int min,int max)
|
||||
{
|
||||
if (x<min) return min;
|
||||
else if (x>max) return max;
|
||||
else return x;
|
||||
}
|
||||
|
||||
static SColor4ub ConvertColor(const RGBColor& src)
|
||||
{
|
||||
SColor4ub result;
|
||||
result.R=clamp(int(src.X*255),0,255);
|
||||
result.G=clamp(int(src.Y*255),0,255);
|
||||
result.B=clamp(int(src.Z*255),0,255);
|
||||
result.A=0xff;
|
||||
return result;
|
||||
}
|
||||
|
||||
static CVector3D SkinPoint(const SModelVertex& vertex,const CMatrix3D* matrices)
|
||||
{
|
||||
CVector3D result(0,0,0),tmp;
|
||||
|
||||
for (u32 i=0;vertex.m_Blend.m_Bone[i]!=0xff && i<SVertexBlend::SIZE;i++) {
|
||||
const CMatrix3D& m=matrices[vertex.m_Blend.m_Bone[i]];
|
||||
m.Transform(vertex.m_Coords,tmp);
|
||||
result+=tmp*vertex.m_Blend.m_Weight[i];
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static CVector3D SkinNormal(const SModelVertex& vertex,const CMatrix3D* invmatrices)
|
||||
{
|
||||
CVector3D result(0,0,0),tmp;
|
||||
|
||||
for (u32 i=0;vertex.m_Blend.m_Bone[i]!=0xff && i<SVertexBlend::SIZE;i++) {
|
||||
const CMatrix3D& m=invmatrices[vertex.m_Blend.m_Bone[i]];
|
||||
m.RotateTransposed(vertex.m_Norm,tmp);
|
||||
result+=tmp*vertex.m_Blend.m_Weight[i];
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void CModelRData::BuildVertices()
|
||||
{
|
||||
CModelDef* mdef=m_Model->GetModelDef();
|
||||
|
||||
// allocate vertices if we haven't got any already
|
||||
if (!m_Vertices) {
|
||||
m_Vertices=new SVertex[mdef->GetNumVertices()];
|
||||
m_Normals=new CVector3D[mdef->GetNumVertices()];
|
||||
}
|
||||
|
||||
// build vertices
|
||||
u32 numVertices=mdef->GetNumVertices();
|
||||
SModelVertex* vertices=mdef->GetVertices();
|
||||
if (m_Model->GetBoneMatrices()) {
|
||||
// boned model - calculate skinned vertex positions/normals
|
||||
for (uint j=0; j<numVertices; j++) {
|
||||
m_Vertices[j].m_Position=SkinPoint(vertices[j],m_Model->GetBoneMatrices());
|
||||
m_Normals[j]=SkinNormal(vertices[j],m_Model->GetInvBoneMatrices());
|
||||
}
|
||||
} else {
|
||||
// just copy regular positions, transform normals to world space
|
||||
const CMatrix3D& trans=m_Model->GetInvTransform();
|
||||
for (uint j=0; j<numVertices; j++) {
|
||||
m_Vertices[j].m_Position=vertices[j].m_Coords;
|
||||
m_Normals[j]=trans.RotateTransposed(vertices[j].m_Norm);
|
||||
}
|
||||
}
|
||||
|
||||
// now fill in UV and vertex colour data
|
||||
for (uint j=0; j<numVertices; j++) {
|
||||
m_Vertices[j].m_UVs[0]=vertices[j].m_U;
|
||||
m_Vertices[j].m_UVs[1]=1-vertices[j].m_V;
|
||||
g_Renderer.m_SHCoeffsUnits.Evaluate(m_Normals[j],m_Vertices[j].m_Color);
|
||||
}
|
||||
|
||||
if (g_Renderer.m_Caps.m_VBO) {
|
||||
if (!m_VB) {
|
||||
glGenBuffersARB(1,(GLuint*) &m_VB);
|
||||
glBindBufferARB(GL_ARRAY_BUFFER_ARB,m_VB);
|
||||
glBufferDataARB(GL_ARRAY_BUFFER_ARB,mdef->GetNumVertices()*sizeof(SVertex),0,mdef->GetNumBones() ? GL_DYNAMIC_DRAW_ARB : GL_STATIC_DRAW_ARB);
|
||||
}
|
||||
glBindBufferARB(GL_ARRAY_BUFFER_ARB,m_VB);
|
||||
glBufferSubDataARB(GL_ARRAY_BUFFER_ARB,0,mdef->GetNumVertices()*sizeof(SVertex),m_Vertices);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CModelRData::RenderStreams(u32 streamflags,bool transparentPass)
|
||||
{
|
||||
// ignore transparent passes if this is a transparent object
|
||||
if (!transparentPass && (m_Flags & MODELRDATA_FLAG_TRANSPARENT)) {
|
||||
return;
|
||||
}
|
||||
|
||||
CModelDef* mdldef=(CModelDef*) m_Model->GetModelDef();
|
||||
|
||||
if (streamflags & STREAM_UV0) g_Renderer.SetTexture(0,m_Model->GetTexture());
|
||||
|
||||
u8* base;
|
||||
if (g_Renderer.m_Caps.m_VBO) {
|
||||
glBindBufferARB(GL_ARRAY_BUFFER_ARB,m_VB);
|
||||
base=0;
|
||||
} else {
|
||||
base=(u8*) &m_Vertices[0];
|
||||
}
|
||||
|
||||
// set vertex pointers
|
||||
u32 stride=sizeof(SVertex);
|
||||
glVertexPointer(3,GL_FLOAT,stride,base+offsetof(SVertex,m_Position));
|
||||
if (streamflags & STREAM_COLOR) glColorPointer(3,GL_FLOAT,stride,base+offsetof(SVertex,m_Color));
|
||||
if (streamflags & STREAM_UV0) glTexCoordPointer(2,GL_FLOAT,stride,base+offsetof(SVertex,m_UVs));
|
||||
|
||||
// render the lot
|
||||
u32 numFaces=mdldef->GetNumFaces();
|
||||
// glDrawRangeElements(GL_TRIANGLES,0,mdldef->GetNumVertices(),numFaces*3,GL_UNSIGNED_SHORT,m_Indices);
|
||||
glDrawElements(GL_TRIANGLES,numFaces*3,GL_UNSIGNED_SHORT,m_Indices);
|
||||
|
||||
// bump stats
|
||||
g_Renderer.m_Stats.m_DrawCalls++;
|
||||
if (transparentPass) {
|
||||
g_Renderer.m_Stats.m_TransparentTris+=numFaces;
|
||||
} else {
|
||||
g_Renderer.m_Stats.m_ModelTris+=numFaces;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CModelRData::Update()
|
||||
{
|
||||
if (m_UpdateFlags!=0) {
|
||||
// renderdata changed : rebuild necessary portions
|
||||
if (m_UpdateFlags & RENDERDATA_UPDATE_VERTICES) {
|
||||
BuildVertices();
|
||||
}
|
||||
if (m_UpdateFlags & RENDERDATA_UPDATE_INDICES) {
|
||||
BuildIndices();
|
||||
}
|
||||
|
||||
m_UpdateFlags=0;
|
||||
}
|
||||
}
|
||||
|
||||
typedef std::pair<int,float> IntFloatPair;
|
||||
static std::vector<IntFloatPair> IndexSorter;
|
||||
|
||||
struct SortFacesByDist {
|
||||
bool operator()(const IntFloatPair& lhs,const IntFloatPair& rhs) {
|
||||
return lhs.second>rhs.second ? true : false;
|
||||
}
|
||||
};
|
||||
|
||||
float CModelRData::BackToFrontIndexSort(CMatrix3D& objToCam)
|
||||
{
|
||||
float mindist=1.0e30f;
|
||||
CVector3D osvtx,csvtx;
|
||||
|
||||
CModelDef* mdldef=(CModelDef*) m_Model->GetModelDef();
|
||||
|
||||
SModelVertex* vtxs=mdldef->GetVertices();
|
||||
|
||||
u32 numFaces=mdldef->GetNumFaces();
|
||||
SModelFace* faces=mdldef->GetFaces();
|
||||
|
||||
IndexSorter.reserve(numFaces);
|
||||
|
||||
SModelFace* facePtr=faces;
|
||||
u32 i;
|
||||
for (i=0;i<numFaces;i++)
|
||||
{
|
||||
osvtx=vtxs[facePtr->m_Verts[0]].m_Coords;
|
||||
osvtx+=vtxs[facePtr->m_Verts[1]].m_Coords;
|
||||
osvtx+=vtxs[facePtr->m_Verts[2]].m_Coords;
|
||||
osvtx*=1.0f/3.0f;
|
||||
|
||||
csvtx=objToCam.Transform(osvtx);
|
||||
float distsqrd=SQR(csvtx.X)+SQR(csvtx.Y)+SQR(csvtx.Z);
|
||||
if (distsqrd<mindist) mindist=distsqrd;
|
||||
|
||||
IndexSorter.push_back(IntFloatPair(i,distsqrd));
|
||||
facePtr++;
|
||||
}
|
||||
|
||||
std::sort(IndexSorter.begin(),IndexSorter.end(),SortFacesByDist());
|
||||
|
||||
// now build index list
|
||||
u32 indices=0;
|
||||
for (i=0;i<numFaces;i++) {
|
||||
SModelFace& face=faces[IndexSorter[i].first];
|
||||
m_Indices[indices++]=face.m_Verts[0];
|
||||
m_Indices[indices++]=face.m_Verts[1];
|
||||
m_Indices[indices++]=face.m_Verts[2];
|
||||
}
|
||||
|
||||
// clear list for next call
|
||||
IndexSorter.clear();
|
||||
|
||||
return mindist;
|
||||
}
|
||||
#include <assert.h>
|
||||
#include <algorithm>
|
||||
#include "res/tex.h"
|
||||
#include "Renderer.h"
|
||||
#include "TransparencyRenderer.h"
|
||||
#include "ModelRData.h"
|
||||
#include "Model.h"
|
||||
|
||||
|
||||
CModelRData::CModelRData(CModel* model)
|
||||
: m_Model(model), m_Vertices(0), m_Normals(0), m_Indices(0), m_VB(0), m_Flags(0)
|
||||
{
|
||||
assert(model);
|
||||
// build all data now
|
||||
Build();
|
||||
}
|
||||
|
||||
CModelRData::~CModelRData()
|
||||
{
|
||||
delete[] m_Indices;
|
||||
delete[] m_Vertices;
|
||||
delete[] m_Normals;
|
||||
if (m_VB) {
|
||||
glGenBuffersARB(1,(GLuint*) &m_VB);
|
||||
}
|
||||
}
|
||||
|
||||
void CModelRData::Build()
|
||||
{
|
||||
// build data
|
||||
BuildVertices();
|
||||
BuildIndices();
|
||||
// force a texture load on models texture
|
||||
g_Renderer.LoadTexture(m_Model->GetTexture(),GL_CLAMP_TO_EDGE);
|
||||
// setup model render flags
|
||||
if (g_Renderer.IsTextureTransparent(m_Model->GetTexture())) {
|
||||
m_Flags|=MODELRDATA_FLAG_TRANSPARENT;
|
||||
}
|
||||
}
|
||||
|
||||
void CModelRData::BuildIndices()
|
||||
{
|
||||
CModelDef* mdef=m_Model->GetModelDef();
|
||||
|
||||
// allocate indices if we haven't got any already
|
||||
if (!m_Indices) {
|
||||
m_Indices=new u16[mdef->GetNumFaces()*3];
|
||||
}
|
||||
|
||||
// build indices
|
||||
u32 indices=0;
|
||||
SModelFace* faces=mdef->GetFaces();
|
||||
for (int j=0; j<mdef->GetNumFaces(); j++) {
|
||||
SModelFace& face=faces[j];
|
||||
m_Indices[indices++]=face.m_Verts[0];
|
||||
m_Indices[indices++]=face.m_Verts[1];
|
||||
m_Indices[indices++]=face.m_Verts[2];
|
||||
}
|
||||
}
|
||||
|
||||
inline int clamp(int x,int min,int max)
|
||||
{
|
||||
if (x<min) return min;
|
||||
else if (x>max) return max;
|
||||
else return x;
|
||||
}
|
||||
|
||||
static SColor4ub ConvertColor(const RGBColor& src)
|
||||
{
|
||||
SColor4ub result;
|
||||
result.R=clamp(int(src.X*255),0,255);
|
||||
result.G=clamp(int(src.Y*255),0,255);
|
||||
result.B=clamp(int(src.Z*255),0,255);
|
||||
result.A=0xff;
|
||||
return result;
|
||||
}
|
||||
|
||||
static CVector3D SkinPoint(const SModelVertex& vertex,const CMatrix3D* matrices)
|
||||
{
|
||||
CVector3D result(0,0,0),tmp;
|
||||
|
||||
for (u32 i=0;vertex.m_Blend.m_Bone[i]!=0xff && i<SVertexBlend::SIZE;i++) {
|
||||
const CMatrix3D& m=matrices[vertex.m_Blend.m_Bone[i]];
|
||||
m.Transform(vertex.m_Coords,tmp);
|
||||
result+=tmp*vertex.m_Blend.m_Weight[i];
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static CVector3D SkinNormal(const SModelVertex& vertex,const CMatrix3D* invmatrices)
|
||||
{
|
||||
CVector3D result(0,0,0),tmp;
|
||||
|
||||
for (u32 i=0;vertex.m_Blend.m_Bone[i]!=0xff && i<SVertexBlend::SIZE;i++) {
|
||||
const CMatrix3D& m=invmatrices[vertex.m_Blend.m_Bone[i]];
|
||||
m.RotateTransposed(vertex.m_Norm,tmp);
|
||||
result+=tmp*vertex.m_Blend.m_Weight[i];
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void CModelRData::BuildVertices()
|
||||
{
|
||||
CModelDef* mdef=m_Model->GetModelDef();
|
||||
|
||||
// allocate vertices if we haven't got any already
|
||||
if (!m_Vertices) {
|
||||
m_Vertices=new SVertex[mdef->GetNumVertices()];
|
||||
m_Normals=new CVector3D[mdef->GetNumVertices()];
|
||||
}
|
||||
|
||||
// build vertices
|
||||
u32 numVertices=mdef->GetNumVertices();
|
||||
SModelVertex* vertices=mdef->GetVertices();
|
||||
if (m_Model->GetBoneMatrices()) {
|
||||
// boned model - calculate skinned vertex positions/normals
|
||||
for (uint j=0; j<numVertices; j++) {
|
||||
m_Vertices[j].m_Position=SkinPoint(vertices[j],m_Model->GetBoneMatrices());
|
||||
m_Normals[j]=SkinNormal(vertices[j],m_Model->GetInvBoneMatrices());
|
||||
}
|
||||
} else {
|
||||
// just copy regular positions, transform normals to world space
|
||||
const CMatrix3D& trans=m_Model->GetInvTransform();
|
||||
for (uint j=0; j<numVertices; j++) {
|
||||
m_Vertices[j].m_Position=vertices[j].m_Coords;
|
||||
m_Normals[j]=trans.RotateTransposed(vertices[j].m_Norm);
|
||||
}
|
||||
}
|
||||
|
||||
// now fill in UV and vertex colour data
|
||||
for (uint j=0; j<numVertices; j++) {
|
||||
m_Vertices[j].m_UVs[0]=vertices[j].m_U;
|
||||
m_Vertices[j].m_UVs[1]=1-vertices[j].m_V;
|
||||
g_Renderer.m_SHCoeffsUnits.Evaluate(m_Normals[j],m_Vertices[j].m_Color);
|
||||
}
|
||||
|
||||
if (g_Renderer.m_Caps.m_VBO) {
|
||||
if (!m_VB) {
|
||||
glGenBuffersARB(1,(GLuint*) &m_VB);
|
||||
glBindBufferARB(GL_ARRAY_BUFFER_ARB,m_VB);
|
||||
glBufferDataARB(GL_ARRAY_BUFFER_ARB,mdef->GetNumVertices()*sizeof(SVertex),0,mdef->GetNumBones() ? GL_DYNAMIC_DRAW_ARB : GL_STATIC_DRAW_ARB);
|
||||
}
|
||||
glBindBufferARB(GL_ARRAY_BUFFER_ARB,m_VB);
|
||||
glBufferSubDataARB(GL_ARRAY_BUFFER_ARB,0,mdef->GetNumVertices()*sizeof(SVertex),m_Vertices);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CModelRData::RenderStreams(u32 streamflags,bool transparentPass)
|
||||
{
|
||||
// ignore transparent passes if this is a transparent object
|
||||
if (!transparentPass && (m_Flags & MODELRDATA_FLAG_TRANSPARENT)) {
|
||||
return;
|
||||
}
|
||||
|
||||
CModelDef* mdldef=(CModelDef*) m_Model->GetModelDef();
|
||||
|
||||
if (streamflags & STREAM_UV0) g_Renderer.SetTexture(0,m_Model->GetTexture());
|
||||
|
||||
u8* base;
|
||||
if (g_Renderer.m_Caps.m_VBO) {
|
||||
glBindBufferARB(GL_ARRAY_BUFFER_ARB,m_VB);
|
||||
base=0;
|
||||
} else {
|
||||
base=(u8*) &m_Vertices[0];
|
||||
}
|
||||
|
||||
// set vertex pointers
|
||||
u32 stride=sizeof(SVertex);
|
||||
glVertexPointer(3,GL_FLOAT,stride,base+offsetof(SVertex,m_Position));
|
||||
if (streamflags & STREAM_COLOR) glColorPointer(3,GL_FLOAT,stride,base+offsetof(SVertex,m_Color));
|
||||
if (streamflags & STREAM_UV0) glTexCoordPointer(2,GL_FLOAT,stride,base+offsetof(SVertex,m_UVs));
|
||||
|
||||
// render the lot
|
||||
u32 numFaces=mdldef->GetNumFaces();
|
||||
// glDrawRangeElements(GL_TRIANGLES,0,mdldef->GetNumVertices(),numFaces*3,GL_UNSIGNED_SHORT,m_Indices);
|
||||
glDrawElements(GL_TRIANGLES,numFaces*3,GL_UNSIGNED_SHORT,m_Indices);
|
||||
|
||||
// bump stats
|
||||
g_Renderer.m_Stats.m_DrawCalls++;
|
||||
if (transparentPass) {
|
||||
g_Renderer.m_Stats.m_TransparentTris+=numFaces;
|
||||
} else {
|
||||
g_Renderer.m_Stats.m_ModelTris+=numFaces;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CModelRData::Update()
|
||||
{
|
||||
if (m_UpdateFlags!=0) {
|
||||
// renderdata changed : rebuild necessary portions
|
||||
if (m_UpdateFlags & RENDERDATA_UPDATE_VERTICES) {
|
||||
BuildVertices();
|
||||
}
|
||||
if (m_UpdateFlags & RENDERDATA_UPDATE_INDICES) {
|
||||
BuildIndices();
|
||||
}
|
||||
|
||||
m_UpdateFlags=0;
|
||||
}
|
||||
}
|
||||
|
||||
typedef std::pair<int,float> IntFloatPair;
|
||||
static std::vector<IntFloatPair> IndexSorter;
|
||||
|
||||
struct SortFacesByDist {
|
||||
bool operator()(const IntFloatPair& lhs,const IntFloatPair& rhs) {
|
||||
return lhs.second>rhs.second ? true : false;
|
||||
}
|
||||
};
|
||||
|
||||
float CModelRData::BackToFrontIndexSort(CMatrix3D& objToCam)
|
||||
{
|
||||
float mindist=1.0e30f;
|
||||
CVector3D osvtx,csvtx;
|
||||
|
||||
CModelDef* mdldef=(CModelDef*) m_Model->GetModelDef();
|
||||
|
||||
SModelVertex* vtxs=mdldef->GetVertices();
|
||||
|
||||
u32 numFaces=mdldef->GetNumFaces();
|
||||
SModelFace* faces=mdldef->GetFaces();
|
||||
|
||||
IndexSorter.reserve(numFaces);
|
||||
|
||||
SModelFace* facePtr=faces;
|
||||
u32 i;
|
||||
for (i=0;i<numFaces;i++)
|
||||
{
|
||||
osvtx=vtxs[facePtr->m_Verts[0]].m_Coords;
|
||||
osvtx+=vtxs[facePtr->m_Verts[1]].m_Coords;
|
||||
osvtx+=vtxs[facePtr->m_Verts[2]].m_Coords;
|
||||
osvtx*=1.0f/3.0f;
|
||||
|
||||
csvtx=objToCam.Transform(osvtx);
|
||||
float distsqrd=SQR(csvtx.X)+SQR(csvtx.Y)+SQR(csvtx.Z);
|
||||
if (distsqrd<mindist) mindist=distsqrd;
|
||||
|
||||
IndexSorter.push_back(IntFloatPair(i,distsqrd));
|
||||
facePtr++;
|
||||
}
|
||||
|
||||
std::sort(IndexSorter.begin(),IndexSorter.end(),SortFacesByDist());
|
||||
|
||||
// now build index list
|
||||
u32 indices=0;
|
||||
for (i=0;i<numFaces;i++) {
|
||||
SModelFace& face=faces[IndexSorter[i].first];
|
||||
m_Indices[indices++]=face.m_Verts[0];
|
||||
m_Indices[indices++]=face.m_Verts[1];
|
||||
m_Indices[indices++]=face.m_Verts[2];
|
||||
}
|
||||
|
||||
// clear list for next call
|
||||
IndexSorter.clear();
|
||||
|
||||
return mindist;
|
||||
}
|
||||
|
@ -4,10 +4,10 @@
|
||||
#include <vector>
|
||||
#include "res/res.h"
|
||||
#include "Vector3D.h"
|
||||
#include "Color.h"
|
||||
#include "Color.h"
|
||||
#include "RenderableObject.h"
|
||||
|
||||
#define MODELRDATA_FLAG_TRANSPARENT (1<<0)
|
||||
|
||||
#define MODELRDATA_FLAG_TRANSPARENT (1<<0)
|
||||
|
||||
class CModel;
|
||||
|
||||
@ -19,9 +19,9 @@ public:
|
||||
|
||||
void Update();
|
||||
void RenderStreams(u32 streamflags,bool transparentPass=false);
|
||||
|
||||
// return render flags for this model
|
||||
u32 GetFlags() const { return m_Flags; }
|
||||
|
||||
// return render flags for this model
|
||||
u32 GetFlags() const { return m_Flags; }
|
||||
|
||||
// sort indices of this object from back to front according to given
|
||||
// object to camera space transform; return sqrd distance to centre of nearest triangle
|
||||
@ -53,8 +53,8 @@ private:
|
||||
// transformed vertex normals - required for recalculating lighting on skinned models
|
||||
CVector3D* m_Normals;
|
||||
// model render indices
|
||||
u16* m_Indices;
|
||||
// model render flags
|
||||
u16* m_Indices;
|
||||
// model render flags
|
||||
u32 m_Flags;
|
||||
};
|
||||
|
||||
|
@ -1,385 +1,385 @@
|
||||
#include "pbuffer.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#include <gl/gl.h>
|
||||
#include <gl/glext.h>
|
||||
#include <gl/wglext.h>
|
||||
|
||||
static HDC lastDC;
|
||||
static HGLRC lastGLRC;
|
||||
|
||||
static bool GotExts=false;
|
||||
static PFNWGLCREATEPBUFFERARBPROC wglCreatePbufferARB=0;
|
||||
static PFNWGLGETPBUFFERDCARBPROC wglGetPbufferDCARB=0;
|
||||
static PFNWGLRELEASEPBUFFERDCARBPROC wglReleasePbufferDCARB=0;
|
||||
static PFNWGLDESTROYPBUFFERARBPROC wglDestroyPbufferARB=0;
|
||||
static PFNWGLQUERYPBUFFERARBPROC wglQueryPbufferARB=0;
|
||||
static PFNWGLGETPIXELFORMATATTRIBIVARBPROC wglGetPixelFormatAttribivARB=0;
|
||||
static PFNWGLGETPIXELFORMATATTRIBFVARBPROC wglGetPixelFormatAttribfvARB=0;
|
||||
static PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARB=0;
|
||||
|
||||
class PBuffer
|
||||
{
|
||||
public:
|
||||
enum { MAX_ATTRIBS = 32 };
|
||||
enum { MAX_PFORMATS = 256 };
|
||||
|
||||
PBuffer();
|
||||
~PBuffer();
|
||||
|
||||
void makeCurrent();
|
||||
|
||||
bool init(int width,int height,int doublebuffer,int colorbits,int depthbits,int stencilbits,
|
||||
int rendertextureformat=0,int rendertexturetarget=0,int havemipmaps=0);
|
||||
void close();
|
||||
|
||||
// return width,height of this pbuffer
|
||||
int GetWidth() const { return _width; }
|
||||
int GetHeight() const { return _height; }
|
||||
|
||||
private:
|
||||
HDC _hDC;
|
||||
HGLRC _hGLRC;
|
||||
HPBUFFERARB _hBuffer;
|
||||
int _width;
|
||||
int _height;
|
||||
int _doublebuffer;
|
||||
int _colorbits;
|
||||
int _depthbits;
|
||||
int _stencilbits;
|
||||
int _rendertextureformat;
|
||||
int _rendertexturetarget;
|
||||
int _havemipmaps;
|
||||
};
|
||||
|
||||
static PBuffer g_PBuffer;
|
||||
|
||||
PBuffer::PBuffer()
|
||||
: _width(0), _height(0), _hDC(0), _hGLRC(0), _hBuffer(0)
|
||||
{
|
||||
}
|
||||
|
||||
PBuffer::~PBuffer()
|
||||
{
|
||||
close();
|
||||
}
|
||||
|
||||
void PBuffer::close()
|
||||
{
|
||||
if (_hBuffer) {
|
||||
wglDeleteContext(_hGLRC);
|
||||
wglReleasePbufferDCARB(_hBuffer,_hDC);
|
||||
wglDestroyPbufferARB(_hBuffer);
|
||||
_hBuffer=0;
|
||||
}
|
||||
}
|
||||
|
||||
static void GetExts()
|
||||
{
|
||||
wglCreatePbufferARB=(PFNWGLCREATEPBUFFERARBPROC) wglGetProcAddress("wglCreatePbufferARB");
|
||||
wglGetPbufferDCARB=(PFNWGLGETPBUFFERDCARBPROC) wglGetProcAddress("wglGetPbufferDCARB");
|
||||
wglReleasePbufferDCARB=(PFNWGLRELEASEPBUFFERDCARBPROC) wglGetProcAddress("wglReleasePbufferDCARB");
|
||||
wglDestroyPbufferARB=(PFNWGLDESTROYPBUFFERARBPROC) wglGetProcAddress("wglDestroyPbufferARB");
|
||||
wglQueryPbufferARB=(PFNWGLQUERYPBUFFERARBPROC) wglGetProcAddress("wglQueryPbufferARB");
|
||||
wglGetPixelFormatAttribivARB=(PFNWGLGETPIXELFORMATATTRIBIVARBPROC) wglGetProcAddress("wglGetPixelFormatAttribivARB");
|
||||
wglGetPixelFormatAttribfvARB=(PFNWGLGETPIXELFORMATATTRIBFVARBPROC) wglGetProcAddress("wglGetPixelFormatAttribfvARB");
|
||||
wglChoosePixelFormatARB=(PFNWGLCHOOSEPIXELFORMATARBPROC) wglGetProcAddress("wglChoosePixelFormatARB");
|
||||
GotExts=true;
|
||||
}
|
||||
|
||||
// This function actually does the creation of the p-buffer.
|
||||
// It can only be called once a window has already been created.
|
||||
bool PBuffer::init(int width,int height,int doublebuffer,int colorbits,int depthbits,int stencilbits,
|
||||
int rendertextureformat,int rendertexturetarget,int havemipmaps)
|
||||
{
|
||||
if (!GotExts) {
|
||||
GetExts();
|
||||
}
|
||||
|
||||
// store requested parameters
|
||||
_width=width;
|
||||
_height=height;
|
||||
_doublebuffer=doublebuffer;
|
||||
_colorbits=colorbits;
|
||||
_depthbits=depthbits;
|
||||
_stencilbits=stencilbits;
|
||||
_rendertextureformat=rendertextureformat;
|
||||
_rendertexturetarget=rendertexturetarget;
|
||||
_havemipmaps=havemipmaps;
|
||||
|
||||
HDC hdc = wglGetCurrentDC();
|
||||
HGLRC hglrc = wglGetCurrentContext();
|
||||
|
||||
// build attributes
|
||||
int iattributes[2*PBuffer::MAX_ATTRIBS];
|
||||
memset(iattributes,0,sizeof(int)*2*MAX_ATTRIBS);
|
||||
float fattributes[2*PBuffer::MAX_ATTRIBS];
|
||||
memset(fattributes,0,sizeof(float)*2*MAX_ATTRIBS);
|
||||
|
||||
int niattribs=0;
|
||||
|
||||
// pixel format must be "p-buffer capable" ..
|
||||
iattributes[2*niattribs] = WGL_DRAW_TO_PBUFFER_ARB;
|
||||
iattributes[2*niattribs+1] = 1;
|
||||
niattribs++;
|
||||
|
||||
// .. use RGBA rather than index mode ..
|
||||
iattributes[2*niattribs] = WGL_PIXEL_TYPE_ARB;
|
||||
iattributes[2*niattribs+1] = WGL_TYPE_RGBA_ARB;
|
||||
niattribs++;
|
||||
|
||||
// .. setup double buffer ..
|
||||
iattributes[2*niattribs] = WGL_DOUBLE_BUFFER_ARB;
|
||||
iattributes[2*niattribs+1] = doublebuffer;
|
||||
niattribs++;
|
||||
|
||||
// .. setup color and alpha bits ..
|
||||
iattributes[2*niattribs] = WGL_COLOR_BITS_ARB;
|
||||
iattributes[2*niattribs+1] = colorbits;
|
||||
niattribs++;
|
||||
iattributes[2*niattribs] = WGL_ALPHA_BITS_ARB;
|
||||
iattributes[2*niattribs+1] = (colorbits==32) ? 8 : 0;
|
||||
niattribs++;
|
||||
|
||||
// .. setup depth/stencil buffer ..
|
||||
iattributes[2*niattribs] = WGL_DEPTH_BITS_ARB;
|
||||
iattributes[2*niattribs+1] = depthbits;
|
||||
niattribs++;
|
||||
iattributes[2*niattribs] = WGL_STENCIL_BITS_ARB;
|
||||
iattributes[2*niattribs+1] = stencilbits;
|
||||
niattribs++;
|
||||
|
||||
|
||||
// .. must support opengl (doh ..)
|
||||
iattributes[2*niattribs] = WGL_SUPPORT_OPENGL_ARB;
|
||||
iattributes[2*niattribs+1] = 1;
|
||||
niattribs++;
|
||||
|
||||
if (rendertextureformat!=0) {
|
||||
// pbuffer meant to be bound as an RGBA texture, so need a color plane
|
||||
iattributes[2*niattribs] = WGL_BIND_TO_TEXTURE_RGBA_ARB;
|
||||
iattributes[2*niattribs+1] = 1;
|
||||
niattribs++;
|
||||
}
|
||||
|
||||
int pformat[MAX_PFORMATS];
|
||||
unsigned int nformats;
|
||||
if (!wglChoosePixelFormatARB(hdc,iattributes,fattributes,MAX_PFORMATS,pformat,&nformats)) {
|
||||
// LOG << "PBuffer creation failed: wglChoosePixelFormatARB() returned 0\n";
|
||||
return false;
|
||||
}
|
||||
if (nformats<=0) {
|
||||
// LOG << "PBuffer creation failed: couldn't find a suitable pixel format\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
// Create the p-buffer.
|
||||
niattribs=0;
|
||||
memset(iattributes,0,sizeof(int)*2*MAX_ATTRIBS);
|
||||
if (rendertextureformat!=0) {
|
||||
|
||||
// set format
|
||||
iattributes[2*niattribs]=WGL_TEXTURE_FORMAT_ARB;
|
||||
iattributes[2*niattribs+1]=rendertextureformat;
|
||||
niattribs++;
|
||||
|
||||
// set target
|
||||
iattributes[2*niattribs]=WGL_TEXTURE_TARGET_ARB;
|
||||
iattributes[2*niattribs+1]=rendertexturetarget;
|
||||
niattribs++;
|
||||
|
||||
// mipmaps ..
|
||||
iattributes[2*niattribs] = WGL_MIPMAP_TEXTURE_ARB;
|
||||
iattributes[2*niattribs+1] = havemipmaps;
|
||||
niattribs++;
|
||||
|
||||
// ask to allocate the largest pbuffer it can, if it is
|
||||
// unable to allocate for the width and height
|
||||
iattributes[2*niattribs]=WGL_PBUFFER_LARGEST_ARB;
|
||||
iattributes[2*niattribs+1]=0;
|
||||
niattribs++;
|
||||
|
||||
}
|
||||
|
||||
_hBuffer=wglCreatePbufferARB(hdc,pformat[0],_width,_height,iattributes );
|
||||
if (!_hBuffer) {
|
||||
// LOG << "PBuffer creation failed: wglCreatePbufferARB returned 0\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get the device context.
|
||||
_hDC=wglGetPbufferDCARB(_hBuffer);
|
||||
if (!_hDC) {
|
||||
// LOG << "PBuffer creation failed: wglGetPbufferDCARB returned 0\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
// Create a gl context for the p-buffer.
|
||||
_hGLRC=wglCreateContext(_hDC);
|
||||
if (!_hGLRC) {
|
||||
// LOG << "PBuffer creation failed: wglCreateContext returned 0\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!wglShareLists(hglrc,_hGLRC)) {
|
||||
// LOG << "PBuffer creation failed: wglShareLists returned 0\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
// Determine the actual width and height we were able to create.
|
||||
wglQueryPbufferARB(_hBuffer,WGL_PBUFFER_WIDTH_ARB,&_width);
|
||||
wglQueryPbufferARB(_hBuffer,WGL_PBUFFER_HEIGHT_ARB,&_height);
|
||||
|
||||
// success ..
|
||||
// LOG << "PBuffer created: " << _width << " x " << _height << "\n";
|
||||
|
||||
// log out attributes of pbuffer's pixel format
|
||||
int values[MAX_ATTRIBS];
|
||||
int iatr[MAX_ATTRIBS] = { WGL_PIXEL_TYPE_ARB, WGL_COLOR_BITS_ARB,
|
||||
WGL_RED_BITS_ARB, WGL_GREEN_BITS_ARB, WGL_BLUE_BITS_ARB,
|
||||
WGL_ALPHA_BITS_ARB, WGL_DEPTH_BITS_ARB, WGL_STENCIL_BITS_ARB, WGL_ACCUM_BITS_ARB,
|
||||
WGL_DOUBLE_BUFFER_ARB, WGL_SUPPORT_OPENGL_ARB, WGL_ACCELERATION_ARB,
|
||||
WGL_BIND_TO_TEXTURE_RGBA_ARB, WGL_SAMPLE_BUFFERS_ARB, WGL_SAMPLES_ARB
|
||||
};
|
||||
|
||||
if (wglGetPixelFormatAttribivARB(hdc,pformat[0],0,15,iatr,values)) {
|
||||
// LOG << "\nPBuffer pixelformat (" << pformat[0] << "):\n";
|
||||
|
||||
if (values[0]==WGL_TYPE_COLORINDEX_ARB) {
|
||||
// LOG << " pixel type = WGL_TYPE_COLORINDEX_ARB\n";
|
||||
} else if (values[0]==WGL_TYPE_RGBA_ARB) {
|
||||
// LOG << " pixel type = WGL_TYPE_RGBA_ARB\n";
|
||||
} else {
|
||||
// LOG << " pixel type = UNKNOWN\n";
|
||||
}
|
||||
|
||||
// LOG << " color bits = " << values[1] << "\n";
|
||||
// LOG << " red = " << values[2] << "\n";
|
||||
// LOG << " green = " << values[3] << "\n";
|
||||
// LOG << " blue = " << values[4] << "\n";
|
||||
// LOG << " alpha = " << values[5] << "\n";
|
||||
// LOG << " depth bits = " << values[6] << "\n";
|
||||
// LOG << " stencil bits = " << values[7] << "\n";
|
||||
// LOG << " accum bits = " << values[8] << "\n";
|
||||
// LOG << " doublebuffer = " << values[9] << "\n";
|
||||
// LOG << " support opengl = " << values[10] << "\n";
|
||||
|
||||
if (values[11]==WGL_FULL_ACCELERATION_ARB) {
|
||||
// LOG << " acceleration = WGL_FULL_ACCELERATION_ARB\n";
|
||||
} else if (values[11]== WGL_GENERIC_ACCELERATION_ARB) {
|
||||
// LOG << " acceleration = WGL_GENERIC_ACCELERATION_ARB\n";
|
||||
} else {
|
||||
// LOG << " acceleration = UNKNOWN\n";
|
||||
}
|
||||
|
||||
// LOG << " bind to texture = " << values[12] << "\n\n";
|
||||
// LOG << " multisample = " << values[13] << "\n";
|
||||
if (values[13]) {
|
||||
// LOG << " sample buffers = " << values[14] << "\n\n";
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void PBuffer::makeCurrent()
|
||||
{
|
||||
lastGLRC=wglGetCurrentContext();
|
||||
lastDC=wglGetCurrentDC();
|
||||
|
||||
// check first for lost pbuffer
|
||||
int lost;
|
||||
wglQueryPbufferARB(_hBuffer,WGL_PBUFFER_LOST_ARB,&lost);
|
||||
|
||||
if (lost) {
|
||||
// ack .. have to recreate it ..
|
||||
close();
|
||||
if (!init(_width,_height,_doublebuffer,_colorbits,_depthbits,_stencilbits,
|
||||
_rendertextureformat,_rendertexturetarget,_havemipmaps)) {
|
||||
// oops .. couldn't rebuild it ..
|
||||
// LOG << "PBuffer lost; couldn't rebuild";
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!wglMakeCurrent(_hDC,_hGLRC)) {
|
||||
// LOG << "PBuffer::makeCurrent - failed to make pbuffer current";
|
||||
}
|
||||
}
|
||||
|
||||
void PBufferMakeCurrent()
|
||||
{
|
||||
g_PBuffer.makeCurrent();
|
||||
}
|
||||
|
||||
|
||||
bool isWGLExtensionSupported(const char *extension)
|
||||
{
|
||||
PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB=(PFNWGLGETEXTENSIONSSTRINGARBPROC) wglGetProcAddress("wglGetExtensionsStringARB");
|
||||
if (!wglGetExtensionsStringARB) {
|
||||
// no function to retrieve WGL extension : maybe worth looking in the regular extensions ..
|
||||
return false;
|
||||
}
|
||||
|
||||
static const char *extensions = NULL;
|
||||
const char *start;
|
||||
char *where, *terminator;
|
||||
|
||||
where = (char *) strchr(extension, ' ');
|
||||
if ((where) || (*extension == '\0'))
|
||||
return false;
|
||||
|
||||
if (!extensions)
|
||||
extensions = (const char *) wglGetExtensionsStringARB(wglGetCurrentDC());
|
||||
|
||||
start = extensions;
|
||||
for (;;) {
|
||||
where = (char *) strstr((const char *) start, extension);
|
||||
if (!where)
|
||||
break;
|
||||
|
||||
terminator = where + strlen(extension);
|
||||
if (where == start || *(where - 1) == ' ') {
|
||||
if (*terminator == ' ' || *terminator == '\0') {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
start = terminator;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void PBufferInit(int width,int height,int doublebuffer,int colorbits,int depthbits,int stencilbits,
|
||||
int rendertextureformat,int rendertexturetarget,int havemipmaps)
|
||||
{
|
||||
g_PBuffer.init(width,height,doublebuffer,colorbits,depthbits,stencilbits,
|
||||
rendertextureformat,rendertexturetarget,havemipmaps);
|
||||
}
|
||||
|
||||
void PBufferClose()
|
||||
{
|
||||
g_PBuffer.close();
|
||||
|
||||
}
|
||||
|
||||
void PBufferMakeUncurrent()
|
||||
{
|
||||
wglMakeCurrent(lastDC,lastGLRC);
|
||||
}
|
||||
|
||||
int PBufferWidth()
|
||||
{
|
||||
return g_PBuffer.GetWidth();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
bool PBufferQuery()
|
||||
{
|
||||
if (!isWGLExtensionSupported("WGL_ARB_pbuffer")) return false;
|
||||
if (!isWGLExtensionSupported("WGL_ARB_pixel_format")) return false;
|
||||
return true;
|
||||
}
|
||||
#include "pbuffer.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#include <gl/gl.h>
|
||||
#include <gl/glext.h>
|
||||
#include <gl/wglext.h>
|
||||
|
||||
static HDC lastDC;
|
||||
static HGLRC lastGLRC;
|
||||
|
||||
static bool GotExts=false;
|
||||
static PFNWGLCREATEPBUFFERARBPROC wglCreatePbufferARB=0;
|
||||
static PFNWGLGETPBUFFERDCARBPROC wglGetPbufferDCARB=0;
|
||||
static PFNWGLRELEASEPBUFFERDCARBPROC wglReleasePbufferDCARB=0;
|
||||
static PFNWGLDESTROYPBUFFERARBPROC wglDestroyPbufferARB=0;
|
||||
static PFNWGLQUERYPBUFFERARBPROC wglQueryPbufferARB=0;
|
||||
static PFNWGLGETPIXELFORMATATTRIBIVARBPROC wglGetPixelFormatAttribivARB=0;
|
||||
static PFNWGLGETPIXELFORMATATTRIBFVARBPROC wglGetPixelFormatAttribfvARB=0;
|
||||
static PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARB=0;
|
||||
|
||||
class PBuffer
|
||||
{
|
||||
public:
|
||||
enum { MAX_ATTRIBS = 32 };
|
||||
enum { MAX_PFORMATS = 256 };
|
||||
|
||||
PBuffer();
|
||||
~PBuffer();
|
||||
|
||||
void makeCurrent();
|
||||
|
||||
bool init(int width,int height,int doublebuffer,int colorbits,int depthbits,int stencilbits,
|
||||
int rendertextureformat=0,int rendertexturetarget=0,int havemipmaps=0);
|
||||
void close();
|
||||
|
||||
// return width,height of this pbuffer
|
||||
int GetWidth() const { return _width; }
|
||||
int GetHeight() const { return _height; }
|
||||
|
||||
private:
|
||||
HDC _hDC;
|
||||
HGLRC _hGLRC;
|
||||
HPBUFFERARB _hBuffer;
|
||||
int _width;
|
||||
int _height;
|
||||
int _doublebuffer;
|
||||
int _colorbits;
|
||||
int _depthbits;
|
||||
int _stencilbits;
|
||||
int _rendertextureformat;
|
||||
int _rendertexturetarget;
|
||||
int _havemipmaps;
|
||||
};
|
||||
|
||||
static PBuffer g_PBuffer;
|
||||
|
||||
PBuffer::PBuffer()
|
||||
: _width(0), _height(0), _hDC(0), _hGLRC(0), _hBuffer(0)
|
||||
{
|
||||
}
|
||||
|
||||
PBuffer::~PBuffer()
|
||||
{
|
||||
close();
|
||||
}
|
||||
|
||||
void PBuffer::close()
|
||||
{
|
||||
if (_hBuffer) {
|
||||
wglDeleteContext(_hGLRC);
|
||||
wglReleasePbufferDCARB(_hBuffer,_hDC);
|
||||
wglDestroyPbufferARB(_hBuffer);
|
||||
_hBuffer=0;
|
||||
}
|
||||
}
|
||||
|
||||
static void GetExts()
|
||||
{
|
||||
wglCreatePbufferARB=(PFNWGLCREATEPBUFFERARBPROC) wglGetProcAddress("wglCreatePbufferARB");
|
||||
wglGetPbufferDCARB=(PFNWGLGETPBUFFERDCARBPROC) wglGetProcAddress("wglGetPbufferDCARB");
|
||||
wglReleasePbufferDCARB=(PFNWGLRELEASEPBUFFERDCARBPROC) wglGetProcAddress("wglReleasePbufferDCARB");
|
||||
wglDestroyPbufferARB=(PFNWGLDESTROYPBUFFERARBPROC) wglGetProcAddress("wglDestroyPbufferARB");
|
||||
wglQueryPbufferARB=(PFNWGLQUERYPBUFFERARBPROC) wglGetProcAddress("wglQueryPbufferARB");
|
||||
wglGetPixelFormatAttribivARB=(PFNWGLGETPIXELFORMATATTRIBIVARBPROC) wglGetProcAddress("wglGetPixelFormatAttribivARB");
|
||||
wglGetPixelFormatAttribfvARB=(PFNWGLGETPIXELFORMATATTRIBFVARBPROC) wglGetProcAddress("wglGetPixelFormatAttribfvARB");
|
||||
wglChoosePixelFormatARB=(PFNWGLCHOOSEPIXELFORMATARBPROC) wglGetProcAddress("wglChoosePixelFormatARB");
|
||||
GotExts=true;
|
||||
}
|
||||
|
||||
// This function actually does the creation of the p-buffer.
|
||||
// It can only be called once a window has already been created.
|
||||
bool PBuffer::init(int width,int height,int doublebuffer,int colorbits,int depthbits,int stencilbits,
|
||||
int rendertextureformat,int rendertexturetarget,int havemipmaps)
|
||||
{
|
||||
if (!GotExts) {
|
||||
GetExts();
|
||||
}
|
||||
|
||||
// store requested parameters
|
||||
_width=width;
|
||||
_height=height;
|
||||
_doublebuffer=doublebuffer;
|
||||
_colorbits=colorbits;
|
||||
_depthbits=depthbits;
|
||||
_stencilbits=stencilbits;
|
||||
_rendertextureformat=rendertextureformat;
|
||||
_rendertexturetarget=rendertexturetarget;
|
||||
_havemipmaps=havemipmaps;
|
||||
|
||||
HDC hdc = wglGetCurrentDC();
|
||||
HGLRC hglrc = wglGetCurrentContext();
|
||||
|
||||
// build attributes
|
||||
int iattributes[2*PBuffer::MAX_ATTRIBS];
|
||||
memset(iattributes,0,sizeof(int)*2*MAX_ATTRIBS);
|
||||
float fattributes[2*PBuffer::MAX_ATTRIBS];
|
||||
memset(fattributes,0,sizeof(float)*2*MAX_ATTRIBS);
|
||||
|
||||
int niattribs=0;
|
||||
|
||||
// pixel format must be "p-buffer capable" ..
|
||||
iattributes[2*niattribs] = WGL_DRAW_TO_PBUFFER_ARB;
|
||||
iattributes[2*niattribs+1] = 1;
|
||||
niattribs++;
|
||||
|
||||
// .. use RGBA rather than index mode ..
|
||||
iattributes[2*niattribs] = WGL_PIXEL_TYPE_ARB;
|
||||
iattributes[2*niattribs+1] = WGL_TYPE_RGBA_ARB;
|
||||
niattribs++;
|
||||
|
||||
// .. setup double buffer ..
|
||||
iattributes[2*niattribs] = WGL_DOUBLE_BUFFER_ARB;
|
||||
iattributes[2*niattribs+1] = doublebuffer;
|
||||
niattribs++;
|
||||
|
||||
// .. setup color and alpha bits ..
|
||||
iattributes[2*niattribs] = WGL_COLOR_BITS_ARB;
|
||||
iattributes[2*niattribs+1] = colorbits;
|
||||
niattribs++;
|
||||
iattributes[2*niattribs] = WGL_ALPHA_BITS_ARB;
|
||||
iattributes[2*niattribs+1] = (colorbits==32) ? 8 : 0;
|
||||
niattribs++;
|
||||
|
||||
// .. setup depth/stencil buffer ..
|
||||
iattributes[2*niattribs] = WGL_DEPTH_BITS_ARB;
|
||||
iattributes[2*niattribs+1] = depthbits;
|
||||
niattribs++;
|
||||
iattributes[2*niattribs] = WGL_STENCIL_BITS_ARB;
|
||||
iattributes[2*niattribs+1] = stencilbits;
|
||||
niattribs++;
|
||||
|
||||
|
||||
// .. must support opengl (doh ..)
|
||||
iattributes[2*niattribs] = WGL_SUPPORT_OPENGL_ARB;
|
||||
iattributes[2*niattribs+1] = 1;
|
||||
niattribs++;
|
||||
|
||||
if (rendertextureformat!=0) {
|
||||
// pbuffer meant to be bound as an RGBA texture, so need a color plane
|
||||
iattributes[2*niattribs] = WGL_BIND_TO_TEXTURE_RGBA_ARB;
|
||||
iattributes[2*niattribs+1] = 1;
|
||||
niattribs++;
|
||||
}
|
||||
|
||||
int pformat[MAX_PFORMATS];
|
||||
unsigned int nformats;
|
||||
if (!wglChoosePixelFormatARB(hdc,iattributes,fattributes,MAX_PFORMATS,pformat,&nformats)) {
|
||||
// LOG << "PBuffer creation failed: wglChoosePixelFormatARB() returned 0\n";
|
||||
return false;
|
||||
}
|
||||
if (nformats<=0) {
|
||||
// LOG << "PBuffer creation failed: couldn't find a suitable pixel format\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
// Create the p-buffer.
|
||||
niattribs=0;
|
||||
memset(iattributes,0,sizeof(int)*2*MAX_ATTRIBS);
|
||||
if (rendertextureformat!=0) {
|
||||
|
||||
// set format
|
||||
iattributes[2*niattribs]=WGL_TEXTURE_FORMAT_ARB;
|
||||
iattributes[2*niattribs+1]=rendertextureformat;
|
||||
niattribs++;
|
||||
|
||||
// set target
|
||||
iattributes[2*niattribs]=WGL_TEXTURE_TARGET_ARB;
|
||||
iattributes[2*niattribs+1]=rendertexturetarget;
|
||||
niattribs++;
|
||||
|
||||
// mipmaps ..
|
||||
iattributes[2*niattribs] = WGL_MIPMAP_TEXTURE_ARB;
|
||||
iattributes[2*niattribs+1] = havemipmaps;
|
||||
niattribs++;
|
||||
|
||||
// ask to allocate the largest pbuffer it can, if it is
|
||||
// unable to allocate for the width and height
|
||||
iattributes[2*niattribs]=WGL_PBUFFER_LARGEST_ARB;
|
||||
iattributes[2*niattribs+1]=0;
|
||||
niattribs++;
|
||||
|
||||
}
|
||||
|
||||
_hBuffer=wglCreatePbufferARB(hdc,pformat[0],_width,_height,iattributes );
|
||||
if (!_hBuffer) {
|
||||
// LOG << "PBuffer creation failed: wglCreatePbufferARB returned 0\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get the device context.
|
||||
_hDC=wglGetPbufferDCARB(_hBuffer);
|
||||
if (!_hDC) {
|
||||
// LOG << "PBuffer creation failed: wglGetPbufferDCARB returned 0\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
// Create a gl context for the p-buffer.
|
||||
_hGLRC=wglCreateContext(_hDC);
|
||||
if (!_hGLRC) {
|
||||
// LOG << "PBuffer creation failed: wglCreateContext returned 0\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!wglShareLists(hglrc,_hGLRC)) {
|
||||
// LOG << "PBuffer creation failed: wglShareLists returned 0\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
// Determine the actual width and height we were able to create.
|
||||
wglQueryPbufferARB(_hBuffer,WGL_PBUFFER_WIDTH_ARB,&_width);
|
||||
wglQueryPbufferARB(_hBuffer,WGL_PBUFFER_HEIGHT_ARB,&_height);
|
||||
|
||||
// success ..
|
||||
// LOG << "PBuffer created: " << _width << " x " << _height << "\n";
|
||||
|
||||
// log out attributes of pbuffer's pixel format
|
||||
int values[MAX_ATTRIBS];
|
||||
int iatr[MAX_ATTRIBS] = { WGL_PIXEL_TYPE_ARB, WGL_COLOR_BITS_ARB,
|
||||
WGL_RED_BITS_ARB, WGL_GREEN_BITS_ARB, WGL_BLUE_BITS_ARB,
|
||||
WGL_ALPHA_BITS_ARB, WGL_DEPTH_BITS_ARB, WGL_STENCIL_BITS_ARB, WGL_ACCUM_BITS_ARB,
|
||||
WGL_DOUBLE_BUFFER_ARB, WGL_SUPPORT_OPENGL_ARB, WGL_ACCELERATION_ARB,
|
||||
WGL_BIND_TO_TEXTURE_RGBA_ARB, WGL_SAMPLE_BUFFERS_ARB, WGL_SAMPLES_ARB
|
||||
};
|
||||
|
||||
if (wglGetPixelFormatAttribivARB(hdc,pformat[0],0,15,iatr,values)) {
|
||||
// LOG << "\nPBuffer pixelformat (" << pformat[0] << "):\n";
|
||||
|
||||
if (values[0]==WGL_TYPE_COLORINDEX_ARB) {
|
||||
// LOG << " pixel type = WGL_TYPE_COLORINDEX_ARB\n";
|
||||
} else if (values[0]==WGL_TYPE_RGBA_ARB) {
|
||||
// LOG << " pixel type = WGL_TYPE_RGBA_ARB\n";
|
||||
} else {
|
||||
// LOG << " pixel type = UNKNOWN\n";
|
||||
}
|
||||
|
||||
// LOG << " color bits = " << values[1] << "\n";
|
||||
// LOG << " red = " << values[2] << "\n";
|
||||
// LOG << " green = " << values[3] << "\n";
|
||||
// LOG << " blue = " << values[4] << "\n";
|
||||
// LOG << " alpha = " << values[5] << "\n";
|
||||
// LOG << " depth bits = " << values[6] << "\n";
|
||||
// LOG << " stencil bits = " << values[7] << "\n";
|
||||
// LOG << " accum bits = " << values[8] << "\n";
|
||||
// LOG << " doublebuffer = " << values[9] << "\n";
|
||||
// LOG << " support opengl = " << values[10] << "\n";
|
||||
|
||||
if (values[11]==WGL_FULL_ACCELERATION_ARB) {
|
||||
// LOG << " acceleration = WGL_FULL_ACCELERATION_ARB\n";
|
||||
} else if (values[11]== WGL_GENERIC_ACCELERATION_ARB) {
|
||||
// LOG << " acceleration = WGL_GENERIC_ACCELERATION_ARB\n";
|
||||
} else {
|
||||
// LOG << " acceleration = UNKNOWN\n";
|
||||
}
|
||||
|
||||
// LOG << " bind to texture = " << values[12] << "\n\n";
|
||||
// LOG << " multisample = " << values[13] << "\n";
|
||||
if (values[13]) {
|
||||
// LOG << " sample buffers = " << values[14] << "\n\n";
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void PBuffer::makeCurrent()
|
||||
{
|
||||
lastGLRC=wglGetCurrentContext();
|
||||
lastDC=wglGetCurrentDC();
|
||||
|
||||
// check first for lost pbuffer
|
||||
int lost;
|
||||
wglQueryPbufferARB(_hBuffer,WGL_PBUFFER_LOST_ARB,&lost);
|
||||
|
||||
if (lost) {
|
||||
// ack .. have to recreate it ..
|
||||
close();
|
||||
if (!init(_width,_height,_doublebuffer,_colorbits,_depthbits,_stencilbits,
|
||||
_rendertextureformat,_rendertexturetarget,_havemipmaps)) {
|
||||
// oops .. couldn't rebuild it ..
|
||||
// LOG << "PBuffer lost; couldn't rebuild";
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!wglMakeCurrent(_hDC,_hGLRC)) {
|
||||
// LOG << "PBuffer::makeCurrent - failed to make pbuffer current";
|
||||
}
|
||||
}
|
||||
|
||||
void PBufferMakeCurrent()
|
||||
{
|
||||
g_PBuffer.makeCurrent();
|
||||
}
|
||||
|
||||
|
||||
bool isWGLExtensionSupported(const char *extension)
|
||||
{
|
||||
PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB=(PFNWGLGETEXTENSIONSSTRINGARBPROC) wglGetProcAddress("wglGetExtensionsStringARB");
|
||||
if (!wglGetExtensionsStringARB) {
|
||||
// no function to retrieve WGL extension : maybe worth looking in the regular extensions ..
|
||||
return false;
|
||||
}
|
||||
|
||||
static const char *extensions = NULL;
|
||||
const char *start;
|
||||
char *where, *terminator;
|
||||
|
||||
where = (char *) strchr(extension, ' ');
|
||||
if ((where) || (*extension == '\0'))
|
||||
return false;
|
||||
|
||||
if (!extensions)
|
||||
extensions = (const char *) wglGetExtensionsStringARB(wglGetCurrentDC());
|
||||
|
||||
start = extensions;
|
||||
for (;;) {
|
||||
where = (char *) strstr((const char *) start, extension);
|
||||
if (!where)
|
||||
break;
|
||||
|
||||
terminator = where + strlen(extension);
|
||||
if (where == start || *(where - 1) == ' ') {
|
||||
if (*terminator == ' ' || *terminator == '\0') {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
start = terminator;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void PBufferInit(int width,int height,int doublebuffer,int colorbits,int depthbits,int stencilbits,
|
||||
int rendertextureformat,int rendertexturetarget,int havemipmaps)
|
||||
{
|
||||
g_PBuffer.init(width,height,doublebuffer,colorbits,depthbits,stencilbits,
|
||||
rendertextureformat,rendertexturetarget,havemipmaps);
|
||||
}
|
||||
|
||||
void PBufferClose()
|
||||
{
|
||||
g_PBuffer.close();
|
||||
|
||||
}
|
||||
|
||||
void PBufferMakeUncurrent()
|
||||
{
|
||||
wglMakeCurrent(lastDC,lastGLRC);
|
||||
}
|
||||
|
||||
int PBufferWidth()
|
||||
{
|
||||
return g_PBuffer.GetWidth();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
bool PBufferQuery()
|
||||
{
|
||||
if (!isWGLExtensionSupported("WGL_ARB_pbuffer")) return false;
|
||||
if (!isWGLExtensionSupported("WGL_ARB_pixel_format")) return false;
|
||||
return true;
|
||||
}
|
||||
|
@ -1,12 +1,12 @@
|
||||
#ifndef _PBUFFER_H
|
||||
#define _PBUFFER_H
|
||||
|
||||
|
||||
extern void PBufferMakeCurrent();
|
||||
extern void PBufferInit(int width,int height,int doublebuffer,int colorbits,int depthbits,int stencilbits,
|
||||
int rendertextureformat=0,int rendertexturetarget=0,int havemipmaps=0);
|
||||
extern void PBufferClose();
|
||||
extern void PBufferMakeUncurrent();
|
||||
extern int PBufferWidth();
|
||||
|
||||
#endif
|
||||
#ifndef _PBUFFER_H
|
||||
#define _PBUFFER_H
|
||||
|
||||
|
||||
extern void PBufferMakeCurrent();
|
||||
extern void PBufferInit(int width,int height,int doublebuffer,int colorbits,int depthbits,int stencilbits,
|
||||
int rendertextureformat=0,int rendertexturetarget=0,int havemipmaps=0);
|
||||
extern void PBufferClose();
|
||||
extern void PBufferMakeUncurrent();
|
||||
extern int PBufferWidth();
|
||||
|
||||
#endif
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,312 +1,312 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Name: Renderer.h
|
||||
// Author: Rich Cross
|
||||
// Contact: rich@wildfiregames.com
|
||||
//
|
||||
// Description: OpenGL renderer class; a higher level interface
|
||||
// on top of OpenGL to handle rendering the basic visual games
|
||||
// types - terrain, models, sprites, particles etc
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef RENDERER_H
|
||||
#define RENDERER_H
|
||||
|
||||
#include <vector>
|
||||
#include "res/res.h"
|
||||
#include "ogl.h"
|
||||
#include "Camera.h"
|
||||
#include "Frustum.h"
|
||||
#include "PatchRData.h"
|
||||
#include "ModelRData.h"
|
||||
#include "SHCoeffs.h"
|
||||
#include "Terrain.h"
|
||||
#include "Singleton.h"
|
||||
|
||||
// necessary declarations
|
||||
class CCamera;
|
||||
class CPatch;
|
||||
class CSprite;
|
||||
class CParticleSys;
|
||||
class COverlay;
|
||||
class CMaterial;
|
||||
class CLightEnv;
|
||||
class CTexture;
|
||||
class CTerrain;
|
||||
|
||||
|
||||
// rendering modes
|
||||
enum ERenderMode { WIREFRAME, SOLID, EDGED_FACES };
|
||||
|
||||
// stream flags
|
||||
#define STREAM_POS 0x01
|
||||
#define STREAM_NORMAL 0x02
|
||||
#define STREAM_COLOR 0x04
|
||||
#define STREAM_UV0 0x08
|
||||
#define STREAM_UV1 0x10
|
||||
#define STREAM_UV2 0x20
|
||||
#define STREAM_UV3 0x40
|
||||
#define STREAM_POSTOUV0 0x80
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// SVertex3D: simple 3D vertex declaration
|
||||
struct SVertex3D
|
||||
{
|
||||
float m_Position[3];
|
||||
float m_TexCoords[2];
|
||||
unsigned int m_Color;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// SVertex2D: simple 2D vertex declaration
|
||||
struct SVertex2D
|
||||
{
|
||||
float m_Position[2];
|
||||
float m_TexCoords[2];
|
||||
unsigned int m_Color;
|
||||
};
|
||||
|
||||
// access to sole renderer object
|
||||
#define g_Renderer CRenderer::GetSingleton()
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CRenderer: base renderer class - primary interface to the rendering engine
|
||||
class CRenderer : public Singleton<CRenderer>
|
||||
{
|
||||
public:
|
||||
// various enumerations and renderer related constants
|
||||
enum { NumAlphaMaps=14 };
|
||||
enum { MaxTextureUnits=16 };
|
||||
enum Option {
|
||||
OPT_NOVBO,
|
||||
OPT_NOPBUFFER,
|
||||
OPT_SHADOWS,
|
||||
OPT_SHADOWCOLOR
|
||||
};
|
||||
|
||||
// stats class - per frame counts of number of draw calls, poly counts etc
|
||||
struct Stats {
|
||||
// set all stats to zero
|
||||
void Reset() { memset(this,0,sizeof(*this)); }
|
||||
// add given stats to this stats
|
||||
Stats& operator+=(const Stats& rhs) {
|
||||
m_Counter++;
|
||||
m_DrawCalls+=rhs.m_DrawCalls;
|
||||
m_TerrainTris+=rhs.m_TerrainTris;
|
||||
m_ModelTris+=rhs.m_ModelTris;
|
||||
m_TransparentTris+=rhs.m_TransparentTris;
|
||||
m_BlendSplats+=rhs.m_BlendSplats;
|
||||
return *this;
|
||||
}
|
||||
// count of the number of stats added together
|
||||
u32 m_Counter;
|
||||
// number of draw calls per frame - total DrawElements + Begin/End immediate mode loops
|
||||
u32 m_DrawCalls;
|
||||
// number of terrain triangles drawn
|
||||
u32 m_TerrainTris;
|
||||
// number of (non-transparent) model triangles drawn
|
||||
u32 m_ModelTris;
|
||||
// number of transparent model triangles drawn
|
||||
u32 m_TransparentTris;
|
||||
// number of splat passes for alphamapping
|
||||
u32 m_BlendSplats;
|
||||
};
|
||||
|
||||
public:
|
||||
// constructor, destructor
|
||||
CRenderer();
|
||||
~CRenderer();
|
||||
|
||||
// open up the renderer: performs any necessary initialisation
|
||||
bool Open(int width,int height,int depth);
|
||||
// shutdown the renderer: performs any necessary cleanup
|
||||
void Close();
|
||||
|
||||
// resize renderer view
|
||||
void Resize(int width,int height);
|
||||
|
||||
// set/get boolean renderer option
|
||||
void SetOptionBool(enum Option opt,bool value);
|
||||
bool GetOptionBool(enum Option opt) const;
|
||||
// set/get color renderer option
|
||||
void SetOptionColor(enum Option opt,const RGBColor& value);
|
||||
const RGBColor& GetOptionColor(enum Option opt) const;
|
||||
|
||||
// return view width
|
||||
int GetWidth() const { return m_Width; }
|
||||
// return view height
|
||||
int GetHeight() const { return m_Height; }
|
||||
// return view aspect ratio
|
||||
float GetAspect() const { return float(m_Width)/float(m_Height); }
|
||||
|
||||
// signal frame start
|
||||
void BeginFrame();
|
||||
// force rendering of any batched objects
|
||||
void FlushFrame();
|
||||
// signal frame end : implicitly flushes batched objects
|
||||
void EndFrame();
|
||||
|
||||
// set color used to clear screen in BeginFrame()
|
||||
void SetClearColor(u32 color);
|
||||
|
||||
// return current frame counter
|
||||
int GetFrameCounter() const { return m_FrameCounter; }
|
||||
|
||||
// set camera used for subsequent rendering operations; includes viewport, projection and modelview matrices
|
||||
void SetCamera(CCamera& camera);
|
||||
|
||||
// submission of objects for rendering; the passed matrix indicating the transform must be scoped such that it is valid beyond
|
||||
// the call to frame end, as must the object itself
|
||||
void Submit(CPatch* patch);
|
||||
void Submit(CModel* model);
|
||||
void Submit(CSprite* sprite);
|
||||
void Submit(CParticleSys* psys);
|
||||
void Submit(COverlay* overlay);
|
||||
|
||||
// basic primitive rendering operations in 2 and 3D; handy for debugging stuff, but also useful in
|
||||
// editor tools (eg for highlighting specific terrain patches)
|
||||
// note:
|
||||
// * all 3D vertices specified in world space
|
||||
// * primitive operations rendered immediatedly, never batched
|
||||
// * primitives rendered in current material (set via SetMaterial)
|
||||
void RenderLine(const SVertex2D* vertices);
|
||||
void RenderLineLoop(int len,const SVertex2D* vertices);
|
||||
void RenderTri(const SVertex2D* vertices);
|
||||
void RenderQuad(const SVertex2D* vertices);
|
||||
void RenderLine(const SVertex3D* vertices);
|
||||
void RenderLineLoop(int len,const SVertex3D* vertices);
|
||||
void RenderTri(const SVertex3D* vertices);
|
||||
void RenderQuad(const SVertex3D* vertices);
|
||||
|
||||
// set the current lighting environment; (note: the passed pointer is just copied to a variable within the renderer,
|
||||
// so the lightenv passed must be scoped such that it is not destructed until after the renderer is no longer rendering)
|
||||
void SetLightEnv(CLightEnv* lightenv) {
|
||||
m_LightEnv=lightenv;
|
||||
}
|
||||
|
||||
// set the mode to render subsequent terrain patches
|
||||
void SetTerrainRenderMode(ERenderMode mode) { m_TerrainRenderMode=mode; }
|
||||
// get the mode to render subsequent terrain patches
|
||||
ERenderMode GetTerrainRenderMode() const { return m_TerrainRenderMode; }
|
||||
|
||||
// set the mode to render subsequent models
|
||||
void SetModelRenderMode(ERenderMode mode) { m_ModelRenderMode=mode; }
|
||||
// get the mode to render subsequent models
|
||||
ERenderMode GetModelRenderMode() const { return m_ModelRenderMode; }
|
||||
|
||||
// try and load the given texture
|
||||
bool LoadTexture(CTexture* texture,u32 wrapflags);
|
||||
// set the given unit to reference the given texture; pass a null texture to disable texturing on any unit
|
||||
void SetTexture(int unit,CTexture* texture);
|
||||
// BindTexture: bind a GL texture object to given unit
|
||||
void BindTexture(int unit,GLuint tex);
|
||||
// query transparency of given texture
|
||||
bool IsTextureTransparent(CTexture* texture);
|
||||
|
||||
// load the default set of alphamaps; return false if any alphamap fails to load, true otherwise
|
||||
bool LoadAlphaMaps(const char* fnames[]);
|
||||
|
||||
// return stats accumulated for current frame
|
||||
const Stats& GetStats() { return m_Stats; }
|
||||
|
||||
protected:
|
||||
friend class CPatchRData;
|
||||
friend class CModelRData;
|
||||
friend class CTransparencyRenderer;
|
||||
|
||||
// recurse down given model building renderdata for it and all it's children
|
||||
void UpdateModelDataRecursive(CModel* model);
|
||||
// update renderdata of everything submitted
|
||||
void UpdateSubmittedObjectData();
|
||||
|
||||
// patch rendering stuff
|
||||
void RenderPatchSubmissions();
|
||||
void RenderPatches();
|
||||
|
||||
// model rendering stuff
|
||||
void BuildTransparentPasses(CModel* model);
|
||||
void RenderModelSubmissions();
|
||||
void RenderModelsRecursive(CModel* model,u32 streamflags);
|
||||
void RenderModelsStreams(u32 streamflags);
|
||||
void RenderModels();
|
||||
|
||||
// shadow rendering stuff
|
||||
void CreateShadowMap();
|
||||
void RenderShadowMap();
|
||||
void ApplyShadowMap();
|
||||
void CRenderer::BuildTransformation(const CVector3D& pos,const CVector3D& right,const CVector3D& up,
|
||||
const CVector3D& dir,CMatrix3D& result);
|
||||
void ConstructLightTransform(const CVector3D& pos,const CVector3D& lightdir,CMatrix3D& result);
|
||||
void CalcShadowMatrices();
|
||||
void CalcShadowBounds(CBound& bounds);
|
||||
|
||||
// RENDERER DATA:
|
||||
// view width
|
||||
int m_Width;
|
||||
// view height
|
||||
int m_Height;
|
||||
// view depth (bpp)
|
||||
int m_Depth;
|
||||
// frame counter
|
||||
int m_FrameCounter;
|
||||
// current terrain rendering mode
|
||||
ERenderMode m_TerrainRenderMode;
|
||||
// current model rendering mode
|
||||
ERenderMode m_ModelRenderMode;
|
||||
// current view camera
|
||||
CCamera m_Camera;
|
||||
// color used to clear screen in BeginFrame
|
||||
float m_ClearColor[4];
|
||||
// submitted object lists for batching
|
||||
std::vector<CPatch*> m_TerrainPatches;
|
||||
std::vector<CModel*> m_Models;
|
||||
std::vector<CSprite*> m_Sprites;
|
||||
std::vector<CParticleSys*> m_ParticleSyses;
|
||||
std::vector<COverlay*> m_Overlays;
|
||||
// current lighting setup
|
||||
CLightEnv* m_LightEnv;
|
||||
// current spherical harmonic coefficients (for unit lighting), derived from lightenv
|
||||
CSHCoeffs m_SHCoeffsUnits;
|
||||
// current spherical harmonic coefficients (for terrain lighting), derived from lightenv
|
||||
CSHCoeffs m_SHCoeffsTerrain;
|
||||
// handle of composite alpha map (all the alpha maps packed into one texture)
|
||||
u32 m_CompositeAlphaMap;
|
||||
// handle of shadow map
|
||||
u32 m_ShadowMap;
|
||||
// size of each side of shadow map
|
||||
u32 m_ShadowMapSize;
|
||||
// per-frame flag: has the shadow map been rendered this frame?
|
||||
bool m_ShadowRendered;
|
||||
// projection matrix of shadow casting light
|
||||
CMatrix3D m_LightProjection;
|
||||
// transformation matrix of shadow casting light
|
||||
CMatrix3D m_LightTransform;
|
||||
// coordinates of each (untransformed) alpha map within the packed texture
|
||||
struct {
|
||||
float u0,u1,v0,v1;
|
||||
} m_AlphaMapCoords[NumAlphaMaps];
|
||||
// card capabilities
|
||||
struct Caps {
|
||||
bool m_VBO;
|
||||
bool m_TextureBorderClamp;
|
||||
bool m_PBuffer;
|
||||
bool m_GenerateMipmaps;
|
||||
} m_Caps;
|
||||
// renderer options
|
||||
struct Options {
|
||||
bool m_NoVBO;
|
||||
bool m_NoPBuffer;
|
||||
bool m_Shadows;
|
||||
RGBColor m_ShadowColor;
|
||||
} m_Options;
|
||||
// build card cap bits
|
||||
void EnumCaps();
|
||||
// per-frame renderer stats
|
||||
Stats m_Stats;
|
||||
// active textures on each unit
|
||||
GLuint m_ActiveTextures[MaxTextureUnits];
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Name: Renderer.h
|
||||
// Author: Rich Cross
|
||||
// Contact: rich@wildfiregames.com
|
||||
//
|
||||
// Description: OpenGL renderer class; a higher level interface
|
||||
// on top of OpenGL to handle rendering the basic visual games
|
||||
// types - terrain, models, sprites, particles etc
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef RENDERER_H
|
||||
#define RENDERER_H
|
||||
|
||||
#include <vector>
|
||||
#include "res/res.h"
|
||||
#include "ogl.h"
|
||||
#include "Camera.h"
|
||||
#include "Frustum.h"
|
||||
#include "PatchRData.h"
|
||||
#include "ModelRData.h"
|
||||
#include "SHCoeffs.h"
|
||||
#include "Terrain.h"
|
||||
#include "Singleton.h"
|
||||
|
||||
// necessary declarations
|
||||
class CCamera;
|
||||
class CPatch;
|
||||
class CSprite;
|
||||
class CParticleSys;
|
||||
class COverlay;
|
||||
class CMaterial;
|
||||
class CLightEnv;
|
||||
class CTexture;
|
||||
class CTerrain;
|
||||
|
||||
|
||||
// rendering modes
|
||||
enum ERenderMode { WIREFRAME, SOLID, EDGED_FACES };
|
||||
|
||||
// stream flags
|
||||
#define STREAM_POS 0x01
|
||||
#define STREAM_NORMAL 0x02
|
||||
#define STREAM_COLOR 0x04
|
||||
#define STREAM_UV0 0x08
|
||||
#define STREAM_UV1 0x10
|
||||
#define STREAM_UV2 0x20
|
||||
#define STREAM_UV3 0x40
|
||||
#define STREAM_POSTOUV0 0x80
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// SVertex3D: simple 3D vertex declaration
|
||||
struct SVertex3D
|
||||
{
|
||||
float m_Position[3];
|
||||
float m_TexCoords[2];
|
||||
unsigned int m_Color;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// SVertex2D: simple 2D vertex declaration
|
||||
struct SVertex2D
|
||||
{
|
||||
float m_Position[2];
|
||||
float m_TexCoords[2];
|
||||
unsigned int m_Color;
|
||||
};
|
||||
|
||||
// access to sole renderer object
|
||||
#define g_Renderer CRenderer::GetSingleton()
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CRenderer: base renderer class - primary interface to the rendering engine
|
||||
class CRenderer : public Singleton<CRenderer>
|
||||
{
|
||||
public:
|
||||
// various enumerations and renderer related constants
|
||||
enum { NumAlphaMaps=14 };
|
||||
enum { MaxTextureUnits=16 };
|
||||
enum Option {
|
||||
OPT_NOVBO,
|
||||
OPT_NOPBUFFER,
|
||||
OPT_SHADOWS,
|
||||
OPT_SHADOWCOLOR
|
||||
};
|
||||
|
||||
// stats class - per frame counts of number of draw calls, poly counts etc
|
||||
struct Stats {
|
||||
// set all stats to zero
|
||||
void Reset() { memset(this,0,sizeof(*this)); }
|
||||
// add given stats to this stats
|
||||
Stats& operator+=(const Stats& rhs) {
|
||||
m_Counter++;
|
||||
m_DrawCalls+=rhs.m_DrawCalls;
|
||||
m_TerrainTris+=rhs.m_TerrainTris;
|
||||
m_ModelTris+=rhs.m_ModelTris;
|
||||
m_TransparentTris+=rhs.m_TransparentTris;
|
||||
m_BlendSplats+=rhs.m_BlendSplats;
|
||||
return *this;
|
||||
}
|
||||
// count of the number of stats added together
|
||||
u32 m_Counter;
|
||||
// number of draw calls per frame - total DrawElements + Begin/End immediate mode loops
|
||||
u32 m_DrawCalls;
|
||||
// number of terrain triangles drawn
|
||||
u32 m_TerrainTris;
|
||||
// number of (non-transparent) model triangles drawn
|
||||
u32 m_ModelTris;
|
||||
// number of transparent model triangles drawn
|
||||
u32 m_TransparentTris;
|
||||
// number of splat passes for alphamapping
|
||||
u32 m_BlendSplats;
|
||||
};
|
||||
|
||||
public:
|
||||
// constructor, destructor
|
||||
CRenderer();
|
||||
~CRenderer();
|
||||
|
||||
// open up the renderer: performs any necessary initialisation
|
||||
bool Open(int width,int height,int depth);
|
||||
// shutdown the renderer: performs any necessary cleanup
|
||||
void Close();
|
||||
|
||||
// resize renderer view
|
||||
void Resize(int width,int height);
|
||||
|
||||
// set/get boolean renderer option
|
||||
void SetOptionBool(enum Option opt,bool value);
|
||||
bool GetOptionBool(enum Option opt) const;
|
||||
// set/get color renderer option
|
||||
void SetOptionColor(enum Option opt,const RGBColor& value);
|
||||
const RGBColor& GetOptionColor(enum Option opt) const;
|
||||
|
||||
// return view width
|
||||
int GetWidth() const { return m_Width; }
|
||||
// return view height
|
||||
int GetHeight() const { return m_Height; }
|
||||
// return view aspect ratio
|
||||
float GetAspect() const { return float(m_Width)/float(m_Height); }
|
||||
|
||||
// signal frame start
|
||||
void BeginFrame();
|
||||
// force rendering of any batched objects
|
||||
void FlushFrame();
|
||||
// signal frame end : implicitly flushes batched objects
|
||||
void EndFrame();
|
||||
|
||||
// set color used to clear screen in BeginFrame()
|
||||
void SetClearColor(u32 color);
|
||||
|
||||
// return current frame counter
|
||||
int GetFrameCounter() const { return m_FrameCounter; }
|
||||
|
||||
// set camera used for subsequent rendering operations; includes viewport, projection and modelview matrices
|
||||
void SetCamera(CCamera& camera);
|
||||
|
||||
// submission of objects for rendering; the passed matrix indicating the transform must be scoped such that it is valid beyond
|
||||
// the call to frame end, as must the object itself
|
||||
void Submit(CPatch* patch);
|
||||
void Submit(CModel* model);
|
||||
void Submit(CSprite* sprite);
|
||||
void Submit(CParticleSys* psys);
|
||||
void Submit(COverlay* overlay);
|
||||
|
||||
// basic primitive rendering operations in 2 and 3D; handy for debugging stuff, but also useful in
|
||||
// editor tools (eg for highlighting specific terrain patches)
|
||||
// note:
|
||||
// * all 3D vertices specified in world space
|
||||
// * primitive operations rendered immediatedly, never batched
|
||||
// * primitives rendered in current material (set via SetMaterial)
|
||||
void RenderLine(const SVertex2D* vertices);
|
||||
void RenderLineLoop(int len,const SVertex2D* vertices);
|
||||
void RenderTri(const SVertex2D* vertices);
|
||||
void RenderQuad(const SVertex2D* vertices);
|
||||
void RenderLine(const SVertex3D* vertices);
|
||||
void RenderLineLoop(int len,const SVertex3D* vertices);
|
||||
void RenderTri(const SVertex3D* vertices);
|
||||
void RenderQuad(const SVertex3D* vertices);
|
||||
|
||||
// set the current lighting environment; (note: the passed pointer is just copied to a variable within the renderer,
|
||||
// so the lightenv passed must be scoped such that it is not destructed until after the renderer is no longer rendering)
|
||||
void SetLightEnv(CLightEnv* lightenv) {
|
||||
m_LightEnv=lightenv;
|
||||
}
|
||||
|
||||
// set the mode to render subsequent terrain patches
|
||||
void SetTerrainRenderMode(ERenderMode mode) { m_TerrainRenderMode=mode; }
|
||||
// get the mode to render subsequent terrain patches
|
||||
ERenderMode GetTerrainRenderMode() const { return m_TerrainRenderMode; }
|
||||
|
||||
// set the mode to render subsequent models
|
||||
void SetModelRenderMode(ERenderMode mode) { m_ModelRenderMode=mode; }
|
||||
// get the mode to render subsequent models
|
||||
ERenderMode GetModelRenderMode() const { return m_ModelRenderMode; }
|
||||
|
||||
// try and load the given texture
|
||||
bool LoadTexture(CTexture* texture,u32 wrapflags);
|
||||
// set the given unit to reference the given texture; pass a null texture to disable texturing on any unit
|
||||
void SetTexture(int unit,CTexture* texture);
|
||||
// BindTexture: bind a GL texture object to given unit
|
||||
void BindTexture(int unit,GLuint tex);
|
||||
// query transparency of given texture
|
||||
bool IsTextureTransparent(CTexture* texture);
|
||||
|
||||
// load the default set of alphamaps; return false if any alphamap fails to load, true otherwise
|
||||
bool LoadAlphaMaps(const char* fnames[]);
|
||||
|
||||
// return stats accumulated for current frame
|
||||
const Stats& GetStats() { return m_Stats; }
|
||||
|
||||
protected:
|
||||
friend class CPatchRData;
|
||||
friend class CModelRData;
|
||||
friend class CTransparencyRenderer;
|
||||
|
||||
// recurse down given model building renderdata for it and all it's children
|
||||
void UpdateModelDataRecursive(CModel* model);
|
||||
// update renderdata of everything submitted
|
||||
void UpdateSubmittedObjectData();
|
||||
|
||||
// patch rendering stuff
|
||||
void RenderPatchSubmissions();
|
||||
void RenderPatches();
|
||||
|
||||
// model rendering stuff
|
||||
void BuildTransparentPasses(CModel* model);
|
||||
void RenderModelSubmissions();
|
||||
void RenderModelsRecursive(CModel* model,u32 streamflags);
|
||||
void RenderModelsStreams(u32 streamflags);
|
||||
void RenderModels();
|
||||
|
||||
// shadow rendering stuff
|
||||
void CreateShadowMap();
|
||||
void RenderShadowMap();
|
||||
void ApplyShadowMap();
|
||||
void CRenderer::BuildTransformation(const CVector3D& pos,const CVector3D& right,const CVector3D& up,
|
||||
const CVector3D& dir,CMatrix3D& result);
|
||||
void ConstructLightTransform(const CVector3D& pos,const CVector3D& lightdir,CMatrix3D& result);
|
||||
void CalcShadowMatrices();
|
||||
void CalcShadowBounds(CBound& bounds);
|
||||
|
||||
// RENDERER DATA:
|
||||
// view width
|
||||
int m_Width;
|
||||
// view height
|
||||
int m_Height;
|
||||
// view depth (bpp)
|
||||
int m_Depth;
|
||||
// frame counter
|
||||
int m_FrameCounter;
|
||||
// current terrain rendering mode
|
||||
ERenderMode m_TerrainRenderMode;
|
||||
// current model rendering mode
|
||||
ERenderMode m_ModelRenderMode;
|
||||
// current view camera
|
||||
CCamera m_Camera;
|
||||
// color used to clear screen in BeginFrame
|
||||
float m_ClearColor[4];
|
||||
// submitted object lists for batching
|
||||
std::vector<CPatch*> m_TerrainPatches;
|
||||
std::vector<CModel*> m_Models;
|
||||
std::vector<CSprite*> m_Sprites;
|
||||
std::vector<CParticleSys*> m_ParticleSyses;
|
||||
std::vector<COverlay*> m_Overlays;
|
||||
// current lighting setup
|
||||
CLightEnv* m_LightEnv;
|
||||
// current spherical harmonic coefficients (for unit lighting), derived from lightenv
|
||||
CSHCoeffs m_SHCoeffsUnits;
|
||||
// current spherical harmonic coefficients (for terrain lighting), derived from lightenv
|
||||
CSHCoeffs m_SHCoeffsTerrain;
|
||||
// handle of composite alpha map (all the alpha maps packed into one texture)
|
||||
u32 m_CompositeAlphaMap;
|
||||
// handle of shadow map
|
||||
u32 m_ShadowMap;
|
||||
// size of each side of shadow map
|
||||
u32 m_ShadowMapSize;
|
||||
// per-frame flag: has the shadow map been rendered this frame?
|
||||
bool m_ShadowRendered;
|
||||
// projection matrix of shadow casting light
|
||||
CMatrix3D m_LightProjection;
|
||||
// transformation matrix of shadow casting light
|
||||
CMatrix3D m_LightTransform;
|
||||
// coordinates of each (untransformed) alpha map within the packed texture
|
||||
struct {
|
||||
float u0,u1,v0,v1;
|
||||
} m_AlphaMapCoords[NumAlphaMaps];
|
||||
// card capabilities
|
||||
struct Caps {
|
||||
bool m_VBO;
|
||||
bool m_TextureBorderClamp;
|
||||
bool m_PBuffer;
|
||||
bool m_GenerateMipmaps;
|
||||
} m_Caps;
|
||||
// renderer options
|
||||
struct Options {
|
||||
bool m_NoVBO;
|
||||
bool m_NoPBuffer;
|
||||
bool m_Shadows;
|
||||
RGBColor m_ShadowColor;
|
||||
} m_Options;
|
||||
// build card cap bits
|
||||
void EnumCaps();
|
||||
// per-frame renderer stats
|
||||
Stats m_Stats;
|
||||
// active textures on each unit
|
||||
GLuint m_ActiveTextures[MaxTextureUnits];
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -1,185 +1,185 @@
|
||||
#include <algorithm>
|
||||
#include "Renderer.h"
|
||||
#include "TransparencyRenderer.h"
|
||||
#include "Model.h"
|
||||
|
||||
|
||||
CTransparencyRenderer g_TransparencyRenderer;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// SortObjectsByDist: sorting class used for back-to-front sort of transparent passes
|
||||
struct SortObjectsByDist {
|
||||
typedef CTransparencyRenderer::SObject SortObj;
|
||||
|
||||
bool operator()(const SortObj& lhs,const SortObj& rhs) {
|
||||
return lhs.m_Dist>rhs.m_Dist? true : false;
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Sort: coarsely sort submitted objects in back to front manner
|
||||
void CTransparencyRenderer::Sort()
|
||||
{
|
||||
std::sort(m_Objects.begin(),m_Objects.end(),SortObjectsByDist());
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Render: render all deferred passes; call Sort before using to ensure passes
|
||||
// are drawn in correct order
|
||||
void CTransparencyRenderer::Render()
|
||||
{
|
||||
// switch on wireframe if we need it
|
||||
if (g_Renderer.m_ModelRenderMode==WIREFRAME) {
|
||||
glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
|
||||
}
|
||||
|
||||
// switch on client states
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glEnableClientState(GL_COLOR_ARRAY);
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
|
||||
// setup texture environment to modulate diffuse color with texture color
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PRIMARY_COLOR);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR);
|
||||
|
||||
// just pass through texture's alpha
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA);
|
||||
|
||||
glEnable(GL_ALPHA_TEST);
|
||||
glAlphaFunc(GL_GREATER,0.975f);
|
||||
|
||||
RenderObjectsStreams(STREAM_POS|STREAM_COLOR|STREAM_UV0);
|
||||
|
||||
glDepthMask(0);
|
||||
glAlphaFunc(GL_LEQUAL,0.975f);
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
RenderObjectsStreams(STREAM_POS|STREAM_COLOR|STREAM_UV0);
|
||||
|
||||
glDisable(GL_BLEND);
|
||||
glDisable(GL_ALPHA_TEST);
|
||||
glDepthMask(1);
|
||||
|
||||
// switch off client states
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
glDisableClientState(GL_COLOR_ARRAY);
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
|
||||
if (g_Renderer.m_ModelRenderMode==WIREFRAME) {
|
||||
// switch wireframe off again
|
||||
glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
|
||||
} else if (g_Renderer.m_ModelRenderMode==EDGED_FACES) {
|
||||
// edged faces: need to make a second pass over the data:
|
||||
// first switch on wireframe
|
||||
glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
|
||||
|
||||
// setup some renderstate ..
|
||||
glDepthMask(0);
|
||||
g_Renderer.SetTexture(0,0);
|
||||
glColor4f(1,1,1,0.75f);
|
||||
glLineWidth(1.0f);
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
// .. and some client states
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
|
||||
// render each model
|
||||
RenderObjectsStreams(STREAM_POS);
|
||||
|
||||
// .. and switch off the client states
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
|
||||
// .. and restore the renderstates
|
||||
glDisable(GL_BLEND);
|
||||
glDepthMask(1);
|
||||
|
||||
// restore fill mode, and we're done
|
||||
glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
|
||||
}
|
||||
}
|
||||
|
||||
void CTransparencyRenderer::Clear()
|
||||
{
|
||||
// all transparent objects rendered; release them
|
||||
m_Objects.clear();
|
||||
}
|
||||
|
||||
void CTransparencyRenderer::Add(CModel* model)
|
||||
{
|
||||
// resize array, get last object in list
|
||||
m_Objects.resize(m_Objects.size()+1);
|
||||
|
||||
SObject& obj=m_Objects.back();
|
||||
obj.m_Model=model;
|
||||
|
||||
// build transform from object to camera space
|
||||
CMatrix3D objToCam,invcam;
|
||||
g_Renderer.m_Camera.m_Orientation.GetInverse(objToCam);
|
||||
objToCam*=model->GetTransform();
|
||||
|
||||
// resort model indices from back to front, according to camera position - and store
|
||||
// the returned sqrd distance to the centre of the nearest triangle
|
||||
CModelRData* modeldata=(CModelRData*) model->GetRenderData();
|
||||
obj.m_Dist=modeldata->BackToFrontIndexSort(objToCam);
|
||||
}
|
||||
|
||||
void CTransparencyRenderer::RenderShadows()
|
||||
{
|
||||
// coarsely sort submitted objects in back to front manner
|
||||
std::sort(m_Objects.begin(),m_Objects.end(),SortObjectsByDist());
|
||||
|
||||
// switch on client states
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
|
||||
glDepthMask(0);
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_REPLACE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PREVIOUS_ARB);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA);
|
||||
|
||||
RenderObjectsStreams(STREAM_POS|STREAM_UV0);
|
||||
|
||||
glDisable(GL_ALPHA_TEST);
|
||||
glDepthMask(1);
|
||||
glDisable(GL_BLEND);
|
||||
|
||||
// switch off client states
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// RenderObjectsStreams: render given streams on all objects
|
||||
void CTransparencyRenderer::RenderObjectsStreams(u32 streamflags)
|
||||
{
|
||||
for (uint i=0;i<m_Objects.size();++i) {
|
||||
CModel* model=m_Objects[i].m_Model;
|
||||
|
||||
glPushMatrix();
|
||||
glMultMatrixf(&model->GetTransform()._11);
|
||||
|
||||
CModelRData* modeldata=(CModelRData*) model->GetRenderData();
|
||||
modeldata->RenderStreams(streamflags,true);
|
||||
|
||||
glPopMatrix();
|
||||
}
|
||||
#include <algorithm>
|
||||
#include "Renderer.h"
|
||||
#include "TransparencyRenderer.h"
|
||||
#include "Model.h"
|
||||
|
||||
|
||||
CTransparencyRenderer g_TransparencyRenderer;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// SortObjectsByDist: sorting class used for back-to-front sort of transparent passes
|
||||
struct SortObjectsByDist {
|
||||
typedef CTransparencyRenderer::SObject SortObj;
|
||||
|
||||
bool operator()(const SortObj& lhs,const SortObj& rhs) {
|
||||
return lhs.m_Dist>rhs.m_Dist? true : false;
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Sort: coarsely sort submitted objects in back to front manner
|
||||
void CTransparencyRenderer::Sort()
|
||||
{
|
||||
std::sort(m_Objects.begin(),m_Objects.end(),SortObjectsByDist());
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Render: render all deferred passes; call Sort before using to ensure passes
|
||||
// are drawn in correct order
|
||||
void CTransparencyRenderer::Render()
|
||||
{
|
||||
// switch on wireframe if we need it
|
||||
if (g_Renderer.m_ModelRenderMode==WIREFRAME) {
|
||||
glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
|
||||
}
|
||||
|
||||
// switch on client states
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glEnableClientState(GL_COLOR_ARRAY);
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
|
||||
// setup texture environment to modulate diffuse color with texture color
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PRIMARY_COLOR);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR);
|
||||
|
||||
// just pass through texture's alpha
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA);
|
||||
|
||||
glEnable(GL_ALPHA_TEST);
|
||||
glAlphaFunc(GL_GREATER,0.975f);
|
||||
|
||||
RenderObjectsStreams(STREAM_POS|STREAM_COLOR|STREAM_UV0);
|
||||
|
||||
glDepthMask(0);
|
||||
glAlphaFunc(GL_LEQUAL,0.975f);
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
RenderObjectsStreams(STREAM_POS|STREAM_COLOR|STREAM_UV0);
|
||||
|
||||
glDisable(GL_BLEND);
|
||||
glDisable(GL_ALPHA_TEST);
|
||||
glDepthMask(1);
|
||||
|
||||
// switch off client states
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
glDisableClientState(GL_COLOR_ARRAY);
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
|
||||
if (g_Renderer.m_ModelRenderMode==WIREFRAME) {
|
||||
// switch wireframe off again
|
||||
glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
|
||||
} else if (g_Renderer.m_ModelRenderMode==EDGED_FACES) {
|
||||
// edged faces: need to make a second pass over the data:
|
||||
// first switch on wireframe
|
||||
glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
|
||||
|
||||
// setup some renderstate ..
|
||||
glDepthMask(0);
|
||||
g_Renderer.SetTexture(0,0);
|
||||
glColor4f(1,1,1,0.75f);
|
||||
glLineWidth(1.0f);
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
// .. and some client states
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
|
||||
// render each model
|
||||
RenderObjectsStreams(STREAM_POS);
|
||||
|
||||
// .. and switch off the client states
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
|
||||
// .. and restore the renderstates
|
||||
glDisable(GL_BLEND);
|
||||
glDepthMask(1);
|
||||
|
||||
// restore fill mode, and we're done
|
||||
glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
|
||||
}
|
||||
}
|
||||
|
||||
void CTransparencyRenderer::Clear()
|
||||
{
|
||||
// all transparent objects rendered; release them
|
||||
m_Objects.clear();
|
||||
}
|
||||
|
||||
void CTransparencyRenderer::Add(CModel* model)
|
||||
{
|
||||
// resize array, get last object in list
|
||||
m_Objects.resize(m_Objects.size()+1);
|
||||
|
||||
SObject& obj=m_Objects.back();
|
||||
obj.m_Model=model;
|
||||
|
||||
// build transform from object to camera space
|
||||
CMatrix3D objToCam,invcam;
|
||||
g_Renderer.m_Camera.m_Orientation.GetInverse(objToCam);
|
||||
objToCam*=model->GetTransform();
|
||||
|
||||
// resort model indices from back to front, according to camera position - and store
|
||||
// the returned sqrd distance to the centre of the nearest triangle
|
||||
CModelRData* modeldata=(CModelRData*) model->GetRenderData();
|
||||
obj.m_Dist=modeldata->BackToFrontIndexSort(objToCam);
|
||||
}
|
||||
|
||||
void CTransparencyRenderer::RenderShadows()
|
||||
{
|
||||
// coarsely sort submitted objects in back to front manner
|
||||
std::sort(m_Objects.begin(),m_Objects.end(),SortObjectsByDist());
|
||||
|
||||
// switch on client states
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
|
||||
glDepthMask(0);
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_REPLACE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PREVIOUS_ARB);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA);
|
||||
|
||||
RenderObjectsStreams(STREAM_POS|STREAM_UV0);
|
||||
|
||||
glDisable(GL_ALPHA_TEST);
|
||||
glDepthMask(1);
|
||||
glDisable(GL_BLEND);
|
||||
|
||||
// switch off client states
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// RenderObjectsStreams: render given streams on all objects
|
||||
void CTransparencyRenderer::RenderObjectsStreams(u32 streamflags)
|
||||
{
|
||||
for (uint i=0;i<m_Objects.size();++i) {
|
||||
CModel* model=m_Objects[i].m_Model;
|
||||
|
||||
glPushMatrix();
|
||||
glMultMatrixf(&model->GetTransform()._11);
|
||||
|
||||
CModelRData* modeldata=(CModelRData*) model->GetRenderData();
|
||||
modeldata->RenderStreams(streamflags,true);
|
||||
|
||||
glPopMatrix();
|
||||
}
|
||||
}
|
@ -1,39 +1,39 @@
|
||||
#ifndef __TRANSPARENCYRENDERER_H
|
||||
#define __TRANSPARENCYRENDERER_H
|
||||
|
||||
#include <vector>
|
||||
|
||||
class CModel;
|
||||
|
||||
class CTransparencyRenderer
|
||||
{
|
||||
public:
|
||||
struct SObject {
|
||||
// the transparent model
|
||||
CModel* m_Model;
|
||||
// sqrd distance from camera to centre of nearest triangle
|
||||
float m_Dist;
|
||||
};
|
||||
|
||||
public:
|
||||
// add object to render in deferred transparency pass
|
||||
void Add(CModel* model);
|
||||
// render all deferred objects
|
||||
void Render();
|
||||
// render shadows from all deferred objects
|
||||
void RenderShadows();
|
||||
// coarsely sort submitted objects in back to front manner
|
||||
void Sort();
|
||||
// empty object list
|
||||
void Clear();
|
||||
|
||||
private:
|
||||
// render given streams on all objects
|
||||
void RenderObjectsStreams(u32 streamflags);
|
||||
// list of transparent objects to render
|
||||
std::vector<SObject> m_Objects;
|
||||
};
|
||||
|
||||
extern CTransparencyRenderer g_TransparencyRenderer;
|
||||
|
||||
#endif
|
||||
#ifndef __TRANSPARENCYRENDERER_H
|
||||
#define __TRANSPARENCYRENDERER_H
|
||||
|
||||
#include <vector>
|
||||
|
||||
class CModel;
|
||||
|
||||
class CTransparencyRenderer
|
||||
{
|
||||
public:
|
||||
struct SObject {
|
||||
// the transparent model
|
||||
CModel* m_Model;
|
||||
// sqrd distance from camera to centre of nearest triangle
|
||||
float m_Dist;
|
||||
};
|
||||
|
||||
public:
|
||||
// add object to render in deferred transparency pass
|
||||
void Add(CModel* model);
|
||||
// render all deferred objects
|
||||
void Render();
|
||||
// render shadows from all deferred objects
|
||||
void RenderShadows();
|
||||
// coarsely sort submitted objects in back to front manner
|
||||
void Sort();
|
||||
// empty object list
|
||||
void Clear();
|
||||
|
||||
private:
|
||||
// render given streams on all objects
|
||||
void RenderObjectsStreams(u32 streamflags);
|
||||
// list of transparent objects to render
|
||||
std::vector<SObject> m_Objects;
|
||||
};
|
||||
|
||||
extern CTransparencyRenderer g_TransparencyRenderer;
|
||||
|
||||
#endif
|
||||
|
@ -1,121 +1,121 @@
|
||||
#include "AlterElevationCommand.h"
|
||||
#include "UIGlobals.h"
|
||||
#include "MiniMap.h"
|
||||
#include "Terrain.h"
|
||||
|
||||
extern CTerrain g_Terrain;
|
||||
|
||||
inline int clamp(int x,int min,int max)
|
||||
{
|
||||
if (x<min) return min;
|
||||
else if (x>max) return max;
|
||||
else return x;
|
||||
}
|
||||
|
||||
|
||||
CAlterElevationCommand::CAlterElevationCommand(int brushSize,int selectionCentre[2])
|
||||
{
|
||||
m_BrushSize=brushSize;
|
||||
m_SelectionCentre[0]=selectionCentre[0];
|
||||
m_SelectionCentre[1]=selectionCentre[1];
|
||||
}
|
||||
|
||||
|
||||
CAlterElevationCommand::~CAlterElevationCommand()
|
||||
{
|
||||
}
|
||||
|
||||
void CAlterElevationCommand::Execute()
|
||||
{
|
||||
int r=m_BrushSize;
|
||||
u32 mapSize=g_Terrain.GetVerticesPerSide();
|
||||
|
||||
// get range of vertices affected by brush
|
||||
int x0=clamp(m_SelectionCentre[0]-r,0,mapSize-1);
|
||||
int x1=clamp(m_SelectionCentre[0]+r+1,0,mapSize-1);
|
||||
int z0=clamp(m_SelectionCentre[1]-r,0,mapSize-1);
|
||||
int z1=clamp(m_SelectionCentre[1]+r+1,0,mapSize-1);
|
||||
|
||||
// resize input/output arrays
|
||||
m_DataIn.resize(x1-x0+1,z1-z0+1);
|
||||
m_DataOut.resize(x1-x0+1,z1-z0+1);
|
||||
|
||||
// fill input data
|
||||
int i,j;
|
||||
for (j=z0;j<=z1;j++) {
|
||||
for (i=x0;i<=x1;i++) {
|
||||
u16 input=g_Terrain.GetHeightMap()[j*mapSize+i];
|
||||
m_DataIn(i-x0,j-z0)=input;
|
||||
}
|
||||
}
|
||||
|
||||
// call on base classes to fill the output data
|
||||
CalcDataOut(x0,x1,z0,z1);
|
||||
|
||||
// now actually apply data to terrain
|
||||
ApplyDataToSelection(m_DataOut);
|
||||
}
|
||||
|
||||
|
||||
void CAlterElevationCommand::ApplyDataToSelection(const CArray2D<u16>& data)
|
||||
{
|
||||
u32 mapSize=g_Terrain.GetVerticesPerSide();
|
||||
|
||||
int r=m_BrushSize;
|
||||
int x0=clamp(m_SelectionCentre[0]-r,0,mapSize-1);
|
||||
int x1=clamp(m_SelectionCentre[0]+r+1,0,mapSize-1);
|
||||
int z0=clamp(m_SelectionCentre[1]-r,0,mapSize-1);
|
||||
int z1=clamp(m_SelectionCentre[1]+r+1,0,mapSize-1);
|
||||
|
||||
|
||||
// copy given data to heightmap
|
||||
int i,j;
|
||||
for (j=z0;j<=z1;j++) {
|
||||
for (i=x0;i<=x1;i++) {
|
||||
int idx=j*mapSize+i;
|
||||
u16 height=data(i-x0,j-z0);
|
||||
// update heightmap
|
||||
g_Terrain.GetHeightMap()[idx]=height;
|
||||
}
|
||||
}
|
||||
|
||||
// flag vertex data as dirty for affected patches, and rebuild bounds of these patches
|
||||
u32 patchesPerSide=g_Terrain.GetPatchesPerSide();
|
||||
int px0=clamp(-1+(x0/16),0,patchesPerSide);
|
||||
int px1=clamp(1+(x1/16),0,patchesPerSide);
|
||||
int pz0=clamp(-1+(z0/16),0,patchesPerSide);
|
||||
int pz1=clamp(1+(z1/16),0,patchesPerSide);
|
||||
for (j=pz0;j<pz1;j++) {
|
||||
for (int i=px0;i<px1;i++) {
|
||||
CPatch* patch=g_Terrain.GetPatch(i,j);
|
||||
patch->CalcBounds();
|
||||
patch->SetDirty(RENDERDATA_UPDATE_VERTICES);
|
||||
}
|
||||
}
|
||||
|
||||
// rebuild this bit of the minimap
|
||||
int w=1+2*m_BrushSize;
|
||||
int x=m_SelectionCentre[1]-m_BrushSize;
|
||||
if (x<0) {
|
||||
w+=x;
|
||||
x=0;
|
||||
}
|
||||
int h=1+2*m_BrushSize;
|
||||
int y=m_SelectionCentre[0]-m_BrushSize;
|
||||
if (y<0) {
|
||||
h+=y;
|
||||
y=0;
|
||||
}
|
||||
g_MiniMap.Rebuild(x,y,w,h);
|
||||
}
|
||||
|
||||
|
||||
void CAlterElevationCommand::Undo()
|
||||
{
|
||||
ApplyDataToSelection(m_DataIn);
|
||||
}
|
||||
|
||||
void CAlterElevationCommand::Redo()
|
||||
{
|
||||
ApplyDataToSelection(m_DataOut);
|
||||
}
|
||||
#include "AlterElevationCommand.h"
|
||||
#include "UIGlobals.h"
|
||||
#include "MiniMap.h"
|
||||
#include "Terrain.h"
|
||||
|
||||
extern CTerrain g_Terrain;
|
||||
|
||||
inline int clamp(int x,int min,int max)
|
||||
{
|
||||
if (x<min) return min;
|
||||
else if (x>max) return max;
|
||||
else return x;
|
||||
}
|
||||
|
||||
|
||||
CAlterElevationCommand::CAlterElevationCommand(int brushSize,int selectionCentre[2])
|
||||
{
|
||||
m_BrushSize=brushSize;
|
||||
m_SelectionCentre[0]=selectionCentre[0];
|
||||
m_SelectionCentre[1]=selectionCentre[1];
|
||||
}
|
||||
|
||||
|
||||
CAlterElevationCommand::~CAlterElevationCommand()
|
||||
{
|
||||
}
|
||||
|
||||
void CAlterElevationCommand::Execute()
|
||||
{
|
||||
int r=m_BrushSize;
|
||||
u32 mapSize=g_Terrain.GetVerticesPerSide();
|
||||
|
||||
// get range of vertices affected by brush
|
||||
int x0=clamp(m_SelectionCentre[0]-r,0,mapSize-1);
|
||||
int x1=clamp(m_SelectionCentre[0]+r+1,0,mapSize-1);
|
||||
int z0=clamp(m_SelectionCentre[1]-r,0,mapSize-1);
|
||||
int z1=clamp(m_SelectionCentre[1]+r+1,0,mapSize-1);
|
||||
|
||||
// resize input/output arrays
|
||||
m_DataIn.resize(x1-x0+1,z1-z0+1);
|
||||
m_DataOut.resize(x1-x0+1,z1-z0+1);
|
||||
|
||||
// fill input data
|
||||
int i,j;
|
||||
for (j=z0;j<=z1;j++) {
|
||||
for (i=x0;i<=x1;i++) {
|
||||
u16 input=g_Terrain.GetHeightMap()[j*mapSize+i];
|
||||
m_DataIn(i-x0,j-z0)=input;
|
||||
}
|
||||
}
|
||||
|
||||
// call on base classes to fill the output data
|
||||
CalcDataOut(x0,x1,z0,z1);
|
||||
|
||||
// now actually apply data to terrain
|
||||
ApplyDataToSelection(m_DataOut);
|
||||
}
|
||||
|
||||
|
||||
void CAlterElevationCommand::ApplyDataToSelection(const CArray2D<u16>& data)
|
||||
{
|
||||
u32 mapSize=g_Terrain.GetVerticesPerSide();
|
||||
|
||||
int r=m_BrushSize;
|
||||
int x0=clamp(m_SelectionCentre[0]-r,0,mapSize-1);
|
||||
int x1=clamp(m_SelectionCentre[0]+r+1,0,mapSize-1);
|
||||
int z0=clamp(m_SelectionCentre[1]-r,0,mapSize-1);
|
||||
int z1=clamp(m_SelectionCentre[1]+r+1,0,mapSize-1);
|
||||
|
||||
|
||||
// copy given data to heightmap
|
||||
int i,j;
|
||||
for (j=z0;j<=z1;j++) {
|
||||
for (i=x0;i<=x1;i++) {
|
||||
int idx=j*mapSize+i;
|
||||
u16 height=data(i-x0,j-z0);
|
||||
// update heightmap
|
||||
g_Terrain.GetHeightMap()[idx]=height;
|
||||
}
|
||||
}
|
||||
|
||||
// flag vertex data as dirty for affected patches, and rebuild bounds of these patches
|
||||
u32 patchesPerSide=g_Terrain.GetPatchesPerSide();
|
||||
int px0=clamp(-1+(x0/16),0,patchesPerSide);
|
||||
int px1=clamp(1+(x1/16),0,patchesPerSide);
|
||||
int pz0=clamp(-1+(z0/16),0,patchesPerSide);
|
||||
int pz1=clamp(1+(z1/16),0,patchesPerSide);
|
||||
for (j=pz0;j<pz1;j++) {
|
||||
for (int i=px0;i<px1;i++) {
|
||||
CPatch* patch=g_Terrain.GetPatch(i,j);
|
||||
patch->CalcBounds();
|
||||
patch->SetDirty(RENDERDATA_UPDATE_VERTICES);
|
||||
}
|
||||
}
|
||||
|
||||
// rebuild this bit of the minimap
|
||||
int w=1+2*m_BrushSize;
|
||||
int x=m_SelectionCentre[1]-m_BrushSize;
|
||||
if (x<0) {
|
||||
w+=x;
|
||||
x=0;
|
||||
}
|
||||
int h=1+2*m_BrushSize;
|
||||
int y=m_SelectionCentre[0]-m_BrushSize;
|
||||
if (y<0) {
|
||||
h+=y;
|
||||
y=0;
|
||||
}
|
||||
g_MiniMap.Rebuild(x,y,w,h);
|
||||
}
|
||||
|
||||
|
||||
void CAlterElevationCommand::Undo()
|
||||
{
|
||||
ApplyDataToSelection(m_DataIn);
|
||||
}
|
||||
|
||||
void CAlterElevationCommand::Redo()
|
||||
{
|
||||
ApplyDataToSelection(m_DataOut);
|
||||
}
|
||||
|
@ -1,45 +1,45 @@
|
||||
#ifndef _ALTERELEVATIONCOMMAND_H
|
||||
#define _ALTERELEVATIONCOMMAND_H
|
||||
|
||||
#include <set>
|
||||
#include "res/res.h"
|
||||
#include "Command.h"
|
||||
#include "Array2D.h"
|
||||
|
||||
|
||||
class CAlterElevationCommand : public CCommand
|
||||
{
|
||||
public:
|
||||
// constructor, destructor
|
||||
CAlterElevationCommand(int brushSize,int selectionCentre[2]);
|
||||
~CAlterElevationCommand();
|
||||
|
||||
// execute this command
|
||||
void Execute();
|
||||
|
||||
// can undo command?
|
||||
bool IsUndoable() const { return true; }
|
||||
// undo
|
||||
void Undo();
|
||||
// redo
|
||||
void Redo();
|
||||
|
||||
// abstract function implemented by subclasses to fill in outgoing data member
|
||||
virtual void CalcDataOut(int x0,int x1,int z0,int z1) = 0;
|
||||
|
||||
protected:
|
||||
void ApplyDataToSelection(const CArray2D<u16>& data);
|
||||
|
||||
// size of brush
|
||||
int m_BrushSize;
|
||||
// centre of brush
|
||||
int m_SelectionCentre[2];
|
||||
// origin of data set
|
||||
int m_SelectionOrigin[2];
|
||||
// input data (original terrain heights)
|
||||
CArray2D<u16> m_DataIn;
|
||||
// output data (final terrain heights)
|
||||
CArray2D<u16> m_DataOut;
|
||||
};
|
||||
|
||||
#endif
|
||||
#ifndef _ALTERELEVATIONCOMMAND_H
|
||||
#define _ALTERELEVATIONCOMMAND_H
|
||||
|
||||
#include <set>
|
||||
#include "res/res.h"
|
||||
#include "Command.h"
|
||||
#include "Array2D.h"
|
||||
|
||||
|
||||
class CAlterElevationCommand : public CCommand
|
||||
{
|
||||
public:
|
||||
// constructor, destructor
|
||||
CAlterElevationCommand(int brushSize,int selectionCentre[2]);
|
||||
~CAlterElevationCommand();
|
||||
|
||||
// execute this command
|
||||
void Execute();
|
||||
|
||||
// can undo command?
|
||||
bool IsUndoable() const { return true; }
|
||||
// undo
|
||||
void Undo();
|
||||
// redo
|
||||
void Redo();
|
||||
|
||||
// abstract function implemented by subclasses to fill in outgoing data member
|
||||
virtual void CalcDataOut(int x0,int x1,int z0,int z1) = 0;
|
||||
|
||||
protected:
|
||||
void ApplyDataToSelection(const CArray2D<u16>& data);
|
||||
|
||||
// size of brush
|
||||
int m_BrushSize;
|
||||
// centre of brush
|
||||
int m_SelectionCentre[2];
|
||||
// origin of data set
|
||||
int m_SelectionOrigin[2];
|
||||
// input data (original terrain heights)
|
||||
CArray2D<u16> m_DataIn;
|
||||
// output data (final terrain heights)
|
||||
CArray2D<u16> m_DataOut;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -1,66 +1,66 @@
|
||||
#include "AlterLightEnvCommand.h"
|
||||
#include "UnitManager.h"
|
||||
#include "ObjectManager.h"
|
||||
#include "Model.h"
|
||||
#include "Terrain.h"
|
||||
|
||||
extern CTerrain g_Terrain;
|
||||
extern CLightEnv g_LightEnv;
|
||||
|
||||
|
||||
CAlterLightEnvCommand::CAlterLightEnvCommand(const CLightEnv& env) : m_LightEnv(env)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
CAlterLightEnvCommand::~CAlterLightEnvCommand()
|
||||
{
|
||||
}
|
||||
|
||||
void CAlterLightEnvCommand::Execute()
|
||||
{
|
||||
// save current lighting environment
|
||||
m_SavedLightEnv=g_LightEnv;
|
||||
// apply this commands lighting environment onto the global lighting environment
|
||||
ApplyData(m_LightEnv);
|
||||
}
|
||||
|
||||
|
||||
void CAlterLightEnvCommand::ApplyData(const CLightEnv& env)
|
||||
{
|
||||
// copy given lighting environment to global environment
|
||||
g_LightEnv=env;
|
||||
|
||||
// dirty the vertices on all patches
|
||||
u32 patchesPerSide=g_Terrain.GetPatchesPerSide();
|
||||
u32 i,j;
|
||||
for (j=0;j<patchesPerSide;j++) {
|
||||
for (i=0;i<patchesPerSide;i++) {
|
||||
CPatch* patch=g_Terrain.GetPatch(i,j);
|
||||
patch->SetDirty(RENDERDATA_UPDATE_VERTICES);
|
||||
}
|
||||
}
|
||||
|
||||
// dirty all models
|
||||
const std::vector<CUnit*>& units=g_UnitMan.GetUnits();
|
||||
for (i=0;i<units.size();++i) {
|
||||
CUnit* unit=units[i];
|
||||
unit->GetModel()->SetDirty(RENDERDATA_UPDATE_VERTICES);
|
||||
}
|
||||
|
||||
CObjectEntry* selobject=g_ObjMan.GetSelectedObject();
|
||||
if (selobject && selobject->m_Model) {
|
||||
selobject->m_Model->SetDirty(RENDERDATA_UPDATE_VERTICES);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CAlterLightEnvCommand::Undo()
|
||||
{
|
||||
ApplyData(m_SavedLightEnv);
|
||||
}
|
||||
|
||||
void CAlterLightEnvCommand::Redo()
|
||||
{
|
||||
ApplyData(m_LightEnv);
|
||||
}
|
||||
#include "AlterLightEnvCommand.h"
|
||||
#include "UnitManager.h"
|
||||
#include "ObjectManager.h"
|
||||
#include "Model.h"
|
||||
#include "Terrain.h"
|
||||
|
||||
extern CTerrain g_Terrain;
|
||||
extern CLightEnv g_LightEnv;
|
||||
|
||||
|
||||
CAlterLightEnvCommand::CAlterLightEnvCommand(const CLightEnv& env) : m_LightEnv(env)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
CAlterLightEnvCommand::~CAlterLightEnvCommand()
|
||||
{
|
||||
}
|
||||
|
||||
void CAlterLightEnvCommand::Execute()
|
||||
{
|
||||
// save current lighting environment
|
||||
m_SavedLightEnv=g_LightEnv;
|
||||
// apply this commands lighting environment onto the global lighting environment
|
||||
ApplyData(m_LightEnv);
|
||||
}
|
||||
|
||||
|
||||
void CAlterLightEnvCommand::ApplyData(const CLightEnv& env)
|
||||
{
|
||||
// copy given lighting environment to global environment
|
||||
g_LightEnv=env;
|
||||
|
||||
// dirty the vertices on all patches
|
||||
u32 patchesPerSide=g_Terrain.GetPatchesPerSide();
|
||||
u32 i,j;
|
||||
for (j=0;j<patchesPerSide;j++) {
|
||||
for (i=0;i<patchesPerSide;i++) {
|
||||
CPatch* patch=g_Terrain.GetPatch(i,j);
|
||||
patch->SetDirty(RENDERDATA_UPDATE_VERTICES);
|
||||
}
|
||||
}
|
||||
|
||||
// dirty all models
|
||||
const std::vector<CUnit*>& units=g_UnitMan.GetUnits();
|
||||
for (i=0;i<units.size();++i) {
|
||||
CUnit* unit=units[i];
|
||||
unit->GetModel()->SetDirty(RENDERDATA_UPDATE_VERTICES);
|
||||
}
|
||||
|
||||
CObjectEntry* selobject=g_ObjMan.GetSelectedObject();
|
||||
if (selobject && selobject->m_Model) {
|
||||
selobject->m_Model->SetDirty(RENDERDATA_UPDATE_VERTICES);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CAlterLightEnvCommand::Undo()
|
||||
{
|
||||
ApplyData(m_SavedLightEnv);
|
||||
}
|
||||
|
||||
void CAlterLightEnvCommand::Redo()
|
||||
{
|
||||
ApplyData(m_LightEnv);
|
||||
}
|
||||
|
@ -1,40 +1,40 @@
|
||||
#ifndef _ALTERLIGHTENVCOMMAND_H
|
||||
#define _ALTERLIGHTENVCOMMAND_H
|
||||
|
||||
#include <set>
|
||||
#include "res/res.h"
|
||||
#include "Command.h"
|
||||
|
||||
#include "LightEnv.h"
|
||||
|
||||
class CAlterLightEnvCommand : public CCommand
|
||||
{
|
||||
public:
|
||||
// constructor, destructor
|
||||
CAlterLightEnvCommand(const CLightEnv& env);
|
||||
~CAlterLightEnvCommand();
|
||||
|
||||
// return the texture name of this command
|
||||
const char* GetName() const { return "Alter Lighting Parameters"; }
|
||||
|
||||
// execute this command
|
||||
void Execute();
|
||||
|
||||
// can undo command?
|
||||
bool IsUndoable() const { return true; }
|
||||
// undo
|
||||
void Undo();
|
||||
// redo
|
||||
void Redo();
|
||||
|
||||
private:
|
||||
// apply given lighting parameters to global environment
|
||||
void ApplyData(const CLightEnv& env);
|
||||
|
||||
// lighting parameters to apply to the environment
|
||||
CLightEnv m_LightEnv;
|
||||
// old lighting parameters - saved for undo/redo
|
||||
CLightEnv m_SavedLightEnv;
|
||||
};
|
||||
|
||||
#endif
|
||||
#ifndef _ALTERLIGHTENVCOMMAND_H
|
||||
#define _ALTERLIGHTENVCOMMAND_H
|
||||
|
||||
#include <set>
|
||||
#include "res/res.h"
|
||||
#include "Command.h"
|
||||
|
||||
#include "LightEnv.h"
|
||||
|
||||
class CAlterLightEnvCommand : public CCommand
|
||||
{
|
||||
public:
|
||||
// constructor, destructor
|
||||
CAlterLightEnvCommand(const CLightEnv& env);
|
||||
~CAlterLightEnvCommand();
|
||||
|
||||
// return the texture name of this command
|
||||
const char* GetName() const { return "Alter Lighting Parameters"; }
|
||||
|
||||
// execute this command
|
||||
void Execute();
|
||||
|
||||
// can undo command?
|
||||
bool IsUndoable() const { return true; }
|
||||
// undo
|
||||
void Undo();
|
||||
// redo
|
||||
void Redo();
|
||||
|
||||
private:
|
||||
// apply given lighting parameters to global environment
|
||||
void ApplyData(const CLightEnv& env);
|
||||
|
||||
// lighting parameters to apply to the environment
|
||||
CLightEnv m_LightEnv;
|
||||
// old lighting parameters - saved for undo/redo
|
||||
CLightEnv m_SavedLightEnv;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -1,202 +1,202 @@
|
||||
#ifndef _ARRAY2D_H
|
||||
#define _ARRAY2D_H
|
||||
|
||||
template <class T>
|
||||
class CArray2D
|
||||
{
|
||||
public:
|
||||
CArray2D();
|
||||
CArray2D(int usize,int vsize);
|
||||
CArray2D(int usize,int vsize,const T* data);
|
||||
CArray2D(const CArray2D& rhs);
|
||||
virtual ~CArray2D();
|
||||
|
||||
CArray2D& operator=(const CArray2D& rhs);
|
||||
|
||||
operator T*();
|
||||
operator const T*() const;
|
||||
|
||||
int usize() const;
|
||||
int vsize() const;
|
||||
void size(int& usize,int& vsize) const;
|
||||
|
||||
void resize(int usize,int vsize);
|
||||
|
||||
void fill(const T* elements);
|
||||
|
||||
T& operator()(int a,int b);
|
||||
const T& operator()(int a,int b) const;
|
||||
|
||||
T& at(int a,int b);
|
||||
const T& at(int a,int b) const;
|
||||
|
||||
protected:
|
||||
// allocate and deallocate are overrideable by subclasses, allowing alternative
|
||||
// (more efficient) allocation in certain circumstances
|
||||
// * if allocation/deallocation is not done using new[]/delete[], it is necessary
|
||||
// to override both functions
|
||||
virtual void allocate();
|
||||
virtual void deallocate();
|
||||
|
||||
int _usize; // no of columns;
|
||||
int _vsize; // no of rows
|
||||
T* _elements;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
template <class T>
|
||||
CArray2D<T>::CArray2D() : _usize(0), _vsize(0), _elements(0)
|
||||
{
|
||||
}
|
||||
|
||||
template <class T>
|
||||
CArray2D<T>::CArray2D(int usize,int vsize)
|
||||
: _usize(usize), _vsize(vsize), _elements(0)
|
||||
{
|
||||
allocate();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
CArray2D<T>::CArray2D(int usize,int vsize,const T* elements)
|
||||
: _usize(usize), _vsize(vsize), _elements(0)
|
||||
{
|
||||
assert(elements!=0);
|
||||
|
||||
allocate();
|
||||
fill(elements);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
CArray2D<T>::CArray2D(const CArray2D<T>& rhs)
|
||||
: _usize(rhs._usize), _vsize(rhs._vsize), _elements(0)
|
||||
{
|
||||
allocate();
|
||||
fill(rhs._elements);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
CArray2D<T>::~CArray2D()
|
||||
{
|
||||
deallocate();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
CArray2D<T>& CArray2D<T>::operator=(const CArray2D<T>& rhs)
|
||||
{
|
||||
if (this==&rhs)
|
||||
return *this;
|
||||
|
||||
deallocate();
|
||||
|
||||
_usize=rhs._usize;
|
||||
_vsize=rhs._vsize;
|
||||
|
||||
allocate();
|
||||
fill(rhs._elements);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void CArray2D<T>::allocate()
|
||||
{
|
||||
assert(_elements==0);
|
||||
_elements=new T[_usize*_vsize];
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void CArray2D<T>::deallocate()
|
||||
{
|
||||
delete[] _elements;
|
||||
_elements=0;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
int CArray2D<T>::usize() const
|
||||
{
|
||||
return _usize;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
int CArray2D<T>::vsize() const
|
||||
{
|
||||
return _vsize;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void CArray2D<T>::size(int& usize,int& vsize) const
|
||||
{
|
||||
usize=_usize;
|
||||
vsize=_vsize;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void CArray2D<T>::resize(int usize,int vsize)
|
||||
{
|
||||
deallocate();
|
||||
|
||||
_usize=usize;
|
||||
_vsize=vsize;
|
||||
allocate();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void CArray2D<T>::fill(const T* elements)
|
||||
{
|
||||
memcpy(_elements,elements,sizeof(T)*_usize*_vsize);
|
||||
}
|
||||
|
||||
|
||||
// operator()(int r,int c)
|
||||
// return the element at (r,c) (ie c'th element in r'th row)
|
||||
template <class T>
|
||||
T& CArray2D<T>::operator()(int u,int v)
|
||||
{
|
||||
assert(u>=0 && u<_usize);
|
||||
assert(v>=0 && v<_vsize);
|
||||
return _elements[(u*_vsize)+v];
|
||||
}
|
||||
|
||||
template <class T>
|
||||
const T& CArray2D<T>::operator()(int u,int v) const
|
||||
{
|
||||
assert(u>=0 && u<_usize);
|
||||
assert(v>=0 && v<_vsize);
|
||||
return _elements[(u*_vsize)+v];
|
||||
}
|
||||
|
||||
template <class T>
|
||||
T& CArray2D<T>::at(int u,int v)
|
||||
{
|
||||
assert(u>=0 && u<_usize);
|
||||
assert(v>=0 && v<_vsize);
|
||||
return _elements[(u*_vsize)+v];
|
||||
}
|
||||
|
||||
template <class T>
|
||||
const T& CArray2D<T>::at(int u,int v) const
|
||||
{
|
||||
assert(u>=0 && u<_usize);
|
||||
assert(v>=0 && v<_vsize);
|
||||
return _elements[(u*_vsize)+v];
|
||||
}
|
||||
|
||||
template <class T>
|
||||
CArray2D<T>::operator T*()
|
||||
{
|
||||
return _elements;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
CArray2D<T>::operator const T*() const
|
||||
{
|
||||
return _elements;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#endif
|
||||
#ifndef _ARRAY2D_H
|
||||
#define _ARRAY2D_H
|
||||
|
||||
template <class T>
|
||||
class CArray2D
|
||||
{
|
||||
public:
|
||||
CArray2D();
|
||||
CArray2D(int usize,int vsize);
|
||||
CArray2D(int usize,int vsize,const T* data);
|
||||
CArray2D(const CArray2D& rhs);
|
||||
virtual ~CArray2D();
|
||||
|
||||
CArray2D& operator=(const CArray2D& rhs);
|
||||
|
||||
operator T*();
|
||||
operator const T*() const;
|
||||
|
||||
int usize() const;
|
||||
int vsize() const;
|
||||
void size(int& usize,int& vsize) const;
|
||||
|
||||
void resize(int usize,int vsize);
|
||||
|
||||
void fill(const T* elements);
|
||||
|
||||
T& operator()(int a,int b);
|
||||
const T& operator()(int a,int b) const;
|
||||
|
||||
T& at(int a,int b);
|
||||
const T& at(int a,int b) const;
|
||||
|
||||
protected:
|
||||
// allocate and deallocate are overrideable by subclasses, allowing alternative
|
||||
// (more efficient) allocation in certain circumstances
|
||||
// * if allocation/deallocation is not done using new[]/delete[], it is necessary
|
||||
// to override both functions
|
||||
virtual void allocate();
|
||||
virtual void deallocate();
|
||||
|
||||
int _usize; // no of columns;
|
||||
int _vsize; // no of rows
|
||||
T* _elements;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
template <class T>
|
||||
CArray2D<T>::CArray2D() : _usize(0), _vsize(0), _elements(0)
|
||||
{
|
||||
}
|
||||
|
||||
template <class T>
|
||||
CArray2D<T>::CArray2D(int usize,int vsize)
|
||||
: _usize(usize), _vsize(vsize), _elements(0)
|
||||
{
|
||||
allocate();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
CArray2D<T>::CArray2D(int usize,int vsize,const T* elements)
|
||||
: _usize(usize), _vsize(vsize), _elements(0)
|
||||
{
|
||||
assert(elements!=0);
|
||||
|
||||
allocate();
|
||||
fill(elements);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
CArray2D<T>::CArray2D(const CArray2D<T>& rhs)
|
||||
: _usize(rhs._usize), _vsize(rhs._vsize), _elements(0)
|
||||
{
|
||||
allocate();
|
||||
fill(rhs._elements);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
CArray2D<T>::~CArray2D()
|
||||
{
|
||||
deallocate();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
CArray2D<T>& CArray2D<T>::operator=(const CArray2D<T>& rhs)
|
||||
{
|
||||
if (this==&rhs)
|
||||
return *this;
|
||||
|
||||
deallocate();
|
||||
|
||||
_usize=rhs._usize;
|
||||
_vsize=rhs._vsize;
|
||||
|
||||
allocate();
|
||||
fill(rhs._elements);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void CArray2D<T>::allocate()
|
||||
{
|
||||
assert(_elements==0);
|
||||
_elements=new T[_usize*_vsize];
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void CArray2D<T>::deallocate()
|
||||
{
|
||||
delete[] _elements;
|
||||
_elements=0;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
int CArray2D<T>::usize() const
|
||||
{
|
||||
return _usize;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
int CArray2D<T>::vsize() const
|
||||
{
|
||||
return _vsize;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void CArray2D<T>::size(int& usize,int& vsize) const
|
||||
{
|
||||
usize=_usize;
|
||||
vsize=_vsize;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void CArray2D<T>::resize(int usize,int vsize)
|
||||
{
|
||||
deallocate();
|
||||
|
||||
_usize=usize;
|
||||
_vsize=vsize;
|
||||
allocate();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void CArray2D<T>::fill(const T* elements)
|
||||
{
|
||||
memcpy(_elements,elements,sizeof(T)*_usize*_vsize);
|
||||
}
|
||||
|
||||
|
||||
// operator()(int r,int c)
|
||||
// return the element at (r,c) (ie c'th element in r'th row)
|
||||
template <class T>
|
||||
T& CArray2D<T>::operator()(int u,int v)
|
||||
{
|
||||
assert(u>=0 && u<_usize);
|
||||
assert(v>=0 && v<_vsize);
|
||||
return _elements[(u*_vsize)+v];
|
||||
}
|
||||
|
||||
template <class T>
|
||||
const T& CArray2D<T>::operator()(int u,int v) const
|
||||
{
|
||||
assert(u>=0 && u<_usize);
|
||||
assert(v>=0 && v<_vsize);
|
||||
return _elements[(u*_vsize)+v];
|
||||
}
|
||||
|
||||
template <class T>
|
||||
T& CArray2D<T>::at(int u,int v)
|
||||
{
|
||||
assert(u>=0 && u<_usize);
|
||||
assert(v>=0 && v<_vsize);
|
||||
return _elements[(u*_vsize)+v];
|
||||
}
|
||||
|
||||
template <class T>
|
||||
const T& CArray2D<T>::at(int u,int v) const
|
||||
{
|
||||
assert(u>=0 && u<_usize);
|
||||
assert(v>=0 && v<_vsize);
|
||||
return _elements[(u*_vsize)+v];
|
||||
}
|
||||
|
||||
template <class T>
|
||||
CArray2D<T>::operator T*()
|
||||
{
|
||||
return _elements;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
CArray2D<T>::operator const T*() const
|
||||
{
|
||||
return _elements;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#endif
|
||||
|
@ -1,92 +1,92 @@
|
||||
#include "stdafx.h"
|
||||
#include "MainFrm.h"
|
||||
#include "EditorData.h"
|
||||
#include "BrushShapeEditorTool.h"
|
||||
#include "BrushShapeEditorDlgBar.h"
|
||||
|
||||
|
||||
BEGIN_MESSAGE_MAP(CBrushShapeEditorDlgBar, CDialogBar)
|
||||
//{{AFX_MSG_MAP(CBrushShapeEditorDlgBar)
|
||||
// NOTE - the ClassWizard will add and remove mapping macros here.
|
||||
//}}AFX_MSG_MAP
|
||||
ON_BN_CLICKED(IDC_BUTTON_BACK, OnButtonBack)
|
||||
ON_BN_CLICKED(IDC_BUTTON_ADD, OnButtonAdd)
|
||||
ON_CBN_SELCHANGE(IDC_COMBO_TERRAINTYPES, OnSelChangeBrush)
|
||||
ON_NOTIFY(NM_RELEASEDCAPTURE, IDC_SLIDER_BRUSHSIZE, OnReleasedCaptureSliderBrushSize)
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
|
||||
CBrushShapeEditorDlgBar::CBrushShapeEditorDlgBar()
|
||||
{
|
||||
}
|
||||
|
||||
CBrushShapeEditorDlgBar::~CBrushShapeEditorDlgBar()
|
||||
{
|
||||
}
|
||||
|
||||
BOOL CBrushShapeEditorDlgBar::Create(CWnd * pParentWnd, LPCTSTR lpszTemplateName,UINT nStyle, UINT nID)
|
||||
{
|
||||
if (!CDialogBar::Create(pParentWnd, lpszTemplateName, nStyle, nID)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!OnInitDialog()) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL CBrushShapeEditorDlgBar::Create(CWnd * pParentWnd, UINT nIDTemplate,UINT nStyle, UINT nID)
|
||||
{
|
||||
if (!Create(pParentWnd, MAKEINTRESOURCE(nIDTemplate), nStyle, nID)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void CBrushShapeEditorDlgBar::OnButtonAdd()
|
||||
{
|
||||
}
|
||||
|
||||
BOOL CBrushShapeEditorDlgBar::OnInitDialog()
|
||||
{
|
||||
// get the current window size and position
|
||||
CRect rect;
|
||||
GetWindowRect(rect);
|
||||
|
||||
// now change the size, position, and Z order of the window.
|
||||
::SetWindowPos(m_hWnd,HWND_TOPMOST,10,rect.top,rect.Width(),rect.Height(),SWP_HIDEWINDOW);
|
||||
|
||||
// set up brush size slider
|
||||
CSliderCtrl* sliderctrl=(CSliderCtrl*) GetDlgItem(IDC_SLIDER_BRUSHSIZE);
|
||||
sliderctrl->SetRange(0,CBrushShapeEditorTool::MAX_BRUSH_SIZE);
|
||||
sliderctrl->SetPos(CBrushShapeEditorTool::GetTool()->GetBrushSize());
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void CBrushShapeEditorDlgBar::OnUpdateCmdUI(CFrameWnd* pTarget, BOOL bDisableIfNoHndler)
|
||||
{
|
||||
bDisableIfNoHndler = FALSE;
|
||||
CDialogBar::OnUpdateCmdUI(pTarget,bDisableIfNoHndler);
|
||||
}
|
||||
|
||||
void CBrushShapeEditorDlgBar::OnReleasedCaptureSliderBrushSize(NMHDR* pNMHDR, LRESULT* pResult)
|
||||
{
|
||||
CSliderCtrl* sliderctrl=(CSliderCtrl*) GetDlgItem(IDC_SLIDER_BRUSHSIZE);
|
||||
CBrushShapeEditorTool::GetTool()->SetBrushSize(sliderctrl->GetPos());
|
||||
*pResult = 0;
|
||||
}
|
||||
|
||||
|
||||
void CBrushShapeEditorDlgBar::OnSelChangeBrush()
|
||||
{
|
||||
}
|
||||
|
||||
void CBrushShapeEditorDlgBar::OnButtonBack()
|
||||
{
|
||||
CMainFrame* mainfrm=(CMainFrame*) AfxGetMainWnd();
|
||||
mainfrm->DeselectTools();
|
||||
}
|
||||
#include "stdafx.h"
|
||||
#include "MainFrm.h"
|
||||
#include "EditorData.h"
|
||||
#include "BrushShapeEditorTool.h"
|
||||
#include "BrushShapeEditorDlgBar.h"
|
||||
|
||||
|
||||
BEGIN_MESSAGE_MAP(CBrushShapeEditorDlgBar, CDialogBar)
|
||||
//{{AFX_MSG_MAP(CBrushShapeEditorDlgBar)
|
||||
// NOTE - the ClassWizard will add and remove mapping macros here.
|
||||
//}}AFX_MSG_MAP
|
||||
ON_BN_CLICKED(IDC_BUTTON_BACK, OnButtonBack)
|
||||
ON_BN_CLICKED(IDC_BUTTON_ADD, OnButtonAdd)
|
||||
ON_CBN_SELCHANGE(IDC_COMBO_TERRAINTYPES, OnSelChangeBrush)
|
||||
ON_NOTIFY(NM_RELEASEDCAPTURE, IDC_SLIDER_BRUSHSIZE, OnReleasedCaptureSliderBrushSize)
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
|
||||
CBrushShapeEditorDlgBar::CBrushShapeEditorDlgBar()
|
||||
{
|
||||
}
|
||||
|
||||
CBrushShapeEditorDlgBar::~CBrushShapeEditorDlgBar()
|
||||
{
|
||||
}
|
||||
|
||||
BOOL CBrushShapeEditorDlgBar::Create(CWnd * pParentWnd, LPCTSTR lpszTemplateName,UINT nStyle, UINT nID)
|
||||
{
|
||||
if (!CDialogBar::Create(pParentWnd, lpszTemplateName, nStyle, nID)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!OnInitDialog()) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL CBrushShapeEditorDlgBar::Create(CWnd * pParentWnd, UINT nIDTemplate,UINT nStyle, UINT nID)
|
||||
{
|
||||
if (!Create(pParentWnd, MAKEINTRESOURCE(nIDTemplate), nStyle, nID)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void CBrushShapeEditorDlgBar::OnButtonAdd()
|
||||
{
|
||||
}
|
||||
|
||||
BOOL CBrushShapeEditorDlgBar::OnInitDialog()
|
||||
{
|
||||
// get the current window size and position
|
||||
CRect rect;
|
||||
GetWindowRect(rect);
|
||||
|
||||
// now change the size, position, and Z order of the window.
|
||||
::SetWindowPos(m_hWnd,HWND_TOPMOST,10,rect.top,rect.Width(),rect.Height(),SWP_HIDEWINDOW);
|
||||
|
||||
// set up brush size slider
|
||||
CSliderCtrl* sliderctrl=(CSliderCtrl*) GetDlgItem(IDC_SLIDER_BRUSHSIZE);
|
||||
sliderctrl->SetRange(0,CBrushShapeEditorTool::MAX_BRUSH_SIZE);
|
||||
sliderctrl->SetPos(CBrushShapeEditorTool::GetTool()->GetBrushSize());
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void CBrushShapeEditorDlgBar::OnUpdateCmdUI(CFrameWnd* pTarget, BOOL bDisableIfNoHndler)
|
||||
{
|
||||
bDisableIfNoHndler = FALSE;
|
||||
CDialogBar::OnUpdateCmdUI(pTarget,bDisableIfNoHndler);
|
||||
}
|
||||
|
||||
void CBrushShapeEditorDlgBar::OnReleasedCaptureSliderBrushSize(NMHDR* pNMHDR, LRESULT* pResult)
|
||||
{
|
||||
CSliderCtrl* sliderctrl=(CSliderCtrl*) GetDlgItem(IDC_SLIDER_BRUSHSIZE);
|
||||
CBrushShapeEditorTool::GetTool()->SetBrushSize(sliderctrl->GetPos());
|
||||
*pResult = 0;
|
||||
}
|
||||
|
||||
|
||||
void CBrushShapeEditorDlgBar::OnSelChangeBrush()
|
||||
{
|
||||
}
|
||||
|
||||
void CBrushShapeEditorDlgBar::OnButtonBack()
|
||||
{
|
||||
CMainFrame* mainfrm=(CMainFrame*) AfxGetMainWnd();
|
||||
mainfrm->DeselectTools();
|
||||
}
|
||||
|
@ -1,31 +1,31 @@
|
||||
#ifndef _BRUSHSHAPEEDITORDLGBAR_H
|
||||
#define _BRUSHSHAPEEDITORDLGBAR_H
|
||||
|
||||
class CBrushShapeEditorDlgBar : public CDialogBar
|
||||
{
|
||||
// DECLARE_DYNAMIC(CInitDialogBar)
|
||||
public:
|
||||
CBrushShapeEditorDlgBar();
|
||||
~CBrushShapeEditorDlgBar();
|
||||
|
||||
BOOL Create(CWnd * pParentWnd, UINT nIDTemplate, UINT nStyle, UINT nID);
|
||||
BOOL Create(CWnd * pParentWnd, LPCTSTR lpszTemplateName, UINT nStyle, UINT nID);
|
||||
void OnUpdateCmdUI(CFrameWnd* pTarget, BOOL bDisableIfNoHndler);
|
||||
|
||||
protected:
|
||||
|
||||
BOOL OnInitDialog();
|
||||
|
||||
// Generated message map functions
|
||||
//{{AFX_MSG(CBrushShapeEditorDlgBar)
|
||||
afx_msg void OnButtonAdd();
|
||||
afx_msg void OnButtonBack();
|
||||
afx_msg void OnReleasedCaptureSliderBrushSize(NMHDR* pNMHDR, LRESULT* pResult);
|
||||
afx_msg void OnSelChangeBrush();
|
||||
//}}AFX_MSG
|
||||
DECLARE_MESSAGE_MAP()
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef _BRUSHSHAPEEDITORDLGBAR_H
|
||||
#define _BRUSHSHAPEEDITORDLGBAR_H
|
||||
|
||||
class CBrushShapeEditorDlgBar : public CDialogBar
|
||||
{
|
||||
// DECLARE_DYNAMIC(CInitDialogBar)
|
||||
public:
|
||||
CBrushShapeEditorDlgBar();
|
||||
~CBrushShapeEditorDlgBar();
|
||||
|
||||
BOOL Create(CWnd * pParentWnd, UINT nIDTemplate, UINT nStyle, UINT nID);
|
||||
BOOL Create(CWnd * pParentWnd, LPCTSTR lpszTemplateName, UINT nStyle, UINT nID);
|
||||
void OnUpdateCmdUI(CFrameWnd* pTarget, BOOL bDisableIfNoHndler);
|
||||
|
||||
protected:
|
||||
|
||||
BOOL OnInitDialog();
|
||||
|
||||
// Generated message map functions
|
||||
//{{AFX_MSG(CBrushShapeEditorDlgBar)
|
||||
afx_msg void OnButtonAdd();
|
||||
afx_msg void OnButtonBack();
|
||||
afx_msg void OnReleasedCaptureSliderBrushSize(NMHDR* pNMHDR, LRESULT* pResult);
|
||||
afx_msg void OnSelChangeBrush();
|
||||
//}}AFX_MSG
|
||||
DECLARE_MESSAGE_MAP()
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -1,86 +1,86 @@
|
||||
#include "BrushShapeEditorTool.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "ogl.h"
|
||||
|
||||
// default tool instance
|
||||
CBrushShapeEditorTool CBrushShapeEditorTool::m_BrushShapeEditorTool;
|
||||
|
||||
|
||||
CBrushShapeEditorTool::CBrushShapeEditorTool() : m_BrushSize(5), m_BrushData(0)
|
||||
{
|
||||
m_BrushData=new bool[m_BrushSize*m_BrushSize];
|
||||
memset(m_BrushData,0,sizeof(bool)*m_BrushSize*m_BrushSize);
|
||||
}
|
||||
|
||||
void CBrushShapeEditorTool::OnDraw()
|
||||
{
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
|
||||
glDepthMask(0);
|
||||
|
||||
// draw grid
|
||||
|
||||
// draw state of each bit in the brush
|
||||
int r=m_BrushSize;
|
||||
// iterate through selected patches
|
||||
for (int j=0;j<r;j++) {
|
||||
for (int i=0;i<r;i++) {
|
||||
if (m_BrushData[j*m_BrushSize+i]) {
|
||||
// draw filled quad here
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
glDepthMask(1);
|
||||
}
|
||||
|
||||
void CBrushShapeEditorTool::OnLButtonDown(unsigned int flags,int px,int py)
|
||||
{
|
||||
// check for bit under cursor
|
||||
if (0) {
|
||||
// switch if on
|
||||
}
|
||||
}
|
||||
|
||||
void CBrushShapeEditorTool::OnRButtonDown(unsigned int flags,int px,int py)
|
||||
{
|
||||
// check for bit under cursor
|
||||
if (0) {
|
||||
// switch it off
|
||||
}
|
||||
}
|
||||
|
||||
void CBrushShapeEditorTool::OnMouseMove(unsigned int flags,int px,int py)
|
||||
{
|
||||
/*
|
||||
if (flags & TOOL_MOUSEFLAG_LBUTTONDOWN) {
|
||||
OnLButtonDown(flags,px,py);
|
||||
} else if (flags & TOOL_MOUSEFLAG_RBUTTONDOWN) {
|
||||
OnRButtonDown(flags,px,py);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
void CBrushShapeEditorTool::SetBrushSize(int size)
|
||||
{
|
||||
// allocate new data
|
||||
bool* newdata=new bool[size*size];
|
||||
memset(newdata,0,sizeof(bool)*size*size);
|
||||
|
||||
// copy data from old to new
|
||||
bool* src=m_BrushData;
|
||||
bool* dst=newdata;
|
||||
u32 copysize=size>m_BrushSize ? m_BrushSize : size;
|
||||
for (u32 j=0;j<copysize;j++) {
|
||||
memcpy(dst,src,copysize*sizeof(bool));
|
||||
dst+=copysize;
|
||||
src+=m_BrushSize;
|
||||
}
|
||||
|
||||
// clean up and assign new data as current
|
||||
delete[] m_BrushData;
|
||||
m_BrushData=newdata;
|
||||
#include "BrushShapeEditorTool.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "ogl.h"
|
||||
|
||||
// default tool instance
|
||||
CBrushShapeEditorTool CBrushShapeEditorTool::m_BrushShapeEditorTool;
|
||||
|
||||
|
||||
CBrushShapeEditorTool::CBrushShapeEditorTool() : m_BrushSize(5), m_BrushData(0)
|
||||
{
|
||||
m_BrushData=new bool[m_BrushSize*m_BrushSize];
|
||||
memset(m_BrushData,0,sizeof(bool)*m_BrushSize*m_BrushSize);
|
||||
}
|
||||
|
||||
void CBrushShapeEditorTool::OnDraw()
|
||||
{
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
|
||||
glDepthMask(0);
|
||||
|
||||
// draw grid
|
||||
|
||||
// draw state of each bit in the brush
|
||||
int r=m_BrushSize;
|
||||
// iterate through selected patches
|
||||
for (int j=0;j<r;j++) {
|
||||
for (int i=0;i<r;i++) {
|
||||
if (m_BrushData[j*m_BrushSize+i]) {
|
||||
// draw filled quad here
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
glDepthMask(1);
|
||||
}
|
||||
|
||||
void CBrushShapeEditorTool::OnLButtonDown(unsigned int flags,int px,int py)
|
||||
{
|
||||
// check for bit under cursor
|
||||
if (0) {
|
||||
// switch if on
|
||||
}
|
||||
}
|
||||
|
||||
void CBrushShapeEditorTool::OnRButtonDown(unsigned int flags,int px,int py)
|
||||
{
|
||||
// check for bit under cursor
|
||||
if (0) {
|
||||
// switch it off
|
||||
}
|
||||
}
|
||||
|
||||
void CBrushShapeEditorTool::OnMouseMove(unsigned int flags,int px,int py)
|
||||
{
|
||||
/*
|
||||
if (flags & TOOL_MOUSEFLAG_LBUTTONDOWN) {
|
||||
OnLButtonDown(flags,px,py);
|
||||
} else if (flags & TOOL_MOUSEFLAG_RBUTTONDOWN) {
|
||||
OnRButtonDown(flags,px,py);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
void CBrushShapeEditorTool::SetBrushSize(int size)
|
||||
{
|
||||
// allocate new data
|
||||
bool* newdata=new bool[size*size];
|
||||
memset(newdata,0,sizeof(bool)*size*size);
|
||||
|
||||
// copy data from old to new
|
||||
bool* src=m_BrushData;
|
||||
bool* dst=newdata;
|
||||
u32 copysize=size>m_BrushSize ? m_BrushSize : size;
|
||||
for (u32 j=0;j<copysize;j++) {
|
||||
memcpy(dst,src,copysize*sizeof(bool));
|
||||
dst+=copysize;
|
||||
src+=m_BrushSize;
|
||||
}
|
||||
|
||||
// clean up and assign new data as current
|
||||
delete[] m_BrushData;
|
||||
m_BrushData=newdata;
|
||||
}
|
@ -1,44 +1,44 @@
|
||||
#ifndef _BRUSHSHAPEEDITORTOOL_H
|
||||
#define _BRUSHSHAPEEDITORTOOL_H
|
||||
|
||||
#include "res/res.h"
|
||||
#include "Tool.h"
|
||||
|
||||
class CPatch;
|
||||
class CMiniPatch;
|
||||
|
||||
class CBrushShapeEditorTool : public CTool
|
||||
{
|
||||
public:
|
||||
enum { MAX_BRUSH_SIZE=8 };
|
||||
|
||||
public:
|
||||
CBrushShapeEditorTool();
|
||||
|
||||
// draw the visual representation of this tool
|
||||
void OnDraw();
|
||||
// callback for left button down event
|
||||
void OnLButtonDown(unsigned int flags,int px,int py);
|
||||
// callback for right button down event
|
||||
void OnRButtonDown(unsigned int flags,int px,int py);
|
||||
// callback for mouse move event
|
||||
void OnMouseMove(unsigned int flags,int px,int py);
|
||||
|
||||
// set current brush size
|
||||
void SetBrushSize(int size);
|
||||
// get current brush size
|
||||
int GetBrushSize() { return m_BrushSize; }
|
||||
|
||||
// get the default brush shape editor instance
|
||||
static CBrushShapeEditorTool* GetTool() { return &m_BrushShapeEditorTool; }
|
||||
|
||||
protected:
|
||||
// current tool brush size
|
||||
int m_BrushSize;
|
||||
// on/off state of each bit in the brush
|
||||
bool* m_BrushData;
|
||||
// default tool instance
|
||||
static CBrushShapeEditorTool m_BrushShapeEditorTool;
|
||||
};
|
||||
|
||||
#endif
|
||||
#ifndef _BRUSHSHAPEEDITORTOOL_H
|
||||
#define _BRUSHSHAPEEDITORTOOL_H
|
||||
|
||||
#include "res/res.h"
|
||||
#include "Tool.h"
|
||||
|
||||
class CPatch;
|
||||
class CMiniPatch;
|
||||
|
||||
class CBrushShapeEditorTool : public CTool
|
||||
{
|
||||
public:
|
||||
enum { MAX_BRUSH_SIZE=8 };
|
||||
|
||||
public:
|
||||
CBrushShapeEditorTool();
|
||||
|
||||
// draw the visual representation of this tool
|
||||
void OnDraw();
|
||||
// callback for left button down event
|
||||
void OnLButtonDown(unsigned int flags,int px,int py);
|
||||
// callback for right button down event
|
||||
void OnRButtonDown(unsigned int flags,int px,int py);
|
||||
// callback for mouse move event
|
||||
void OnMouseMove(unsigned int flags,int px,int py);
|
||||
|
||||
// set current brush size
|
||||
void SetBrushSize(int size);
|
||||
// get current brush size
|
||||
int GetBrushSize() { return m_BrushSize; }
|
||||
|
||||
// get the default brush shape editor instance
|
||||
static CBrushShapeEditorTool* GetTool() { return &m_BrushShapeEditorTool; }
|
||||
|
||||
protected:
|
||||
// current tool brush size
|
||||
int m_BrushSize;
|
||||
// on/off state of each bit in the brush
|
||||
bool* m_BrushData;
|
||||
// default tool instance
|
||||
static CBrushShapeEditorTool m_BrushShapeEditorTool;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -1,150 +1,150 @@
|
||||
#include "BrushTool.h"
|
||||
#include "UIGlobals.h"
|
||||
#include "HFTracer.h"
|
||||
#include "NaviCam.h"
|
||||
#include "TextureManager.h"
|
||||
#include "Camera.h"
|
||||
#include "Terrain.h"
|
||||
#include "Renderer.h"
|
||||
#include "ogl.h"
|
||||
#include <list>
|
||||
|
||||
extern CCamera g_Camera;
|
||||
extern CTerrain g_Terrain;
|
||||
|
||||
CBrushTool::CBrushTool() : m_BrushSize(1), m_LButtonDown(false), m_RButtonDown(false)
|
||||
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
static void RenderTileOutline(int gx,int gz)
|
||||
{
|
||||
CMiniPatch* mpatch=g_Terrain.GetTile(gx,gz);
|
||||
if (!mpatch) return;
|
||||
|
||||
u32 mapSize=g_Terrain.GetVerticesPerSide();
|
||||
|
||||
CVector3D V[4];
|
||||
g_Terrain.CalcPosition(gx,gz,V[0]);
|
||||
g_Terrain.CalcPosition(gx+1,gz,V[1]);
|
||||
g_Terrain.CalcPosition(gx+1,gz+1,V[2]);
|
||||
g_Terrain.CalcPosition(gx,gz+1,V[3]);
|
||||
|
||||
glLineWidth(2);
|
||||
glColor4f(0.05f,0.95f,0.1f,0.75f);
|
||||
|
||||
glBegin (GL_LINE_LOOP);
|
||||
|
||||
for(int i = 0; i < 4; i++)
|
||||
glVertex3fv(&V[i].X);
|
||||
|
||||
glEnd ();
|
||||
|
||||
glColor4f (0.1f,0.9f,0.15f,0.35f);
|
||||
|
||||
glBegin (GL_QUADS);
|
||||
|
||||
for(i = 0; i < 4; i++)
|
||||
glVertex3fv(&V[i].X);
|
||||
|
||||
glEnd ();
|
||||
}
|
||||
|
||||
void CBrushTool::OnDraw()
|
||||
{
|
||||
glActiveTexture (GL_TEXTURE0);
|
||||
glDisable (GL_TEXTURE_2D);
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
glDepthMask(0);
|
||||
|
||||
int r=m_BrushSize;
|
||||
// iterate through selected patches
|
||||
for (int j=m_SelectionCentre[1]-r;j<=m_SelectionCentre[1]+r;j++) {
|
||||
for (int i=m_SelectionCentre[0]-r;i<=m_SelectionCentre[0]+r;i++) {
|
||||
RenderTileOutline(i,j);
|
||||
}
|
||||
}
|
||||
|
||||
glDepthMask(1);
|
||||
|
||||
glDisable(GL_BLEND);
|
||||
}
|
||||
|
||||
void CBrushTool::OnLButtonDown(unsigned int flags,int px,int py)
|
||||
{
|
||||
m_LButtonDown=true;
|
||||
OnTriggerLeft();
|
||||
}
|
||||
|
||||
void CBrushTool::OnLButtonUp(unsigned int flags,int px,int py)
|
||||
{
|
||||
m_LButtonDown=false;
|
||||
}
|
||||
|
||||
void CBrushTool::OnRButtonDown(unsigned int flags,int px,int py)
|
||||
{
|
||||
m_RButtonDown=true;
|
||||
OnTriggerRight();
|
||||
}
|
||||
|
||||
void CBrushTool::OnRButtonUp(unsigned int flags,int px,int py)
|
||||
{
|
||||
m_RButtonDown=false;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
// BuildCameraRay: calculate origin and ray direction of a ray through
|
||||
// the pixel (px,py) on the screen
|
||||
void CBrushTool::BuildCameraRay(int px,int py,CVector3D& origin,CVector3D& dir)
|
||||
{
|
||||
// get points on far plane of frustum in camera space
|
||||
CCamera& camera=g_NaviCam.GetCamera();
|
||||
CVector3D cPts[4];
|
||||
camera.GetCameraPlanePoints(camera.GetFarPlane(),cPts);
|
||||
|
||||
// transform to world space
|
||||
CVector3D wPts[4];
|
||||
for (int i=0;i<4;i++) {
|
||||
wPts[i]=camera.m_Orientation.Transform(cPts[i]);
|
||||
}
|
||||
|
||||
// get world space position of mouse point
|
||||
float dx=float(px)/float(g_Renderer.GetWidth());
|
||||
float dz=1-float(py)/float(g_Renderer.GetHeight());
|
||||
CVector3D vdx=wPts[1]-wPts[0];
|
||||
CVector3D vdz=wPts[3]-wPts[0];
|
||||
CVector3D pt=wPts[0]+(vdx*dx)+(vdz*dz);
|
||||
|
||||
// copy origin
|
||||
origin=camera.m_Orientation.GetTranslation();
|
||||
// build direction
|
||||
dir=pt-origin;
|
||||
dir.Normalize();
|
||||
}
|
||||
|
||||
void CBrushTool::OnMouseMove(unsigned int flags,int px,int py)
|
||||
{
|
||||
// build camera ray
|
||||
CVector3D rayorigin,raydir;
|
||||
BuildCameraRay(px,py,rayorigin,raydir);
|
||||
|
||||
// intersect with terrain
|
||||
CVector3D ipt;
|
||||
CHFTracer hftracer(g_Terrain.GetHeightMap(),g_Terrain.GetVerticesPerSide(),float(CELL_SIZE),HEIGHT_SCALE);
|
||||
if (hftracer.RayIntersect(rayorigin,raydir,m_SelectionCentre[0],m_SelectionCentre[1],m_SelectionPoint)) {
|
||||
// drag trigger supported?
|
||||
if (SupportDragTrigger()) {
|
||||
// yes - handle mouse button down state
|
||||
if (m_LButtonDown) {
|
||||
OnTriggerLeft();
|
||||
} else if (m_RButtonDown) {
|
||||
OnTriggerRight();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#include "BrushTool.h"
|
||||
#include "UIGlobals.h"
|
||||
#include "HFTracer.h"
|
||||
#include "NaviCam.h"
|
||||
#include "TextureManager.h"
|
||||
#include "Camera.h"
|
||||
#include "Terrain.h"
|
||||
#include "Renderer.h"
|
||||
#include "ogl.h"
|
||||
#include <list>
|
||||
|
||||
extern CCamera g_Camera;
|
||||
extern CTerrain g_Terrain;
|
||||
|
||||
CBrushTool::CBrushTool() : m_BrushSize(1), m_LButtonDown(false), m_RButtonDown(false)
|
||||
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
static void RenderTileOutline(int gx,int gz)
|
||||
{
|
||||
CMiniPatch* mpatch=g_Terrain.GetTile(gx,gz);
|
||||
if (!mpatch) return;
|
||||
|
||||
u32 mapSize=g_Terrain.GetVerticesPerSide();
|
||||
|
||||
CVector3D V[4];
|
||||
g_Terrain.CalcPosition(gx,gz,V[0]);
|
||||
g_Terrain.CalcPosition(gx+1,gz,V[1]);
|
||||
g_Terrain.CalcPosition(gx+1,gz+1,V[2]);
|
||||
g_Terrain.CalcPosition(gx,gz+1,V[3]);
|
||||
|
||||
glLineWidth(2);
|
||||
glColor4f(0.05f,0.95f,0.1f,0.75f);
|
||||
|
||||
glBegin (GL_LINE_LOOP);
|
||||
|
||||
for(int i = 0; i < 4; i++)
|
||||
glVertex3fv(&V[i].X);
|
||||
|
||||
glEnd ();
|
||||
|
||||
glColor4f (0.1f,0.9f,0.15f,0.35f);
|
||||
|
||||
glBegin (GL_QUADS);
|
||||
|
||||
for(i = 0; i < 4; i++)
|
||||
glVertex3fv(&V[i].X);
|
||||
|
||||
glEnd ();
|
||||
}
|
||||
|
||||
void CBrushTool::OnDraw()
|
||||
{
|
||||
glActiveTexture (GL_TEXTURE0);
|
||||
glDisable (GL_TEXTURE_2D);
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
glDepthMask(0);
|
||||
|
||||
int r=m_BrushSize;
|
||||
// iterate through selected patches
|
||||
for (int j=m_SelectionCentre[1]-r;j<=m_SelectionCentre[1]+r;j++) {
|
||||
for (int i=m_SelectionCentre[0]-r;i<=m_SelectionCentre[0]+r;i++) {
|
||||
RenderTileOutline(i,j);
|
||||
}
|
||||
}
|
||||
|
||||
glDepthMask(1);
|
||||
|
||||
glDisable(GL_BLEND);
|
||||
}
|
||||
|
||||
void CBrushTool::OnLButtonDown(unsigned int flags,int px,int py)
|
||||
{
|
||||
m_LButtonDown=true;
|
||||
OnTriggerLeft();
|
||||
}
|
||||
|
||||
void CBrushTool::OnLButtonUp(unsigned int flags,int px,int py)
|
||||
{
|
||||
m_LButtonDown=false;
|
||||
}
|
||||
|
||||
void CBrushTool::OnRButtonDown(unsigned int flags,int px,int py)
|
||||
{
|
||||
m_RButtonDown=true;
|
||||
OnTriggerRight();
|
||||
}
|
||||
|
||||
void CBrushTool::OnRButtonUp(unsigned int flags,int px,int py)
|
||||
{
|
||||
m_RButtonDown=false;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
// BuildCameraRay: calculate origin and ray direction of a ray through
|
||||
// the pixel (px,py) on the screen
|
||||
void CBrushTool::BuildCameraRay(int px,int py,CVector3D& origin,CVector3D& dir)
|
||||
{
|
||||
// get points on far plane of frustum in camera space
|
||||
CCamera& camera=g_NaviCam.GetCamera();
|
||||
CVector3D cPts[4];
|
||||
camera.GetCameraPlanePoints(camera.GetFarPlane(),cPts);
|
||||
|
||||
// transform to world space
|
||||
CVector3D wPts[4];
|
||||
for (int i=0;i<4;i++) {
|
||||
wPts[i]=camera.m_Orientation.Transform(cPts[i]);
|
||||
}
|
||||
|
||||
// get world space position of mouse point
|
||||
float dx=float(px)/float(g_Renderer.GetWidth());
|
||||
float dz=1-float(py)/float(g_Renderer.GetHeight());
|
||||
CVector3D vdx=wPts[1]-wPts[0];
|
||||
CVector3D vdz=wPts[3]-wPts[0];
|
||||
CVector3D pt=wPts[0]+(vdx*dx)+(vdz*dz);
|
||||
|
||||
// copy origin
|
||||
origin=camera.m_Orientation.GetTranslation();
|
||||
// build direction
|
||||
dir=pt-origin;
|
||||
dir.Normalize();
|
||||
}
|
||||
|
||||
void CBrushTool::OnMouseMove(unsigned int flags,int px,int py)
|
||||
{
|
||||
// build camera ray
|
||||
CVector3D rayorigin,raydir;
|
||||
BuildCameraRay(px,py,rayorigin,raydir);
|
||||
|
||||
// intersect with terrain
|
||||
CVector3D ipt;
|
||||
CHFTracer hftracer(g_Terrain.GetHeightMap(),g_Terrain.GetVerticesPerSide(),float(CELL_SIZE),HEIGHT_SCALE);
|
||||
if (hftracer.RayIntersect(rayorigin,raydir,m_SelectionCentre[0],m_SelectionCentre[1],m_SelectionPoint)) {
|
||||
// drag trigger supported?
|
||||
if (SupportDragTrigger()) {
|
||||
// yes - handle mouse button down state
|
||||
if (m_LButtonDown) {
|
||||
OnTriggerLeft();
|
||||
} else if (m_RButtonDown) {
|
||||
OnTriggerRight();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,64 +1,64 @@
|
||||
#ifndef _BRUSHTOOL_H
|
||||
#define _BRUSHTOOL_H
|
||||
|
||||
#include "res/res.h"
|
||||
#include "Tool.h"
|
||||
#include "Vector3D.h"
|
||||
|
||||
class CPatch;
|
||||
class CMiniPatch;
|
||||
|
||||
class CBrushTool : public CTool
|
||||
{
|
||||
public:
|
||||
CBrushTool();
|
||||
|
||||
// draw the visual representation of this tool
|
||||
virtual void OnDraw();
|
||||
// callback for left button down event
|
||||
virtual void OnLButtonDown(unsigned int flags,int px,int py);
|
||||
// callback for left button up event
|
||||
virtual void OnLButtonUp(unsigned int flags,int px,int py);
|
||||
// callback for right button down event
|
||||
virtual void OnRButtonDown(unsigned int flags,int px,int py);
|
||||
// callback for right button up event
|
||||
virtual void OnRButtonUp(unsigned int flags,int px,int py);
|
||||
// callback for mouse move event
|
||||
virtual void OnMouseMove(unsigned int flags,int px,int py);
|
||||
|
||||
// action to take when tool is triggered via left mouse, or left mouse + drag
|
||||
virtual void OnTriggerLeft() {};
|
||||
// action to take when tool is triggered via right mouse, or right mouse + drag
|
||||
virtual void OnTriggerRight() {};
|
||||
|
||||
// set current brush size
|
||||
void SetBrushSize(int size) { m_BrushSize=size; }
|
||||
// get current brush size
|
||||
int GetBrushSize() { return m_BrushSize; }
|
||||
|
||||
// virtual function: allow multiple triggers by click and drag? - else requires individual clicks
|
||||
// to invoke trigger .. default to off
|
||||
virtual bool SupportDragTrigger() { return false; }
|
||||
|
||||
protected:
|
||||
// build camera ray through screen point (px,py)
|
||||
void BuildCameraRay(int px,int py,CVector3D& origin,CVector3D& dir);
|
||||
// return true if given tile is on border of selection, false otherwise
|
||||
bool IsBorderSelection(int gx,int gz);
|
||||
// return true if given tile is a neighbour of the a border of selection, false otherwise
|
||||
bool IsNeighbourSelection(int gx,int gz);
|
||||
// build a selection of the given radius around the given minipatch
|
||||
void BuildSelection(int radius,CPatch* patch,CMiniPatch* minipatch);
|
||||
// left mouse button currently down?
|
||||
bool m_LButtonDown;
|
||||
// right mouse button currently down?
|
||||
bool m_RButtonDown;
|
||||
// current tool brush size
|
||||
int m_BrushSize;
|
||||
// centre of current selection
|
||||
int m_SelectionCentre[2];
|
||||
// world space "projection" of mouse point - somewhere in the m_SelectionCentre tile
|
||||
CVector3D m_SelectionPoint;
|
||||
};
|
||||
|
||||
#endif
|
||||
#ifndef _BRUSHTOOL_H
|
||||
#define _BRUSHTOOL_H
|
||||
|
||||
#include "res/res.h"
|
||||
#include "Tool.h"
|
||||
#include "Vector3D.h"
|
||||
|
||||
class CPatch;
|
||||
class CMiniPatch;
|
||||
|
||||
class CBrushTool : public CTool
|
||||
{
|
||||
public:
|
||||
CBrushTool();
|
||||
|
||||
// draw the visual representation of this tool
|
||||
virtual void OnDraw();
|
||||
// callback for left button down event
|
||||
virtual void OnLButtonDown(unsigned int flags,int px,int py);
|
||||
// callback for left button up event
|
||||
virtual void OnLButtonUp(unsigned int flags,int px,int py);
|
||||
// callback for right button down event
|
||||
virtual void OnRButtonDown(unsigned int flags,int px,int py);
|
||||
// callback for right button up event
|
||||
virtual void OnRButtonUp(unsigned int flags,int px,int py);
|
||||
// callback for mouse move event
|
||||
virtual void OnMouseMove(unsigned int flags,int px,int py);
|
||||
|
||||
// action to take when tool is triggered via left mouse, or left mouse + drag
|
||||
virtual void OnTriggerLeft() {};
|
||||
// action to take when tool is triggered via right mouse, or right mouse + drag
|
||||
virtual void OnTriggerRight() {};
|
||||
|
||||
// set current brush size
|
||||
void SetBrushSize(int size) { m_BrushSize=size; }
|
||||
// get current brush size
|
||||
int GetBrushSize() { return m_BrushSize; }
|
||||
|
||||
// virtual function: allow multiple triggers by click and drag? - else requires individual clicks
|
||||
// to invoke trigger .. default to off
|
||||
virtual bool SupportDragTrigger() { return false; }
|
||||
|
||||
protected:
|
||||
// build camera ray through screen point (px,py)
|
||||
void BuildCameraRay(int px,int py,CVector3D& origin,CVector3D& dir);
|
||||
// return true if given tile is on border of selection, false otherwise
|
||||
bool IsBorderSelection(int gx,int gz);
|
||||
// return true if given tile is a neighbour of the a border of selection, false otherwise
|
||||
bool IsNeighbourSelection(int gx,int gz);
|
||||
// build a selection of the given radius around the given minipatch
|
||||
void BuildSelection(int radius,CPatch* patch,CMiniPatch* minipatch);
|
||||
// left mouse button currently down?
|
||||
bool m_LButtonDown;
|
||||
// right mouse button currently down?
|
||||
bool m_RButtonDown;
|
||||
// current tool brush size
|
||||
int m_BrushSize;
|
||||
// centre of current selection
|
||||
int m_SelectionCentre[2];
|
||||
// world space "projection" of mouse point - somewhere in the m_SelectionCentre tile
|
||||
CVector3D m_SelectionPoint;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -1,56 +1,56 @@
|
||||
// ColorButton.cpp : implementation file
|
||||
//
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "ScEd.h"
|
||||
#include "ColorButton.h"
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CColorButton
|
||||
|
||||
CColorButton::CColorButton() : m_Color(0)
|
||||
{
|
||||
}
|
||||
|
||||
CColorButton::~CColorButton()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
BEGIN_MESSAGE_MAP(CColorButton, CButton)
|
||||
//{{AFX_MSG_MAP(CColorButton)
|
||||
ON_CONTROL_REFLECT(BN_CLICKED, OnClicked)
|
||||
//}}AFX_MSG_MAP
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CColorButton message handlers
|
||||
|
||||
void CColorButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
|
||||
{
|
||||
CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
|
||||
CRect rect = lpDrawItemStruct->rcItem;
|
||||
|
||||
// draw button edges
|
||||
pDC->DrawFrameControl(rect, DFC_BUTTON,DFCS_BUTTONPUSH | DFCS_FLAT );
|
||||
|
||||
// deflate the drawing rect by the size of the button's edges
|
||||
rect.DeflateRect( CSize(GetSystemMetrics(SM_CXEDGE), GetSystemMetrics(SM_CYEDGE)));
|
||||
|
||||
// fill the interior color
|
||||
pDC->FillSolidRect(rect,m_Color);
|
||||
}
|
||||
|
||||
|
||||
void CColorButton::OnClicked()
|
||||
{
|
||||
CColorDialog dlg;
|
||||
if (dlg.DoModal()==IDOK) {
|
||||
// store color in button
|
||||
m_Color=dlg.m_cc.rgbResult;
|
||||
// force redraw
|
||||
Invalidate();
|
||||
UpdateWindow();
|
||||
}
|
||||
}
|
||||
// ColorButton.cpp : implementation file
|
||||
//
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "ScEd.h"
|
||||
#include "ColorButton.h"
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CColorButton
|
||||
|
||||
CColorButton::CColorButton() : m_Color(0)
|
||||
{
|
||||
}
|
||||
|
||||
CColorButton::~CColorButton()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
BEGIN_MESSAGE_MAP(CColorButton, CButton)
|
||||
//{{AFX_MSG_MAP(CColorButton)
|
||||
ON_CONTROL_REFLECT(BN_CLICKED, OnClicked)
|
||||
//}}AFX_MSG_MAP
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CColorButton message handlers
|
||||
|
||||
void CColorButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
|
||||
{
|
||||
CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
|
||||
CRect rect = lpDrawItemStruct->rcItem;
|
||||
|
||||
// draw button edges
|
||||
pDC->DrawFrameControl(rect, DFC_BUTTON,DFCS_BUTTONPUSH | DFCS_FLAT );
|
||||
|
||||
// deflate the drawing rect by the size of the button's edges
|
||||
rect.DeflateRect( CSize(GetSystemMetrics(SM_CXEDGE), GetSystemMetrics(SM_CYEDGE)));
|
||||
|
||||
// fill the interior color
|
||||
pDC->FillSolidRect(rect,m_Color);
|
||||
}
|
||||
|
||||
|
||||
void CColorButton::OnClicked()
|
||||
{
|
||||
CColorDialog dlg;
|
||||
if (dlg.DoModal()==IDOK) {
|
||||
// store color in button
|
||||
m_Color=dlg.m_cc.rgbResult;
|
||||
// force redraw
|
||||
Invalidate();
|
||||
UpdateWindow();
|
||||
}
|
||||
}
|
||||
|
@ -1,77 +1,77 @@
|
||||
#if !defined(AFX_COLORBUTTON_H__DBA27321_CEB1_4D75_9225_AFF2B02FCD82__INCLUDED_)
|
||||
#define AFX_COLORBUTTON_H__DBA27321_CEB1_4D75_9225_AFF2B02FCD82__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
// ColorButton.h : header file
|
||||
//
|
||||
|
||||
#include "Color.h"
|
||||
|
||||
inline void ColorRefToRGBColor(COLORREF c,RGBColor& result)
|
||||
{
|
||||
result.X=(c & 0xff)/255.0f;
|
||||
result.Y=((c>>8) & 0xff)/255.0f;
|
||||
result.Z=((c>>16) & 0xff)/255.0f;
|
||||
}
|
||||
|
||||
inline void RGBColorToColorRef(const RGBColor& c,COLORREF& result)
|
||||
{
|
||||
int r=int(c.X*255);
|
||||
if (r<0) r=0;
|
||||
if (r>255) r=255;
|
||||
|
||||
int g=int(c.Y*255);
|
||||
if (g<0) g=0;
|
||||
if (g>255) g=255;
|
||||
|
||||
int b=int(c.Z*255);
|
||||
if (b<0) b=0;
|
||||
if (b>255) b=255;
|
||||
|
||||
result=r | (g<<8) | (b<<16);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CColorButton window
|
||||
|
||||
class CColorButton : public CButton
|
||||
{
|
||||
// Construction
|
||||
public:
|
||||
CColorButton();
|
||||
|
||||
// Attributes
|
||||
public:
|
||||
COLORREF m_Color;
|
||||
|
||||
// Operations
|
||||
public:
|
||||
|
||||
// Overrides
|
||||
// ClassWizard generated virtual function overrides
|
||||
//{{AFX_VIRTUAL(CColorButton)
|
||||
public:
|
||||
virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
|
||||
//}}AFX_VIRTUAL
|
||||
|
||||
// Implementation
|
||||
public:
|
||||
virtual ~CColorButton();
|
||||
|
||||
// Generated message map functions
|
||||
protected:
|
||||
//{{AFX_MSG(CColorButton)
|
||||
afx_msg void OnClicked();
|
||||
//}}AFX_MSG
|
||||
|
||||
DECLARE_MESSAGE_MAP()
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//{{AFX_INSERT_LOCATION}}
|
||||
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
|
||||
|
||||
#endif // !defined(AFX_COLORBUTTON_H__DBA27321_CEB1_4D75_9225_AFF2B02FCD82__INCLUDED_)
|
||||
#if !defined(AFX_COLORBUTTON_H__DBA27321_CEB1_4D75_9225_AFF2B02FCD82__INCLUDED_)
|
||||
#define AFX_COLORBUTTON_H__DBA27321_CEB1_4D75_9225_AFF2B02FCD82__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
// ColorButton.h : header file
|
||||
//
|
||||
|
||||
#include "Color.h"
|
||||
|
||||
inline void ColorRefToRGBColor(COLORREF c,RGBColor& result)
|
||||
{
|
||||
result.X=(c & 0xff)/255.0f;
|
||||
result.Y=((c>>8) & 0xff)/255.0f;
|
||||
result.Z=((c>>16) & 0xff)/255.0f;
|
||||
}
|
||||
|
||||
inline void RGBColorToColorRef(const RGBColor& c,COLORREF& result)
|
||||
{
|
||||
int r=int(c.X*255);
|
||||
if (r<0) r=0;
|
||||
if (r>255) r=255;
|
||||
|
||||
int g=int(c.Y*255);
|
||||
if (g<0) g=0;
|
||||
if (g>255) g=255;
|
||||
|
||||
int b=int(c.Z*255);
|
||||
if (b<0) b=0;
|
||||
if (b>255) b=255;
|
||||
|
||||
result=r | (g<<8) | (b<<16);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CColorButton window
|
||||
|
||||
class CColorButton : public CButton
|
||||
{
|
||||
// Construction
|
||||
public:
|
||||
CColorButton();
|
||||
|
||||
// Attributes
|
||||
public:
|
||||
COLORREF m_Color;
|
||||
|
||||
// Operations
|
||||
public:
|
||||
|
||||
// Overrides
|
||||
// ClassWizard generated virtual function overrides
|
||||
//{{AFX_VIRTUAL(CColorButton)
|
||||
public:
|
||||
virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
|
||||
//}}AFX_VIRTUAL
|
||||
|
||||
// Implementation
|
||||
public:
|
||||
virtual ~CColorButton();
|
||||
|
||||
// Generated message map functions
|
||||
protected:
|
||||
//{{AFX_MSG(CColorButton)
|
||||
afx_msg void OnClicked();
|
||||
//}}AFX_MSG
|
||||
|
||||
DECLARE_MESSAGE_MAP()
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//{{AFX_INSERT_LOCATION}}
|
||||
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
|
||||
|
||||
#endif // !defined(AFX_COLORBUTTON_H__DBA27321_CEB1_4D75_9225_AFF2B02FCD82__INCLUDED_)
|
||||
|
@ -1,24 +1,24 @@
|
||||
#ifndef _COMMAND_H
|
||||
#define _COMMAND_H
|
||||
|
||||
class CCommand
|
||||
{
|
||||
public:
|
||||
// virtual destructor
|
||||
virtual ~CCommand() {}
|
||||
|
||||
// return the texture name of this command
|
||||
virtual const char* GetName() const { return 0; }
|
||||
|
||||
// execute this command
|
||||
virtual void Execute() = 0;
|
||||
|
||||
// can undo command?
|
||||
virtual bool IsUndoable() const = 0;
|
||||
// undo
|
||||
virtual void Undo() {}
|
||||
// redo
|
||||
virtual void Redo() {}
|
||||
};
|
||||
|
||||
#endif
|
||||
#ifndef _COMMAND_H
|
||||
#define _COMMAND_H
|
||||
|
||||
class CCommand
|
||||
{
|
||||
public:
|
||||
// virtual destructor
|
||||
virtual ~CCommand() {}
|
||||
|
||||
// return the texture name of this command
|
||||
virtual const char* GetName() const { return 0; }
|
||||
|
||||
// execute this command
|
||||
virtual void Execute() = 0;
|
||||
|
||||
// can undo command?
|
||||
virtual bool IsUndoable() const = 0;
|
||||
// undo
|
||||
virtual void Undo() {}
|
||||
// redo
|
||||
virtual void Redo() {}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -1,127 +1,127 @@
|
||||
#include "Command.h"
|
||||
#include "CommandManager.h"
|
||||
|
||||
CCommandManager g_CmdMan;
|
||||
|
||||
CCommandManager::CCommandManager() : m_CommandHistoryLength(128), m_HistoryPos(-1)
|
||||
{
|
||||
}
|
||||
|
||||
CCommandManager::~CCommandManager()
|
||||
{
|
||||
ClearHistory();
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Append: add given command to the end of the history list, without
|
||||
// executing it
|
||||
void CCommandManager::Append(CCommand* cmd)
|
||||
{
|
||||
if (cmd->IsUndoable()) {
|
||||
// remove all existing commands from current position to end
|
||||
CommandList::iterator iter=GetIterator(m_HistoryPos+1);
|
||||
for (CommandList::iterator i=iter;i!=m_CommandHistory.end();++i) {
|
||||
delete *i;
|
||||
}
|
||||
m_CommandHistory.erase(iter,m_CommandHistory.end());
|
||||
|
||||
// add new command to end
|
||||
m_CommandHistory.push_back(cmd);
|
||||
|
||||
// check for history that's too big
|
||||
if (m_CommandHistory.size()>m_CommandHistoryLength) {
|
||||
CCommand* cmd=m_CommandHistory.front();
|
||||
m_CommandHistory.pop_front();
|
||||
delete cmd;
|
||||
}
|
||||
|
||||
// update history position to point at last command executed
|
||||
m_HistoryPos=m_CommandHistory.size()-1;
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Execute: execute the given command, then add it to the end of the history list
|
||||
void CCommandManager::Execute(CCommand* cmd)
|
||||
{
|
||||
cmd->Execute();
|
||||
Append(cmd);
|
||||
}
|
||||
|
||||
CCommandManager::CommandList::iterator CCommandManager::GetIterator(int pos)
|
||||
{
|
||||
if (pos<0 || uint(pos)>=m_CommandHistory.size()) return m_CommandHistory.end();
|
||||
|
||||
typedef CommandList::iterator Iter;
|
||||
int count=0;
|
||||
for (Iter iter=m_CommandHistory.begin();iter!=m_CommandHistory.end();++iter) {
|
||||
if (count==pos) {
|
||||
return iter;
|
||||
}
|
||||
count++;
|
||||
}
|
||||
|
||||
// hmm .. shouldn't get here
|
||||
return m_CommandHistory.end();
|
||||
}
|
||||
|
||||
CCommand* CCommandManager::GetUndoCommand()
|
||||
{
|
||||
CommandList::iterator iter=GetIterator(m_HistoryPos);
|
||||
if (iter!=m_CommandHistory.end()) {
|
||||
return *iter;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void CCommandManager::Undo()
|
||||
{
|
||||
CCommand* cmd=GetUndoCommand();
|
||||
if (cmd) {
|
||||
cmd->Undo();
|
||||
m_HistoryPos--;
|
||||
}
|
||||
}
|
||||
|
||||
const char* CCommandManager::GetUndoName()
|
||||
{
|
||||
CCommand* cmd=GetUndoCommand();
|
||||
return cmd ? cmd->GetName() : 0;
|
||||
}
|
||||
|
||||
CCommand* CCommandManager::GetRedoCommand()
|
||||
{
|
||||
CommandList::iterator iter=GetIterator(m_HistoryPos+1);
|
||||
if (iter!=m_CommandHistory.end()) {
|
||||
return *iter;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void CCommandManager::Redo()
|
||||
{
|
||||
CCommand* cmd=GetRedoCommand();
|
||||
if (cmd) {
|
||||
cmd->Redo();
|
||||
m_HistoryPos++;
|
||||
}
|
||||
}
|
||||
|
||||
const char* CCommandManager::GetRedoName()
|
||||
{
|
||||
CCommand* cmd=GetRedoCommand();
|
||||
return cmd ? cmd->GetName() : 0;
|
||||
}
|
||||
|
||||
|
||||
void CCommandManager::ClearHistory()
|
||||
{
|
||||
// empty out command history
|
||||
while (m_CommandHistory.size()>0) {
|
||||
CCommand* cmd=m_CommandHistory.front();
|
||||
m_CommandHistory.pop_front();
|
||||
delete cmd;
|
||||
}
|
||||
}
|
||||
#include "Command.h"
|
||||
#include "CommandManager.h"
|
||||
|
||||
CCommandManager g_CmdMan;
|
||||
|
||||
CCommandManager::CCommandManager() : m_CommandHistoryLength(128), m_HistoryPos(-1)
|
||||
{
|
||||
}
|
||||
|
||||
CCommandManager::~CCommandManager()
|
||||
{
|
||||
ClearHistory();
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Append: add given command to the end of the history list, without
|
||||
// executing it
|
||||
void CCommandManager::Append(CCommand* cmd)
|
||||
{
|
||||
if (cmd->IsUndoable()) {
|
||||
// remove all existing commands from current position to end
|
||||
CommandList::iterator iter=GetIterator(m_HistoryPos+1);
|
||||
for (CommandList::iterator i=iter;i!=m_CommandHistory.end();++i) {
|
||||
delete *i;
|
||||
}
|
||||
m_CommandHistory.erase(iter,m_CommandHistory.end());
|
||||
|
||||
// add new command to end
|
||||
m_CommandHistory.push_back(cmd);
|
||||
|
||||
// check for history that's too big
|
||||
if (m_CommandHistory.size()>m_CommandHistoryLength) {
|
||||
CCommand* cmd=m_CommandHistory.front();
|
||||
m_CommandHistory.pop_front();
|
||||
delete cmd;
|
||||
}
|
||||
|
||||
// update history position to point at last command executed
|
||||
m_HistoryPos=m_CommandHistory.size()-1;
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Execute: execute the given command, then add it to the end of the history list
|
||||
void CCommandManager::Execute(CCommand* cmd)
|
||||
{
|
||||
cmd->Execute();
|
||||
Append(cmd);
|
||||
}
|
||||
|
||||
CCommandManager::CommandList::iterator CCommandManager::GetIterator(int pos)
|
||||
{
|
||||
if (pos<0 || uint(pos)>=m_CommandHistory.size()) return m_CommandHistory.end();
|
||||
|
||||
typedef CommandList::iterator Iter;
|
||||
int count=0;
|
||||
for (Iter iter=m_CommandHistory.begin();iter!=m_CommandHistory.end();++iter) {
|
||||
if (count==pos) {
|
||||
return iter;
|
||||
}
|
||||
count++;
|
||||
}
|
||||
|
||||
// hmm .. shouldn't get here
|
||||
return m_CommandHistory.end();
|
||||
}
|
||||
|
||||
CCommand* CCommandManager::GetUndoCommand()
|
||||
{
|
||||
CommandList::iterator iter=GetIterator(m_HistoryPos);
|
||||
if (iter!=m_CommandHistory.end()) {
|
||||
return *iter;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void CCommandManager::Undo()
|
||||
{
|
||||
CCommand* cmd=GetUndoCommand();
|
||||
if (cmd) {
|
||||
cmd->Undo();
|
||||
m_HistoryPos--;
|
||||
}
|
||||
}
|
||||
|
||||
const char* CCommandManager::GetUndoName()
|
||||
{
|
||||
CCommand* cmd=GetUndoCommand();
|
||||
return cmd ? cmd->GetName() : 0;
|
||||
}
|
||||
|
||||
CCommand* CCommandManager::GetRedoCommand()
|
||||
{
|
||||
CommandList::iterator iter=GetIterator(m_HistoryPos+1);
|
||||
if (iter!=m_CommandHistory.end()) {
|
||||
return *iter;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void CCommandManager::Redo()
|
||||
{
|
||||
CCommand* cmd=GetRedoCommand();
|
||||
if (cmd) {
|
||||
cmd->Redo();
|
||||
m_HistoryPos++;
|
||||
}
|
||||
}
|
||||
|
||||
const char* CCommandManager::GetRedoName()
|
||||
{
|
||||
CCommand* cmd=GetRedoCommand();
|
||||
return cmd ? cmd->GetName() : 0;
|
||||
}
|
||||
|
||||
|
||||
void CCommandManager::ClearHistory()
|
||||
{
|
||||
// empty out command history
|
||||
while (m_CommandHistory.size()>0) {
|
||||
CCommand* cmd=m_CommandHistory.front();
|
||||
m_CommandHistory.pop_front();
|
||||
delete cmd;
|
||||
}
|
||||
}
|
||||
|
@ -1,39 +1,39 @@
|
||||
#ifndef _COMMANDMANAGER_H
|
||||
#define _COMMANDMANAGER_H
|
||||
|
||||
class CCommand;
|
||||
#include <list>
|
||||
#include "res/res.h"
|
||||
|
||||
class CCommandManager
|
||||
{
|
||||
public:
|
||||
CCommandManager();
|
||||
~CCommandManager();
|
||||
|
||||
void Append(CCommand* cmd);
|
||||
void Execute(CCommand* cmd);
|
||||
|
||||
void Undo();
|
||||
const char* GetUndoName();
|
||||
|
||||
void Redo();
|
||||
const char* GetRedoName();
|
||||
|
||||
void ClearHistory();
|
||||
|
||||
private:
|
||||
typedef std::list<CCommand*> CommandList;
|
||||
|
||||
CommandList::iterator GetIterator(int pos);
|
||||
CCommand* GetUndoCommand();
|
||||
CCommand* GetRedoCommand();
|
||||
|
||||
i32 m_HistoryPos;
|
||||
u32 m_CommandHistoryLength;
|
||||
CommandList m_CommandHistory;
|
||||
};
|
||||
|
||||
extern CCommandManager g_CmdMan;
|
||||
|
||||
#endif
|
||||
#ifndef _COMMANDMANAGER_H
|
||||
#define _COMMANDMANAGER_H
|
||||
|
||||
class CCommand;
|
||||
#include <list>
|
||||
#include "res/res.h"
|
||||
|
||||
class CCommandManager
|
||||
{
|
||||
public:
|
||||
CCommandManager();
|
||||
~CCommandManager();
|
||||
|
||||
void Append(CCommand* cmd);
|
||||
void Execute(CCommand* cmd);
|
||||
|
||||
void Undo();
|
||||
const char* GetUndoName();
|
||||
|
||||
void Redo();
|
||||
const char* GetRedoName();
|
||||
|
||||
void ClearHistory();
|
||||
|
||||
private:
|
||||
typedef std::list<CCommand*> CommandList;
|
||||
|
||||
CommandList::iterator GetIterator(int pos);
|
||||
CCommand* GetUndoCommand();
|
||||
CCommand* GetRedoCommand();
|
||||
|
||||
i32 m_HistoryPos;
|
||||
u32 m_CommandHistoryLength;
|
||||
CommandList m_CommandHistory;
|
||||
};
|
||||
|
||||
extern CCommandManager g_CmdMan;
|
||||
|
||||
#endif
|
||||
|
@ -1,96 +1,96 @@
|
||||
// DirectionButton.cpp : implementation file
|
||||
//
|
||||
|
||||
#include <math.h>
|
||||
#include "stdafx.h"
|
||||
#include "ScEd.h"
|
||||
#include "DirectionButton.h"
|
||||
|
||||
#include "MathUtil.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CDirectionButton
|
||||
|
||||
CDirectionButton::CDirectionButton() : m_Direction(0)
|
||||
{
|
||||
}
|
||||
|
||||
CDirectionButton::~CDirectionButton()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
BEGIN_MESSAGE_MAP(CDirectionButton, CButton)
|
||||
//{{AFX_MSG_MAP(CDirectionButton)
|
||||
// NOTE - the ClassWizard will add and remove mapping macros here.
|
||||
//}}AFX_MSG_MAP
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CDirectionButton message handlers
|
||||
|
||||
void CDirectionButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
|
||||
{
|
||||
CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
|
||||
CRect rect = lpDrawItemStruct->rcItem;
|
||||
|
||||
// draw button edges
|
||||
pDC->DrawFrameControl(rect, DFC_BUTTON,DFCS_BUTTONPUSH | DFCS_FLAT );
|
||||
|
||||
// deflate the drawing rect by the size of the button's edges
|
||||
rect.DeflateRect( CSize(GetSystemMetrics(SM_CXEDGE), GetSystemMetrics(SM_CYEDGE)));
|
||||
// fill the interior color
|
||||
pDC->FillSolidRect(rect,RGB(0,0,0));
|
||||
|
||||
// shrink rect before drawing anything else
|
||||
rect.DeflateRect(15,15);
|
||||
|
||||
// create a hollow brush
|
||||
CBrush brush;
|
||||
brush.CreateStockObject(HOLLOW_BRUSH);
|
||||
CBrush* oldbrush=pDC->SelectObject(&brush);
|
||||
|
||||
// draw circle
|
||||
pDC->SetROP2(R2_WHITE);
|
||||
pDC->Ellipse(&rect);
|
||||
|
||||
// draw direction arrow
|
||||
pDC->SetROP2(R2_COPYPEN);
|
||||
CPen pen;
|
||||
pen.CreatePen(PS_SOLID,1,RGB(255,0,0));
|
||||
CPen* oldpen=pDC->SelectObject(&pen);
|
||||
|
||||
float cx=float(rect.bottom+rect.top)/2.0f;
|
||||
float cy=float(rect.bottom+rect.top)/2.0f;
|
||||
|
||||
float dy=float(rect.bottom-rect.top)/2.0f;
|
||||
float dx=float(rect.right-rect.left)/2.0f;
|
||||
float r=(float) sqrt(dx*dx+dy*dy);
|
||||
|
||||
float dirx=sin(DEGTORAD(m_Direction));
|
||||
float diry=cos(DEGTORAD(m_Direction));
|
||||
|
||||
CPoint m_One(int(cx+dirx*r),int(cy+diry*r));
|
||||
CPoint m_Two(int(cx+dirx*(r-14)),int(cy+diry*(r-14)));
|
||||
|
||||
double slopy , cosy , siny;
|
||||
double Par = 6.5; //length of Arrow (>)
|
||||
slopy = atan2( float( m_One.y - m_Two.y ),float( m_One.x - m_Two.x ) );
|
||||
cosy = cos( slopy );
|
||||
siny = sin( slopy ); //need math.h for these functions
|
||||
|
||||
//draw a line between the 2 endpoint
|
||||
pDC->MoveTo( m_One );
|
||||
pDC->LineTo( m_Two );
|
||||
|
||||
pDC->MoveTo( m_Two );
|
||||
pDC->LineTo( m_Two.x + int( Par * cosy - ( Par / 2.0 * siny ) ),
|
||||
m_Two.y + int( Par * siny + ( Par / 2.0 * cosy ) ) );
|
||||
pDC->LineTo( m_Two.x + int( Par * cosy + Par / 2.0 * siny ),
|
||||
m_Two.y - int( Par / 2.0 * cosy - Par * siny ) );
|
||||
pDC->LineTo( m_Two );
|
||||
|
||||
|
||||
pDC->SelectObject(oldpen);
|
||||
pDC->SelectObject(oldbrush);
|
||||
}
|
||||
// DirectionButton.cpp : implementation file
|
||||
//
|
||||
|
||||
#include <math.h>
|
||||
#include "stdafx.h"
|
||||
#include "ScEd.h"
|
||||
#include "DirectionButton.h"
|
||||
|
||||
#include "MathUtil.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CDirectionButton
|
||||
|
||||
CDirectionButton::CDirectionButton() : m_Direction(0)
|
||||
{
|
||||
}
|
||||
|
||||
CDirectionButton::~CDirectionButton()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
BEGIN_MESSAGE_MAP(CDirectionButton, CButton)
|
||||
//{{AFX_MSG_MAP(CDirectionButton)
|
||||
// NOTE - the ClassWizard will add and remove mapping macros here.
|
||||
//}}AFX_MSG_MAP
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CDirectionButton message handlers
|
||||
|
||||
void CDirectionButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
|
||||
{
|
||||
CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
|
||||
CRect rect = lpDrawItemStruct->rcItem;
|
||||
|
||||
// draw button edges
|
||||
pDC->DrawFrameControl(rect, DFC_BUTTON,DFCS_BUTTONPUSH | DFCS_FLAT );
|
||||
|
||||
// deflate the drawing rect by the size of the button's edges
|
||||
rect.DeflateRect( CSize(GetSystemMetrics(SM_CXEDGE), GetSystemMetrics(SM_CYEDGE)));
|
||||
// fill the interior color
|
||||
pDC->FillSolidRect(rect,RGB(0,0,0));
|
||||
|
||||
// shrink rect before drawing anything else
|
||||
rect.DeflateRect(15,15);
|
||||
|
||||
// create a hollow brush
|
||||
CBrush brush;
|
||||
brush.CreateStockObject(HOLLOW_BRUSH);
|
||||
CBrush* oldbrush=pDC->SelectObject(&brush);
|
||||
|
||||
// draw circle
|
||||
pDC->SetROP2(R2_WHITE);
|
||||
pDC->Ellipse(&rect);
|
||||
|
||||
// draw direction arrow
|
||||
pDC->SetROP2(R2_COPYPEN);
|
||||
CPen pen;
|
||||
pen.CreatePen(PS_SOLID,1,RGB(255,0,0));
|
||||
CPen* oldpen=pDC->SelectObject(&pen);
|
||||
|
||||
float cx=float(rect.bottom+rect.top)/2.0f;
|
||||
float cy=float(rect.bottom+rect.top)/2.0f;
|
||||
|
||||
float dy=float(rect.bottom-rect.top)/2.0f;
|
||||
float dx=float(rect.right-rect.left)/2.0f;
|
||||
float r=(float) sqrt(dx*dx+dy*dy);
|
||||
|
||||
float dirx=sin(DEGTORAD(m_Direction));
|
||||
float diry=cos(DEGTORAD(m_Direction));
|
||||
|
||||
CPoint m_One(int(cx+dirx*r),int(cy+diry*r));
|
||||
CPoint m_Two(int(cx+dirx*(r-14)),int(cy+diry*(r-14)));
|
||||
|
||||
double slopy , cosy , siny;
|
||||
double Par = 6.5; //length of Arrow (>)
|
||||
slopy = atan2( float( m_One.y - m_Two.y ),float( m_One.x - m_Two.x ) );
|
||||
cosy = cos( slopy );
|
||||
siny = sin( slopy ); //need math.h for these functions
|
||||
|
||||
//draw a line between the 2 endpoint
|
||||
pDC->MoveTo( m_One );
|
||||
pDC->LineTo( m_Two );
|
||||
|
||||
pDC->MoveTo( m_Two );
|
||||
pDC->LineTo( m_Two.x + int( Par * cosy - ( Par / 2.0 * siny ) ),
|
||||
m_Two.y + int( Par * siny + ( Par / 2.0 * cosy ) ) );
|
||||
pDC->LineTo( m_Two.x + int( Par * cosy + Par / 2.0 * siny ),
|
||||
m_Two.y - int( Par / 2.0 * cosy - Par * siny ) );
|
||||
pDC->LineTo( m_Two );
|
||||
|
||||
|
||||
pDC->SelectObject(oldpen);
|
||||
pDC->SelectObject(oldbrush);
|
||||
}
|
||||
|
@ -1,51 +1,51 @@
|
||||
#if !defined(AFX_DIRECTIONBUTTON_H__C66DCA94_4F09_41D8_8CAA_C2AF5EDA38D8__INCLUDED_)
|
||||
#define AFX_DIRECTIONBUTTON_H__C66DCA94_4F09_41D8_8CAA_C2AF5EDA38D8__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
// DirectionButton.h : header file
|
||||
//
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CDirectionButton window
|
||||
|
||||
class CDirectionButton : public CButton
|
||||
{
|
||||
// Construction
|
||||
public:
|
||||
CDirectionButton();
|
||||
|
||||
// Attributes
|
||||
public:
|
||||
float m_Direction;
|
||||
|
||||
// Operations
|
||||
public:
|
||||
|
||||
// Overrides
|
||||
// ClassWizard generated virtual function overrides
|
||||
//{{AFX_VIRTUAL(CDirectionButton)
|
||||
public:
|
||||
virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
|
||||
//}}AFX_VIRTUAL
|
||||
|
||||
// Implementation
|
||||
public:
|
||||
virtual ~CDirectionButton();
|
||||
|
||||
// Generated message map functions
|
||||
protected:
|
||||
//{{AFX_MSG(CDirectionButton)
|
||||
// NOTE - the ClassWizard will add and remove member functions here.
|
||||
//}}AFX_MSG
|
||||
|
||||
DECLARE_MESSAGE_MAP()
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//{{AFX_INSERT_LOCATION}}
|
||||
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
|
||||
|
||||
#endif // !defined(AFX_DIRECTIONBUTTON_H__C66DCA94_4F09_41D8_8CAA_C2AF5EDA38D8__INCLUDED_)
|
||||
#if !defined(AFX_DIRECTIONBUTTON_H__C66DCA94_4F09_41D8_8CAA_C2AF5EDA38D8__INCLUDED_)
|
||||
#define AFX_DIRECTIONBUTTON_H__C66DCA94_4F09_41D8_8CAA_C2AF5EDA38D8__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
// DirectionButton.h : header file
|
||||
//
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CDirectionButton window
|
||||
|
||||
class CDirectionButton : public CButton
|
||||
{
|
||||
// Construction
|
||||
public:
|
||||
CDirectionButton();
|
||||
|
||||
// Attributes
|
||||
public:
|
||||
float m_Direction;
|
||||
|
||||
// Operations
|
||||
public:
|
||||
|
||||
// Overrides
|
||||
// ClassWizard generated virtual function overrides
|
||||
//{{AFX_VIRTUAL(CDirectionButton)
|
||||
public:
|
||||
virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
|
||||
//}}AFX_VIRTUAL
|
||||
|
||||
// Implementation
|
||||
public:
|
||||
virtual ~CDirectionButton();
|
||||
|
||||
// Generated message map functions
|
||||
protected:
|
||||
//{{AFX_MSG(CDirectionButton)
|
||||
// NOTE - the ClassWizard will add and remove member functions here.
|
||||
//}}AFX_MSG
|
||||
|
||||
DECLARE_MESSAGE_MAP()
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//{{AFX_INSERT_LOCATION}}
|
||||
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
|
||||
|
||||
#endif // !defined(AFX_DIRECTIONBUTTON_H__C66DCA94_4F09_41D8_8CAA_C2AF5EDA38D8__INCLUDED_)
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,82 +1,82 @@
|
||||
#ifndef _EDITORDATA_H
|
||||
#define _EDITORDATA_H
|
||||
|
||||
#include "MiniMap.h"
|
||||
#include "InfoBox.h"
|
||||
#include "PaintTextureTool.h"
|
||||
#include "NaviCam.h"
|
||||
#include "CStr.h"
|
||||
#include "Terrain.h"
|
||||
#include "Renderer.h"
|
||||
#include "Camera.h"
|
||||
#include "LightEnv.h"
|
||||
|
||||
class CEditorData
|
||||
{
|
||||
public:
|
||||
enum EditMode { SCENARIO_EDIT, UNIT_EDIT, BRUSH_EDIT, TEST_MODE };
|
||||
|
||||
public:
|
||||
CEditorData();
|
||||
|
||||
void SetMode(EditMode mode);
|
||||
EditMode GetMode() const { return m_Mode; }
|
||||
|
||||
// initialise editor at given width, height and bpp
|
||||
bool Init();
|
||||
void Terminate();
|
||||
|
||||
void OnCameraChanged();
|
||||
void OnDraw();
|
||||
void OnScreenShot(const char* filename);
|
||||
|
||||
CInfoBox& GetInfoBox() { return m_InfoBox; }
|
||||
|
||||
// terrain plane
|
||||
CPlane m_TerrainPlane;
|
||||
|
||||
// set the scenario name
|
||||
void SetScenarioName(const char* name) { m_ScenarioName=name; }
|
||||
// get the scenario name
|
||||
const char* GetScenarioName() const { return (const char*) m_ScenarioName; }
|
||||
|
||||
bool LoadTerrain(const char* filename);
|
||||
|
||||
// update time dependent data in the world to account for changes over
|
||||
// the given time (in ms)
|
||||
void UpdateWorld(float time);
|
||||
|
||||
void RenderNoCull();
|
||||
|
||||
private:
|
||||
bool InitScene();
|
||||
void LoadAlphaMaps();
|
||||
void InitResources();
|
||||
void InitCamera();
|
||||
void RenderTerrain();
|
||||
void RenderModels();
|
||||
void RenderWorld();
|
||||
void RenderObEdGrid();
|
||||
|
||||
void InitSingletons();
|
||||
|
||||
void StartTestMode();
|
||||
void StopTestMode();
|
||||
|
||||
// current editing mode
|
||||
EditMode m_Mode;
|
||||
// camera to use in object viewing mode
|
||||
CCamera m_ObjectCamera;
|
||||
// transform of model in object viewing mode
|
||||
CMatrix3D m_ModelMatrix;
|
||||
// information panel
|
||||
CInfoBox m_InfoBox;
|
||||
// the (short) name of this scenario used in title bar and as default save name
|
||||
CStr m_ScenarioName;
|
||||
};
|
||||
|
||||
extern CEditorData g_EditorData;
|
||||
extern CTerrain g_Terrain;
|
||||
extern CLightEnv g_LightEnv;
|
||||
|
||||
#endif
|
||||
#ifndef _EDITORDATA_H
|
||||
#define _EDITORDATA_H
|
||||
|
||||
#include "MiniMap.h"
|
||||
#include "InfoBox.h"
|
||||
#include "PaintTextureTool.h"
|
||||
#include "NaviCam.h"
|
||||
#include "CStr.h"
|
||||
#include "Terrain.h"
|
||||
#include "Renderer.h"
|
||||
#include "Camera.h"
|
||||
#include "LightEnv.h"
|
||||
|
||||
class CEditorData
|
||||
{
|
||||
public:
|
||||
enum EditMode { SCENARIO_EDIT, UNIT_EDIT, BRUSH_EDIT, TEST_MODE };
|
||||
|
||||
public:
|
||||
CEditorData();
|
||||
|
||||
void SetMode(EditMode mode);
|
||||
EditMode GetMode() const { return m_Mode; }
|
||||
|
||||
// initialise editor at given width, height and bpp
|
||||
bool Init();
|
||||
void Terminate();
|
||||
|
||||
void OnCameraChanged();
|
||||
void OnDraw();
|
||||
void OnScreenShot(const char* filename);
|
||||
|
||||
CInfoBox& GetInfoBox() { return m_InfoBox; }
|
||||
|
||||
// terrain plane
|
||||
CPlane m_TerrainPlane;
|
||||
|
||||
// set the scenario name
|
||||
void SetScenarioName(const char* name) { m_ScenarioName=name; }
|
||||
// get the scenario name
|
||||
const char* GetScenarioName() const { return (const char*) m_ScenarioName; }
|
||||
|
||||
bool LoadTerrain(const char* filename);
|
||||
|
||||
// update time dependent data in the world to account for changes over
|
||||
// the given time (in ms)
|
||||
void UpdateWorld(float time);
|
||||
|
||||
void RenderNoCull();
|
||||
|
||||
private:
|
||||
bool InitScene();
|
||||
void LoadAlphaMaps();
|
||||
void InitResources();
|
||||
void InitCamera();
|
||||
void RenderTerrain();
|
||||
void RenderModels();
|
||||
void RenderWorld();
|
||||
void RenderObEdGrid();
|
||||
|
||||
void InitSingletons();
|
||||
|
||||
void StartTestMode();
|
||||
void StopTestMode();
|
||||
|
||||
// current editing mode
|
||||
EditMode m_Mode;
|
||||
// camera to use in object viewing mode
|
||||
CCamera m_ObjectCamera;
|
||||
// transform of model in object viewing mode
|
||||
CMatrix3D m_ModelMatrix;
|
||||
// information panel
|
||||
CInfoBox m_InfoBox;
|
||||
// the (short) name of this scenario used in title bar and as default save name
|
||||
CStr m_ScenarioName;
|
||||
};
|
||||
|
||||
extern CEditorData g_EditorData;
|
||||
extern CTerrain g_Terrain;
|
||||
extern CLightEnv g_LightEnv;
|
||||
|
||||
#endif
|
||||
|
@ -1,187 +1,187 @@
|
||||
#include "stdafx.h"
|
||||
#include "ToolManager.h"
|
||||
#include "ElevToolsDlgBar.h"
|
||||
#include "RaiseElevationTool.h"
|
||||
#include "SmoothElevationTool.h"
|
||||
#include "UIGlobals.h"
|
||||
|
||||
BEGIN_MESSAGE_MAP(CElevToolsDlgBar, CDialogBar)
|
||||
//{{AFX_MSG_MAP(CElevToolsDlgBar)
|
||||
// NOTE - the ClassWizard will add and remove mapping macros here.
|
||||
//}}AFX_MSG_MAP
|
||||
ON_BN_CLICKED(IDC_RADIO_RAISE, OnRadioRaise)
|
||||
ON_BN_CLICKED(IDC_RADIO_SMOOTH, OnRadioSmooth)
|
||||
ON_NOTIFY(NM_RELEASEDCAPTURE, IDC_SLIDER_BRUSHEFFECT, OnReleasedCaptureSliderBrushEffect)
|
||||
ON_NOTIFY(NM_RELEASEDCAPTURE, IDC_SLIDER_BRUSHSIZE, OnReleasedCaptureSliderBrushSize)
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
|
||||
CElevToolsDlgBar::CElevToolsDlgBar() : m_Mode(RAISELOWER_MODE)
|
||||
{
|
||||
}
|
||||
|
||||
CElevToolsDlgBar::~CElevToolsDlgBar()
|
||||
{
|
||||
}
|
||||
|
||||
BOOL CElevToolsDlgBar::Create(CWnd * pParentWnd, LPCTSTR lpszTemplateName,UINT nStyle, UINT nID)
|
||||
{
|
||||
if (!CDialogBar::Create(pParentWnd, lpszTemplateName, nStyle, nID)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!OnInitDialog()) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL CElevToolsDlgBar::Create(CWnd * pParentWnd, UINT nIDTemplate,UINT nStyle, UINT nID)
|
||||
{
|
||||
if (!Create(pParentWnd, MAKEINTRESOURCE(nIDTemplate), nStyle, nID)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void CElevToolsDlgBar::SetRaiseControls()
|
||||
{
|
||||
// set up brush size slider
|
||||
CSliderCtrl* sizectrl=(CSliderCtrl*) GetDlgItem(IDC_SLIDER_BRUSHSIZE);
|
||||
sizectrl->SetRange(0,CRaiseElevationTool::MAX_BRUSH_SIZE,TRUE);
|
||||
sizectrl->SetPos(CRaiseElevationTool::GetTool()->GetBrushSize());
|
||||
|
||||
// set up brush effect slider
|
||||
CSliderCtrl* effectctrl=(CSliderCtrl*) GetDlgItem(IDC_SLIDER_BRUSHEFFECT);
|
||||
effectctrl->SetRange(1,CRaiseElevationTool::MAX_SPEED/16,TRUE);
|
||||
effectctrl->SetPos(CRaiseElevationTool::GetTool()->GetSpeed()/16);
|
||||
|
||||
// setup radio buttons
|
||||
CheckDlgButton(IDC_RADIO_RAISE,TRUE);
|
||||
CheckDlgButton(IDC_RADIO_SMOOTH,FALSE);
|
||||
}
|
||||
|
||||
void CElevToolsDlgBar::SetSmoothControls()
|
||||
{
|
||||
// set up brush size slider
|
||||
CSliderCtrl* sizectrl=(CSliderCtrl*) GetDlgItem(IDC_SLIDER_BRUSHSIZE);
|
||||
sizectrl->SetRange(0,CSmoothElevationTool::MAX_BRUSH_SIZE,TRUE);
|
||||
sizectrl->SetPos(CSmoothElevationTool::GetTool()->GetBrushSize());
|
||||
|
||||
// set up brush effect slider
|
||||
CSliderCtrl* effectctrl=(CSliderCtrl*) GetDlgItem(IDC_SLIDER_BRUSHEFFECT);
|
||||
effectctrl->SetRange(1,int(CSmoothElevationTool::MAX_SMOOTH_POWER),TRUE);
|
||||
effectctrl->SetPos(int(CSmoothElevationTool::GetTool()->GetSmoothPower()));
|
||||
|
||||
// setup radio buttons
|
||||
CheckDlgButton(IDC_RADIO_RAISE,FALSE);
|
||||
CheckDlgButton(IDC_RADIO_SMOOTH,TRUE);
|
||||
}
|
||||
|
||||
BOOL CElevToolsDlgBar::OnInitDialog()
|
||||
{
|
||||
// get the current window size and position
|
||||
CRect rect;
|
||||
GetWindowRect(rect);
|
||||
|
||||
// now change the size, position, and Z order of the window.
|
||||
::SetWindowPos(m_hWnd,HWND_TOPMOST,10,rect.top,rect.Width(),rect.Height(),SWP_HIDEWINDOW);
|
||||
|
||||
// initially show raise controls
|
||||
SetRaiseControls();
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void CElevToolsDlgBar::OnUpdateCmdUI(CFrameWnd* pTarget, BOOL bDisableIfNoHndler)
|
||||
{
|
||||
bDisableIfNoHndler = FALSE;
|
||||
CDialogBar::OnUpdateCmdUI(pTarget,bDisableIfNoHndler);
|
||||
}
|
||||
|
||||
void CElevToolsDlgBar::OnReleasedCaptureSliderBrushSize(NMHDR* pNMHDR, LRESULT* pResult)
|
||||
{
|
||||
CSliderCtrl* sliderctrl=(CSliderCtrl*) GetDlgItem(IDC_SLIDER_BRUSHSIZE);
|
||||
if (IsDlgButtonChecked(IDC_RADIO_RAISE)) {
|
||||
CRaiseElevationTool::GetTool()->SetBrushSize(sliderctrl->GetPos());
|
||||
} else {
|
||||
CSmoothElevationTool::GetTool()->SetBrushSize(sliderctrl->GetPos());
|
||||
}
|
||||
|
||||
*pResult = 0;
|
||||
}
|
||||
|
||||
void CElevToolsDlgBar::OnReleasedCaptureSliderBrushEffect(NMHDR* pNMHDR, LRESULT* pResult)
|
||||
{
|
||||
CSliderCtrl* sliderctrl=(CSliderCtrl*) GetDlgItem(IDC_SLIDER_BRUSHEFFECT);
|
||||
if (IsDlgButtonChecked(IDC_RADIO_RAISE)) {
|
||||
CRaiseElevationTool::GetTool()->SetSpeed(sliderctrl->GetPos()*16);
|
||||
} else {
|
||||
CSmoothElevationTool::GetTool()->SetSmoothPower(float(sliderctrl->GetPos()));
|
||||
}
|
||||
|
||||
*pResult = 0;
|
||||
}
|
||||
|
||||
void CElevToolsDlgBar::OnShow()
|
||||
{
|
||||
switch (m_Mode) {
|
||||
case RAISELOWER_MODE:
|
||||
SetRaiseControls();
|
||||
g_ToolMan.SetActiveTool(CRaiseElevationTool::GetTool());
|
||||
break;
|
||||
|
||||
case SMOOTH_MODE:
|
||||
SetSmoothControls();
|
||||
g_ToolMan.SetActiveTool(CSmoothElevationTool::GetTool());
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
void CElevToolsDlgBar::OnRadioRaise()
|
||||
{
|
||||
// set UI elements for raise/lower
|
||||
SetRaiseControls();
|
||||
|
||||
// set current tool
|
||||
g_ToolMan.SetActiveTool(CRaiseElevationTool::GetTool());
|
||||
|
||||
// redraw sliders
|
||||
CWnd* sizeslider=GetDlgItem(IDC_SLIDER_BRUSHSIZE);
|
||||
sizeslider->Invalidate();
|
||||
sizeslider->UpdateWindow();
|
||||
|
||||
CWnd* effectslider=GetDlgItem(IDC_SLIDER_BRUSHEFFECT);
|
||||
effectslider->Invalidate();
|
||||
effectslider->UpdateWindow();
|
||||
|
||||
// store mode
|
||||
m_Mode=RAISELOWER_MODE;
|
||||
}
|
||||
|
||||
void CElevToolsDlgBar::OnRadioSmooth()
|
||||
{
|
||||
// set UI elements for smooth
|
||||
SetSmoothControls();
|
||||
|
||||
// set current tool
|
||||
g_ToolMan.SetActiveTool(CSmoothElevationTool::GetTool());
|
||||
|
||||
// redraw sliders
|
||||
CWnd* sizeslider=GetDlgItem(IDC_SLIDER_BRUSHSIZE);
|
||||
sizeslider->Invalidate();
|
||||
sizeslider->UpdateWindow();
|
||||
|
||||
CWnd* effectslider=GetDlgItem(IDC_SLIDER_BRUSHEFFECT);
|
||||
effectslider->Invalidate();
|
||||
effectslider->UpdateWindow();
|
||||
|
||||
// store mode
|
||||
m_Mode=SMOOTH_MODE;
|
||||
}
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "ToolManager.h"
|
||||
#include "ElevToolsDlgBar.h"
|
||||
#include "RaiseElevationTool.h"
|
||||
#include "SmoothElevationTool.h"
|
||||
#include "UIGlobals.h"
|
||||
|
||||
BEGIN_MESSAGE_MAP(CElevToolsDlgBar, CDialogBar)
|
||||
//{{AFX_MSG_MAP(CElevToolsDlgBar)
|
||||
// NOTE - the ClassWizard will add and remove mapping macros here.
|
||||
//}}AFX_MSG_MAP
|
||||
ON_BN_CLICKED(IDC_RADIO_RAISE, OnRadioRaise)
|
||||
ON_BN_CLICKED(IDC_RADIO_SMOOTH, OnRadioSmooth)
|
||||
ON_NOTIFY(NM_RELEASEDCAPTURE, IDC_SLIDER_BRUSHEFFECT, OnReleasedCaptureSliderBrushEffect)
|
||||
ON_NOTIFY(NM_RELEASEDCAPTURE, IDC_SLIDER_BRUSHSIZE, OnReleasedCaptureSliderBrushSize)
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
|
||||
CElevToolsDlgBar::CElevToolsDlgBar() : m_Mode(RAISELOWER_MODE)
|
||||
{
|
||||
}
|
||||
|
||||
CElevToolsDlgBar::~CElevToolsDlgBar()
|
||||
{
|
||||
}
|
||||
|
||||
BOOL CElevToolsDlgBar::Create(CWnd * pParentWnd, LPCTSTR lpszTemplateName,UINT nStyle, UINT nID)
|
||||
{
|
||||
if (!CDialogBar::Create(pParentWnd, lpszTemplateName, nStyle, nID)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!OnInitDialog()) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL CElevToolsDlgBar::Create(CWnd * pParentWnd, UINT nIDTemplate,UINT nStyle, UINT nID)
|
||||
{
|
||||
if (!Create(pParentWnd, MAKEINTRESOURCE(nIDTemplate), nStyle, nID)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void CElevToolsDlgBar::SetRaiseControls()
|
||||
{
|
||||
// set up brush size slider
|
||||
CSliderCtrl* sizectrl=(CSliderCtrl*) GetDlgItem(IDC_SLIDER_BRUSHSIZE);
|
||||
sizectrl->SetRange(0,CRaiseElevationTool::MAX_BRUSH_SIZE,TRUE);
|
||||
sizectrl->SetPos(CRaiseElevationTool::GetTool()->GetBrushSize());
|
||||
|
||||
// set up brush effect slider
|
||||
CSliderCtrl* effectctrl=(CSliderCtrl*) GetDlgItem(IDC_SLIDER_BRUSHEFFECT);
|
||||
effectctrl->SetRange(1,CRaiseElevationTool::MAX_SPEED/16,TRUE);
|
||||
effectctrl->SetPos(CRaiseElevationTool::GetTool()->GetSpeed()/16);
|
||||
|
||||
// setup radio buttons
|
||||
CheckDlgButton(IDC_RADIO_RAISE,TRUE);
|
||||
CheckDlgButton(IDC_RADIO_SMOOTH,FALSE);
|
||||
}
|
||||
|
||||
void CElevToolsDlgBar::SetSmoothControls()
|
||||
{
|
||||
// set up brush size slider
|
||||
CSliderCtrl* sizectrl=(CSliderCtrl*) GetDlgItem(IDC_SLIDER_BRUSHSIZE);
|
||||
sizectrl->SetRange(0,CSmoothElevationTool::MAX_BRUSH_SIZE,TRUE);
|
||||
sizectrl->SetPos(CSmoothElevationTool::GetTool()->GetBrushSize());
|
||||
|
||||
// set up brush effect slider
|
||||
CSliderCtrl* effectctrl=(CSliderCtrl*) GetDlgItem(IDC_SLIDER_BRUSHEFFECT);
|
||||
effectctrl->SetRange(1,int(CSmoothElevationTool::MAX_SMOOTH_POWER),TRUE);
|
||||
effectctrl->SetPos(int(CSmoothElevationTool::GetTool()->GetSmoothPower()));
|
||||
|
||||
// setup radio buttons
|
||||
CheckDlgButton(IDC_RADIO_RAISE,FALSE);
|
||||
CheckDlgButton(IDC_RADIO_SMOOTH,TRUE);
|
||||
}
|
||||
|
||||
BOOL CElevToolsDlgBar::OnInitDialog()
|
||||
{
|
||||
// get the current window size and position
|
||||
CRect rect;
|
||||
GetWindowRect(rect);
|
||||
|
||||
// now change the size, position, and Z order of the window.
|
||||
::SetWindowPos(m_hWnd,HWND_TOPMOST,10,rect.top,rect.Width(),rect.Height(),SWP_HIDEWINDOW);
|
||||
|
||||
// initially show raise controls
|
||||
SetRaiseControls();
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void CElevToolsDlgBar::OnUpdateCmdUI(CFrameWnd* pTarget, BOOL bDisableIfNoHndler)
|
||||
{
|
||||
bDisableIfNoHndler = FALSE;
|
||||
CDialogBar::OnUpdateCmdUI(pTarget,bDisableIfNoHndler);
|
||||
}
|
||||
|
||||
void CElevToolsDlgBar::OnReleasedCaptureSliderBrushSize(NMHDR* pNMHDR, LRESULT* pResult)
|
||||
{
|
||||
CSliderCtrl* sliderctrl=(CSliderCtrl*) GetDlgItem(IDC_SLIDER_BRUSHSIZE);
|
||||
if (IsDlgButtonChecked(IDC_RADIO_RAISE)) {
|
||||
CRaiseElevationTool::GetTool()->SetBrushSize(sliderctrl->GetPos());
|
||||
} else {
|
||||
CSmoothElevationTool::GetTool()->SetBrushSize(sliderctrl->GetPos());
|
||||
}
|
||||
|
||||
*pResult = 0;
|
||||
}
|
||||
|
||||
void CElevToolsDlgBar::OnReleasedCaptureSliderBrushEffect(NMHDR* pNMHDR, LRESULT* pResult)
|
||||
{
|
||||
CSliderCtrl* sliderctrl=(CSliderCtrl*) GetDlgItem(IDC_SLIDER_BRUSHEFFECT);
|
||||
if (IsDlgButtonChecked(IDC_RADIO_RAISE)) {
|
||||
CRaiseElevationTool::GetTool()->SetSpeed(sliderctrl->GetPos()*16);
|
||||
} else {
|
||||
CSmoothElevationTool::GetTool()->SetSmoothPower(float(sliderctrl->GetPos()));
|
||||
}
|
||||
|
||||
*pResult = 0;
|
||||
}
|
||||
|
||||
void CElevToolsDlgBar::OnShow()
|
||||
{
|
||||
switch (m_Mode) {
|
||||
case RAISELOWER_MODE:
|
||||
SetRaiseControls();
|
||||
g_ToolMan.SetActiveTool(CRaiseElevationTool::GetTool());
|
||||
break;
|
||||
|
||||
case SMOOTH_MODE:
|
||||
SetSmoothControls();
|
||||
g_ToolMan.SetActiveTool(CSmoothElevationTool::GetTool());
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
void CElevToolsDlgBar::OnRadioRaise()
|
||||
{
|
||||
// set UI elements for raise/lower
|
||||
SetRaiseControls();
|
||||
|
||||
// set current tool
|
||||
g_ToolMan.SetActiveTool(CRaiseElevationTool::GetTool());
|
||||
|
||||
// redraw sliders
|
||||
CWnd* sizeslider=GetDlgItem(IDC_SLIDER_BRUSHSIZE);
|
||||
sizeslider->Invalidate();
|
||||
sizeslider->UpdateWindow();
|
||||
|
||||
CWnd* effectslider=GetDlgItem(IDC_SLIDER_BRUSHEFFECT);
|
||||
effectslider->Invalidate();
|
||||
effectslider->UpdateWindow();
|
||||
|
||||
// store mode
|
||||
m_Mode=RAISELOWER_MODE;
|
||||
}
|
||||
|
||||
void CElevToolsDlgBar::OnRadioSmooth()
|
||||
{
|
||||
// set UI elements for smooth
|
||||
SetSmoothControls();
|
||||
|
||||
// set current tool
|
||||
g_ToolMan.SetActiveTool(CSmoothElevationTool::GetTool());
|
||||
|
||||
// redraw sliders
|
||||
CWnd* sizeslider=GetDlgItem(IDC_SLIDER_BRUSHSIZE);
|
||||
sizeslider->Invalidate();
|
||||
sizeslider->UpdateWindow();
|
||||
|
||||
CWnd* effectslider=GetDlgItem(IDC_SLIDER_BRUSHEFFECT);
|
||||
effectslider->Invalidate();
|
||||
effectslider->UpdateWindow();
|
||||
|
||||
// store mode
|
||||
m_Mode=SMOOTH_MODE;
|
||||
}
|
||||
|
||||
|
@ -1,38 +1,38 @@
|
||||
#ifndef _ELEVTOOLSDLGBAR_H
|
||||
#define _ELEVTOOLSDLGBAR_H
|
||||
|
||||
class CElevToolsDlgBar : public CDialogBar
|
||||
{
|
||||
public:
|
||||
enum Mode { RAISELOWER_MODE, SMOOTH_MODE };
|
||||
|
||||
CElevToolsDlgBar();
|
||||
~CElevToolsDlgBar();
|
||||
|
||||
BOOL Create(CWnd * pParentWnd, UINT nIDTemplate, UINT nStyle, UINT nID);
|
||||
BOOL Create(CWnd * pParentWnd, LPCTSTR lpszTemplateName, UINT nStyle, UINT nID);
|
||||
void OnUpdateCmdUI(CFrameWnd* pTarget, BOOL bDisableIfNoHndler);
|
||||
|
||||
void OnShow();
|
||||
|
||||
protected:
|
||||
BOOL OnInitDialog();
|
||||
|
||||
void SetRaiseControls();
|
||||
void SetSmoothControls();
|
||||
|
||||
// current operating mode
|
||||
Mode m_Mode;
|
||||
|
||||
// Generated message map functions
|
||||
//{{AFX_MSG(CElevToolsDlgBar)
|
||||
afx_msg void OnRadioRaise();
|
||||
afx_msg void OnRadioSmooth();
|
||||
afx_msg void OnReleasedCaptureSliderBrushSize(NMHDR* pNMHDR, LRESULT* pResult);
|
||||
afx_msg void OnReleasedCaptureSliderBrushEffect(NMHDR* pNMHDR, LRESULT* pResult);
|
||||
//}}AFX_MSG
|
||||
DECLARE_MESSAGE_MAP()
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
#ifndef _ELEVTOOLSDLGBAR_H
|
||||
#define _ELEVTOOLSDLGBAR_H
|
||||
|
||||
class CElevToolsDlgBar : public CDialogBar
|
||||
{
|
||||
public:
|
||||
enum Mode { RAISELOWER_MODE, SMOOTH_MODE };
|
||||
|
||||
CElevToolsDlgBar();
|
||||
~CElevToolsDlgBar();
|
||||
|
||||
BOOL Create(CWnd * pParentWnd, UINT nIDTemplate, UINT nStyle, UINT nID);
|
||||
BOOL Create(CWnd * pParentWnd, LPCTSTR lpszTemplateName, UINT nStyle, UINT nID);
|
||||
void OnUpdateCmdUI(CFrameWnd* pTarget, BOOL bDisableIfNoHndler);
|
||||
|
||||
void OnShow();
|
||||
|
||||
protected:
|
||||
BOOL OnInitDialog();
|
||||
|
||||
void SetRaiseControls();
|
||||
void SetSmoothControls();
|
||||
|
||||
// current operating mode
|
||||
Mode m_Mode;
|
||||
|
||||
// Generated message map functions
|
||||
//{{AFX_MSG(CElevToolsDlgBar)
|
||||
afx_msg void OnRadioRaise();
|
||||
afx_msg void OnRadioSmooth();
|
||||
afx_msg void OnReleasedCaptureSliderBrushSize(NMHDR* pNMHDR, LRESULT* pResult);
|
||||
afx_msg void OnReleasedCaptureSliderBrushEffect(NMHDR* pNMHDR, LRESULT* pResult);
|
||||
//}}AFX_MSG
|
||||
DECLARE_MESSAGE_MAP()
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -1,98 +1,98 @@
|
||||
// ElevationButton.cpp : implementation file
|
||||
//
|
||||
|
||||
#include <math.h>
|
||||
#include "stdafx.h"
|
||||
#include "ScEd.h"
|
||||
#include "ElevationButton.h"
|
||||
|
||||
#include "MathUtil.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CElevationButton
|
||||
|
||||
CElevationButton::CElevationButton() : m_Elevation(45)
|
||||
{
|
||||
}
|
||||
|
||||
CElevationButton::~CElevationButton()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
BEGIN_MESSAGE_MAP(CElevationButton, CButton)
|
||||
//{{AFX_MSG_MAP(CElevationButton)
|
||||
// NOTE - the ClassWizard will add and remove mapping macros here.
|
||||
//}}AFX_MSG_MAP
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CElevationButton message handlers
|
||||
|
||||
void CElevationButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
|
||||
{
|
||||
CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
|
||||
CRect rect = lpDrawItemStruct->rcItem;
|
||||
|
||||
// draw button edges
|
||||
pDC->DrawFrameControl(rect, DFC_BUTTON,DFCS_BUTTONPUSH | DFCS_FLAT );
|
||||
|
||||
// deflate the drawing rect by the size of the button's edges
|
||||
rect.DeflateRect( CSize(GetSystemMetrics(SM_CXEDGE), GetSystemMetrics(SM_CYEDGE)));
|
||||
|
||||
// fill the interior color
|
||||
pDC->FillSolidRect(rect,RGB(0,0,0));
|
||||
|
||||
// shrink rect before drawing anything else
|
||||
rect.DeflateRect(15,5);
|
||||
|
||||
// create a hollow brush
|
||||
CBrush brush;
|
||||
brush.CreateStockObject(HOLLOW_BRUSH);
|
||||
CBrush* oldbrush=pDC->SelectObject(&brush);
|
||||
|
||||
// draw horizon
|
||||
pDC->SetROP2(R2_WHITE);
|
||||
pDC->MoveTo(rect.left,rect.bottom);
|
||||
pDC->LineTo(rect.right,rect.bottom);
|
||||
|
||||
// draw direction arrow
|
||||
pDC->SetROP2(R2_COPYPEN);
|
||||
CPen pen;
|
||||
pen.CreatePen(PS_SOLID,1,RGB(255,0,0));
|
||||
CPen* oldpen=pDC->SelectObject(&pen);
|
||||
|
||||
float dy=float(rect.bottom-rect.top)/2.0f;
|
||||
float dx=float(rect.right-rect.left)/2.0f;
|
||||
float r=(float) sqrt(2*dx*dx);
|
||||
|
||||
float cx=float(rect.left+rect.right)/2.0f;
|
||||
float cy=float(rect.bottom);
|
||||
|
||||
float dirx=cos(DEGTORAD(m_Elevation));
|
||||
float diry=-sin(DEGTORAD(m_Elevation));
|
||||
|
||||
CPoint m_One(int(cx+dirx*r),int(cy+diry*r));
|
||||
CPoint m_Two(int(cx+dirx*(r-14)),int(cy+diry*(r-14)));
|
||||
|
||||
double slopy , cosy , siny;
|
||||
double Par = 6.5; //length of Arrow (>)
|
||||
slopy = atan2( float( m_One.y - m_Two.y ),float( m_One.x - m_Two.x ) );
|
||||
cosy = cos( slopy );
|
||||
siny = sin( slopy ); //need math.h for these functions
|
||||
|
||||
//draw a line between the 2 endpoint
|
||||
pDC->MoveTo( m_One );
|
||||
pDC->LineTo( m_Two );
|
||||
|
||||
pDC->MoveTo( m_Two );
|
||||
pDC->LineTo( m_Two.x + int( Par * cosy - ( Par / 2.0 * siny ) ),
|
||||
m_Two.y + int( Par * siny + ( Par / 2.0 * cosy ) ) );
|
||||
pDC->LineTo( m_Two.x + int( Par * cosy + Par / 2.0 * siny ),
|
||||
m_Two.y - int( Par / 2.0 * cosy - Par * siny ) );
|
||||
pDC->LineTo( m_Two );
|
||||
|
||||
|
||||
pDC->SelectObject(oldpen);
|
||||
pDC->SelectObject(oldbrush);
|
||||
}
|
||||
// ElevationButton.cpp : implementation file
|
||||
//
|
||||
|
||||
#include <math.h>
|
||||
#include "stdafx.h"
|
||||
#include "ScEd.h"
|
||||
#include "ElevationButton.h"
|
||||
|
||||
#include "MathUtil.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CElevationButton
|
||||
|
||||
CElevationButton::CElevationButton() : m_Elevation(45)
|
||||
{
|
||||
}
|
||||
|
||||
CElevationButton::~CElevationButton()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
BEGIN_MESSAGE_MAP(CElevationButton, CButton)
|
||||
//{{AFX_MSG_MAP(CElevationButton)
|
||||
// NOTE - the ClassWizard will add and remove mapping macros here.
|
||||
//}}AFX_MSG_MAP
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CElevationButton message handlers
|
||||
|
||||
void CElevationButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
|
||||
{
|
||||
CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
|
||||
CRect rect = lpDrawItemStruct->rcItem;
|
||||
|
||||
// draw button edges
|
||||
pDC->DrawFrameControl(rect, DFC_BUTTON,DFCS_BUTTONPUSH | DFCS_FLAT );
|
||||
|
||||
// deflate the drawing rect by the size of the button's edges
|
||||
rect.DeflateRect( CSize(GetSystemMetrics(SM_CXEDGE), GetSystemMetrics(SM_CYEDGE)));
|
||||
|
||||
// fill the interior color
|
||||
pDC->FillSolidRect(rect,RGB(0,0,0));
|
||||
|
||||
// shrink rect before drawing anything else
|
||||
rect.DeflateRect(15,5);
|
||||
|
||||
// create a hollow brush
|
||||
CBrush brush;
|
||||
brush.CreateStockObject(HOLLOW_BRUSH);
|
||||
CBrush* oldbrush=pDC->SelectObject(&brush);
|
||||
|
||||
// draw horizon
|
||||
pDC->SetROP2(R2_WHITE);
|
||||
pDC->MoveTo(rect.left,rect.bottom);
|
||||
pDC->LineTo(rect.right,rect.bottom);
|
||||
|
||||
// draw direction arrow
|
||||
pDC->SetROP2(R2_COPYPEN);
|
||||
CPen pen;
|
||||
pen.CreatePen(PS_SOLID,1,RGB(255,0,0));
|
||||
CPen* oldpen=pDC->SelectObject(&pen);
|
||||
|
||||
float dy=float(rect.bottom-rect.top)/2.0f;
|
||||
float dx=float(rect.right-rect.left)/2.0f;
|
||||
float r=(float) sqrt(2*dx*dx);
|
||||
|
||||
float cx=float(rect.left+rect.right)/2.0f;
|
||||
float cy=float(rect.bottom);
|
||||
|
||||
float dirx=cos(DEGTORAD(m_Elevation));
|
||||
float diry=-sin(DEGTORAD(m_Elevation));
|
||||
|
||||
CPoint m_One(int(cx+dirx*r),int(cy+diry*r));
|
||||
CPoint m_Two(int(cx+dirx*(r-14)),int(cy+diry*(r-14)));
|
||||
|
||||
double slopy , cosy , siny;
|
||||
double Par = 6.5; //length of Arrow (>)
|
||||
slopy = atan2( float( m_One.y - m_Two.y ),float( m_One.x - m_Two.x ) );
|
||||
cosy = cos( slopy );
|
||||
siny = sin( slopy ); //need math.h for these functions
|
||||
|
||||
//draw a line between the 2 endpoint
|
||||
pDC->MoveTo( m_One );
|
||||
pDC->LineTo( m_Two );
|
||||
|
||||
pDC->MoveTo( m_Two );
|
||||
pDC->LineTo( m_Two.x + int( Par * cosy - ( Par / 2.0 * siny ) ),
|
||||
m_Two.y + int( Par * siny + ( Par / 2.0 * cosy ) ) );
|
||||
pDC->LineTo( m_Two.x + int( Par * cosy + Par / 2.0 * siny ),
|
||||
m_Two.y - int( Par / 2.0 * cosy - Par * siny ) );
|
||||
pDC->LineTo( m_Two );
|
||||
|
||||
|
||||
pDC->SelectObject(oldpen);
|
||||
pDC->SelectObject(oldbrush);
|
||||
}
|
||||
|
@ -1,51 +1,51 @@
|
||||
#if !defined(AFX_ELEVATIONBUTTON_H__7CD052F1_193A_46B3_9EC6_81A52F9A2399__INCLUDED_)
|
||||
#define AFX_ELEVATIONBUTTON_H__7CD052F1_193A_46B3_9EC6_81A52F9A2399__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
// ElevationButton.h : header file
|
||||
//
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CElevationButton window
|
||||
|
||||
class CElevationButton : public CButton
|
||||
{
|
||||
// Construction
|
||||
public:
|
||||
CElevationButton();
|
||||
|
||||
// Attributes
|
||||
public:
|
||||
float m_Elevation;
|
||||
|
||||
// Operations
|
||||
public:
|
||||
|
||||
// Overrides
|
||||
// ClassWizard generated virtual function overrides
|
||||
//{{AFX_VIRTUAL(CElevationButton)
|
||||
public:
|
||||
virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
|
||||
//}}AFX_VIRTUAL
|
||||
|
||||
// Implementation
|
||||
public:
|
||||
virtual ~CElevationButton();
|
||||
|
||||
// Generated message map functions
|
||||
protected:
|
||||
//{{AFX_MSG(CElevationButton)
|
||||
// NOTE - the ClassWizard will add and remove member functions here.
|
||||
//}}AFX_MSG
|
||||
|
||||
DECLARE_MESSAGE_MAP()
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//{{AFX_INSERT_LOCATION}}
|
||||
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
|
||||
|
||||
#endif // !defined(AFX_ELEVATIONBUTTON_H__7CD052F1_193A_46B3_9EC6_81A52F9A2399__INCLUDED_)
|
||||
#if !defined(AFX_ELEVATIONBUTTON_H__7CD052F1_193A_46B3_9EC6_81A52F9A2399__INCLUDED_)
|
||||
#define AFX_ELEVATIONBUTTON_H__7CD052F1_193A_46B3_9EC6_81A52F9A2399__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
// ElevationButton.h : header file
|
||||
//
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CElevationButton window
|
||||
|
||||
class CElevationButton : public CButton
|
||||
{
|
||||
// Construction
|
||||
public:
|
||||
CElevationButton();
|
||||
|
||||
// Attributes
|
||||
public:
|
||||
float m_Elevation;
|
||||
|
||||
// Operations
|
||||
public:
|
||||
|
||||
// Overrides
|
||||
// ClassWizard generated virtual function overrides
|
||||
//{{AFX_VIRTUAL(CElevationButton)
|
||||
public:
|
||||
virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
|
||||
//}}AFX_VIRTUAL
|
||||
|
||||
// Implementation
|
||||
public:
|
||||
virtual ~CElevationButton();
|
||||
|
||||
// Generated message map functions
|
||||
protected:
|
||||
//{{AFX_MSG(CElevationButton)
|
||||
// NOTE - the ClassWizard will add and remove member functions here.
|
||||
//}}AFX_MSG
|
||||
|
||||
DECLARE_MESSAGE_MAP()
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//{{AFX_INSERT_LOCATION}}
|
||||
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
|
||||
|
||||
#endif // !defined(AFX_ELEVATIONBUTTON_H__7CD052F1_193A_46B3_9EC6_81A52F9A2399__INCLUDED_)
|
||||
|
@ -1,31 +1,31 @@
|
||||
// ImageListCtrl.cpp : implementation file
|
||||
//
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "ScEd.h"
|
||||
#include "ImageListCtrl.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CImageListCtrl
|
||||
|
||||
CImageListCtrl::CImageListCtrl()
|
||||
{
|
||||
}
|
||||
|
||||
CImageListCtrl::~CImageListCtrl()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
BEGIN_MESSAGE_MAP(CImageListCtrl, CListCtrl)
|
||||
//{{AFX_MSG_MAP(CImageListCtrl)
|
||||
ON_WM_DRAWITEM()
|
||||
//}}AFX_MSG_MAP
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CImageListCtrl message handlers
|
||||
|
||||
void CImageListCtrl::OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct)
|
||||
{
|
||||
}
|
||||
// ImageListCtrl.cpp : implementation file
|
||||
//
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "ScEd.h"
|
||||
#include "ImageListCtrl.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CImageListCtrl
|
||||
|
||||
CImageListCtrl::CImageListCtrl()
|
||||
{
|
||||
}
|
||||
|
||||
CImageListCtrl::~CImageListCtrl()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
BEGIN_MESSAGE_MAP(CImageListCtrl, CListCtrl)
|
||||
//{{AFX_MSG_MAP(CImageListCtrl)
|
||||
ON_WM_DRAWITEM()
|
||||
//}}AFX_MSG_MAP
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CImageListCtrl message handlers
|
||||
|
||||
void CImageListCtrl::OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct)
|
||||
{
|
||||
}
|
||||
|
@ -1,48 +1,48 @@
|
||||
#if !defined(AFX_IMAGELISTCTRL_H__EAFCDB8A_5A00_4F1E_966A_3036315B92E0__INCLUDED_)
|
||||
#define AFX_IMAGELISTCTRL_H__EAFCDB8A_5A00_4F1E_966A_3036315B92E0__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
// ImageListCtrl.h : header file
|
||||
//
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CImageListCtrl window
|
||||
|
||||
class CImageListCtrl : public CListCtrl
|
||||
{
|
||||
// Construction
|
||||
public:
|
||||
CImageListCtrl();
|
||||
|
||||
// Attributes
|
||||
public:
|
||||
|
||||
// Operations
|
||||
public:
|
||||
|
||||
// Overrides
|
||||
// ClassWizard generated virtual function overrides
|
||||
//{{AFX_VIRTUAL(CImageListCtrl)
|
||||
//}}AFX_VIRTUAL
|
||||
|
||||
// Implementation
|
||||
public:
|
||||
virtual ~CImageListCtrl();
|
||||
|
||||
// Generated message map functions
|
||||
protected:
|
||||
//{{AFX_MSG(CImageListCtrl)
|
||||
afx_msg void OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct);
|
||||
//}}AFX_MSG
|
||||
|
||||
DECLARE_MESSAGE_MAP()
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//{{AFX_INSERT_LOCATION}}
|
||||
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
|
||||
|
||||
#endif // !defined(AFX_IMAGELISTCTRL_H__EAFCDB8A_5A00_4F1E_966A_3036315B92E0__INCLUDED_)
|
||||
#if !defined(AFX_IMAGELISTCTRL_H__EAFCDB8A_5A00_4F1E_966A_3036315B92E0__INCLUDED_)
|
||||
#define AFX_IMAGELISTCTRL_H__EAFCDB8A_5A00_4F1E_966A_3036315B92E0__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
// ImageListCtrl.h : header file
|
||||
//
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CImageListCtrl window
|
||||
|
||||
class CImageListCtrl : public CListCtrl
|
||||
{
|
||||
// Construction
|
||||
public:
|
||||
CImageListCtrl();
|
||||
|
||||
// Attributes
|
||||
public:
|
||||
|
||||
// Operations
|
||||
public:
|
||||
|
||||
// Overrides
|
||||
// ClassWizard generated virtual function overrides
|
||||
//{{AFX_VIRTUAL(CImageListCtrl)
|
||||
//}}AFX_VIRTUAL
|
||||
|
||||
// Implementation
|
||||
public:
|
||||
virtual ~CImageListCtrl();
|
||||
|
||||
// Generated message map functions
|
||||
protected:
|
||||
//{{AFX_MSG(CImageListCtrl)
|
||||
afx_msg void OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct);
|
||||
//}}AFX_MSG
|
||||
|
||||
DECLARE_MESSAGE_MAP()
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//{{AFX_INSERT_LOCATION}}
|
||||
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
|
||||
|
||||
#endif // !defined(AFX_IMAGELISTCTRL_H__EAFCDB8A_5A00_4F1E_966A_3036315B92E0__INCLUDED_)
|
||||
|
@ -1,241 +1,241 @@
|
||||
#include "InfoBox.h"
|
||||
#include "UIGlobals.h"
|
||||
#include "types.h"
|
||||
#include "ogl.h"
|
||||
#include "timer.h"
|
||||
#include "NPFont.h"
|
||||
#include "NPFontManager.h"
|
||||
#include "OverlayText.h"
|
||||
#include "Renderer.h"
|
||||
|
||||
|
||||
static const char* DefaultFontName="mods/official/fonts/verdana18.fnt";
|
||||
|
||||
CInfoBox::CInfoBox() : m_Font(0), m_Visible(false)
|
||||
{
|
||||
m_LastFPSTime=get_time();
|
||||
m_Stats.Reset();
|
||||
}
|
||||
|
||||
void CInfoBox::Initialise()
|
||||
{
|
||||
m_Font=NPFontManager::instance().add(DefaultFontName);
|
||||
}
|
||||
|
||||
void CInfoBox::Render()
|
||||
{
|
||||
if (!m_Visible) return;
|
||||
|
||||
const u32 panelColor=0x80f9527d;
|
||||
const u32 borderColor=0xfffa0043;
|
||||
|
||||
// setup renderstate
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glDepthMask(0);
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
// load identity modelview
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
|
||||
// setup ortho view
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
int w=g_Renderer.GetWidth();
|
||||
int h=g_Renderer.GetHeight();
|
||||
glOrtho(0,w,0,h,-1,1);
|
||||
|
||||
glColor4ubv((const GLubyte*) &panelColor);
|
||||
|
||||
// render infobox as quad
|
||||
glBegin(GL_QUADS);
|
||||
glVertex2i(3,h-180);
|
||||
glVertex2i(150,h-180);
|
||||
glVertex2i(150,h-2);
|
||||
glVertex2i(3,h-2);
|
||||
glEnd();
|
||||
|
||||
// render border
|
||||
glColor4ubv((const GLubyte*) &borderColor);
|
||||
|
||||
glLineWidth(2);
|
||||
glBegin(GL_LINE_LOOP);
|
||||
glVertex2i(1,h-182);
|
||||
glVertex2i(152,h-182);
|
||||
glVertex2i(152,h-1);
|
||||
glVertex2i(1,h-1);
|
||||
glEnd();
|
||||
|
||||
// render any info now, assuming we've got a font
|
||||
if (m_Font) {
|
||||
RenderInfo();
|
||||
}
|
||||
|
||||
// restore matrices
|
||||
glPopMatrix();
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPopMatrix();
|
||||
|
||||
// restore renderstate
|
||||
glDisable(GL_BLEND);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDepthMask(1);
|
||||
}
|
||||
|
||||
void render(COverlayText* overlaytext)
|
||||
{
|
||||
// get font on overlay
|
||||
NPFont* font=overlaytext->GetFont();
|
||||
if (!font) return;
|
||||
|
||||
const CStr& str=overlaytext->GetString();
|
||||
int len=str.Length();
|
||||
if (len==0) return;
|
||||
|
||||
// bind to font texture
|
||||
g_Renderer.SetTexture(0,&font->texture());
|
||||
|
||||
// setup texenv
|
||||
glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
|
||||
|
||||
glTexEnvi (GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_REPLACE);
|
||||
glTexEnvi (GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PRIMARY_COLOR);
|
||||
glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR);
|
||||
|
||||
glTexEnvi (GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);
|
||||
glTexEnvf (GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE);
|
||||
glTexEnvf (GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA);
|
||||
|
||||
// get overlay's position
|
||||
float x,y;
|
||||
overlaytext->GetPosition(x,y);
|
||||
|
||||
// setup color
|
||||
const CColor& color=overlaytext->GetColor();
|
||||
glColor4fv((float*) &color);
|
||||
|
||||
float x0=x;
|
||||
float ftw=float(font->textureWidth());
|
||||
float fth=float(font->textureHeight());
|
||||
float fdy=float(font->height())/fth;
|
||||
|
||||
// submit quad verts for each character
|
||||
glBegin(GL_QUADS);
|
||||
|
||||
for (int i=0;i<len;i++) {
|
||||
// get pointer to char widths
|
||||
const NPFont::CharData& cdata=font->chardata(str[i]);
|
||||
const int* cw=&cdata._widthA;
|
||||
|
||||
if (cw[0]>0) x0+=cw[0];
|
||||
|
||||
// find the tile for this character
|
||||
unsigned char c0=unsigned char(str[i]-32);
|
||||
int ix=c0%font->numCols();
|
||||
int iy=c0/font->numCols();
|
||||
|
||||
// calc UV coords of character in texture
|
||||
float u0=float(ix*font->maxcharwidth()+cw[0]-1)/ftw;
|
||||
float v0=float(iy*(font->height()+1))/fth;
|
||||
float u1=u0+float(cw[1]+1)/ftw;
|
||||
float v1=v0+fdy;
|
||||
|
||||
glTexCoord2f(u0,v0);
|
||||
glVertex2f(x0,y);
|
||||
|
||||
glTexCoord2f(u1,v0);
|
||||
glVertex2f(x0+float(cw[1]+1),y);
|
||||
|
||||
glTexCoord2f(u1,v1);
|
||||
glVertex2f(x0+float(cw[1]+1),y+font->height());
|
||||
|
||||
glTexCoord2f(u0,v1);
|
||||
glVertex2f(x0,y+font->height());
|
||||
|
||||
// translate such that next character is rendered in correct position
|
||||
x0+=float(cw[1]+1);
|
||||
if (cw[2]>0) x0+=cw[2];
|
||||
}
|
||||
glEnd();
|
||||
|
||||
// unbind texture ..
|
||||
g_Renderer.SetTexture(0,0);
|
||||
}
|
||||
|
||||
|
||||
void CInfoBox::RenderInfo()
|
||||
{
|
||||
int w=g_Renderer.GetWidth();
|
||||
int h=g_Renderer.GetHeight();
|
||||
|
||||
char buf[32];
|
||||
|
||||
if (m_LastStats.m_Counter) {
|
||||
u32 dy=m_Font->height()+2;
|
||||
float y=float(h-dy);
|
||||
|
||||
sprintf(buf,"FPS: %d",int(m_LastStats.m_Counter/m_LastTickTime));
|
||||
COverlayText fpstext(5,y,0,DefaultFontName,buf,CColor(1,1,1,1));
|
||||
render(&fpstext);
|
||||
y-=dy;
|
||||
|
||||
sprintf(buf,"FT: %.2f",1000*m_LastTickTime/float(m_LastStats.m_Counter));
|
||||
COverlayText fttext(5,y,0,DefaultFontName,buf,CColor(1,1,1,1));
|
||||
render(&fttext);
|
||||
y-=dy;
|
||||
|
||||
u32 totalTris=m_LastStats.m_TerrainTris+m_LastStats.m_ModelTris+m_LastStats.m_TransparentTris;
|
||||
sprintf(buf,"TPF: %d",int(totalTris/m_LastStats.m_Counter));
|
||||
COverlayText tpftext(5,y,0,DefaultFontName,buf,CColor(1,1,1,1));
|
||||
render(&tpftext);
|
||||
y-=dy;
|
||||
|
||||
sprintf(buf,"TeTPF: %d",int(m_LastStats.m_TerrainTris/m_LastStats.m_Counter));
|
||||
COverlayText tetpftext(5,y,0,DefaultFontName,buf,CColor(1,1,1,1));
|
||||
render(&tetpftext);
|
||||
y-=dy;
|
||||
|
||||
sprintf(buf,"MTPF: %d",int(m_LastStats.m_ModelTris/m_LastStats.m_Counter));
|
||||
COverlayText mtpftext(5,y,0,DefaultFontName,buf,CColor(1,1,1,1));
|
||||
render(&mtpftext);
|
||||
y-=dy;
|
||||
|
||||
sprintf(buf,"TrTPF: %d",int(m_LastStats.m_TransparentTris/m_LastStats.m_Counter));
|
||||
COverlayText trtpftext(5,y,0,DefaultFontName,buf,CColor(1,1,1,1));
|
||||
render(&trtpftext);
|
||||
y-=dy;
|
||||
|
||||
sprintf(buf,"DCPF: %d",int(m_LastStats.m_DrawCalls/m_LastStats.m_Counter));
|
||||
COverlayText dcpftext(5,y,0,DefaultFontName,buf,CColor(1,1,1,1));
|
||||
render(&dcpftext);
|
||||
y-=dy;
|
||||
|
||||
sprintf(buf,"SPPF: %d",int(m_LastStats.m_BlendSplats/m_LastStats.m_Counter));
|
||||
COverlayText sppftext(5,y,0,DefaultFontName,buf,CColor(1,1,1,1));
|
||||
render(&sppftext);
|
||||
y-=dy;
|
||||
}
|
||||
}
|
||||
|
||||
void CInfoBox::OnFrameComplete()
|
||||
{
|
||||
// accumulate stats
|
||||
m_Stats+=g_Renderer.GetStats();
|
||||
|
||||
// fps check
|
||||
double cur_time=get_time();
|
||||
if (cur_time-m_LastFPSTime>1) {
|
||||
// save tick time
|
||||
m_LastTickTime=cur_time-m_LastFPSTime;
|
||||
// save stats
|
||||
m_LastStats=m_Stats;
|
||||
// save time
|
||||
m_LastFPSTime=cur_time;
|
||||
// reset stats
|
||||
m_Stats.Reset();
|
||||
}
|
||||
#include "InfoBox.h"
|
||||
#include "UIGlobals.h"
|
||||
#include "types.h"
|
||||
#include "ogl.h"
|
||||
#include "timer.h"
|
||||
#include "NPFont.h"
|
||||
#include "NPFontManager.h"
|
||||
#include "OverlayText.h"
|
||||
#include "Renderer.h"
|
||||
|
||||
|
||||
static const char* DefaultFontName="mods/official/fonts/verdana18.fnt";
|
||||
|
||||
CInfoBox::CInfoBox() : m_Font(0), m_Visible(false)
|
||||
{
|
||||
m_LastFPSTime=get_time();
|
||||
m_Stats.Reset();
|
||||
}
|
||||
|
||||
void CInfoBox::Initialise()
|
||||
{
|
||||
m_Font=NPFontManager::instance().add(DefaultFontName);
|
||||
}
|
||||
|
||||
void CInfoBox::Render()
|
||||
{
|
||||
if (!m_Visible) return;
|
||||
|
||||
const u32 panelColor=0x80f9527d;
|
||||
const u32 borderColor=0xfffa0043;
|
||||
|
||||
// setup renderstate
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glDepthMask(0);
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
// load identity modelview
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
|
||||
// setup ortho view
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
int w=g_Renderer.GetWidth();
|
||||
int h=g_Renderer.GetHeight();
|
||||
glOrtho(0,w,0,h,-1,1);
|
||||
|
||||
glColor4ubv((const GLubyte*) &panelColor);
|
||||
|
||||
// render infobox as quad
|
||||
glBegin(GL_QUADS);
|
||||
glVertex2i(3,h-180);
|
||||
glVertex2i(150,h-180);
|
||||
glVertex2i(150,h-2);
|
||||
glVertex2i(3,h-2);
|
||||
glEnd();
|
||||
|
||||
// render border
|
||||
glColor4ubv((const GLubyte*) &borderColor);
|
||||
|
||||
glLineWidth(2);
|
||||
glBegin(GL_LINE_LOOP);
|
||||
glVertex2i(1,h-182);
|
||||
glVertex2i(152,h-182);
|
||||
glVertex2i(152,h-1);
|
||||
glVertex2i(1,h-1);
|
||||
glEnd();
|
||||
|
||||
// render any info now, assuming we've got a font
|
||||
if (m_Font) {
|
||||
RenderInfo();
|
||||
}
|
||||
|
||||
// restore matrices
|
||||
glPopMatrix();
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPopMatrix();
|
||||
|
||||
// restore renderstate
|
||||
glDisable(GL_BLEND);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDepthMask(1);
|
||||
}
|
||||
|
||||
void render(COverlayText* overlaytext)
|
||||
{
|
||||
// get font on overlay
|
||||
NPFont* font=overlaytext->GetFont();
|
||||
if (!font) return;
|
||||
|
||||
const CStr& str=overlaytext->GetString();
|
||||
int len=str.Length();
|
||||
if (len==0) return;
|
||||
|
||||
// bind to font texture
|
||||
g_Renderer.SetTexture(0,&font->texture());
|
||||
|
||||
// setup texenv
|
||||
glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
|
||||
|
||||
glTexEnvi (GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_REPLACE);
|
||||
glTexEnvi (GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PRIMARY_COLOR);
|
||||
glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR);
|
||||
|
||||
glTexEnvi (GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);
|
||||
glTexEnvf (GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE);
|
||||
glTexEnvf (GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA);
|
||||
|
||||
// get overlay's position
|
||||
float x,y;
|
||||
overlaytext->GetPosition(x,y);
|
||||
|
||||
// setup color
|
||||
const CColor& color=overlaytext->GetColor();
|
||||
glColor4fv((float*) &color);
|
||||
|
||||
float x0=x;
|
||||
float ftw=float(font->textureWidth());
|
||||
float fth=float(font->textureHeight());
|
||||
float fdy=float(font->height())/fth;
|
||||
|
||||
// submit quad verts for each character
|
||||
glBegin(GL_QUADS);
|
||||
|
||||
for (int i=0;i<len;i++) {
|
||||
// get pointer to char widths
|
||||
const NPFont::CharData& cdata=font->chardata(str[i]);
|
||||
const int* cw=&cdata._widthA;
|
||||
|
||||
if (cw[0]>0) x0+=cw[0];
|
||||
|
||||
// find the tile for this character
|
||||
unsigned char c0=unsigned char(str[i]-32);
|
||||
int ix=c0%font->numCols();
|
||||
int iy=c0/font->numCols();
|
||||
|
||||
// calc UV coords of character in texture
|
||||
float u0=float(ix*font->maxcharwidth()+cw[0]-1)/ftw;
|
||||
float v0=float(iy*(font->height()+1))/fth;
|
||||
float u1=u0+float(cw[1]+1)/ftw;
|
||||
float v1=v0+fdy;
|
||||
|
||||
glTexCoord2f(u0,v0);
|
||||
glVertex2f(x0,y);
|
||||
|
||||
glTexCoord2f(u1,v0);
|
||||
glVertex2f(x0+float(cw[1]+1),y);
|
||||
|
||||
glTexCoord2f(u1,v1);
|
||||
glVertex2f(x0+float(cw[1]+1),y+font->height());
|
||||
|
||||
glTexCoord2f(u0,v1);
|
||||
glVertex2f(x0,y+font->height());
|
||||
|
||||
// translate such that next character is rendered in correct position
|
||||
x0+=float(cw[1]+1);
|
||||
if (cw[2]>0) x0+=cw[2];
|
||||
}
|
||||
glEnd();
|
||||
|
||||
// unbind texture ..
|
||||
g_Renderer.SetTexture(0,0);
|
||||
}
|
||||
|
||||
|
||||
void CInfoBox::RenderInfo()
|
||||
{
|
||||
int w=g_Renderer.GetWidth();
|
||||
int h=g_Renderer.GetHeight();
|
||||
|
||||
char buf[32];
|
||||
|
||||
if (m_LastStats.m_Counter) {
|
||||
u32 dy=m_Font->height()+2;
|
||||
float y=float(h-dy);
|
||||
|
||||
sprintf(buf,"FPS: %d",int(m_LastStats.m_Counter/m_LastTickTime));
|
||||
COverlayText fpstext(5,y,0,DefaultFontName,buf,CColor(1,1,1,1));
|
||||
render(&fpstext);
|
||||
y-=dy;
|
||||
|
||||
sprintf(buf,"FT: %.2f",1000*m_LastTickTime/float(m_LastStats.m_Counter));
|
||||
COverlayText fttext(5,y,0,DefaultFontName,buf,CColor(1,1,1,1));
|
||||
render(&fttext);
|
||||
y-=dy;
|
||||
|
||||
u32 totalTris=m_LastStats.m_TerrainTris+m_LastStats.m_ModelTris+m_LastStats.m_TransparentTris;
|
||||
sprintf(buf,"TPF: %d",int(totalTris/m_LastStats.m_Counter));
|
||||
COverlayText tpftext(5,y,0,DefaultFontName,buf,CColor(1,1,1,1));
|
||||
render(&tpftext);
|
||||
y-=dy;
|
||||
|
||||
sprintf(buf,"TeTPF: %d",int(m_LastStats.m_TerrainTris/m_LastStats.m_Counter));
|
||||
COverlayText tetpftext(5,y,0,DefaultFontName,buf,CColor(1,1,1,1));
|
||||
render(&tetpftext);
|
||||
y-=dy;
|
||||
|
||||
sprintf(buf,"MTPF: %d",int(m_LastStats.m_ModelTris/m_LastStats.m_Counter));
|
||||
COverlayText mtpftext(5,y,0,DefaultFontName,buf,CColor(1,1,1,1));
|
||||
render(&mtpftext);
|
||||
y-=dy;
|
||||
|
||||
sprintf(buf,"TrTPF: %d",int(m_LastStats.m_TransparentTris/m_LastStats.m_Counter));
|
||||
COverlayText trtpftext(5,y,0,DefaultFontName,buf,CColor(1,1,1,1));
|
||||
render(&trtpftext);
|
||||
y-=dy;
|
||||
|
||||
sprintf(buf,"DCPF: %d",int(m_LastStats.m_DrawCalls/m_LastStats.m_Counter));
|
||||
COverlayText dcpftext(5,y,0,DefaultFontName,buf,CColor(1,1,1,1));
|
||||
render(&dcpftext);
|
||||
y-=dy;
|
||||
|
||||
sprintf(buf,"SPPF: %d",int(m_LastStats.m_BlendSplats/m_LastStats.m_Counter));
|
||||
COverlayText sppftext(5,y,0,DefaultFontName,buf,CColor(1,1,1,1));
|
||||
render(&sppftext);
|
||||
y-=dy;
|
||||
}
|
||||
}
|
||||
|
||||
void CInfoBox::OnFrameComplete()
|
||||
{
|
||||
// accumulate stats
|
||||
m_Stats+=g_Renderer.GetStats();
|
||||
|
||||
// fps check
|
||||
double cur_time=get_time();
|
||||
if (cur_time-m_LastFPSTime>1) {
|
||||
// save tick time
|
||||
m_LastTickTime=cur_time-m_LastFPSTime;
|
||||
// save stats
|
||||
m_LastStats=m_Stats;
|
||||
// save time
|
||||
m_LastFPSTime=cur_time;
|
||||
// reset stats
|
||||
m_Stats.Reset();
|
||||
}
|
||||
}
|
@ -1,45 +1,45 @@
|
||||
#ifndef _INFOBOX_H
|
||||
#define _INFOBOX_H
|
||||
|
||||
class NPFont;
|
||||
|
||||
#include "Renderer.h"
|
||||
|
||||
class CInfoBox
|
||||
{
|
||||
public:
|
||||
CInfoBox();
|
||||
|
||||
// setup the infobox
|
||||
void Initialise();
|
||||
// render out the info box
|
||||
void Render();
|
||||
// frame has been rendered out, update stats
|
||||
void OnFrameComplete();
|
||||
|
||||
// set visibility
|
||||
void SetVisible(bool flag) { m_Visible=flag; }
|
||||
// get visibility
|
||||
bool GetVisible() const { return m_Visible; }
|
||||
|
||||
private:
|
||||
// text output: render any relevant current information
|
||||
void RenderInfo();
|
||||
|
||||
// currently visible?
|
||||
bool m_Visible;
|
||||
// font to use rendering out text to the info box
|
||||
NPFont* m_Font;
|
||||
// current frame rate
|
||||
double m_FPS;
|
||||
// last known frame time
|
||||
double m_LastFPSTime;
|
||||
// accumulated stats
|
||||
CRenderer::Stats m_Stats;
|
||||
// time of the last 1 second "tick"
|
||||
double m_LastTickTime;
|
||||
// stats from last 1 second "tick"
|
||||
CRenderer::Stats m_LastStats;
|
||||
};
|
||||
|
||||
#endif
|
||||
#ifndef _INFOBOX_H
|
||||
#define _INFOBOX_H
|
||||
|
||||
class NPFont;
|
||||
|
||||
#include "Renderer.h"
|
||||
|
||||
class CInfoBox
|
||||
{
|
||||
public:
|
||||
CInfoBox();
|
||||
|
||||
// setup the infobox
|
||||
void Initialise();
|
||||
// render out the info box
|
||||
void Render();
|
||||
// frame has been rendered out, update stats
|
||||
void OnFrameComplete();
|
||||
|
||||
// set visibility
|
||||
void SetVisible(bool flag) { m_Visible=flag; }
|
||||
// get visibility
|
||||
bool GetVisible() const { return m_Visible; }
|
||||
|
||||
private:
|
||||
// text output: render any relevant current information
|
||||
void RenderInfo();
|
||||
|
||||
// currently visible?
|
||||
bool m_Visible;
|
||||
// font to use rendering out text to the info box
|
||||
NPFont* m_Font;
|
||||
// current frame rate
|
||||
double m_FPS;
|
||||
// last known frame time
|
||||
double m_LastFPSTime;
|
||||
// accumulated stats
|
||||
CRenderer::Stats m_Stats;
|
||||
// time of the last 1 second "tick"
|
||||
double m_LastTickTime;
|
||||
// stats from last 1 second "tick"
|
||||
CRenderer::Stats m_LastStats;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -1,170 +1,170 @@
|
||||
// LightSettingsDlg.cpp : implementation file
|
||||
//
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "ScEd.h"
|
||||
#include "LightSettingsDlg.h"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "Terrain.h"
|
||||
#include "LightEnv.h"
|
||||
|
||||
#include "CommandManager.h"
|
||||
#include "AlterLightEnvCommand.h"
|
||||
|
||||
|
||||
extern CTerrain g_Terrain;
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CLightSettingsDlg dialog
|
||||
|
||||
|
||||
CLightSettingsDlg::CLightSettingsDlg(CWnd* pParent /*=NULL*/)
|
||||
: CDialog(CLightSettingsDlg::IDD, pParent), m_PreviousPreview(false)
|
||||
{
|
||||
//{{AFX_DATA_INIT(CLightSettingsDlg)
|
||||
m_Direction = 270;
|
||||
m_Elevation = 45;
|
||||
//}}AFX_DATA_INIT
|
||||
}
|
||||
|
||||
|
||||
void CLightSettingsDlg::DoDataExchange(CDataExchange* pDX)
|
||||
{
|
||||
CDialog::DoDataExchange(pDX);
|
||||
//{{AFX_DATA_MAP(CLightSettingsDlg)
|
||||
DDX_Control(pDX, IDC_BUTTON_UNITSAMBIENTCOLOR, m_UnitsAmbientColor);
|
||||
DDX_Control(pDX, IDC_BUTTON_DIRECTION, m_DirectionButton);
|
||||
DDX_Control(pDX, IDC_BUTTON_ELEVATION, m_ElevationButton);
|
||||
DDX_Control(pDX, IDC_BUTTON_TERRAINAMBIENTCOLOR, m_TerrainAmbientColor);
|
||||
DDX_Control(pDX, IDC_BUTTON_SUNCOLOR, m_SunColor);
|
||||
DDX_Text(pDX, IDC_EDIT_DIRECTION, m_Direction);
|
||||
DDX_Text(pDX, IDC_EDIT_ELEVATION, m_Elevation);
|
||||
//}}AFX_DATA_MAP
|
||||
}
|
||||
|
||||
|
||||
BEGIN_MESSAGE_MAP(CLightSettingsDlg, CDialog)
|
||||
//{{AFX_MSG_MAP(CLightSettingsDlg)
|
||||
ON_BN_CLICKED(IDC_BUTTON_APPLY, OnButtonApply)
|
||||
ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_DIRECTION, OnDeltaposSpinDirection)
|
||||
ON_EN_CHANGE(IDC_EDIT_DIRECTION, OnChangeEditDirection)
|
||||
ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_ELEVATION, OnDeltaposSpinElevation)
|
||||
ON_EN_CHANGE(IDC_EDIT_ELEVATION, OnChangeEditElevation)
|
||||
//}}AFX_MSG_MAP
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CLightSettingsDlg message handlers
|
||||
|
||||
|
||||
void CLightSettingsDlg::OnButtonApply()
|
||||
{
|
||||
UpdateData(TRUE);
|
||||
|
||||
// have we previously applied a lightenv?
|
||||
if (m_PreviousPreview) {
|
||||
// yes - undo it
|
||||
g_CmdMan.Undo();
|
||||
}
|
||||
|
||||
// build a lighting environment from the parameters
|
||||
CLightEnv env;
|
||||
env.m_Elevation=DEGTORAD(m_ElevationButton.m_Elevation);
|
||||
env.m_Rotation=DEGTORAD(m_DirectionButton.m_Direction);
|
||||
ColorRefToRGBColor(m_SunColor.m_Color,env.m_SunColor);
|
||||
ColorRefToRGBColor(m_TerrainAmbientColor.m_Color,env.m_TerrainAmbientColor);
|
||||
ColorRefToRGBColor(m_TerrainAmbientColor.m_Color,env.m_UnitsAmbientColor);
|
||||
|
||||
// create and execute an AlterLightEnv command
|
||||
CAlterLightEnvCommand* cmd=new CAlterLightEnvCommand(env);
|
||||
g_CmdMan.Execute(cmd);
|
||||
|
||||
AfxGetMainWnd()->Invalidate();
|
||||
AfxGetMainWnd()->UpdateWindow();
|
||||
|
||||
m_PreviousPreview=true;
|
||||
}
|
||||
|
||||
BOOL CLightSettingsDlg::OnInitDialog()
|
||||
{
|
||||
CDialog::OnInitDialog();
|
||||
|
||||
CSpinButtonCtrl* dirspin=(CSpinButtonCtrl*) GetDlgItem(IDC_SPIN_DIRECTION);
|
||||
assert(dirspin);
|
||||
dirspin->SetRange32(0,359);
|
||||
dirspin->SetPos(m_Direction);
|
||||
m_DirectionButton.m_Direction=float(m_Direction);
|
||||
|
||||
CSpinButtonCtrl* espin=(CSpinButtonCtrl*) GetDlgItem(IDC_SPIN_ELEVATION);
|
||||
assert(espin);
|
||||
espin->SetRange32(0,90);
|
||||
espin->SetPos(m_Elevation);
|
||||
m_ElevationButton.m_Elevation=float(m_Elevation);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void CLightSettingsDlg::OnDeltaposSpinDirection(NMHDR* pNMHDR, LRESULT* pResult)
|
||||
{
|
||||
NM_UPDOWN* pNMUpDown = (NM_UPDOWN*)pNMHDR;
|
||||
|
||||
// update direction button
|
||||
if (!UpdateData(TRUE)) return;
|
||||
CSpinButtonCtrl* dirspin=(CSpinButtonCtrl*) GetDlgItem(IDC_SPIN_DIRECTION);
|
||||
m_Direction=dirspin->GetPos()+pNMUpDown->iDelta;
|
||||
m_DirectionButton.m_Direction=float(m_Direction);
|
||||
m_DirectionButton.Invalidate();
|
||||
m_DirectionButton.UpdateWindow();
|
||||
|
||||
UpdateData(FALSE);
|
||||
|
||||
*pResult = 0;
|
||||
}
|
||||
|
||||
void CLightSettingsDlg::OnChangeEditDirection()
|
||||
{
|
||||
if (IsWindow(m_DirectionButton.m_hWnd)) {
|
||||
if (!UpdateData(TRUE)) return;
|
||||
m_DirectionButton.m_Direction=float(m_Direction);
|
||||
m_DirectionButton.Invalidate();
|
||||
m_DirectionButton.UpdateWindow();
|
||||
|
||||
CSpinButtonCtrl* dirspin=(CSpinButtonCtrl*) GetDlgItem(IDC_SPIN_DIRECTION);
|
||||
if (dirspin) dirspin->SetPos(m_Direction);
|
||||
}
|
||||
}
|
||||
|
||||
void CLightSettingsDlg::OnDeltaposSpinElevation(NMHDR* pNMHDR, LRESULT* pResult)
|
||||
{
|
||||
NM_UPDOWN* pNMUpDown = (NM_UPDOWN*)pNMHDR;
|
||||
|
||||
// update elevation button
|
||||
if (!UpdateData(TRUE)) return;
|
||||
CSpinButtonCtrl* espin=(CSpinButtonCtrl*) GetDlgItem(IDC_SPIN_ELEVATION);
|
||||
m_Elevation=espin->GetPos()+pNMUpDown->iDelta;
|
||||
m_ElevationButton.m_Elevation=float(m_Elevation);
|
||||
m_ElevationButton.Invalidate();
|
||||
m_ElevationButton.UpdateWindow();
|
||||
|
||||
UpdateData(FALSE);
|
||||
|
||||
*pResult = 0;
|
||||
}
|
||||
|
||||
void CLightSettingsDlg::OnChangeEditElevation()
|
||||
{
|
||||
if (IsWindow(m_ElevationButton.m_hWnd)) {
|
||||
if (!UpdateData(TRUE)) return;
|
||||
|
||||
m_ElevationButton.m_Elevation=float(m_Elevation);
|
||||
m_ElevationButton.Invalidate();
|
||||
m_ElevationButton.UpdateWindow();
|
||||
|
||||
CSpinButtonCtrl* espin=(CSpinButtonCtrl*) GetDlgItem(IDC_SPIN_ELEVATION);
|
||||
if (espin) espin->SetPos(m_Elevation);
|
||||
}
|
||||
}
|
||||
|
||||
// LightSettingsDlg.cpp : implementation file
|
||||
//
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "ScEd.h"
|
||||
#include "LightSettingsDlg.h"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "Terrain.h"
|
||||
#include "LightEnv.h"
|
||||
|
||||
#include "CommandManager.h"
|
||||
#include "AlterLightEnvCommand.h"
|
||||
|
||||
|
||||
extern CTerrain g_Terrain;
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CLightSettingsDlg dialog
|
||||
|
||||
|
||||
CLightSettingsDlg::CLightSettingsDlg(CWnd* pParent /*=NULL*/)
|
||||
: CDialog(CLightSettingsDlg::IDD, pParent), m_PreviousPreview(false)
|
||||
{
|
||||
//{{AFX_DATA_INIT(CLightSettingsDlg)
|
||||
m_Direction = 270;
|
||||
m_Elevation = 45;
|
||||
//}}AFX_DATA_INIT
|
||||
}
|
||||
|
||||
|
||||
void CLightSettingsDlg::DoDataExchange(CDataExchange* pDX)
|
||||
{
|
||||
CDialog::DoDataExchange(pDX);
|
||||
//{{AFX_DATA_MAP(CLightSettingsDlg)
|
||||
DDX_Control(pDX, IDC_BUTTON_UNITSAMBIENTCOLOR, m_UnitsAmbientColor);
|
||||
DDX_Control(pDX, IDC_BUTTON_DIRECTION, m_DirectionButton);
|
||||
DDX_Control(pDX, IDC_BUTTON_ELEVATION, m_ElevationButton);
|
||||
DDX_Control(pDX, IDC_BUTTON_TERRAINAMBIENTCOLOR, m_TerrainAmbientColor);
|
||||
DDX_Control(pDX, IDC_BUTTON_SUNCOLOR, m_SunColor);
|
||||
DDX_Text(pDX, IDC_EDIT_DIRECTION, m_Direction);
|
||||
DDX_Text(pDX, IDC_EDIT_ELEVATION, m_Elevation);
|
||||
//}}AFX_DATA_MAP
|
||||
}
|
||||
|
||||
|
||||
BEGIN_MESSAGE_MAP(CLightSettingsDlg, CDialog)
|
||||
//{{AFX_MSG_MAP(CLightSettingsDlg)
|
||||
ON_BN_CLICKED(IDC_BUTTON_APPLY, OnButtonApply)
|
||||
ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_DIRECTION, OnDeltaposSpinDirection)
|
||||
ON_EN_CHANGE(IDC_EDIT_DIRECTION, OnChangeEditDirection)
|
||||
ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_ELEVATION, OnDeltaposSpinElevation)
|
||||
ON_EN_CHANGE(IDC_EDIT_ELEVATION, OnChangeEditElevation)
|
||||
//}}AFX_MSG_MAP
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CLightSettingsDlg message handlers
|
||||
|
||||
|
||||
void CLightSettingsDlg::OnButtonApply()
|
||||
{
|
||||
UpdateData(TRUE);
|
||||
|
||||
// have we previously applied a lightenv?
|
||||
if (m_PreviousPreview) {
|
||||
// yes - undo it
|
||||
g_CmdMan.Undo();
|
||||
}
|
||||
|
||||
// build a lighting environment from the parameters
|
||||
CLightEnv env;
|
||||
env.m_Elevation=DEGTORAD(m_ElevationButton.m_Elevation);
|
||||
env.m_Rotation=DEGTORAD(m_DirectionButton.m_Direction);
|
||||
ColorRefToRGBColor(m_SunColor.m_Color,env.m_SunColor);
|
||||
ColorRefToRGBColor(m_TerrainAmbientColor.m_Color,env.m_TerrainAmbientColor);
|
||||
ColorRefToRGBColor(m_TerrainAmbientColor.m_Color,env.m_UnitsAmbientColor);
|
||||
|
||||
// create and execute an AlterLightEnv command
|
||||
CAlterLightEnvCommand* cmd=new CAlterLightEnvCommand(env);
|
||||
g_CmdMan.Execute(cmd);
|
||||
|
||||
AfxGetMainWnd()->Invalidate();
|
||||
AfxGetMainWnd()->UpdateWindow();
|
||||
|
||||
m_PreviousPreview=true;
|
||||
}
|
||||
|
||||
BOOL CLightSettingsDlg::OnInitDialog()
|
||||
{
|
||||
CDialog::OnInitDialog();
|
||||
|
||||
CSpinButtonCtrl* dirspin=(CSpinButtonCtrl*) GetDlgItem(IDC_SPIN_DIRECTION);
|
||||
assert(dirspin);
|
||||
dirspin->SetRange32(0,359);
|
||||
dirspin->SetPos(m_Direction);
|
||||
m_DirectionButton.m_Direction=float(m_Direction);
|
||||
|
||||
CSpinButtonCtrl* espin=(CSpinButtonCtrl*) GetDlgItem(IDC_SPIN_ELEVATION);
|
||||
assert(espin);
|
||||
espin->SetRange32(0,90);
|
||||
espin->SetPos(m_Elevation);
|
||||
m_ElevationButton.m_Elevation=float(m_Elevation);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void CLightSettingsDlg::OnDeltaposSpinDirection(NMHDR* pNMHDR, LRESULT* pResult)
|
||||
{
|
||||
NM_UPDOWN* pNMUpDown = (NM_UPDOWN*)pNMHDR;
|
||||
|
||||
// update direction button
|
||||
if (!UpdateData(TRUE)) return;
|
||||
CSpinButtonCtrl* dirspin=(CSpinButtonCtrl*) GetDlgItem(IDC_SPIN_DIRECTION);
|
||||
m_Direction=dirspin->GetPos()+pNMUpDown->iDelta;
|
||||
m_DirectionButton.m_Direction=float(m_Direction);
|
||||
m_DirectionButton.Invalidate();
|
||||
m_DirectionButton.UpdateWindow();
|
||||
|
||||
UpdateData(FALSE);
|
||||
|
||||
*pResult = 0;
|
||||
}
|
||||
|
||||
void CLightSettingsDlg::OnChangeEditDirection()
|
||||
{
|
||||
if (IsWindow(m_DirectionButton.m_hWnd)) {
|
||||
if (!UpdateData(TRUE)) return;
|
||||
m_DirectionButton.m_Direction=float(m_Direction);
|
||||
m_DirectionButton.Invalidate();
|
||||
m_DirectionButton.UpdateWindow();
|
||||
|
||||
CSpinButtonCtrl* dirspin=(CSpinButtonCtrl*) GetDlgItem(IDC_SPIN_DIRECTION);
|
||||
if (dirspin) dirspin->SetPos(m_Direction);
|
||||
}
|
||||
}
|
||||
|
||||
void CLightSettingsDlg::OnDeltaposSpinElevation(NMHDR* pNMHDR, LRESULT* pResult)
|
||||
{
|
||||
NM_UPDOWN* pNMUpDown = (NM_UPDOWN*)pNMHDR;
|
||||
|
||||
// update elevation button
|
||||
if (!UpdateData(TRUE)) return;
|
||||
CSpinButtonCtrl* espin=(CSpinButtonCtrl*) GetDlgItem(IDC_SPIN_ELEVATION);
|
||||
m_Elevation=espin->GetPos()+pNMUpDown->iDelta;
|
||||
m_ElevationButton.m_Elevation=float(m_Elevation);
|
||||
m_ElevationButton.Invalidate();
|
||||
m_ElevationButton.UpdateWindow();
|
||||
|
||||
UpdateData(FALSE);
|
||||
|
||||
*pResult = 0;
|
||||
}
|
||||
|
||||
void CLightSettingsDlg::OnChangeEditElevation()
|
||||
{
|
||||
if (IsWindow(m_ElevationButton.m_hWnd)) {
|
||||
if (!UpdateData(TRUE)) return;
|
||||
|
||||
m_ElevationButton.m_Elevation=float(m_Elevation);
|
||||
m_ElevationButton.Invalidate();
|
||||
m_ElevationButton.UpdateWindow();
|
||||
|
||||
CSpinButtonCtrl* espin=(CSpinButtonCtrl*) GetDlgItem(IDC_SPIN_ELEVATION);
|
||||
if (espin) espin->SetPos(m_Elevation);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,64 +1,64 @@
|
||||
#if !defined(AFX_LIGHTSETTINGSDLG_H__B2A613AF_961F_4365_90A3_82DF9F713401__INCLUDED_)
|
||||
#define AFX_LIGHTSETTINGSDLG_H__B2A613AF_961F_4365_90A3_82DF9F713401__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
// LightSettingsDlg.h : header file
|
||||
//
|
||||
|
||||
#include "ColorButton.h"
|
||||
#include "DirectionButton.h"
|
||||
#include "ElevationButton.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CLightSettingsDlg dialog
|
||||
|
||||
class CLightSettingsDlg : public CDialog
|
||||
{
|
||||
// Construction
|
||||
public:
|
||||
CLightSettingsDlg(CWnd* pParent = NULL); // standard constructor
|
||||
|
||||
bool m_PreviousPreview;
|
||||
// Dialog Data
|
||||
|
||||
//{{AFX_DATA(CLightSettingsDlg)
|
||||
enum { IDD = IDD_DIALOG_LIGHTSETTINGS };
|
||||
CColorButton m_UnitsAmbientColor;
|
||||
CDirectionButton m_DirectionButton;
|
||||
CElevationButton m_ElevationButton;
|
||||
CColorButton m_TerrainAmbientColor;
|
||||
CColorButton m_SunColor;
|
||||
int m_Direction;
|
||||
int m_Elevation;
|
||||
//}}AFX_DATA
|
||||
|
||||
|
||||
// Overrides
|
||||
// ClassWizard generated virtual function overrides
|
||||
//{{AFX_VIRTUAL(CLightSettingsDlg)
|
||||
protected:
|
||||
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
|
||||
//}}AFX_VIRTUAL
|
||||
|
||||
// Implementation
|
||||
|
||||
protected:
|
||||
// Generated message map functions
|
||||
//{{AFX_MSG(CLightSettingsDlg)
|
||||
afx_msg void OnButtonApply();
|
||||
virtual BOOL OnInitDialog();
|
||||
afx_msg void OnDeltaposSpinDirection(NMHDR* pNMHDR, LRESULT* pResult);
|
||||
afx_msg void OnChangeEditDirection();
|
||||
afx_msg void OnButtonTerrainambientcolor();
|
||||
afx_msg void OnDeltaposSpinElevation(NMHDR* pNMHDR, LRESULT* pResult);
|
||||
afx_msg void OnChangeEditElevation();
|
||||
//}}AFX_MSG
|
||||
DECLARE_MESSAGE_MAP()
|
||||
};
|
||||
|
||||
//{{AFX_INSERT_LOCATION}}
|
||||
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
|
||||
|
||||
#endif // !defined(AFX_LIGHTSETTINGSDLG_H__B2A613AF_961F_4365_90A3_82DF9F713401__INCLUDED_)
|
||||
#if !defined(AFX_LIGHTSETTINGSDLG_H__B2A613AF_961F_4365_90A3_82DF9F713401__INCLUDED_)
|
||||
#define AFX_LIGHTSETTINGSDLG_H__B2A613AF_961F_4365_90A3_82DF9F713401__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
// LightSettingsDlg.h : header file
|
||||
//
|
||||
|
||||
#include "ColorButton.h"
|
||||
#include "DirectionButton.h"
|
||||
#include "ElevationButton.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CLightSettingsDlg dialog
|
||||
|
||||
class CLightSettingsDlg : public CDialog
|
||||
{
|
||||
// Construction
|
||||
public:
|
||||
CLightSettingsDlg(CWnd* pParent = NULL); // standard constructor
|
||||
|
||||
bool m_PreviousPreview;
|
||||
// Dialog Data
|
||||
|
||||
//{{AFX_DATA(CLightSettingsDlg)
|
||||
enum { IDD = IDD_DIALOG_LIGHTSETTINGS };
|
||||
CColorButton m_UnitsAmbientColor;
|
||||
CDirectionButton m_DirectionButton;
|
||||
CElevationButton m_ElevationButton;
|
||||
CColorButton m_TerrainAmbientColor;
|
||||
CColorButton m_SunColor;
|
||||
int m_Direction;
|
||||
int m_Elevation;
|
||||
//}}AFX_DATA
|
||||
|
||||
|
||||
// Overrides
|
||||
// ClassWizard generated virtual function overrides
|
||||
//{{AFX_VIRTUAL(CLightSettingsDlg)
|
||||
protected:
|
||||
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
|
||||
//}}AFX_VIRTUAL
|
||||
|
||||
// Implementation
|
||||
|
||||
protected:
|
||||
// Generated message map functions
|
||||
//{{AFX_MSG(CLightSettingsDlg)
|
||||
afx_msg void OnButtonApply();
|
||||
virtual BOOL OnInitDialog();
|
||||
afx_msg void OnDeltaposSpinDirection(NMHDR* pNMHDR, LRESULT* pResult);
|
||||
afx_msg void OnChangeEditDirection();
|
||||
afx_msg void OnButtonTerrainambientcolor();
|
||||
afx_msg void OnDeltaposSpinElevation(NMHDR* pNMHDR, LRESULT* pResult);
|
||||
afx_msg void OnChangeEditElevation();
|
||||
//}}AFX_MSG
|
||||
DECLARE_MESSAGE_MAP()
|
||||
};
|
||||
|
||||
//{{AFX_INSERT_LOCATION}}
|
||||
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
|
||||
|
||||
#endif // !defined(AFX_LIGHTSETTINGSDLG_H__B2A613AF_961F_4365_90A3_82DF9F713401__INCLUDED_)
|
||||
|
@ -1,107 +1,107 @@
|
||||
// MainFrameDlgBar.cpp : implementation file
|
||||
//
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "ScEd.h"
|
||||
#include "MainFrm.h"
|
||||
#include "MainFrameDlgBar.h"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define new DEBUG_NEW
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
|
||||
BEGIN_MESSAGE_MAP(CMainFrameDlgBar, CDialogBar)
|
||||
//{{AFX_MSG_MAP(CMainFrameDlgBar)
|
||||
ON_BN_CLICKED(IDC_BUTTON_SELECT, OnButtonSelect)
|
||||
ON_BN_CLICKED(IDC_BUTTON_TEXTURETOOLS, OnButtonTextureTools)
|
||||
ON_BN_CLICKED(IDC_BUTTON_ELEVATIONTOOLS, OnButtonElevationTools)
|
||||
ON_BN_CLICKED(IDC_BUTTON_MODELTOOLS, OnButtonModelTools)
|
||||
//}}AFX_MSG_MAP
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CMainFrameDlgBar dialog
|
||||
|
||||
|
||||
CMainFrameDlgBar::CMainFrameDlgBar()
|
||||
{
|
||||
//{{AFX_DATA_INIT(CMainFrameDlgBar)
|
||||
// NOTE: the ClassWizard will add member initialization here
|
||||
//}}AFX_DATA_INIT
|
||||
}
|
||||
|
||||
BOOL CMainFrameDlgBar::Create(CWnd * pParentWnd, LPCTSTR lpszTemplateName,UINT nStyle, UINT nID)
|
||||
{
|
||||
if (!CDialogBar::Create(pParentWnd, lpszTemplateName, nStyle, nID)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!OnInitDialog()) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL CMainFrameDlgBar::Create(CWnd * pParentWnd, UINT nIDTemplate,UINT nStyle, UINT nID)
|
||||
{
|
||||
if (!Create(pParentWnd, MAKEINTRESOURCE(nIDTemplate), nStyle, nID)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void CMainFrameDlgBar::OnUpdateCmdUI(CFrameWnd* pTarget, BOOL bDisableIfNoHndler)
|
||||
{
|
||||
bDisableIfNoHndler = FALSE;
|
||||
CDialogBar::OnUpdateCmdUI(pTarget,bDisableIfNoHndler);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CMainFrameDlgBar message handlers
|
||||
|
||||
void CMainFrameDlgBar::OnButtonSelect()
|
||||
{
|
||||
CMainFrame* parent=(CMainFrame*) GetParent();
|
||||
parent->DeselectTools();
|
||||
}
|
||||
|
||||
void CMainFrameDlgBar::OnButtonTextureTools()
|
||||
{
|
||||
CMainFrame* parent=(CMainFrame*) GetParent();
|
||||
parent->OnTextureTools();
|
||||
}
|
||||
|
||||
void CMainFrameDlgBar::OnButtonElevationTools()
|
||||
{
|
||||
CMainFrame* parent=(CMainFrame*) GetParent();
|
||||
parent->OnElevationTools();
|
||||
}
|
||||
|
||||
void CMainFrameDlgBar::OnButtonModelTools()
|
||||
{
|
||||
CMainFrame* parent=(CMainFrame*) GetParent();
|
||||
parent->OnUnitTools();
|
||||
}
|
||||
|
||||
BOOL CMainFrameDlgBar::OnInitDialog()
|
||||
{
|
||||
CButton* btnSelect=(CButton*) GetDlgItem(IDC_BUTTON_SELECT);
|
||||
btnSelect->SetBitmap(::LoadBitmap(::GetModuleHandle(0),MAKEINTRESOURCE(IDB_BITMAP_SELECT)));
|
||||
|
||||
CButton* btnTexTools=(CButton*) GetDlgItem(IDC_BUTTON_TEXTURETOOLS);
|
||||
btnTexTools->SetBitmap(::LoadBitmap(::GetModuleHandle(0),MAKEINTRESOURCE(IDB_BITMAP_TEXTURETOOLS)));
|
||||
|
||||
CButton* btnElevTools=(CButton*) GetDlgItem(IDC_BUTTON_ELEVATIONTOOLS);
|
||||
btnElevTools->SetBitmap(::LoadBitmap(::GetModuleHandle(0),MAKEINTRESOURCE(IDB_BITMAP_ELEVATIONTOOLS)));
|
||||
|
||||
CButton* btnMdlTools=(CButton*) GetDlgItem(IDC_BUTTON_MODELTOOLS);
|
||||
btnMdlTools->SetBitmap(::LoadBitmap(::GetModuleHandle(0),MAKEINTRESOURCE(IDB_BITMAP_MODELTOOLS)));
|
||||
|
||||
return TRUE; // return TRUE unless you set the focus to a control
|
||||
// EXCEPTION: OCX Property Pages should return FALSE
|
||||
}
|
||||
// MainFrameDlgBar.cpp : implementation file
|
||||
//
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "ScEd.h"
|
||||
#include "MainFrm.h"
|
||||
#include "MainFrameDlgBar.h"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define new DEBUG_NEW
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
|
||||
BEGIN_MESSAGE_MAP(CMainFrameDlgBar, CDialogBar)
|
||||
//{{AFX_MSG_MAP(CMainFrameDlgBar)
|
||||
ON_BN_CLICKED(IDC_BUTTON_SELECT, OnButtonSelect)
|
||||
ON_BN_CLICKED(IDC_BUTTON_TEXTURETOOLS, OnButtonTextureTools)
|
||||
ON_BN_CLICKED(IDC_BUTTON_ELEVATIONTOOLS, OnButtonElevationTools)
|
||||
ON_BN_CLICKED(IDC_BUTTON_MODELTOOLS, OnButtonModelTools)
|
||||
//}}AFX_MSG_MAP
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CMainFrameDlgBar dialog
|
||||
|
||||
|
||||
CMainFrameDlgBar::CMainFrameDlgBar()
|
||||
{
|
||||
//{{AFX_DATA_INIT(CMainFrameDlgBar)
|
||||
// NOTE: the ClassWizard will add member initialization here
|
||||
//}}AFX_DATA_INIT
|
||||
}
|
||||
|
||||
BOOL CMainFrameDlgBar::Create(CWnd * pParentWnd, LPCTSTR lpszTemplateName,UINT nStyle, UINT nID)
|
||||
{
|
||||
if (!CDialogBar::Create(pParentWnd, lpszTemplateName, nStyle, nID)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!OnInitDialog()) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL CMainFrameDlgBar::Create(CWnd * pParentWnd, UINT nIDTemplate,UINT nStyle, UINT nID)
|
||||
{
|
||||
if (!Create(pParentWnd, MAKEINTRESOURCE(nIDTemplate), nStyle, nID)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void CMainFrameDlgBar::OnUpdateCmdUI(CFrameWnd* pTarget, BOOL bDisableIfNoHndler)
|
||||
{
|
||||
bDisableIfNoHndler = FALSE;
|
||||
CDialogBar::OnUpdateCmdUI(pTarget,bDisableIfNoHndler);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CMainFrameDlgBar message handlers
|
||||
|
||||
void CMainFrameDlgBar::OnButtonSelect()
|
||||
{
|
||||
CMainFrame* parent=(CMainFrame*) GetParent();
|
||||
parent->DeselectTools();
|
||||
}
|
||||
|
||||
void CMainFrameDlgBar::OnButtonTextureTools()
|
||||
{
|
||||
CMainFrame* parent=(CMainFrame*) GetParent();
|
||||
parent->OnTextureTools();
|
||||
}
|
||||
|
||||
void CMainFrameDlgBar::OnButtonElevationTools()
|
||||
{
|
||||
CMainFrame* parent=(CMainFrame*) GetParent();
|
||||
parent->OnElevationTools();
|
||||
}
|
||||
|
||||
void CMainFrameDlgBar::OnButtonModelTools()
|
||||
{
|
||||
CMainFrame* parent=(CMainFrame*) GetParent();
|
||||
parent->OnUnitTools();
|
||||
}
|
||||
|
||||
BOOL CMainFrameDlgBar::OnInitDialog()
|
||||
{
|
||||
CButton* btnSelect=(CButton*) GetDlgItem(IDC_BUTTON_SELECT);
|
||||
btnSelect->SetBitmap(::LoadBitmap(::GetModuleHandle(0),MAKEINTRESOURCE(IDB_BITMAP_SELECT)));
|
||||
|
||||
CButton* btnTexTools=(CButton*) GetDlgItem(IDC_BUTTON_TEXTURETOOLS);
|
||||
btnTexTools->SetBitmap(::LoadBitmap(::GetModuleHandle(0),MAKEINTRESOURCE(IDB_BITMAP_TEXTURETOOLS)));
|
||||
|
||||
CButton* btnElevTools=(CButton*) GetDlgItem(IDC_BUTTON_ELEVATIONTOOLS);
|
||||
btnElevTools->SetBitmap(::LoadBitmap(::GetModuleHandle(0),MAKEINTRESOURCE(IDB_BITMAP_ELEVATIONTOOLS)));
|
||||
|
||||
CButton* btnMdlTools=(CButton*) GetDlgItem(IDC_BUTTON_MODELTOOLS);
|
||||
btnMdlTools->SetBitmap(::LoadBitmap(::GetModuleHandle(0),MAKEINTRESOURCE(IDB_BITMAP_MODELTOOLS)));
|
||||
|
||||
return TRUE; // return TRUE unless you set the focus to a control
|
||||
// EXCEPTION: OCX Property Pages should return FALSE
|
||||
}
|
||||
|
@ -1,53 +1,53 @@
|
||||
#if !defined(AFX_MAINFRAMEDLGBAR_H__B1EBAF6A_9AB1_4797_B859_3D47D8B011E0__INCLUDED_)
|
||||
#define AFX_MAINFRAMEDLGBAR_H__B1EBAF6A_9AB1_4797_B859_3D47D8B011E0__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
// MainFrameDlgBar.h : header file
|
||||
//
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CMainFrameDlgBar dialog
|
||||
|
||||
class CMainFrameDlgBar : public CDialogBar
|
||||
{
|
||||
// Construction
|
||||
public:
|
||||
CMainFrameDlgBar(); // standard constructor
|
||||
|
||||
BOOL Create(CWnd * pParentWnd, UINT nIDTemplate, UINT nStyle, UINT nID);
|
||||
BOOL Create(CWnd * pParentWnd, LPCTSTR lpszTemplateName, UINT nStyle, UINT nID);
|
||||
void OnUpdateCmdUI(CFrameWnd* pTarget, BOOL bDisableIfNoHndler);
|
||||
|
||||
// Dialog Data
|
||||
//{{AFX_DATA(CMainFrameDlgBar)
|
||||
enum { IDD = IDR_MAINFRAME };
|
||||
// NOTE: the ClassWizard will add data members here
|
||||
//}}AFX_DATA
|
||||
|
||||
|
||||
// Overrides
|
||||
// ClassWizard generated virtual function overrides
|
||||
//{{AFX_VIRTUAL(CMainFrameDlgBar)
|
||||
protected:
|
||||
//}}AFX_VIRTUAL
|
||||
|
||||
// Implementation
|
||||
protected:
|
||||
BOOL OnInitDialog();
|
||||
|
||||
// Generated message map functions
|
||||
//{{AFX_MSG(CMainFrameDlgBar)
|
||||
afx_msg void OnButtonSelect();
|
||||
afx_msg void OnButtonTextureTools();
|
||||
afx_msg void OnButtonElevationTools();
|
||||
afx_msg void OnButtonModelTools();
|
||||
//}}AFX_MSG
|
||||
DECLARE_MESSAGE_MAP()
|
||||
};
|
||||
|
||||
//{{AFX_INSERT_LOCATION}}
|
||||
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
|
||||
|
||||
#endif // !defined(AFX_MAINFRAMEDLGBAR_H__B1EBAF6A_9AB1_4797_B859_3D47D8B011E0__INCLUDED_)
|
||||
#if !defined(AFX_MAINFRAMEDLGBAR_H__B1EBAF6A_9AB1_4797_B859_3D47D8B011E0__INCLUDED_)
|
||||
#define AFX_MAINFRAMEDLGBAR_H__B1EBAF6A_9AB1_4797_B859_3D47D8B011E0__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
// MainFrameDlgBar.h : header file
|
||||
//
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CMainFrameDlgBar dialog
|
||||
|
||||
class CMainFrameDlgBar : public CDialogBar
|
||||
{
|
||||
// Construction
|
||||
public:
|
||||
CMainFrameDlgBar(); // standard constructor
|
||||
|
||||
BOOL Create(CWnd * pParentWnd, UINT nIDTemplate, UINT nStyle, UINT nID);
|
||||
BOOL Create(CWnd * pParentWnd, LPCTSTR lpszTemplateName, UINT nStyle, UINT nID);
|
||||
void OnUpdateCmdUI(CFrameWnd* pTarget, BOOL bDisableIfNoHndler);
|
||||
|
||||
// Dialog Data
|
||||
//{{AFX_DATA(CMainFrameDlgBar)
|
||||
enum { IDD = IDR_MAINFRAME };
|
||||
// NOTE: the ClassWizard will add data members here
|
||||
//}}AFX_DATA
|
||||
|
||||
|
||||
// Overrides
|
||||
// ClassWizard generated virtual function overrides
|
||||
//{{AFX_VIRTUAL(CMainFrameDlgBar)
|
||||
protected:
|
||||
//}}AFX_VIRTUAL
|
||||
|
||||
// Implementation
|
||||
protected:
|
||||
BOOL OnInitDialog();
|
||||
|
||||
// Generated message map functions
|
||||
//{{AFX_MSG(CMainFrameDlgBar)
|
||||
afx_msg void OnButtonSelect();
|
||||
afx_msg void OnButtonTextureTools();
|
||||
afx_msg void OnButtonElevationTools();
|
||||
afx_msg void OnButtonModelTools();
|
||||
//}}AFX_MSG
|
||||
DECLARE_MESSAGE_MAP()
|
||||
};
|
||||
|
||||
//{{AFX_INSERT_LOCATION}}
|
||||
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
|
||||
|
||||
#endif // !defined(AFX_MAINFRAMEDLGBAR_H__B1EBAF6A_9AB1_4797_B859_3D47D8B011E0__INCLUDED_)
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,117 +1,117 @@
|
||||
// MainFrm.h : interface of the CMainFrame class
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if !defined(AFX_MAINFRM_H__5804C3C3_DA2E_4546_9BE5_886FB4BEF254__INCLUDED_)
|
||||
#define AFX_MAINFRM_H__5804C3C3_DA2E_4546_9BE5_886FB4BEF254__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
|
||||
#include "MainFrameDlgBar.h"
|
||||
#include "TexToolsDlgBar.h"
|
||||
#include "ElevToolsDlgBar.h"
|
||||
#include "UnitToolsDlgBar.h"
|
||||
#include "UnitPropertiesDlgBar.h"
|
||||
#include "BrushShapeEditorDlgBar.h"
|
||||
|
||||
class CObjectEntry;
|
||||
|
||||
class CMainFrame : public CFrameWnd
|
||||
{
|
||||
|
||||
protected: // create from serialization only
|
||||
CMainFrame();
|
||||
DECLARE_DYNCREATE(CMainFrame)
|
||||
|
||||
// Attributes
|
||||
public:
|
||||
|
||||
// Operations
|
||||
public:
|
||||
void OnUnitTools();
|
||||
void OnObjectProperties(CObjectEntry* obj);
|
||||
|
||||
void DeselectTools();
|
||||
|
||||
void SetTitle();
|
||||
|
||||
// Overrides
|
||||
// ClassWizard generated virtual function overrides
|
||||
//{{AFX_VIRTUAL(CMainFrame)
|
||||
virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
|
||||
virtual void PostNcDestroy();
|
||||
//}}AFX_VIRTUAL
|
||||
|
||||
// Implementation
|
||||
public:
|
||||
virtual ~CMainFrame();
|
||||
#ifdef _DEBUG
|
||||
virtual void AssertValid() const;
|
||||
virtual void Dump(CDumpContext& dc) const;
|
||||
#endif
|
||||
|
||||
|
||||
protected: // control bar embedded members
|
||||
CStatusBar m_wndStatusBar;
|
||||
CMainFrameDlgBar m_wndDlgBar;
|
||||
CTexToolsDlgBar m_wndTexToolsBar;
|
||||
CElevToolsDlgBar m_wndElevToolsBar;
|
||||
CUnitToolsDlgBar m_wndUnitToolsBar;
|
||||
CUnitPropertiesDlgBar m_wndUnitPropsBar;
|
||||
CBrushShapeEditorDlgBar m_wndBrushShapeEditorBar;
|
||||
|
||||
// Generated message map functions
|
||||
protected:
|
||||
friend class CMainFrameDlgBar;
|
||||
friend class CScEdView;
|
||||
|
||||
void DisableCtrlBars();
|
||||
void DisableToolbarButtons();
|
||||
|
||||
//{{AFX_MSG(CMainFrame)
|
||||
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
|
||||
afx_msg void OnTerrainLoad();
|
||||
afx_msg void OnLightingSettings();
|
||||
afx_msg void OnViewScreenshot();
|
||||
afx_msg void OnTextureTools();
|
||||
afx_msg void OnToolsOptions();
|
||||
afx_msg void OnToolsBrushShapeEditor();
|
||||
afx_msg void OnEditUndo();
|
||||
afx_msg void OnUpdateEditUndo(CCmdUI* pCmdUI);
|
||||
afx_msg void OnEditRedo();
|
||||
afx_msg void OnUpdateEditRedo(CCmdUI* pCmdUI);
|
||||
afx_msg void OnElevationTools();
|
||||
afx_msg void OnResizeMap();
|
||||
afx_msg void OnViewTerrainGrid();
|
||||
afx_msg void OnUpdateViewTerrainGrid(CCmdUI* pCmdUI);
|
||||
afx_msg void OnViewTerrainSolid();
|
||||
afx_msg void OnUpdateViewTerrainSolid(CCmdUI* pCmdUI);
|
||||
afx_msg void OnViewTerrainWireframe();
|
||||
afx_msg void OnUpdateViewTerrainWireframe(CCmdUI* pCmdUI);
|
||||
afx_msg void OnViewModelGrid();
|
||||
afx_msg void OnUpdateViewModelGrid(CCmdUI* pCmdUI);
|
||||
afx_msg void OnViewModelSolid();
|
||||
afx_msg void OnUpdateViewModelSolid(CCmdUI* pCmdUI);
|
||||
afx_msg void OnViewModelWireframe();
|
||||
afx_msg void OnUpdateViewModelWireframe(CCmdUI* pCmdUI);
|
||||
afx_msg void OnFileSaveMap();
|
||||
afx_msg void OnFileLoadMap();
|
||||
afx_msg void OnViewRenderStats();
|
||||
afx_msg void OnUpdateViewRenderStats(CCmdUI* pCmdUI);
|
||||
afx_msg LRESULT OnMouseWheel(WPARAM wParam,LPARAM lParam);
|
||||
afx_msg void OnTestGo();
|
||||
afx_msg void OnUpdateTestGo(CCmdUI* pCmdUI);
|
||||
afx_msg void OnTestStop();
|
||||
afx_msg void OnUpdateTestStop(CCmdUI* pCmdUI);
|
||||
//}}AFX_MSG
|
||||
DECLARE_MESSAGE_MAP()
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//{{AFX_INSERT_LOCATION}}
|
||||
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
|
||||
|
||||
#endif // !defined(AFX_MAINFRM_H__5804C3C3_DA2E_4546_9BE5_886FB4BEF254__INCLUDED_)
|
||||
// MainFrm.h : interface of the CMainFrame class
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if !defined(AFX_MAINFRM_H__5804C3C3_DA2E_4546_9BE5_886FB4BEF254__INCLUDED_)
|
||||
#define AFX_MAINFRM_H__5804C3C3_DA2E_4546_9BE5_886FB4BEF254__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
|
||||
#include "MainFrameDlgBar.h"
|
||||
#include "TexToolsDlgBar.h"
|
||||
#include "ElevToolsDlgBar.h"
|
||||
#include "UnitToolsDlgBar.h"
|
||||
#include "UnitPropertiesDlgBar.h"
|
||||
#include "BrushShapeEditorDlgBar.h"
|
||||
|
||||
class CObjectEntry;
|
||||
|
||||
class CMainFrame : public CFrameWnd
|
||||
{
|
||||
|
||||
protected: // create from serialization only
|
||||
CMainFrame();
|
||||
DECLARE_DYNCREATE(CMainFrame)
|
||||
|
||||
// Attributes
|
||||
public:
|
||||
|
||||
// Operations
|
||||
public:
|
||||
void OnUnitTools();
|
||||
void OnObjectProperties(CObjectEntry* obj);
|
||||
|
||||
void DeselectTools();
|
||||
|
||||
void SetTitle();
|
||||
|
||||
// Overrides
|
||||
// ClassWizard generated virtual function overrides
|
||||
//{{AFX_VIRTUAL(CMainFrame)
|
||||
virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
|
||||
virtual void PostNcDestroy();
|
||||
//}}AFX_VIRTUAL
|
||||
|
||||
// Implementation
|
||||
public:
|
||||
virtual ~CMainFrame();
|
||||
#ifdef _DEBUG
|
||||
virtual void AssertValid() const;
|
||||
virtual void Dump(CDumpContext& dc) const;
|
||||
#endif
|
||||
|
||||
|
||||
protected: // control bar embedded members
|
||||
CStatusBar m_wndStatusBar;
|
||||
CMainFrameDlgBar m_wndDlgBar;
|
||||
CTexToolsDlgBar m_wndTexToolsBar;
|
||||
CElevToolsDlgBar m_wndElevToolsBar;
|
||||
CUnitToolsDlgBar m_wndUnitToolsBar;
|
||||
CUnitPropertiesDlgBar m_wndUnitPropsBar;
|
||||
CBrushShapeEditorDlgBar m_wndBrushShapeEditorBar;
|
||||
|
||||
// Generated message map functions
|
||||
protected:
|
||||
friend class CMainFrameDlgBar;
|
||||
friend class CScEdView;
|
||||
|
||||
void DisableCtrlBars();
|
||||
void DisableToolbarButtons();
|
||||
|
||||
//{{AFX_MSG(CMainFrame)
|
||||
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
|
||||
afx_msg void OnTerrainLoad();
|
||||
afx_msg void OnLightingSettings();
|
||||
afx_msg void OnViewScreenshot();
|
||||
afx_msg void OnTextureTools();
|
||||
afx_msg void OnToolsOptions();
|
||||
afx_msg void OnToolsBrushShapeEditor();
|
||||
afx_msg void OnEditUndo();
|
||||
afx_msg void OnUpdateEditUndo(CCmdUI* pCmdUI);
|
||||
afx_msg void OnEditRedo();
|
||||
afx_msg void OnUpdateEditRedo(CCmdUI* pCmdUI);
|
||||
afx_msg void OnElevationTools();
|
||||
afx_msg void OnResizeMap();
|
||||
afx_msg void OnViewTerrainGrid();
|
||||
afx_msg void OnUpdateViewTerrainGrid(CCmdUI* pCmdUI);
|
||||
afx_msg void OnViewTerrainSolid();
|
||||
afx_msg void OnUpdateViewTerrainSolid(CCmdUI* pCmdUI);
|
||||
afx_msg void OnViewTerrainWireframe();
|
||||
afx_msg void OnUpdateViewTerrainWireframe(CCmdUI* pCmdUI);
|
||||
afx_msg void OnViewModelGrid();
|
||||
afx_msg void OnUpdateViewModelGrid(CCmdUI* pCmdUI);
|
||||
afx_msg void OnViewModelSolid();
|
||||
afx_msg void OnUpdateViewModelSolid(CCmdUI* pCmdUI);
|
||||
afx_msg void OnViewModelWireframe();
|
||||
afx_msg void OnUpdateViewModelWireframe(CCmdUI* pCmdUI);
|
||||
afx_msg void OnFileSaveMap();
|
||||
afx_msg void OnFileLoadMap();
|
||||
afx_msg void OnViewRenderStats();
|
||||
afx_msg void OnUpdateViewRenderStats(CCmdUI* pCmdUI);
|
||||
afx_msg LRESULT OnMouseWheel(WPARAM wParam,LPARAM lParam);
|
||||
afx_msg void OnTestGo();
|
||||
afx_msg void OnUpdateTestGo(CCmdUI* pCmdUI);
|
||||
afx_msg void OnTestStop();
|
||||
afx_msg void OnUpdateTestStop(CCmdUI* pCmdUI);
|
||||
//}}AFX_MSG
|
||||
DECLARE_MESSAGE_MAP()
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//{{AFX_INSERT_LOCATION}}
|
||||
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
|
||||
|
||||
#endif // !defined(AFX_MAINFRM_H__5804C3C3_DA2E_4546_9BE5_886FB4BEF254__INCLUDED_)
|
||||
|
@ -1,86 +1,86 @@
|
||||
// MapSizeDlg.cpp : implementation file
|
||||
//
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "ScEd.h"
|
||||
#include "MapSizeDlg.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CMapSizeDlg dialog
|
||||
|
||||
|
||||
CMapSizeDlg::CMapSizeDlg(CWnd* pParent /*=NULL*/)
|
||||
: CDialog(CMapSizeDlg::IDD, pParent), m_MapSize(11)
|
||||
{
|
||||
//{{AFX_DATA_INIT(CMapSizeDlg)
|
||||
// NOTE: the ClassWizard will add member initialization here
|
||||
//}}AFX_DATA_INIT
|
||||
}
|
||||
|
||||
|
||||
void CMapSizeDlg::DoDataExchange(CDataExchange* pDX)
|
||||
{
|
||||
CDialog::DoDataExchange(pDX);
|
||||
//{{AFX_DATA_MAP(CMapSizeDlg)
|
||||
// NOTE: the ClassWizard will add DDX and DDV calls here
|
||||
//}}AFX_DATA_MAP
|
||||
}
|
||||
|
||||
|
||||
BEGIN_MESSAGE_MAP(CMapSizeDlg, CDialog)
|
||||
//{{AFX_MSG_MAP(CMapSizeDlg)
|
||||
ON_BN_CLICKED(IDC_RADIO_HUGE, OnRadioHuge)
|
||||
ON_BN_CLICKED(IDC_RADIO_LARGE, OnRadioLarge)
|
||||
ON_BN_CLICKED(IDC_RADIO_MEDIUM, OnRadioMedium)
|
||||
ON_BN_CLICKED(IDC_RADIO_SMALL, OnRadioSmall)
|
||||
//}}AFX_MSG_MAP
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CMapSizeDlg message handlers
|
||||
|
||||
BOOL CMapSizeDlg::OnInitDialog()
|
||||
{
|
||||
CDialog::OnInitDialog();
|
||||
|
||||
OnRadioMedium();
|
||||
|
||||
return TRUE; // return TRUE unless you set the focus to a control
|
||||
// EXCEPTION: OCX Property Pages should return FALSE
|
||||
}
|
||||
|
||||
void CMapSizeDlg::OnRadioHuge()
|
||||
{
|
||||
CheckDlgButton(IDC_RADIO_SMALL,FALSE);
|
||||
CheckDlgButton(IDC_RADIO_MEDIUM,FALSE);
|
||||
CheckDlgButton(IDC_RADIO_LARGE,FALSE);
|
||||
CheckDlgButton(IDC_RADIO_HUGE,TRUE);
|
||||
m_MapSize=17;
|
||||
}
|
||||
|
||||
void CMapSizeDlg::OnRadioLarge()
|
||||
{
|
||||
CheckDlgButton(IDC_RADIO_SMALL,FALSE);
|
||||
CheckDlgButton(IDC_RADIO_MEDIUM,FALSE);
|
||||
CheckDlgButton(IDC_RADIO_LARGE,TRUE);
|
||||
CheckDlgButton(IDC_RADIO_HUGE,FALSE);
|
||||
m_MapSize=13;
|
||||
}
|
||||
|
||||
void CMapSizeDlg::OnRadioMedium()
|
||||
{
|
||||
CheckDlgButton(IDC_RADIO_SMALL,FALSE);
|
||||
CheckDlgButton(IDC_RADIO_MEDIUM,TRUE);
|
||||
CheckDlgButton(IDC_RADIO_LARGE,FALSE);
|
||||
CheckDlgButton(IDC_RADIO_HUGE,FALSE);
|
||||
m_MapSize=11;
|
||||
}
|
||||
|
||||
void CMapSizeDlg::OnRadioSmall()
|
||||
{
|
||||
CheckDlgButton(IDC_RADIO_SMALL,TRUE);
|
||||
CheckDlgButton(IDC_RADIO_MEDIUM,FALSE);
|
||||
CheckDlgButton(IDC_RADIO_LARGE,FALSE);
|
||||
CheckDlgButton(IDC_RADIO_HUGE,FALSE);
|
||||
m_MapSize=9;
|
||||
}
|
||||
// MapSizeDlg.cpp : implementation file
|
||||
//
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "ScEd.h"
|
||||
#include "MapSizeDlg.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CMapSizeDlg dialog
|
||||
|
||||
|
||||
CMapSizeDlg::CMapSizeDlg(CWnd* pParent /*=NULL*/)
|
||||
: CDialog(CMapSizeDlg::IDD, pParent), m_MapSize(11)
|
||||
{
|
||||
//{{AFX_DATA_INIT(CMapSizeDlg)
|
||||
// NOTE: the ClassWizard will add member initialization here
|
||||
//}}AFX_DATA_INIT
|
||||
}
|
||||
|
||||
|
||||
void CMapSizeDlg::DoDataExchange(CDataExchange* pDX)
|
||||
{
|
||||
CDialog::DoDataExchange(pDX);
|
||||
//{{AFX_DATA_MAP(CMapSizeDlg)
|
||||
// NOTE: the ClassWizard will add DDX and DDV calls here
|
||||
//}}AFX_DATA_MAP
|
||||
}
|
||||
|
||||
|
||||
BEGIN_MESSAGE_MAP(CMapSizeDlg, CDialog)
|
||||
//{{AFX_MSG_MAP(CMapSizeDlg)
|
||||
ON_BN_CLICKED(IDC_RADIO_HUGE, OnRadioHuge)
|
||||
ON_BN_CLICKED(IDC_RADIO_LARGE, OnRadioLarge)
|
||||
ON_BN_CLICKED(IDC_RADIO_MEDIUM, OnRadioMedium)
|
||||
ON_BN_CLICKED(IDC_RADIO_SMALL, OnRadioSmall)
|
||||
//}}AFX_MSG_MAP
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CMapSizeDlg message handlers
|
||||
|
||||
BOOL CMapSizeDlg::OnInitDialog()
|
||||
{
|
||||
CDialog::OnInitDialog();
|
||||
|
||||
OnRadioMedium();
|
||||
|
||||
return TRUE; // return TRUE unless you set the focus to a control
|
||||
// EXCEPTION: OCX Property Pages should return FALSE
|
||||
}
|
||||
|
||||
void CMapSizeDlg::OnRadioHuge()
|
||||
{
|
||||
CheckDlgButton(IDC_RADIO_SMALL,FALSE);
|
||||
CheckDlgButton(IDC_RADIO_MEDIUM,FALSE);
|
||||
CheckDlgButton(IDC_RADIO_LARGE,FALSE);
|
||||
CheckDlgButton(IDC_RADIO_HUGE,TRUE);
|
||||
m_MapSize=17;
|
||||
}
|
||||
|
||||
void CMapSizeDlg::OnRadioLarge()
|
||||
{
|
||||
CheckDlgButton(IDC_RADIO_SMALL,FALSE);
|
||||
CheckDlgButton(IDC_RADIO_MEDIUM,FALSE);
|
||||
CheckDlgButton(IDC_RADIO_LARGE,TRUE);
|
||||
CheckDlgButton(IDC_RADIO_HUGE,FALSE);
|
||||
m_MapSize=13;
|
||||
}
|
||||
|
||||
void CMapSizeDlg::OnRadioMedium()
|
||||
{
|
||||
CheckDlgButton(IDC_RADIO_SMALL,FALSE);
|
||||
CheckDlgButton(IDC_RADIO_MEDIUM,TRUE);
|
||||
CheckDlgButton(IDC_RADIO_LARGE,FALSE);
|
||||
CheckDlgButton(IDC_RADIO_HUGE,FALSE);
|
||||
m_MapSize=11;
|
||||
}
|
||||
|
||||
void CMapSizeDlg::OnRadioSmall()
|
||||
{
|
||||
CheckDlgButton(IDC_RADIO_SMALL,TRUE);
|
||||
CheckDlgButton(IDC_RADIO_MEDIUM,FALSE);
|
||||
CheckDlgButton(IDC_RADIO_LARGE,FALSE);
|
||||
CheckDlgButton(IDC_RADIO_HUGE,FALSE);
|
||||
m_MapSize=9;
|
||||
}
|
||||
|
@ -1,52 +1,52 @@
|
||||
#if !defined(AFX_MAPSIZEDLG_H__F43F9B80_73CB_4DEB_8630_F0690664D510__INCLUDED_)
|
||||
#define AFX_MAPSIZEDLG_H__F43F9B80_73CB_4DEB_8630_F0690664D510__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
// MapSizeDlg.h : header file
|
||||
//
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CMapSizeDlg dialog
|
||||
|
||||
class CMapSizeDlg : public CDialog
|
||||
{
|
||||
// Construction
|
||||
public:
|
||||
CMapSizeDlg(CWnd* pParent = NULL); // standard constructor
|
||||
|
||||
int m_MapSize;
|
||||
|
||||
// Dialog Data
|
||||
//{{AFX_DATA(CMapSizeDlg)
|
||||
enum { IDD = IDD_DIALOG_MAPSIZE };
|
||||
// NOTE: the ClassWizard will add data members here
|
||||
//}}AFX_DATA
|
||||
|
||||
|
||||
// Overrides
|
||||
// ClassWizard generated virtual function overrides
|
||||
//{{AFX_VIRTUAL(CMapSizeDlg)
|
||||
protected:
|
||||
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
|
||||
//}}AFX_VIRTUAL
|
||||
|
||||
// Implementation
|
||||
protected:
|
||||
|
||||
// Generated message map functions
|
||||
//{{AFX_MSG(CMapSizeDlg)
|
||||
virtual BOOL OnInitDialog();
|
||||
afx_msg void OnRadioHuge();
|
||||
afx_msg void OnRadioLarge();
|
||||
afx_msg void OnRadioMedium();
|
||||
afx_msg void OnRadioSmall();
|
||||
//}}AFX_MSG
|
||||
DECLARE_MESSAGE_MAP()
|
||||
};
|
||||
|
||||
//{{AFX_INSERT_LOCATION}}
|
||||
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
|
||||
|
||||
#endif // !defined(AFX_MAPSIZEDLG_H__F43F9B80_73CB_4DEB_8630_F0690664D510__INCLUDED_)
|
||||
#if !defined(AFX_MAPSIZEDLG_H__F43F9B80_73CB_4DEB_8630_F0690664D510__INCLUDED_)
|
||||
#define AFX_MAPSIZEDLG_H__F43F9B80_73CB_4DEB_8630_F0690664D510__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
// MapSizeDlg.h : header file
|
||||
//
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CMapSizeDlg dialog
|
||||
|
||||
class CMapSizeDlg : public CDialog
|
||||
{
|
||||
// Construction
|
||||
public:
|
||||
CMapSizeDlg(CWnd* pParent = NULL); // standard constructor
|
||||
|
||||
int m_MapSize;
|
||||
|
||||
// Dialog Data
|
||||
//{{AFX_DATA(CMapSizeDlg)
|
||||
enum { IDD = IDD_DIALOG_MAPSIZE };
|
||||
// NOTE: the ClassWizard will add data members here
|
||||
//}}AFX_DATA
|
||||
|
||||
|
||||
// Overrides
|
||||
// ClassWizard generated virtual function overrides
|
||||
//{{AFX_VIRTUAL(CMapSizeDlg)
|
||||
protected:
|
||||
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
|
||||
//}}AFX_VIRTUAL
|
||||
|
||||
// Implementation
|
||||
protected:
|
||||
|
||||
// Generated message map functions
|
||||
//{{AFX_MSG(CMapSizeDlg)
|
||||
virtual BOOL OnInitDialog();
|
||||
afx_msg void OnRadioHuge();
|
||||
afx_msg void OnRadioLarge();
|
||||
afx_msg void OnRadioMedium();
|
||||
afx_msg void OnRadioSmall();
|
||||
//}}AFX_MSG
|
||||
DECLARE_MESSAGE_MAP()
|
||||
};
|
||||
|
||||
//{{AFX_INSERT_LOCATION}}
|
||||
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
|
||||
|
||||
#endif // !defined(AFX_MAPSIZEDLG_H__F43F9B80_73CB_4DEB_8630_F0690664D510__INCLUDED_)
|
||||
|
@ -1,259 +1,259 @@
|
||||
#include "MiniMap.h"
|
||||
#include "UIGlobals.h"
|
||||
#include "TextureManager.h"
|
||||
#include "Terrain.h"
|
||||
#include "Renderer.h"
|
||||
#include "ogl.h"
|
||||
|
||||
extern CTerrain g_Terrain;
|
||||
|
||||
static unsigned int ScaleColor(unsigned int color,float x)
|
||||
{
|
||||
unsigned int r=unsigned int(float(color & 0xff)*x);
|
||||
unsigned int g=unsigned int(float((color>>8) & 0xff)*x);
|
||||
unsigned int b=unsigned int(float((color>>16) & 0xff)*x);
|
||||
return (0xff000000 | r | g<<8 | b<<16);
|
||||
}
|
||||
|
||||
static int RoundUpToPowerOf2(int x)
|
||||
{
|
||||
if ((x & (x-1))==0) return x;
|
||||
int d=x;
|
||||
while (d & (d-1)) {
|
||||
d&=(d-1);
|
||||
}
|
||||
return d<<1;
|
||||
}
|
||||
|
||||
CMiniMap::CMiniMap() : m_Handle(0)
|
||||
{
|
||||
}
|
||||
|
||||
void CMiniMap::Initialise()
|
||||
{
|
||||
// get rid of existing texture, if we've got one
|
||||
if (m_Handle) {
|
||||
glDeleteTextures(1,&m_Handle);
|
||||
}
|
||||
|
||||
// allocate a handle, bind to it
|
||||
glGenTextures(1,&m_Handle);
|
||||
g_Renderer.BindTexture(0,m_Handle);
|
||||
|
||||
// allocate an image big enough to fit the entire map into
|
||||
m_Size=RoundUpToPowerOf2(g_Terrain.GetVerticesPerSide());
|
||||
glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA8,m_Size,m_Size,0,GL_BGRA_EXT,GL_UNSIGNED_BYTE,0);
|
||||
|
||||
// set texture parameters
|
||||
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP);
|
||||
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP);
|
||||
|
||||
// force a rebuild to get correct initial view
|
||||
Rebuild();
|
||||
}
|
||||
|
||||
void CMiniMap::Render()
|
||||
{
|
||||
// setup renderstate
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glDepthMask(0);
|
||||
|
||||
// load identity modelview
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
|
||||
// setup ortho view
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
int w=g_Renderer.GetWidth();
|
||||
int h=g_Renderer.GetHeight();
|
||||
glOrtho(0,w,0,h,-1,1);
|
||||
|
||||
// bind to the minimap
|
||||
g_Renderer.BindTexture(0,m_Handle);
|
||||
glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_REPLACE);
|
||||
|
||||
float tclimit=float(g_Terrain.GetVerticesPerSide()-1)/float(m_Size);
|
||||
|
||||
// render minimap as quad
|
||||
glBegin(GL_QUADS);
|
||||
|
||||
glTexCoord2f(0,tclimit);
|
||||
glVertex2i(w-200,200);
|
||||
|
||||
glTexCoord2f(0,0);
|
||||
glVertex2i(w-200,2);
|
||||
|
||||
glTexCoord2f(tclimit,0);
|
||||
glVertex2i(w-3,2);
|
||||
|
||||
glTexCoord2f(tclimit,tclimit);
|
||||
glVertex2i(w-3,200);
|
||||
|
||||
glEnd();
|
||||
|
||||
// switch off textures
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
|
||||
// render border
|
||||
glLineWidth(2);
|
||||
glColor3f(0.4f,0.35f,0.8f);
|
||||
glBegin(GL_LINE_LOOP);
|
||||
glVertex2i(w-202,202);
|
||||
glVertex2i(w-1,202);
|
||||
glVertex2i(w-1,1);
|
||||
glVertex2i(w-202,1);
|
||||
glEnd();
|
||||
|
||||
// render view rect
|
||||
glScissor(w-200,2,w,198);
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
glLineWidth(2);
|
||||
glColor3f(1.0f,0.3f,0.3f);
|
||||
glBegin(GL_LINE_LOOP);
|
||||
glVertex2f(w-200+m_ViewRect[0][0],m_ViewRect[0][1]);
|
||||
glVertex2f(w-200+m_ViewRect[1][0],m_ViewRect[1][1]);
|
||||
glVertex2f(w-200+m_ViewRect[2][0],m_ViewRect[2][1]);
|
||||
glVertex2f(w-200+m_ViewRect[3][0],m_ViewRect[3][1]);
|
||||
glEnd();
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
|
||||
// restore matrices
|
||||
glPopMatrix();
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPopMatrix();
|
||||
|
||||
// restore renderstate
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDepthMask(1);
|
||||
}
|
||||
|
||||
void CMiniMap::Update(int x,int y,unsigned int color)
|
||||
{
|
||||
// bind to the minimap
|
||||
g_Renderer.BindTexture(0,m_Handle);
|
||||
|
||||
// get height at this pixel
|
||||
int hmap=(int) g_Terrain.GetHeightMap()[y*g_Terrain.GetVerticesPerSide() + x]>>8;
|
||||
// shift from 0-255 to 170-255
|
||||
int val=(hmap/3)+170;
|
||||
|
||||
// get modulated color
|
||||
unsigned int mcolor=ScaleColor(color,float(val)/255.0f);
|
||||
|
||||
// subimage to update pixel (ugh)
|
||||
glTexSubImage2D(GL_TEXTURE_2D,0,x,y,1,1,GL_BGRA_EXT,GL_UNSIGNED_BYTE,&mcolor);
|
||||
}
|
||||
|
||||
void CMiniMap::Update(int x,int y,int w,int h,unsigned int color)
|
||||
{
|
||||
// bind to the minimap
|
||||
g_Renderer.BindTexture(0,m_Handle);
|
||||
|
||||
u32 mapSize=g_Terrain.GetVerticesPerSide();
|
||||
unsigned int* data=new unsigned int[w*h];
|
||||
unsigned int* dataptr=data;
|
||||
|
||||
for (int j=0;j<h;j++) {
|
||||
for (int i=0;i<w;i++) {
|
||||
// get height at this pixel
|
||||
int hmap=int(g_Terrain.GetHeightMap()[(y+j)*mapSize + x+i])>>8;
|
||||
// shift from 0-255 to 170-255
|
||||
int val=(hmap/3)+170;
|
||||
// load scaled color into data pointer
|
||||
*dataptr++=ScaleColor(color,float(val)/255.0f);
|
||||
}
|
||||
}
|
||||
|
||||
// subimage to update pixels
|
||||
glTexSubImage2D(GL_TEXTURE_2D,0,x,y,w,h,GL_BGRA_EXT,GL_UNSIGNED_BYTE,data);
|
||||
delete[] data;
|
||||
}
|
||||
|
||||
void CMiniMap::Rebuild()
|
||||
{
|
||||
// bind to the minimap
|
||||
g_Renderer.BindTexture(0,m_Handle);
|
||||
|
||||
u32 mapSize=g_Terrain.GetVerticesPerSide();
|
||||
unsigned int* data=new unsigned int[(mapSize-1)*(mapSize-1)];
|
||||
unsigned int* dataptr=data;
|
||||
|
||||
for (uint pj=0; pj<g_Terrain.GetPatchesPerSide(); pj++)
|
||||
{
|
||||
for (int tj=0; tj<16; tj++)
|
||||
{
|
||||
for (uint pi=0; pi<g_Terrain.GetPatchesPerSide(); pi++)
|
||||
{
|
||||
for (int ti=0; ti<16; ti++)
|
||||
{
|
||||
int i=pi*16+ti;
|
||||
int j=pj*16+tj;
|
||||
|
||||
// get base color from textures on tile
|
||||
unsigned int color;
|
||||
CMiniPatch* mp=g_Terrain.GetTile(i,j);
|
||||
if (mp) {
|
||||
CTextureEntry* tex=mp->Tex1 ? g_TexMan.FindTexture(mp->Tex1) : 0;
|
||||
color=tex ? tex->m_BaseColor : 0xffffffff;
|
||||
} else {
|
||||
color=0xffffffff;
|
||||
}
|
||||
|
||||
// get height at this pixel
|
||||
int hmap=int(g_Terrain.GetHeightMap()[j*mapSize + i])>>8;
|
||||
// shift from 0-255 to 170-255
|
||||
int val=(hmap/3)+170;
|
||||
// load scaled color into data pointer
|
||||
*dataptr++=ScaleColor(color,float(val)/255.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// subimage to update pixels
|
||||
glTexSubImage2D(GL_TEXTURE_2D,0,0,0,(mapSize-1),(mapSize-1),GL_BGRA_EXT,GL_UNSIGNED_BYTE,data);
|
||||
delete[] data;
|
||||
}
|
||||
|
||||
void CMiniMap::Rebuild(int x,int y,int w,int h)
|
||||
{
|
||||
// bind to the minimap
|
||||
g_Renderer.BindTexture(0,m_Handle);
|
||||
|
||||
u32 mapSize=g_Terrain.GetVerticesPerSide();
|
||||
unsigned int* data=new unsigned int[w*h];
|
||||
unsigned int* dataptr=data;
|
||||
|
||||
for (int j=0;j<h;j++) {
|
||||
for (int i=0;i<w;i++) {
|
||||
// get height at this pixel
|
||||
int hmap=int(g_Terrain.GetHeightMap()[(y+j)*mapSize + x+i])>>8;
|
||||
// shift from 0-255 to 170-255
|
||||
int val=(hmap/3)+170;
|
||||
|
||||
CMiniPatch* mp=g_Terrain.GetTile(x+i,y+j);
|
||||
|
||||
unsigned int color;
|
||||
if (mp) {
|
||||
// get texture on this time
|
||||
CTextureEntry* tex=mp->Tex1 ? g_TexMan.FindTexture(mp->Tex1) : 0;
|
||||
color=tex ? tex->m_BaseColor : 0xffffffff;
|
||||
} else {
|
||||
color=0xffffffff;
|
||||
}
|
||||
|
||||
// load scaled color into data pointer
|
||||
*dataptr++=ScaleColor(color,float(val)/255.0f);
|
||||
}
|
||||
}
|
||||
|
||||
// subimage to update pixels
|
||||
glTexSubImage2D(GL_TEXTURE_2D,0,x,y,w,h,GL_BGRA_EXT,GL_UNSIGNED_BYTE,data);
|
||||
delete[] data;
|
||||
}
|
||||
#include "MiniMap.h"
|
||||
#include "UIGlobals.h"
|
||||
#include "TextureManager.h"
|
||||
#include "Terrain.h"
|
||||
#include "Renderer.h"
|
||||
#include "ogl.h"
|
||||
|
||||
extern CTerrain g_Terrain;
|
||||
|
||||
static unsigned int ScaleColor(unsigned int color,float x)
|
||||
{
|
||||
unsigned int r=unsigned int(float(color & 0xff)*x);
|
||||
unsigned int g=unsigned int(float((color>>8) & 0xff)*x);
|
||||
unsigned int b=unsigned int(float((color>>16) & 0xff)*x);
|
||||
return (0xff000000 | r | g<<8 | b<<16);
|
||||
}
|
||||
|
||||
static int RoundUpToPowerOf2(int x)
|
||||
{
|
||||
if ((x & (x-1))==0) return x;
|
||||
int d=x;
|
||||
while (d & (d-1)) {
|
||||
d&=(d-1);
|
||||
}
|
||||
return d<<1;
|
||||
}
|
||||
|
||||
CMiniMap::CMiniMap() : m_Handle(0)
|
||||
{
|
||||
}
|
||||
|
||||
void CMiniMap::Initialise()
|
||||
{
|
||||
// get rid of existing texture, if we've got one
|
||||
if (m_Handle) {
|
||||
glDeleteTextures(1,&m_Handle);
|
||||
}
|
||||
|
||||
// allocate a handle, bind to it
|
||||
glGenTextures(1,&m_Handle);
|
||||
g_Renderer.BindTexture(0,m_Handle);
|
||||
|
||||
// allocate an image big enough to fit the entire map into
|
||||
m_Size=RoundUpToPowerOf2(g_Terrain.GetVerticesPerSide());
|
||||
glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA8,m_Size,m_Size,0,GL_BGRA_EXT,GL_UNSIGNED_BYTE,0);
|
||||
|
||||
// set texture parameters
|
||||
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP);
|
||||
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP);
|
||||
|
||||
// force a rebuild to get correct initial view
|
||||
Rebuild();
|
||||
}
|
||||
|
||||
void CMiniMap::Render()
|
||||
{
|
||||
// setup renderstate
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glDepthMask(0);
|
||||
|
||||
// load identity modelview
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
|
||||
// setup ortho view
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
int w=g_Renderer.GetWidth();
|
||||
int h=g_Renderer.GetHeight();
|
||||
glOrtho(0,w,0,h,-1,1);
|
||||
|
||||
// bind to the minimap
|
||||
g_Renderer.BindTexture(0,m_Handle);
|
||||
glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_REPLACE);
|
||||
|
||||
float tclimit=float(g_Terrain.GetVerticesPerSide()-1)/float(m_Size);
|
||||
|
||||
// render minimap as quad
|
||||
glBegin(GL_QUADS);
|
||||
|
||||
glTexCoord2f(0,tclimit);
|
||||
glVertex2i(w-200,200);
|
||||
|
||||
glTexCoord2f(0,0);
|
||||
glVertex2i(w-200,2);
|
||||
|
||||
glTexCoord2f(tclimit,0);
|
||||
glVertex2i(w-3,2);
|
||||
|
||||
glTexCoord2f(tclimit,tclimit);
|
||||
glVertex2i(w-3,200);
|
||||
|
||||
glEnd();
|
||||
|
||||
// switch off textures
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
|
||||
// render border
|
||||
glLineWidth(2);
|
||||
glColor3f(0.4f,0.35f,0.8f);
|
||||
glBegin(GL_LINE_LOOP);
|
||||
glVertex2i(w-202,202);
|
||||
glVertex2i(w-1,202);
|
||||
glVertex2i(w-1,1);
|
||||
glVertex2i(w-202,1);
|
||||
glEnd();
|
||||
|
||||
// render view rect
|
||||
glScissor(w-200,2,w,198);
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
glLineWidth(2);
|
||||
glColor3f(1.0f,0.3f,0.3f);
|
||||
glBegin(GL_LINE_LOOP);
|
||||
glVertex2f(w-200+m_ViewRect[0][0],m_ViewRect[0][1]);
|
||||
glVertex2f(w-200+m_ViewRect[1][0],m_ViewRect[1][1]);
|
||||
glVertex2f(w-200+m_ViewRect[2][0],m_ViewRect[2][1]);
|
||||
glVertex2f(w-200+m_ViewRect[3][0],m_ViewRect[3][1]);
|
||||
glEnd();
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
|
||||
// restore matrices
|
||||
glPopMatrix();
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPopMatrix();
|
||||
|
||||
// restore renderstate
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDepthMask(1);
|
||||
}
|
||||
|
||||
void CMiniMap::Update(int x,int y,unsigned int color)
|
||||
{
|
||||
// bind to the minimap
|
||||
g_Renderer.BindTexture(0,m_Handle);
|
||||
|
||||
// get height at this pixel
|
||||
int hmap=(int) g_Terrain.GetHeightMap()[y*g_Terrain.GetVerticesPerSide() + x]>>8;
|
||||
// shift from 0-255 to 170-255
|
||||
int val=(hmap/3)+170;
|
||||
|
||||
// get modulated color
|
||||
unsigned int mcolor=ScaleColor(color,float(val)/255.0f);
|
||||
|
||||
// subimage to update pixel (ugh)
|
||||
glTexSubImage2D(GL_TEXTURE_2D,0,x,y,1,1,GL_BGRA_EXT,GL_UNSIGNED_BYTE,&mcolor);
|
||||
}
|
||||
|
||||
void CMiniMap::Update(int x,int y,int w,int h,unsigned int color)
|
||||
{
|
||||
// bind to the minimap
|
||||
g_Renderer.BindTexture(0,m_Handle);
|
||||
|
||||
u32 mapSize=g_Terrain.GetVerticesPerSide();
|
||||
unsigned int* data=new unsigned int[w*h];
|
||||
unsigned int* dataptr=data;
|
||||
|
||||
for (int j=0;j<h;j++) {
|
||||
for (int i=0;i<w;i++) {
|
||||
// get height at this pixel
|
||||
int hmap=int(g_Terrain.GetHeightMap()[(y+j)*mapSize + x+i])>>8;
|
||||
// shift from 0-255 to 170-255
|
||||
int val=(hmap/3)+170;
|
||||
// load scaled color into data pointer
|
||||
*dataptr++=ScaleColor(color,float(val)/255.0f);
|
||||
}
|
||||
}
|
||||
|
||||
// subimage to update pixels
|
||||
glTexSubImage2D(GL_TEXTURE_2D,0,x,y,w,h,GL_BGRA_EXT,GL_UNSIGNED_BYTE,data);
|
||||
delete[] data;
|
||||
}
|
||||
|
||||
void CMiniMap::Rebuild()
|
||||
{
|
||||
// bind to the minimap
|
||||
g_Renderer.BindTexture(0,m_Handle);
|
||||
|
||||
u32 mapSize=g_Terrain.GetVerticesPerSide();
|
||||
unsigned int* data=new unsigned int[(mapSize-1)*(mapSize-1)];
|
||||
unsigned int* dataptr=data;
|
||||
|
||||
for (uint pj=0; pj<g_Terrain.GetPatchesPerSide(); pj++)
|
||||
{
|
||||
for (int tj=0; tj<16; tj++)
|
||||
{
|
||||
for (uint pi=0; pi<g_Terrain.GetPatchesPerSide(); pi++)
|
||||
{
|
||||
for (int ti=0; ti<16; ti++)
|
||||
{
|
||||
int i=pi*16+ti;
|
||||
int j=pj*16+tj;
|
||||
|
||||
// get base color from textures on tile
|
||||
unsigned int color;
|
||||
CMiniPatch* mp=g_Terrain.GetTile(i,j);
|
||||
if (mp) {
|
||||
CTextureEntry* tex=mp->Tex1 ? g_TexMan.FindTexture(mp->Tex1) : 0;
|
||||
color=tex ? tex->m_BaseColor : 0xffffffff;
|
||||
} else {
|
||||
color=0xffffffff;
|
||||
}
|
||||
|
||||
// get height at this pixel
|
||||
int hmap=int(g_Terrain.GetHeightMap()[j*mapSize + i])>>8;
|
||||
// shift from 0-255 to 170-255
|
||||
int val=(hmap/3)+170;
|
||||
// load scaled color into data pointer
|
||||
*dataptr++=ScaleColor(color,float(val)/255.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// subimage to update pixels
|
||||
glTexSubImage2D(GL_TEXTURE_2D,0,0,0,(mapSize-1),(mapSize-1),GL_BGRA_EXT,GL_UNSIGNED_BYTE,data);
|
||||
delete[] data;
|
||||
}
|
||||
|
||||
void CMiniMap::Rebuild(int x,int y,int w,int h)
|
||||
{
|
||||
// bind to the minimap
|
||||
g_Renderer.BindTexture(0,m_Handle);
|
||||
|
||||
u32 mapSize=g_Terrain.GetVerticesPerSide();
|
||||
unsigned int* data=new unsigned int[w*h];
|
||||
unsigned int* dataptr=data;
|
||||
|
||||
for (int j=0;j<h;j++) {
|
||||
for (int i=0;i<w;i++) {
|
||||
// get height at this pixel
|
||||
int hmap=int(g_Terrain.GetHeightMap()[(y+j)*mapSize + x+i])>>8;
|
||||
// shift from 0-255 to 170-255
|
||||
int val=(hmap/3)+170;
|
||||
|
||||
CMiniPatch* mp=g_Terrain.GetTile(x+i,y+j);
|
||||
|
||||
unsigned int color;
|
||||
if (mp) {
|
||||
// get texture on this time
|
||||
CTextureEntry* tex=mp->Tex1 ? g_TexMan.FindTexture(mp->Tex1) : 0;
|
||||
color=tex ? tex->m_BaseColor : 0xffffffff;
|
||||
} else {
|
||||
color=0xffffffff;
|
||||
}
|
||||
|
||||
// load scaled color into data pointer
|
||||
*dataptr++=ScaleColor(color,float(val)/255.0f);
|
||||
}
|
||||
}
|
||||
|
||||
// subimage to update pixels
|
||||
glTexSubImage2D(GL_TEXTURE_2D,0,x,y,w,h,GL_BGRA_EXT,GL_UNSIGNED_BYTE,data);
|
||||
delete[] data;
|
||||
}
|
||||
|
@ -1,28 +1,28 @@
|
||||
#ifndef _MINIMAP_H
|
||||
#define _MINIMAP_H
|
||||
|
||||
class CMiniMap
|
||||
{
|
||||
public:
|
||||
CMiniMap();
|
||||
|
||||
void Initialise();
|
||||
void Render();
|
||||
void Update(int x,int y,unsigned int color);
|
||||
void Update(int x,int y,int w,int h,unsigned int color);
|
||||
void Rebuild();
|
||||
void Rebuild(int x,int y,int w,int h);
|
||||
|
||||
// current viewing frustum, in minimap coordinate space
|
||||
float m_ViewRect[4][2];
|
||||
|
||||
private:
|
||||
// texture handle
|
||||
unsigned int m_Handle;
|
||||
// size of the map texture
|
||||
unsigned int m_Size;
|
||||
};
|
||||
|
||||
extern CMiniMap g_MiniMap;
|
||||
|
||||
#endif
|
||||
#ifndef _MINIMAP_H
|
||||
#define _MINIMAP_H
|
||||
|
||||
class CMiniMap
|
||||
{
|
||||
public:
|
||||
CMiniMap();
|
||||
|
||||
void Initialise();
|
||||
void Render();
|
||||
void Update(int x,int y,unsigned int color);
|
||||
void Update(int x,int y,int w,int h,unsigned int color);
|
||||
void Rebuild();
|
||||
void Rebuild(int x,int y,int w,int h);
|
||||
|
||||
// current viewing frustum, in minimap coordinate space
|
||||
float m_ViewRect[4][2];
|
||||
|
||||
private:
|
||||
// texture handle
|
||||
unsigned int m_Handle;
|
||||
// size of the map texture
|
||||
unsigned int m_Size;
|
||||
};
|
||||
|
||||
extern CMiniMap g_MiniMap;
|
||||
|
||||
#endif
|
||||
|
@ -1,68 +1,68 @@
|
||||
#include "stdafx.h"
|
||||
#include "NaviCam.h"
|
||||
#include "EditorData.h"
|
||||
#include <stdarg.h>
|
||||
|
||||
CNaviCam g_NaviCam;
|
||||
|
||||
static void DbgText(char* str, ...)
|
||||
{
|
||||
char buf[1024];
|
||||
|
||||
va_list args;
|
||||
va_start(args, str);
|
||||
vsprintf(buf, str, args);
|
||||
va_end(args);
|
||||
|
||||
OutputDebugString(buf);
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// CNaviCam constructor
|
||||
CNaviCam::CNaviCam() : m_CameraZoom(10)
|
||||
{
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// OnMouseWheelScroll: handler for wheel scroll event - dir is positive for
|
||||
// upward scroll (away from user), or negative for downward scroll (towards
|
||||
// user)
|
||||
void CNaviCam::OnMouseWheelScroll(u32 flags,int px,int py,float dir)
|
||||
{
|
||||
CVector3D forward=m_Camera.m_Orientation.GetIn();
|
||||
float factor=dir*dir;
|
||||
if (dir<0) factor=-factor;
|
||||
|
||||
// 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_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
|
||||
m_CameraZoom-=(factor)*0.1f;
|
||||
if (m_CameraZoom<0.01f) m_CameraZoom=0.01f;
|
||||
m_Camera.m_Orientation.Translate(forward*(factor*m_CameraZoom));
|
||||
}
|
||||
g_EditorData.OnCameraChanged();
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// OnMButtonDown: handler for middle button down event
|
||||
void CNaviCam::OnMButtonDown(u32 flags,int px,int py)
|
||||
{
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// OnMButtonUp: handler for middle button up event
|
||||
void CNaviCam::OnMButtonUp(u32 flags,int px,int py)
|
||||
{
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// OnMouseMove: handler for mouse move (only called when middle button down)
|
||||
void CNaviCam::OnMouseMove(u32 flags,int px,int py)
|
||||
{
|
||||
}
|
||||
#include "stdafx.h"
|
||||
#include "NaviCam.h"
|
||||
#include "EditorData.h"
|
||||
#include <stdarg.h>
|
||||
|
||||
CNaviCam g_NaviCam;
|
||||
|
||||
static void DbgText(char* str, ...)
|
||||
{
|
||||
char buf[1024];
|
||||
|
||||
va_list args;
|
||||
va_start(args, str);
|
||||
vsprintf(buf, str, args);
|
||||
va_end(args);
|
||||
|
||||
OutputDebugString(buf);
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// CNaviCam constructor
|
||||
CNaviCam::CNaviCam() : m_CameraZoom(10)
|
||||
{
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// OnMouseWheelScroll: handler for wheel scroll event - dir is positive for
|
||||
// upward scroll (away from user), or negative for downward scroll (towards
|
||||
// user)
|
||||
void CNaviCam::OnMouseWheelScroll(u32 flags,int px,int py,float dir)
|
||||
{
|
||||
CVector3D forward=m_Camera.m_Orientation.GetIn();
|
||||
float factor=dir*dir;
|
||||
if (dir<0) factor=-factor;
|
||||
|
||||
// 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_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
|
||||
m_CameraZoom-=(factor)*0.1f;
|
||||
if (m_CameraZoom<0.01f) m_CameraZoom=0.01f;
|
||||
m_Camera.m_Orientation.Translate(forward*(factor*m_CameraZoom));
|
||||
}
|
||||
g_EditorData.OnCameraChanged();
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// OnMButtonDown: handler for middle button down event
|
||||
void CNaviCam::OnMButtonDown(u32 flags,int px,int py)
|
||||
{
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// OnMButtonUp: handler for middle button up event
|
||||
void CNaviCam::OnMButtonUp(u32 flags,int px,int py)
|
||||
{
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// OnMouseMove: handler for mouse move (only called when middle button down)
|
||||
void CNaviCam::OnMouseMove(u32 flags,int px,int py)
|
||||
{
|
||||
}
|
||||
|
@ -1,46 +1,46 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
// navicam.h
|
||||
//
|
||||
// - header containing NaviCam class, used to produce MAX style navigation controls
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#ifndef _NAVICAM_H
|
||||
#define _NAVICAM_H
|
||||
|
||||
#include "res/res.h"
|
||||
#include "Camera.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
// CNaviCam: MAX style navigation controller
|
||||
class CNaviCam
|
||||
{
|
||||
public:
|
||||
// constructor
|
||||
CNaviCam();
|
||||
|
||||
// handler for wheel scroll event - dir is positive for
|
||||
// upward scroll (away from user), or negative for downward scroll (towards
|
||||
// user)
|
||||
void OnMouseWheelScroll(u32 flags,int px,int py,float dir);
|
||||
// handler for middle button down event
|
||||
void OnMButtonDown(u32 flags,int px,int py);
|
||||
// handler for middle button up event
|
||||
void OnMButtonUp(u32 flags,int px,int py);
|
||||
// handler for mouse move (only called when middle button down)
|
||||
void OnMouseMove(u32 flags,int px,int py);
|
||||
|
||||
// return the regular camera object
|
||||
CCamera& GetCamera() { return m_Camera; }
|
||||
|
||||
private:
|
||||
// the regular camera object that defines FOV, orientation, etc
|
||||
CCamera m_Camera;
|
||||
// current zoom of camera
|
||||
float m_CameraZoom;
|
||||
};
|
||||
|
||||
extern CNaviCam g_NaviCam;
|
||||
|
||||
|
||||
#endif
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
// navicam.h
|
||||
//
|
||||
// - header containing NaviCam class, used to produce MAX style navigation controls
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#ifndef _NAVICAM_H
|
||||
#define _NAVICAM_H
|
||||
|
||||
#include "res/res.h"
|
||||
#include "Camera.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
// CNaviCam: MAX style navigation controller
|
||||
class CNaviCam
|
||||
{
|
||||
public:
|
||||
// constructor
|
||||
CNaviCam();
|
||||
|
||||
// handler for wheel scroll event - dir is positive for
|
||||
// upward scroll (away from user), or negative for downward scroll (towards
|
||||
// user)
|
||||
void OnMouseWheelScroll(u32 flags,int px,int py,float dir);
|
||||
// handler for middle button down event
|
||||
void OnMButtonDown(u32 flags,int px,int py);
|
||||
// handler for middle button up event
|
||||
void OnMButtonUp(u32 flags,int px,int py);
|
||||
// handler for mouse move (only called when middle button down)
|
||||
void OnMouseMove(u32 flags,int px,int py);
|
||||
|
||||
// return the regular camera object
|
||||
CCamera& GetCamera() { return m_Camera; }
|
||||
|
||||
private:
|
||||
// the regular camera object that defines FOV, orientation, etc
|
||||
CCamera m_Camera;
|
||||
// current zoom of camera
|
||||
float m_CameraZoom;
|
||||
};
|
||||
|
||||
extern CNaviCam g_NaviCam;
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -1,46 +1,46 @@
|
||||
// NavigatePropPage.cpp : implementation file
|
||||
//
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "ScEd.h"
|
||||
#include "NavigatePropPage.h"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define new DEBUG_NEW
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CNavigatePropPage property page
|
||||
|
||||
IMPLEMENT_DYNCREATE(CNavigatePropPage, CPropertyPage)
|
||||
|
||||
CNavigatePropPage::CNavigatePropPage() : CPropertyPage(CNavigatePropPage::IDD)
|
||||
{
|
||||
//{{AFX_DATA_INIT(CNavigatePropPage)
|
||||
// NOTE: the ClassWizard will add member initialization here
|
||||
//}}AFX_DATA_INIT
|
||||
}
|
||||
|
||||
CNavigatePropPage::~CNavigatePropPage()
|
||||
{
|
||||
}
|
||||
|
||||
void CNavigatePropPage::DoDataExchange(CDataExchange* pDX)
|
||||
{
|
||||
CPropertyPage::DoDataExchange(pDX);
|
||||
//{{AFX_DATA_MAP(CNavigatePropPage)
|
||||
// NOTE: the ClassWizard will add DDX and DDV calls here
|
||||
//}}AFX_DATA_MAP
|
||||
}
|
||||
|
||||
|
||||
BEGIN_MESSAGE_MAP(CNavigatePropPage, CPropertyPage)
|
||||
//{{AFX_MSG_MAP(CNavigatePropPage)
|
||||
// NOTE: the ClassWizard will add message map macros here
|
||||
//}}AFX_MSG_MAP
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CNavigatePropPage message handlers
|
||||
// NavigatePropPage.cpp : implementation file
|
||||
//
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "ScEd.h"
|
||||
#include "NavigatePropPage.h"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define new DEBUG_NEW
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CNavigatePropPage property page
|
||||
|
||||
IMPLEMENT_DYNCREATE(CNavigatePropPage, CPropertyPage)
|
||||
|
||||
CNavigatePropPage::CNavigatePropPage() : CPropertyPage(CNavigatePropPage::IDD)
|
||||
{
|
||||
//{{AFX_DATA_INIT(CNavigatePropPage)
|
||||
// NOTE: the ClassWizard will add member initialization here
|
||||
//}}AFX_DATA_INIT
|
||||
}
|
||||
|
||||
CNavigatePropPage::~CNavigatePropPage()
|
||||
{
|
||||
}
|
||||
|
||||
void CNavigatePropPage::DoDataExchange(CDataExchange* pDX)
|
||||
{
|
||||
CPropertyPage::DoDataExchange(pDX);
|
||||
//{{AFX_DATA_MAP(CNavigatePropPage)
|
||||
// NOTE: the ClassWizard will add DDX and DDV calls here
|
||||
//}}AFX_DATA_MAP
|
||||
}
|
||||
|
||||
|
||||
BEGIN_MESSAGE_MAP(CNavigatePropPage, CPropertyPage)
|
||||
//{{AFX_MSG_MAP(CNavigatePropPage)
|
||||
// NOTE: the ClassWizard will add message map macros here
|
||||
//}}AFX_MSG_MAP
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CNavigatePropPage message handlers
|
||||
|
@ -1,51 +1,51 @@
|
||||
#if !defined(AFX_NAVIGATEPROPPAGE_H__BD8DC549_74F0_425E_9970_77BAE8F735E5__INCLUDED_)
|
||||
#define AFX_NAVIGATEPROPPAGE_H__BD8DC549_74F0_425E_9970_77BAE8F735E5__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
// NavigatePropPage.h : header file
|
||||
//
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CNavigatePropPage dialog
|
||||
|
||||
class CNavigatePropPage : public CPropertyPage
|
||||
{
|
||||
DECLARE_DYNCREATE(CNavigatePropPage)
|
||||
|
||||
// Construction
|
||||
public:
|
||||
CNavigatePropPage();
|
||||
~CNavigatePropPage();
|
||||
|
||||
// Dialog Data
|
||||
//{{AFX_DATA(CNavigatePropPage)
|
||||
enum { IDD = IDD_PROPPAGE_NAVIGATION };
|
||||
int m_ScrollSpeed;
|
||||
// NOTE - ClassWizard will add data members here.
|
||||
// DO NOT EDIT what you see in these blocks of generated code !
|
||||
//}}AFX_DATA
|
||||
|
||||
|
||||
// Overrides
|
||||
// ClassWizard generate virtual function overrides
|
||||
//{{AFX_VIRTUAL(CNavigatePropPage)
|
||||
protected:
|
||||
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
|
||||
//}}AFX_VIRTUAL
|
||||
|
||||
// Implementation
|
||||
protected:
|
||||
// Generated message map functions
|
||||
//{{AFX_MSG(CNavigatePropPage)
|
||||
// NOTE: the ClassWizard will add member functions here
|
||||
//}}AFX_MSG
|
||||
DECLARE_MESSAGE_MAP()
|
||||
|
||||
};
|
||||
|
||||
//{{AFX_INSERT_LOCATION}}
|
||||
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
|
||||
|
||||
#endif // !defined(AFX_NAVIGATEPROPPAGE_H__BD8DC549_74F0_425E_9970_77BAE8F735E5__INCLUDED_)
|
||||
#if !defined(AFX_NAVIGATEPROPPAGE_H__BD8DC549_74F0_425E_9970_77BAE8F735E5__INCLUDED_)
|
||||
#define AFX_NAVIGATEPROPPAGE_H__BD8DC549_74F0_425E_9970_77BAE8F735E5__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
// NavigatePropPage.h : header file
|
||||
//
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CNavigatePropPage dialog
|
||||
|
||||
class CNavigatePropPage : public CPropertyPage
|
||||
{
|
||||
DECLARE_DYNCREATE(CNavigatePropPage)
|
||||
|
||||
// Construction
|
||||
public:
|
||||
CNavigatePropPage();
|
||||
~CNavigatePropPage();
|
||||
|
||||
// Dialog Data
|
||||
//{{AFX_DATA(CNavigatePropPage)
|
||||
enum { IDD = IDD_PROPPAGE_NAVIGATION };
|
||||
int m_ScrollSpeed;
|
||||
// NOTE - ClassWizard will add data members here.
|
||||
// DO NOT EDIT what you see in these blocks of generated code !
|
||||
//}}AFX_DATA
|
||||
|
||||
|
||||
// Overrides
|
||||
// ClassWizard generate virtual function overrides
|
||||
//{{AFX_VIRTUAL(CNavigatePropPage)
|
||||
protected:
|
||||
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
|
||||
//}}AFX_VIRTUAL
|
||||
|
||||
// Implementation
|
||||
protected:
|
||||
// Generated message map functions
|
||||
//{{AFX_MSG(CNavigatePropPage)
|
||||
// NOTE: the ClassWizard will add member functions here
|
||||
//}}AFX_MSG
|
||||
DECLARE_MESSAGE_MAP()
|
||||
|
||||
};
|
||||
|
||||
//{{AFX_INSERT_LOCATION}}
|
||||
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
|
||||
|
||||
#endif // !defined(AFX_NAVIGATEPROPPAGE_H__BD8DC549_74F0_425E_9970_77BAE8F735E5__INCLUDED_)
|
||||
|
@ -1,50 +1,50 @@
|
||||
// OptionsDlg.cpp : implementation file
|
||||
//
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "ScEd.h"
|
||||
#include "OptionsDlg.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// COptionsDlg dialog
|
||||
|
||||
|
||||
COptionsDlg::COptionsDlg(CWnd* pParent /*=NULL*/)
|
||||
: CDialog(COptionsDlg::IDD, pParent)
|
||||
{
|
||||
//{{AFX_DATA_INIT(COptionsDlg)
|
||||
m_ScrollSpeed = 0;
|
||||
//}}AFX_DATA_INIT
|
||||
}
|
||||
|
||||
|
||||
void COptionsDlg::DoDataExchange(CDataExchange* pDX)
|
||||
{
|
||||
CDialog::DoDataExchange(pDX);
|
||||
//{{AFX_DATA_MAP(COptionsDlg)
|
||||
DDX_Slider(pDX, IDC_SLIDER_RTSSCROLLSPEED, m_ScrollSpeed);
|
||||
//}}AFX_DATA_MAP
|
||||
}
|
||||
|
||||
|
||||
BEGIN_MESSAGE_MAP(COptionsDlg, CDialog)
|
||||
//{{AFX_MSG_MAP(COptionsDlg)
|
||||
//}}AFX_MSG_MAP
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// COptionsDlg message handlers
|
||||
|
||||
BOOL COptionsDlg::OnInitDialog()
|
||||
{
|
||||
CDialog::OnInitDialog();
|
||||
|
||||
// set up scroll speed slider
|
||||
CSliderCtrl* sliderctrl=(CSliderCtrl*) GetDlgItem(IDC_SLIDER_RTSSCROLLSPEED);
|
||||
sliderctrl->SetRange(0,10,TRUE);
|
||||
sliderctrl->SetPos(m_ScrollSpeed);
|
||||
|
||||
|
||||
return TRUE; // return TRUE unless you set the focus to a control
|
||||
// EXCEPTION: OCX Property Pages should return FALSE
|
||||
}
|
||||
// OptionsDlg.cpp : implementation file
|
||||
//
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "ScEd.h"
|
||||
#include "OptionsDlg.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// COptionsDlg dialog
|
||||
|
||||
|
||||
COptionsDlg::COptionsDlg(CWnd* pParent /*=NULL*/)
|
||||
: CDialog(COptionsDlg::IDD, pParent)
|
||||
{
|
||||
//{{AFX_DATA_INIT(COptionsDlg)
|
||||
m_ScrollSpeed = 0;
|
||||
//}}AFX_DATA_INIT
|
||||
}
|
||||
|
||||
|
||||
void COptionsDlg::DoDataExchange(CDataExchange* pDX)
|
||||
{
|
||||
CDialog::DoDataExchange(pDX);
|
||||
//{{AFX_DATA_MAP(COptionsDlg)
|
||||
DDX_Slider(pDX, IDC_SLIDER_RTSSCROLLSPEED, m_ScrollSpeed);
|
||||
//}}AFX_DATA_MAP
|
||||
}
|
||||
|
||||
|
||||
BEGIN_MESSAGE_MAP(COptionsDlg, CDialog)
|
||||
//{{AFX_MSG_MAP(COptionsDlg)
|
||||
//}}AFX_MSG_MAP
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// COptionsDlg message handlers
|
||||
|
||||
BOOL COptionsDlg::OnInitDialog()
|
||||
{
|
||||
CDialog::OnInitDialog();
|
||||
|
||||
// set up scroll speed slider
|
||||
CSliderCtrl* sliderctrl=(CSliderCtrl*) GetDlgItem(IDC_SLIDER_RTSSCROLLSPEED);
|
||||
sliderctrl->SetRange(0,10,TRUE);
|
||||
sliderctrl->SetPos(m_ScrollSpeed);
|
||||
|
||||
|
||||
return TRUE; // return TRUE unless you set the focus to a control
|
||||
// EXCEPTION: OCX Property Pages should return FALSE
|
||||
}
|
||||
|
@ -1,46 +1,46 @@
|
||||
#if !defined(AFX_OPTIONSDLG_H__D9A7A4A5_A6D1_4793_98E8_5558D40B905A__INCLUDED_)
|
||||
#define AFX_OPTIONSDLG_H__D9A7A4A5_A6D1_4793_98E8_5558D40B905A__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
// OptionsDlg.h : header file
|
||||
//
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// COptionsDlg dialog
|
||||
|
||||
class COptionsDlg : public CDialog
|
||||
{
|
||||
// Construction
|
||||
public:
|
||||
COptionsDlg(CWnd* pParent = NULL); // standard constructor
|
||||
|
||||
// Dialog Data
|
||||
//{{AFX_DATA(COptionsDlg)
|
||||
enum { IDD = IDD_DIALOG_OPTIONS };
|
||||
int m_ScrollSpeed;
|
||||
//}}AFX_DATA
|
||||
|
||||
|
||||
// Overrides
|
||||
// ClassWizard generated virtual function overrides
|
||||
//{{AFX_VIRTUAL(COptionsDlg)
|
||||
protected:
|
||||
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
|
||||
//}}AFX_VIRTUAL
|
||||
|
||||
// Implementation
|
||||
protected:
|
||||
|
||||
// Generated message map functions
|
||||
//{{AFX_MSG(COptionsDlg)
|
||||
virtual BOOL OnInitDialog();
|
||||
//}}AFX_MSG
|
||||
DECLARE_MESSAGE_MAP()
|
||||
};
|
||||
|
||||
//{{AFX_INSERT_LOCATION}}
|
||||
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
|
||||
|
||||
#endif // !defined(AFX_OPTIONSDLG_H__D9A7A4A5_A6D1_4793_98E8_5558D40B905A__INCLUDED_)
|
||||
#if !defined(AFX_OPTIONSDLG_H__D9A7A4A5_A6D1_4793_98E8_5558D40B905A__INCLUDED_)
|
||||
#define AFX_OPTIONSDLG_H__D9A7A4A5_A6D1_4793_98E8_5558D40B905A__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
// OptionsDlg.h : header file
|
||||
//
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// COptionsDlg dialog
|
||||
|
||||
class COptionsDlg : public CDialog
|
||||
{
|
||||
// Construction
|
||||
public:
|
||||
COptionsDlg(CWnd* pParent = NULL); // standard constructor
|
||||
|
||||
// Dialog Data
|
||||
//{{AFX_DATA(COptionsDlg)
|
||||
enum { IDD = IDD_DIALOG_OPTIONS };
|
||||
int m_ScrollSpeed;
|
||||
//}}AFX_DATA
|
||||
|
||||
|
||||
// Overrides
|
||||
// ClassWizard generated virtual function overrides
|
||||
//{{AFX_VIRTUAL(COptionsDlg)
|
||||
protected:
|
||||
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
|
||||
//}}AFX_VIRTUAL
|
||||
|
||||
// Implementation
|
||||
protected:
|
||||
|
||||
// Generated message map functions
|
||||
//{{AFX_MSG(COptionsDlg)
|
||||
virtual BOOL OnInitDialog();
|
||||
//}}AFX_MSG
|
||||
DECLARE_MESSAGE_MAP()
|
||||
};
|
||||
|
||||
//{{AFX_INSERT_LOCATION}}
|
||||
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
|
||||
|
||||
#endif // !defined(AFX_OPTIONSDLG_H__D9A7A4A5_A6D1_4793_98E8_5558D40B905A__INCLUDED_)
|
||||
|
@ -1,67 +1,67 @@
|
||||
// OptionsPropSheet.cpp : implementation file
|
||||
//
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "ScEd.h"
|
||||
#include "OptionsPropSheet.h"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define new DEBUG_NEW
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// COptionsPropSheet
|
||||
|
||||
IMPLEMENT_DYNAMIC(COptionsPropSheet, CPropertySheet)
|
||||
|
||||
COptionsPropSheet::COptionsPropSheet(UINT nIDCaption, CWnd* pParentWnd, UINT iSelectPage)
|
||||
:CPropertySheet(nIDCaption, pParentWnd, iSelectPage)
|
||||
{
|
||||
AddPage(&m_NavigatePage);
|
||||
AddPage(&m_ShadowsPage);
|
||||
}
|
||||
|
||||
COptionsPropSheet::COptionsPropSheet(LPCTSTR pszCaption, CWnd* pParentWnd, UINT iSelectPage)
|
||||
:CPropertySheet(pszCaption, pParentWnd, iSelectPage)
|
||||
{
|
||||
AddPage(&m_NavigatePage);
|
||||
AddPage(&m_ShadowsPage);
|
||||
}
|
||||
|
||||
COptionsPropSheet::~COptionsPropSheet()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
BEGIN_MESSAGE_MAP(COptionsPropSheet, CPropertySheet)
|
||||
//{{AFX_MSG_MAP(COptionsPropSheet)
|
||||
// NOTE - the ClassWizard will add and remove mapping macros here.
|
||||
//}}AFX_MSG_MAP
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// COptionsPropSheet message handlers
|
||||
|
||||
BOOL COptionsPropSheet::OnInitDialog()
|
||||
{
|
||||
BOOL bResult = CPropertySheet::OnInitDialog();
|
||||
|
||||
// NAVIGATION CONTROLS:
|
||||
// setup scroll speed slider
|
||||
CSliderCtrl* sliderctrl=(CSliderCtrl*) m_NavigatePage.GetDlgItem(IDC_SLIDER_RTSSCROLLSPEED);
|
||||
sliderctrl->SetRange(0,10,TRUE);
|
||||
sliderctrl->SetPos(m_NavigatePage.m_ScrollSpeed);
|
||||
|
||||
// SHADOW CONTROLS:
|
||||
// setup checkbox
|
||||
// CSliderCtrl* sliderctrl=(CSliderCtrl*) m_NavigatePage.GetDlgItem(IDC_SLIDER_RTSSCROLLSPEED);
|
||||
// sliderctrl->SetRange(0,10,TRUE);
|
||||
// sliderctrl->SetPos(m_NavigatePage.m_ScrollSpeed);
|
||||
|
||||
// setup shadow colour
|
||||
|
||||
// setup quality slider
|
||||
return bResult;
|
||||
}
|
||||
// OptionsPropSheet.cpp : implementation file
|
||||
//
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "ScEd.h"
|
||||
#include "OptionsPropSheet.h"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define new DEBUG_NEW
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// COptionsPropSheet
|
||||
|
||||
IMPLEMENT_DYNAMIC(COptionsPropSheet, CPropertySheet)
|
||||
|
||||
COptionsPropSheet::COptionsPropSheet(UINT nIDCaption, CWnd* pParentWnd, UINT iSelectPage)
|
||||
:CPropertySheet(nIDCaption, pParentWnd, iSelectPage)
|
||||
{
|
||||
AddPage(&m_NavigatePage);
|
||||
AddPage(&m_ShadowsPage);
|
||||
}
|
||||
|
||||
COptionsPropSheet::COptionsPropSheet(LPCTSTR pszCaption, CWnd* pParentWnd, UINT iSelectPage)
|
||||
:CPropertySheet(pszCaption, pParentWnd, iSelectPage)
|
||||
{
|
||||
AddPage(&m_NavigatePage);
|
||||
AddPage(&m_ShadowsPage);
|
||||
}
|
||||
|
||||
COptionsPropSheet::~COptionsPropSheet()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
BEGIN_MESSAGE_MAP(COptionsPropSheet, CPropertySheet)
|
||||
//{{AFX_MSG_MAP(COptionsPropSheet)
|
||||
// NOTE - the ClassWizard will add and remove mapping macros here.
|
||||
//}}AFX_MSG_MAP
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// COptionsPropSheet message handlers
|
||||
|
||||
BOOL COptionsPropSheet::OnInitDialog()
|
||||
{
|
||||
BOOL bResult = CPropertySheet::OnInitDialog();
|
||||
|
||||
// NAVIGATION CONTROLS:
|
||||
// setup scroll speed slider
|
||||
CSliderCtrl* sliderctrl=(CSliderCtrl*) m_NavigatePage.GetDlgItem(IDC_SLIDER_RTSSCROLLSPEED);
|
||||
sliderctrl->SetRange(0,10,TRUE);
|
||||
sliderctrl->SetPos(m_NavigatePage.m_ScrollSpeed);
|
||||
|
||||
// SHADOW CONTROLS:
|
||||
// setup checkbox
|
||||
// CSliderCtrl* sliderctrl=(CSliderCtrl*) m_NavigatePage.GetDlgItem(IDC_SLIDER_RTSSCROLLSPEED);
|
||||
// sliderctrl->SetRange(0,10,TRUE);
|
||||
// sliderctrl->SetPos(m_NavigatePage.m_ScrollSpeed);
|
||||
|
||||
// setup shadow colour
|
||||
|
||||
// setup quality slider
|
||||
return bResult;
|
||||
}
|
||||
|
@ -1,57 +1,57 @@
|
||||
#if !defined(AFX_OPTIONSPROPSHEET_H__11CE8789_3E13_4D06_966E_6A6DA9C36E13__INCLUDED_)
|
||||
#define AFX_OPTIONSPROPSHEET_H__11CE8789_3E13_4D06_966E_6A6DA9C36E13__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
// OptionsPropSheet.h : header file
|
||||
//
|
||||
|
||||
#include "NavigatePropPage.h"
|
||||
#include "ShadowsPropPage.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// COptionsPropSheet
|
||||
|
||||
class COptionsPropSheet : public CPropertySheet
|
||||
{
|
||||
DECLARE_DYNAMIC(COptionsPropSheet)
|
||||
|
||||
// Construction
|
||||
public:
|
||||
COptionsPropSheet(UINT nIDCaption, CWnd* pParentWnd = NULL, UINT iSelectPage = 0);
|
||||
COptionsPropSheet(LPCTSTR pszCaption, CWnd* pParentWnd = NULL, UINT iSelectPage = 0);
|
||||
|
||||
// Attributes
|
||||
public:
|
||||
CNavigatePropPage m_NavigatePage;
|
||||
CShadowsPropPage m_ShadowsPage;
|
||||
|
||||
// Operations
|
||||
public:
|
||||
|
||||
// Overrides
|
||||
// ClassWizard generated virtual function overrides
|
||||
//{{AFX_VIRTUAL(COptionsPropSheet)
|
||||
public:
|
||||
virtual BOOL OnInitDialog();
|
||||
//}}AFX_VIRTUAL
|
||||
|
||||
// Implementation
|
||||
public:
|
||||
virtual ~COptionsPropSheet();
|
||||
|
||||
// Generated message map functions
|
||||
protected:
|
||||
//{{AFX_MSG(COptionsPropSheet)
|
||||
// NOTE - the ClassWizard will add and remove member functions here.
|
||||
//}}AFX_MSG
|
||||
DECLARE_MESSAGE_MAP()
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//{{AFX_INSERT_LOCATION}}
|
||||
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
|
||||
|
||||
#endif // !defined(AFX_OPTIONSPROPSHEET_H__11CE8789_3E13_4D06_966E_6A6DA9C36E13__INCLUDED_)
|
||||
#if !defined(AFX_OPTIONSPROPSHEET_H__11CE8789_3E13_4D06_966E_6A6DA9C36E13__INCLUDED_)
|
||||
#define AFX_OPTIONSPROPSHEET_H__11CE8789_3E13_4D06_966E_6A6DA9C36E13__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
// OptionsPropSheet.h : header file
|
||||
//
|
||||
|
||||
#include "NavigatePropPage.h"
|
||||
#include "ShadowsPropPage.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// COptionsPropSheet
|
||||
|
||||
class COptionsPropSheet : public CPropertySheet
|
||||
{
|
||||
DECLARE_DYNAMIC(COptionsPropSheet)
|
||||
|
||||
// Construction
|
||||
public:
|
||||
COptionsPropSheet(UINT nIDCaption, CWnd* pParentWnd = NULL, UINT iSelectPage = 0);
|
||||
COptionsPropSheet(LPCTSTR pszCaption, CWnd* pParentWnd = NULL, UINT iSelectPage = 0);
|
||||
|
||||
// Attributes
|
||||
public:
|
||||
CNavigatePropPage m_NavigatePage;
|
||||
CShadowsPropPage m_ShadowsPage;
|
||||
|
||||
// Operations
|
||||
public:
|
||||
|
||||
// Overrides
|
||||
// ClassWizard generated virtual function overrides
|
||||
//{{AFX_VIRTUAL(COptionsPropSheet)
|
||||
public:
|
||||
virtual BOOL OnInitDialog();
|
||||
//}}AFX_VIRTUAL
|
||||
|
||||
// Implementation
|
||||
public:
|
||||
virtual ~COptionsPropSheet();
|
||||
|
||||
// Generated message map functions
|
||||
protected:
|
||||
//{{AFX_MSG(COptionsPropSheet)
|
||||
// NOTE - the ClassWizard will add and remove member functions here.
|
||||
//}}AFX_MSG
|
||||
DECLARE_MESSAGE_MAP()
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//{{AFX_INSERT_LOCATION}}
|
||||
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
|
||||
|
||||
#endif // !defined(AFX_OPTIONSPROPSHEET_H__11CE8789_3E13_4D06_966E_6A6DA9C36E13__INCLUDED_)
|
||||
|
@ -1,56 +1,56 @@
|
||||
#include "PaintObjectCommand.h"
|
||||
#include "UnitManager.h"
|
||||
#include "ObjectEntry.h"
|
||||
#include "Model.h"
|
||||
|
||||
#include "BaseEntity.h"
|
||||
#include "BaseEntityCollection.h"
|
||||
#include "EntityManager.h"
|
||||
|
||||
CPaintObjectCommand::CPaintObjectCommand(CObjectEntry* object,const CMatrix3D& transform)
|
||||
: m_Object(object), m_Transform(transform), m_Unit(0)
|
||||
{
|
||||
}
|
||||
|
||||
CPaintObjectCommand::~CPaintObjectCommand()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void CPaintObjectCommand::Execute()
|
||||
{
|
||||
// create new unit
|
||||
m_Unit=new CUnit(m_Object,m_Object->m_Model->Clone());
|
||||
m_Unit->GetModel()->SetTransform(m_Transform);
|
||||
|
||||
// add this unit to list of units stored in unit manager
|
||||
g_UnitMan.AddUnit(m_Unit);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Finalize: notification that command has finished (ie object stopped rotating) - convert
|
||||
// unit to entity if there's a template for it
|
||||
void CPaintObjectCommand::Finalize()
|
||||
{
|
||||
CBaseEntity* templateObject = g_EntityTemplateCollection.getTemplateByActor(m_Object);
|
||||
if( templateObject )
|
||||
{
|
||||
CVector3D orient = m_Unit->GetModel()->GetTransform().GetIn();
|
||||
CVector3D position = m_Unit->GetModel()->GetTransform().GetTranslation();
|
||||
g_UnitMan.RemoveUnit(m_Unit);
|
||||
g_EntityManager.create( templateObject, position, atan2( orient.X, orient.Z ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CPaintObjectCommand::Undo()
|
||||
{
|
||||
// remove model from unit managers list
|
||||
g_UnitMan.RemoveUnit(m_Unit);
|
||||
}
|
||||
|
||||
void CPaintObjectCommand::Redo()
|
||||
{
|
||||
// add the unit back to the unit manager
|
||||
g_UnitMan.AddUnit(m_Unit);
|
||||
}
|
||||
#include "PaintObjectCommand.h"
|
||||
#include "UnitManager.h"
|
||||
#include "ObjectEntry.h"
|
||||
#include "Model.h"
|
||||
|
||||
#include "BaseEntity.h"
|
||||
#include "BaseEntityCollection.h"
|
||||
#include "EntityManager.h"
|
||||
|
||||
CPaintObjectCommand::CPaintObjectCommand(CObjectEntry* object,const CMatrix3D& transform)
|
||||
: m_Object(object), m_Transform(transform), m_Unit(0)
|
||||
{
|
||||
}
|
||||
|
||||
CPaintObjectCommand::~CPaintObjectCommand()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void CPaintObjectCommand::Execute()
|
||||
{
|
||||
// create new unit
|
||||
m_Unit=new CUnit(m_Object,m_Object->m_Model->Clone());
|
||||
m_Unit->GetModel()->SetTransform(m_Transform);
|
||||
|
||||
// add this unit to list of units stored in unit manager
|
||||
g_UnitMan.AddUnit(m_Unit);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Finalize: notification that command has finished (ie object stopped rotating) - convert
|
||||
// unit to entity if there's a template for it
|
||||
void CPaintObjectCommand::Finalize()
|
||||
{
|
||||
CBaseEntity* templateObject = g_EntityTemplateCollection.getTemplateByActor(m_Object);
|
||||
if( templateObject )
|
||||
{
|
||||
CVector3D orient = m_Unit->GetModel()->GetTransform().GetIn();
|
||||
CVector3D position = m_Unit->GetModel()->GetTransform().GetTranslation();
|
||||
g_UnitMan.RemoveUnit(m_Unit);
|
||||
g_EntityManager.create( templateObject, position, atan2( orient.X, orient.Z ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CPaintObjectCommand::Undo()
|
||||
{
|
||||
// remove model from unit managers list
|
||||
g_UnitMan.RemoveUnit(m_Unit);
|
||||
}
|
||||
|
||||
void CPaintObjectCommand::Redo()
|
||||
{
|
||||
// add the unit back to the unit manager
|
||||
g_UnitMan.AddUnit(m_Unit);
|
||||
}
|
||||
|
@ -1,46 +1,46 @@
|
||||
#ifndef _PAINTOBJECTCOMMAND_H
|
||||
#define _PAINTOBJECTCOMMAND_H
|
||||
|
||||
#include "Command.h"
|
||||
#include "Matrix3D.h"
|
||||
|
||||
class CUnit;
|
||||
class CObjectEntry;
|
||||
|
||||
class CPaintObjectCommand : public CCommand
|
||||
{
|
||||
public:
|
||||
// constructor, destructor
|
||||
CPaintObjectCommand(CObjectEntry* object,const CMatrix3D& transform);
|
||||
~CPaintObjectCommand();
|
||||
|
||||
// return the texture name of this command
|
||||
const char* GetName() const { return "Add Unit"; }
|
||||
|
||||
// execute this command
|
||||
void Execute();
|
||||
|
||||
// can undo command?
|
||||
bool IsUndoable() const { return false; }
|
||||
// undo
|
||||
void Undo();
|
||||
// redo
|
||||
void Redo();
|
||||
|
||||
// notification that command has finished (ie object stopped rotating) - convert
|
||||
// unit to entity if there's a template for it
|
||||
void Finalize();
|
||||
|
||||
// return unit added to world
|
||||
CUnit* GetUnit() { return m_Unit; }
|
||||
|
||||
private:
|
||||
// unit to add to world
|
||||
CUnit* m_Unit;
|
||||
// object to paint
|
||||
CObjectEntry* m_Object;
|
||||
// model transformation
|
||||
CMatrix3D m_Transform;
|
||||
};
|
||||
|
||||
#endif
|
||||
#ifndef _PAINTOBJECTCOMMAND_H
|
||||
#define _PAINTOBJECTCOMMAND_H
|
||||
|
||||
#include "Command.h"
|
||||
#include "Matrix3D.h"
|
||||
|
||||
class CUnit;
|
||||
class CObjectEntry;
|
||||
|
||||
class CPaintObjectCommand : public CCommand
|
||||
{
|
||||
public:
|
||||
// constructor, destructor
|
||||
CPaintObjectCommand(CObjectEntry* object,const CMatrix3D& transform);
|
||||
~CPaintObjectCommand();
|
||||
|
||||
// return the texture name of this command
|
||||
const char* GetName() const { return "Add Unit"; }
|
||||
|
||||
// execute this command
|
||||
void Execute();
|
||||
|
||||
// can undo command?
|
||||
bool IsUndoable() const { return false; }
|
||||
// undo
|
||||
void Undo();
|
||||
// redo
|
||||
void Redo();
|
||||
|
||||
// notification that command has finished (ie object stopped rotating) - convert
|
||||
// unit to entity if there's a template for it
|
||||
void Finalize();
|
||||
|
||||
// return unit added to world
|
||||
CUnit* GetUnit() { return m_Unit; }
|
||||
|
||||
private:
|
||||
// unit to add to world
|
||||
CUnit* m_Unit;
|
||||
// object to paint
|
||||
CObjectEntry* m_Object;
|
||||
// model transformation
|
||||
CMatrix3D m_Transform;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -1,85 +1,85 @@
|
||||
#include "timer.h"
|
||||
#include "CommandManager.h"
|
||||
#include "ObjectEntry.h"
|
||||
#include "Unit.h"
|
||||
#include "PaintObjectTool.h"
|
||||
#include "MiniPatch.h"
|
||||
#include "Terrain.h"
|
||||
#include "Renderer.h"
|
||||
#include "ObjectManager.h"
|
||||
#include "PaintObjectCommand.h"
|
||||
|
||||
// rotate object at 180 degrees each second when applying to terrain
|
||||
#define ROTATION_SPEED PI
|
||||
|
||||
// default tool instance
|
||||
CPaintObjectTool CPaintObjectTool::m_PaintObjectTool;
|
||||
|
||||
CPaintObjectTool::CPaintObjectTool() : m_PaintCmd(0), m_Rotation(0)
|
||||
{
|
||||
m_BrushSize=0;
|
||||
}
|
||||
|
||||
void CPaintObjectTool::BuildTransform()
|
||||
{
|
||||
m_ObjectTransform.SetIdentity();
|
||||
m_ObjectTransform.RotateY(m_Rotation);
|
||||
m_ObjectTransform.Translate(m_Position);
|
||||
}
|
||||
|
||||
void CPaintObjectTool::PaintSelection()
|
||||
{
|
||||
if (m_PaintCmd) {
|
||||
// already applied object to terrain, now we're just rotating it
|
||||
double curtime=get_time();
|
||||
m_Rotation+=ROTATION_SPEED*float(curtime-m_LastTriggerTime);
|
||||
BuildTransform();
|
||||
m_PaintCmd->GetUnit()->GetModel()->SetTransform(m_ObjectTransform);
|
||||
m_LastTriggerTime=curtime;
|
||||
} else {
|
||||
m_Rotation=0;
|
||||
m_Position=m_SelectionPoint;
|
||||
m_LastTriggerTime=get_time();
|
||||
|
||||
CObjectEntry* obj=g_ObjMan.GetSelectedObject();
|
||||
if (obj && obj->m_Model) {
|
||||
// get up to date transform
|
||||
BuildTransform();
|
||||
|
||||
// now paint the object
|
||||
m_PaintCmd=new CPaintObjectCommand(obj,m_ObjectTransform);
|
||||
m_PaintCmd->Execute();
|
||||
g_CmdMan.Append(m_PaintCmd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CPaintObjectTool::OnLButtonUp(unsigned int flags,int px,int py)
|
||||
{
|
||||
CBrushTool::OnLButtonUp(flags,px,py);
|
||||
// terminate current command, if we've got one
|
||||
if (m_PaintCmd) {
|
||||
m_PaintCmd->Finalize();
|
||||
m_PaintCmd=0;
|
||||
m_Rotation=0;
|
||||
}
|
||||
}
|
||||
|
||||
void CPaintObjectTool::OnDraw()
|
||||
{
|
||||
// don't draw object if we're currently rotating it on the terrain
|
||||
if (m_PaintCmd) return;
|
||||
|
||||
// don't draw unless we have a valid object to apply
|
||||
CObjectEntry* obj=g_ObjMan.GetSelectedObject();
|
||||
if (!obj || !obj->m_Model) return;
|
||||
|
||||
// try to get object transform, in world space
|
||||
m_Position=m_SelectionPoint;
|
||||
BuildTransform();
|
||||
|
||||
// render the current object at the same position as the selected tile
|
||||
m_Model=obj->m_Model;
|
||||
m_Model->SetTransform(m_ObjectTransform);
|
||||
g_Renderer.Submit(m_Model);
|
||||
}
|
||||
#include "timer.h"
|
||||
#include "CommandManager.h"
|
||||
#include "ObjectEntry.h"
|
||||
#include "Unit.h"
|
||||
#include "PaintObjectTool.h"
|
||||
#include "MiniPatch.h"
|
||||
#include "Terrain.h"
|
||||
#include "Renderer.h"
|
||||
#include "ObjectManager.h"
|
||||
#include "PaintObjectCommand.h"
|
||||
|
||||
// rotate object at 180 degrees each second when applying to terrain
|
||||
#define ROTATION_SPEED PI
|
||||
|
||||
// default tool instance
|
||||
CPaintObjectTool CPaintObjectTool::m_PaintObjectTool;
|
||||
|
||||
CPaintObjectTool::CPaintObjectTool() : m_PaintCmd(0), m_Rotation(0)
|
||||
{
|
||||
m_BrushSize=0;
|
||||
}
|
||||
|
||||
void CPaintObjectTool::BuildTransform()
|
||||
{
|
||||
m_ObjectTransform.SetIdentity();
|
||||
m_ObjectTransform.RotateY(m_Rotation);
|
||||
m_ObjectTransform.Translate(m_Position);
|
||||
}
|
||||
|
||||
void CPaintObjectTool::PaintSelection()
|
||||
{
|
||||
if (m_PaintCmd) {
|
||||
// already applied object to terrain, now we're just rotating it
|
||||
double curtime=get_time();
|
||||
m_Rotation+=ROTATION_SPEED*float(curtime-m_LastTriggerTime);
|
||||
BuildTransform();
|
||||
m_PaintCmd->GetUnit()->GetModel()->SetTransform(m_ObjectTransform);
|
||||
m_LastTriggerTime=curtime;
|
||||
} else {
|
||||
m_Rotation=0;
|
||||
m_Position=m_SelectionPoint;
|
||||
m_LastTriggerTime=get_time();
|
||||
|
||||
CObjectEntry* obj=g_ObjMan.GetSelectedObject();
|
||||
if (obj && obj->m_Model) {
|
||||
// get up to date transform
|
||||
BuildTransform();
|
||||
|
||||
// now paint the object
|
||||
m_PaintCmd=new CPaintObjectCommand(obj,m_ObjectTransform);
|
||||
m_PaintCmd->Execute();
|
||||
g_CmdMan.Append(m_PaintCmd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CPaintObjectTool::OnLButtonUp(unsigned int flags,int px,int py)
|
||||
{
|
||||
CBrushTool::OnLButtonUp(flags,px,py);
|
||||
// terminate current command, if we've got one
|
||||
if (m_PaintCmd) {
|
||||
m_PaintCmd->Finalize();
|
||||
m_PaintCmd=0;
|
||||
m_Rotation=0;
|
||||
}
|
||||
}
|
||||
|
||||
void CPaintObjectTool::OnDraw()
|
||||
{
|
||||
// don't draw object if we're currently rotating it on the terrain
|
||||
if (m_PaintCmd) return;
|
||||
|
||||
// don't draw unless we have a valid object to apply
|
||||
CObjectEntry* obj=g_ObjMan.GetSelectedObject();
|
||||
if (!obj || !obj->m_Model) return;
|
||||
|
||||
// try to get object transform, in world space
|
||||
m_Position=m_SelectionPoint;
|
||||
BuildTransform();
|
||||
|
||||
// render the current object at the same position as the selected tile
|
||||
m_Model=obj->m_Model;
|
||||
m_Model->SetTransform(m_ObjectTransform);
|
||||
g_Renderer.Submit(m_Model);
|
||||
}
|
||||
|
@ -1,57 +1,57 @@
|
||||
#ifndef _PAINTOBJECTTOOL_H
|
||||
#define _PAINTOBJECTTOOL_H
|
||||
|
||||
#include <set>
|
||||
#include "res/res.h"
|
||||
|
||||
#include "BrushTool.h"
|
||||
#include "Vector3D.h"
|
||||
#include "Matrix3D.h"
|
||||
#include "Model.h"
|
||||
|
||||
class CObjectEntry;
|
||||
class CPaintObjectCommand;
|
||||
|
||||
class CPaintObjectTool : public CBrushTool
|
||||
{
|
||||
public:
|
||||
CPaintObjectTool();
|
||||
|
||||
// draw this tool
|
||||
void OnDraw();
|
||||
|
||||
// callback for left button up event
|
||||
void OnLButtonUp(unsigned int flags,int px,int py);
|
||||
|
||||
// tool triggered via left mouse button; paint current selection
|
||||
void OnTriggerLeft() { PaintSelection(); }
|
||||
|
||||
// allow multiple triggers by click and hold - subsequent triggers rotate
|
||||
// the last applied object, rather than adding new objects
|
||||
bool SupportDragTrigger() { return true; }
|
||||
|
||||
// get the default paint model instance
|
||||
static CPaintObjectTool* GetTool() { return &m_PaintObjectTool; }
|
||||
|
||||
private:
|
||||
// apply current object to current selection
|
||||
void PaintSelection();
|
||||
// build the m_ObjectTransform member from current tile selection
|
||||
void BuildTransform();
|
||||
// currently active command, or null if no object currently being applied
|
||||
CPaintObjectCommand* m_PaintCmd;
|
||||
// Y-rotation of object currently being applied
|
||||
float m_Rotation;
|
||||
// position of object when first dropped
|
||||
CVector3D m_Position;
|
||||
// time of last trigger
|
||||
double m_LastTriggerTime;
|
||||
// current transform of selected object
|
||||
CMatrix3D m_ObjectTransform;
|
||||
// model of current object
|
||||
CModel* m_Model;
|
||||
// default tool instance
|
||||
static CPaintObjectTool m_PaintObjectTool;
|
||||
};
|
||||
|
||||
#endif
|
||||
#ifndef _PAINTOBJECTTOOL_H
|
||||
#define _PAINTOBJECTTOOL_H
|
||||
|
||||
#include <set>
|
||||
#include "res/res.h"
|
||||
|
||||
#include "BrushTool.h"
|
||||
#include "Vector3D.h"
|
||||
#include "Matrix3D.h"
|
||||
#include "Model.h"
|
||||
|
||||
class CObjectEntry;
|
||||
class CPaintObjectCommand;
|
||||
|
||||
class CPaintObjectTool : public CBrushTool
|
||||
{
|
||||
public:
|
||||
CPaintObjectTool();
|
||||
|
||||
// draw this tool
|
||||
void OnDraw();
|
||||
|
||||
// callback for left button up event
|
||||
void OnLButtonUp(unsigned int flags,int px,int py);
|
||||
|
||||
// tool triggered via left mouse button; paint current selection
|
||||
void OnTriggerLeft() { PaintSelection(); }
|
||||
|
||||
// allow multiple triggers by click and hold - subsequent triggers rotate
|
||||
// the last applied object, rather than adding new objects
|
||||
bool SupportDragTrigger() { return true; }
|
||||
|
||||
// get the default paint model instance
|
||||
static CPaintObjectTool* GetTool() { return &m_PaintObjectTool; }
|
||||
|
||||
private:
|
||||
// apply current object to current selection
|
||||
void PaintSelection();
|
||||
// build the m_ObjectTransform member from current tile selection
|
||||
void BuildTransform();
|
||||
// currently active command, or null if no object currently being applied
|
||||
CPaintObjectCommand* m_PaintCmd;
|
||||
// Y-rotation of object currently being applied
|
||||
float m_Rotation;
|
||||
// position of object when first dropped
|
||||
CVector3D m_Position;
|
||||
// time of last trigger
|
||||
double m_LastTriggerTime;
|
||||
// current transform of selected object
|
||||
CMatrix3D m_ObjectTransform;
|
||||
// model of current object
|
||||
CModel* m_Model;
|
||||
// default tool instance
|
||||
static CPaintObjectTool m_PaintObjectTool;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -1,97 +1,97 @@
|
||||
#include "PaintTextureCommand.h"
|
||||
#include "UIGlobals.h"
|
||||
#include "MiniMap.h"
|
||||
#include "textureEntry.h"
|
||||
#include "Terrain.h"
|
||||
|
||||
extern CTerrain g_Terrain;
|
||||
|
||||
inline int clamp(int x,int min,int max)
|
||||
{
|
||||
if (x<min) return min;
|
||||
else if (x>max) return max;
|
||||
else return x;
|
||||
}
|
||||
|
||||
CPaintTextureCommand::CPaintTextureCommand(CTextureEntry* tex,int brushSize,int selectionCentre[2])
|
||||
{
|
||||
m_Texture=tex;
|
||||
m_BrushSize=brushSize;
|
||||
m_SelectionCentre[0]=selectionCentre[0];
|
||||
m_SelectionCentre[1]=selectionCentre[1];
|
||||
}
|
||||
|
||||
|
||||
CPaintTextureCommand::~CPaintTextureCommand()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
void CPaintTextureCommand::Execute()
|
||||
{
|
||||
int r=m_BrushSize;
|
||||
u32 patchesPerSide=g_Terrain.GetPatchesPerSide();
|
||||
u32 mapSize=g_Terrain.GetVerticesPerSide();
|
||||
|
||||
// get range of tiles affected by brush
|
||||
int x0=clamp(m_SelectionCentre[0]-r,0,mapSize-1);
|
||||
int x1=clamp(m_SelectionCentre[0]+r+1,0,mapSize-1);
|
||||
int z0=clamp(m_SelectionCentre[1]-r,0,mapSize-1);
|
||||
int z1=clamp(m_SelectionCentre[1]+r+1,0,mapSize-1);
|
||||
|
||||
// iterate through tiles affected by brush
|
||||
for (int j=m_SelectionCentre[1]-r;j<=m_SelectionCentre[1]+r;j++) {
|
||||
for (int i=m_SelectionCentre[0]-r;i<=m_SelectionCentre[0]+r;i++) {
|
||||
|
||||
// try and get minipatch, if there is one
|
||||
CMiniPatch* nmp=g_Terrain.GetTile(i,j);
|
||||
|
||||
if (nmp) {
|
||||
nmp->Tex1=m_Texture ? m_Texture->m_Handle : 0;
|
||||
nmp->Tex1Priority=m_Texture ? ((int) m_Texture->m_Type) : 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// invalidate affected patches
|
||||
int px0=clamp(-1+(x0/16),0,patchesPerSide);
|
||||
int px1=clamp(1+(x1/16),0,patchesPerSide);
|
||||
int pz0=clamp(-1+(z0/16),0,patchesPerSide);
|
||||
int pz1=clamp(1+(z1/16),0,patchesPerSide);
|
||||
for (j=pz0;j<pz1;j++) {
|
||||
for (int i=px0;i<px1;i++) {
|
||||
CPatch* patch=g_Terrain.GetPatch(i,j);
|
||||
patch->SetDirty(RENDERDATA_UPDATE_INDICES);
|
||||
}
|
||||
}
|
||||
|
||||
// rebuild this bit of the minimap
|
||||
int w=1+2*m_BrushSize;
|
||||
int x=m_SelectionCentre[1]-m_BrushSize;
|
||||
if (x<0) {
|
||||
w+=x;
|
||||
x=0;
|
||||
}
|
||||
int h=1+2*m_BrushSize;
|
||||
int y=m_SelectionCentre[0]-m_BrushSize;
|
||||
if (y<0) {
|
||||
h+=y;
|
||||
y=0;
|
||||
}
|
||||
g_MiniMap.Rebuild(x,y,w,h);
|
||||
}
|
||||
|
||||
void CPaintTextureCommand::Undo()
|
||||
{
|
||||
ApplyDataToSelection(m_DataIn);
|
||||
}
|
||||
|
||||
void CPaintTextureCommand::Redo()
|
||||
{
|
||||
ApplyDataToSelection(m_DataOut);
|
||||
}
|
||||
|
||||
void CPaintTextureCommand::ApplyDataToSelection(const CArray2D<TextureSet>& data)
|
||||
{
|
||||
}
|
||||
#include "PaintTextureCommand.h"
|
||||
#include "UIGlobals.h"
|
||||
#include "MiniMap.h"
|
||||
#include "textureEntry.h"
|
||||
#include "Terrain.h"
|
||||
|
||||
extern CTerrain g_Terrain;
|
||||
|
||||
inline int clamp(int x,int min,int max)
|
||||
{
|
||||
if (x<min) return min;
|
||||
else if (x>max) return max;
|
||||
else return x;
|
||||
}
|
||||
|
||||
CPaintTextureCommand::CPaintTextureCommand(CTextureEntry* tex,int brushSize,int selectionCentre[2])
|
||||
{
|
||||
m_Texture=tex;
|
||||
m_BrushSize=brushSize;
|
||||
m_SelectionCentre[0]=selectionCentre[0];
|
||||
m_SelectionCentre[1]=selectionCentre[1];
|
||||
}
|
||||
|
||||
|
||||
CPaintTextureCommand::~CPaintTextureCommand()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
void CPaintTextureCommand::Execute()
|
||||
{
|
||||
int r=m_BrushSize;
|
||||
u32 patchesPerSide=g_Terrain.GetPatchesPerSide();
|
||||
u32 mapSize=g_Terrain.GetVerticesPerSide();
|
||||
|
||||
// get range of tiles affected by brush
|
||||
int x0=clamp(m_SelectionCentre[0]-r,0,mapSize-1);
|
||||
int x1=clamp(m_SelectionCentre[0]+r+1,0,mapSize-1);
|
||||
int z0=clamp(m_SelectionCentre[1]-r,0,mapSize-1);
|
||||
int z1=clamp(m_SelectionCentre[1]+r+1,0,mapSize-1);
|
||||
|
||||
// iterate through tiles affected by brush
|
||||
for (int j=m_SelectionCentre[1]-r;j<=m_SelectionCentre[1]+r;j++) {
|
||||
for (int i=m_SelectionCentre[0]-r;i<=m_SelectionCentre[0]+r;i++) {
|
||||
|
||||
// try and get minipatch, if there is one
|
||||
CMiniPatch* nmp=g_Terrain.GetTile(i,j);
|
||||
|
||||
if (nmp) {
|
||||
nmp->Tex1=m_Texture ? m_Texture->m_Handle : 0;
|
||||
nmp->Tex1Priority=m_Texture ? ((int) m_Texture->m_Type) : 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// invalidate affected patches
|
||||
int px0=clamp(-1+(x0/16),0,patchesPerSide);
|
||||
int px1=clamp(1+(x1/16),0,patchesPerSide);
|
||||
int pz0=clamp(-1+(z0/16),0,patchesPerSide);
|
||||
int pz1=clamp(1+(z1/16),0,patchesPerSide);
|
||||
for (j=pz0;j<pz1;j++) {
|
||||
for (int i=px0;i<px1;i++) {
|
||||
CPatch* patch=g_Terrain.GetPatch(i,j);
|
||||
patch->SetDirty(RENDERDATA_UPDATE_INDICES);
|
||||
}
|
||||
}
|
||||
|
||||
// rebuild this bit of the minimap
|
||||
int w=1+2*m_BrushSize;
|
||||
int x=m_SelectionCentre[1]-m_BrushSize;
|
||||
if (x<0) {
|
||||
w+=x;
|
||||
x=0;
|
||||
}
|
||||
int h=1+2*m_BrushSize;
|
||||
int y=m_SelectionCentre[0]-m_BrushSize;
|
||||
if (y<0) {
|
||||
h+=y;
|
||||
y=0;
|
||||
}
|
||||
g_MiniMap.Rebuild(x,y,w,h);
|
||||
}
|
||||
|
||||
void CPaintTextureCommand::Undo()
|
||||
{
|
||||
ApplyDataToSelection(m_DataIn);
|
||||
}
|
||||
|
||||
void CPaintTextureCommand::Redo()
|
||||
{
|
||||
ApplyDataToSelection(m_DataOut);
|
||||
}
|
||||
|
||||
void CPaintTextureCommand::ApplyDataToSelection(const CArray2D<TextureSet>& data)
|
||||
{
|
||||
}
|
||||
|
@ -1,68 +1,68 @@
|
||||
#ifndef _PAINTTEXTURECOMMAND_H
|
||||
#define _PAINTTEXTURECOMMAND_H
|
||||
|
||||
#include <set>
|
||||
#include "res/res.h"
|
||||
#include "Command.h"
|
||||
#include "Array2D.h"
|
||||
|
||||
struct TextureSet
|
||||
{
|
||||
Handle m_Texture;
|
||||
int m_Priority;
|
||||
};
|
||||
|
||||
class CTextureEntry;
|
||||
|
||||
class CPaintTextureCommand : public CCommand
|
||||
{
|
||||
public:
|
||||
// constructor, destructor
|
||||
CPaintTextureCommand(CTextureEntry* tex,int brushSize,int selectionCentre[2]);
|
||||
~CPaintTextureCommand();
|
||||
|
||||
// return the texture name of this command
|
||||
const char* GetName() const { return "Apply Texture"; }
|
||||
|
||||
// execute this command
|
||||
void Execute();
|
||||
|
||||
// can undo command?
|
||||
bool IsUndoable() const { return true; }
|
||||
// undo
|
||||
void Undo();
|
||||
// redo
|
||||
void Redo();
|
||||
|
||||
private:
|
||||
bool IsValidDataIndex(const CArray2D<TextureSet>& array,int x,int y) {
|
||||
if (x<0 || y<0) return 0;
|
||||
int ix=x-m_SelectionOrigin[0];
|
||||
int iy=y-m_SelectionOrigin[1];
|
||||
return ix>=0 && ix<array.usize() && iy>=0 && iy<array.vsize();
|
||||
}
|
||||
|
||||
TextureSet* DataIn(int x,int y) {
|
||||
return IsValidDataIndex(m_DataIn,x,y) ? &m_DataIn(x-m_SelectionOrigin[0],y-m_SelectionOrigin[1]) : 0;
|
||||
}
|
||||
TextureSet* DataOut(int x,int y) {
|
||||
return IsValidDataIndex(m_DataOut,x,y) ? &m_DataOut(x-m_SelectionOrigin[0],y-m_SelectionOrigin[1]) : 0;
|
||||
}
|
||||
|
||||
void ApplyDataToSelection(const CArray2D<TextureSet>& data);
|
||||
|
||||
// texture being painted
|
||||
CTextureEntry* m_Texture;
|
||||
// size of brush
|
||||
int m_BrushSize;
|
||||
// centre of brush
|
||||
int m_SelectionCentre[2];
|
||||
// origin of data set
|
||||
int m_SelectionOrigin[2];
|
||||
// input data (textures applied to the selection)
|
||||
CArray2D<TextureSet> m_DataIn;
|
||||
// output data (new textures applied to the selection after painting)
|
||||
CArray2D<TextureSet> m_DataOut;
|
||||
};
|
||||
|
||||
#endif
|
||||
#ifndef _PAINTTEXTURECOMMAND_H
|
||||
#define _PAINTTEXTURECOMMAND_H
|
||||
|
||||
#include <set>
|
||||
#include "res/res.h"
|
||||
#include "Command.h"
|
||||
#include "Array2D.h"
|
||||
|
||||
struct TextureSet
|
||||
{
|
||||
Handle m_Texture;
|
||||
int m_Priority;
|
||||
};
|
||||
|
||||
class CTextureEntry;
|
||||
|
||||
class CPaintTextureCommand : public CCommand
|
||||
{
|
||||
public:
|
||||
// constructor, destructor
|
||||
CPaintTextureCommand(CTextureEntry* tex,int brushSize,int selectionCentre[2]);
|
||||
~CPaintTextureCommand();
|
||||
|
||||
// return the texture name of this command
|
||||
const char* GetName() const { return "Apply Texture"; }
|
||||
|
||||
// execute this command
|
||||
void Execute();
|
||||
|
||||
// can undo command?
|
||||
bool IsUndoable() const { return true; }
|
||||
// undo
|
||||
void Undo();
|
||||
// redo
|
||||
void Redo();
|
||||
|
||||
private:
|
||||
bool IsValidDataIndex(const CArray2D<TextureSet>& array,int x,int y) {
|
||||
if (x<0 || y<0) return 0;
|
||||
int ix=x-m_SelectionOrigin[0];
|
||||
int iy=y-m_SelectionOrigin[1];
|
||||
return ix>=0 && ix<array.usize() && iy>=0 && iy<array.vsize();
|
||||
}
|
||||
|
||||
TextureSet* DataIn(int x,int y) {
|
||||
return IsValidDataIndex(m_DataIn,x,y) ? &m_DataIn(x-m_SelectionOrigin[0],y-m_SelectionOrigin[1]) : 0;
|
||||
}
|
||||
TextureSet* DataOut(int x,int y) {
|
||||
return IsValidDataIndex(m_DataOut,x,y) ? &m_DataOut(x-m_SelectionOrigin[0],y-m_SelectionOrigin[1]) : 0;
|
||||
}
|
||||
|
||||
void ApplyDataToSelection(const CArray2D<TextureSet>& data);
|
||||
|
||||
// texture being painted
|
||||
CTextureEntry* m_Texture;
|
||||
// size of brush
|
||||
int m_BrushSize;
|
||||
// centre of brush
|
||||
int m_SelectionCentre[2];
|
||||
// origin of data set
|
||||
int m_SelectionOrigin[2];
|
||||
// input data (textures applied to the selection)
|
||||
CArray2D<TextureSet> m_DataIn;
|
||||
// output data (new textures applied to the selection after painting)
|
||||
CArray2D<TextureSet> m_DataOut;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -1,21 +1,21 @@
|
||||
#include "CommandManager.h"
|
||||
#include "TextureEntry.h"
|
||||
#include "PaintTextureTool.h"
|
||||
#include "PaintTextureCommand.h"
|
||||
|
||||
// default tool instance
|
||||
CPaintTextureTool CPaintTextureTool::m_PaintTextureTool;
|
||||
|
||||
CPaintTextureTool::CPaintTextureTool()
|
||||
{
|
||||
m_SelectedTexture=0;
|
||||
}
|
||||
|
||||
void CPaintTextureTool::PaintSelection()
|
||||
{
|
||||
// apply current texture to current selection
|
||||
CPaintTextureCommand* paintCmd=new CPaintTextureCommand(m_SelectedTexture,m_BrushSize,m_SelectionCentre);
|
||||
g_CmdMan.Execute(paintCmd);
|
||||
}
|
||||
|
||||
|
||||
#include "CommandManager.h"
|
||||
#include "TextureEntry.h"
|
||||
#include "PaintTextureTool.h"
|
||||
#include "PaintTextureCommand.h"
|
||||
|
||||
// default tool instance
|
||||
CPaintTextureTool CPaintTextureTool::m_PaintTextureTool;
|
||||
|
||||
CPaintTextureTool::CPaintTextureTool()
|
||||
{
|
||||
m_SelectedTexture=0;
|
||||
}
|
||||
|
||||
void CPaintTextureTool::PaintSelection()
|
||||
{
|
||||
// apply current texture to current selection
|
||||
CPaintTextureCommand* paintCmd=new CPaintTextureCommand(m_SelectedTexture,m_BrushSize,m_SelectionCentre);
|
||||
g_CmdMan.Execute(paintCmd);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,43 +1,43 @@
|
||||
#ifndef _PAINTTEXTURETOOL_H
|
||||
#define _PAINTTEXTURETOOL_H
|
||||
|
||||
#include <set>
|
||||
#include "res/res.h"
|
||||
#include "BrushTool.h"
|
||||
|
||||
class CTextureEntry;
|
||||
|
||||
class CPaintTextureTool : public CBrushTool
|
||||
{
|
||||
public:
|
||||
enum { MAX_BRUSH_SIZE=8 };
|
||||
|
||||
public:
|
||||
CPaintTextureTool();
|
||||
|
||||
// tool triggered via left mouse button; paint current selection
|
||||
void OnTriggerLeft() { PaintSelection(); }
|
||||
|
||||
// set current painting texture
|
||||
void SetSelectedTexture(CTextureEntry* tex) { m_SelectedTexture=tex; }
|
||||
// get current painting texture
|
||||
CTextureEntry* GetSelectedTexture() { return m_SelectedTexture; }
|
||||
|
||||
// allow multiple triggers by click and drag
|
||||
bool SupportDragTrigger() { return true; }
|
||||
|
||||
// get the default paint texture instance
|
||||
static CPaintTextureTool* GetTool() { return &m_PaintTextureTool; }
|
||||
|
||||
private:
|
||||
// apply current texture to current selection
|
||||
void PaintSelection();
|
||||
|
||||
// currently selected texture for painting
|
||||
CTextureEntry* m_SelectedTexture;
|
||||
|
||||
// default tool instance
|
||||
static CPaintTextureTool m_PaintTextureTool;
|
||||
};
|
||||
|
||||
#endif
|
||||
#ifndef _PAINTTEXTURETOOL_H
|
||||
#define _PAINTTEXTURETOOL_H
|
||||
|
||||
#include <set>
|
||||
#include "res/res.h"
|
||||
#include "BrushTool.h"
|
||||
|
||||
class CTextureEntry;
|
||||
|
||||
class CPaintTextureTool : public CBrushTool
|
||||
{
|
||||
public:
|
||||
enum { MAX_BRUSH_SIZE=8 };
|
||||
|
||||
public:
|
||||
CPaintTextureTool();
|
||||
|
||||
// tool triggered via left mouse button; paint current selection
|
||||
void OnTriggerLeft() { PaintSelection(); }
|
||||
|
||||
// set current painting texture
|
||||
void SetSelectedTexture(CTextureEntry* tex) { m_SelectedTexture=tex; }
|
||||
// get current painting texture
|
||||
CTextureEntry* GetSelectedTexture() { return m_SelectedTexture; }
|
||||
|
||||
// allow multiple triggers by click and drag
|
||||
bool SupportDragTrigger() { return true; }
|
||||
|
||||
// get the default paint texture instance
|
||||
static CPaintTextureTool* GetTool() { return &m_PaintTextureTool; }
|
||||
|
||||
private:
|
||||
// apply current texture to current selection
|
||||
void PaintSelection();
|
||||
|
||||
// currently selected texture for painting
|
||||
CTextureEntry* m_SelectedTexture;
|
||||
|
||||
// default tool instance
|
||||
static CPaintTextureTool m_PaintTextureTool;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -1,36 +1,36 @@
|
||||
#include "RaiseElevationCommand.h"
|
||||
#include "Terrain.h"
|
||||
|
||||
extern CTerrain g_Terrain;
|
||||
|
||||
inline int clamp(int x,int min,int max)
|
||||
{
|
||||
if (x<min) return min;
|
||||
else if (x>max) return max;
|
||||
else return x;
|
||||
}
|
||||
|
||||
|
||||
CRaiseElevationCommand::CRaiseElevationCommand(int deltaheight,int brushSize,int selectionCentre[2])
|
||||
: CAlterElevationCommand(brushSize,selectionCentre), m_DeltaHeight(deltaheight)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
CRaiseElevationCommand::~CRaiseElevationCommand()
|
||||
{
|
||||
}
|
||||
|
||||
void CRaiseElevationCommand::CalcDataOut(int x0,int x1,int z0,int z1)
|
||||
{
|
||||
// fill output data
|
||||
u32 mapSize=g_Terrain.GetVerticesPerSide();
|
||||
int i,j;
|
||||
for (j=z0;j<=z1;j++) {
|
||||
for (i=x0;i<=x1;i++) {
|
||||
u32 input=g_Terrain.GetHeightMap()[j*mapSize+i];
|
||||
u16 output=clamp(input+m_DeltaHeight,0,65535);
|
||||
m_DataOut(i-x0,j-z0)=output;
|
||||
}
|
||||
}
|
||||
}
|
||||
#include "RaiseElevationCommand.h"
|
||||
#include "Terrain.h"
|
||||
|
||||
extern CTerrain g_Terrain;
|
||||
|
||||
inline int clamp(int x,int min,int max)
|
||||
{
|
||||
if (x<min) return min;
|
||||
else if (x>max) return max;
|
||||
else return x;
|
||||
}
|
||||
|
||||
|
||||
CRaiseElevationCommand::CRaiseElevationCommand(int deltaheight,int brushSize,int selectionCentre[2])
|
||||
: CAlterElevationCommand(brushSize,selectionCentre), m_DeltaHeight(deltaheight)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
CRaiseElevationCommand::~CRaiseElevationCommand()
|
||||
{
|
||||
}
|
||||
|
||||
void CRaiseElevationCommand::CalcDataOut(int x0,int x1,int z0,int z1)
|
||||
{
|
||||
// fill output data
|
||||
u32 mapSize=g_Terrain.GetVerticesPerSide();
|
||||
int i,j;
|
||||
for (j=z0;j<=z1;j++) {
|
||||
for (i=x0;i<=x1;i++) {
|
||||
u32 input=g_Terrain.GetHeightMap()[j*mapSize+i];
|
||||
u16 output=clamp(input+m_DeltaHeight,0,65535);
|
||||
m_DataOut(i-x0,j-z0)=output;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user