diff --git a/source/graphics/Camera.cpp b/source/graphics/Camera.cpp index 058dfa5761..6c16658944 100755 --- a/source/graphics/Camera.cpp +++ b/source/graphics/Camera.cpp @@ -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]); + } +} diff --git a/source/graphics/Camera.h b/source/graphics/Camera.h index 301834c1c8..0ad8c7ace3 100755 --- a/source/graphics/Camera.h +++ b/source/graphics/Camera.h @@ -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 diff --git a/source/graphics/HFTracer.cpp b/source/graphics/HFTracer.cpp index 9cf00a9657..f4e2b70985 100755 --- a/source/graphics/HFTracer.cpp +++ b/source/graphics/HFTracer.cpp @@ -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)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 && d0) { - 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=0 && cz=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)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 && d0) { + 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=0 && cz=0); + + // fell off end of heightmap with no intersection; return a miss + return false; +} diff --git a/source/graphics/HFTracer.h b/source/graphics/HFTracer.h index 97f0a02850..ad3add7a6d 100755 --- a/source/graphics/HFTracer.h +++ b/source/graphics/HFTracer.h @@ -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 \ No newline at end of file diff --git a/source/graphics/Model.cpp b/source/graphics/Model.cpp index ce19fa0527..a985801c51 100755 --- a/source/graphics/Model.cpp +++ b/source/graphics/Model.cpp @@ -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;iGetNumBones(); - 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;iGetNumVertices(); - SModelVertex* verts=m_pModelDef->GetVertices(); - - for (int i=0;iGetNumVertices(); - SModelVertex* verts=m_pModelDef->GetVertices(); - - // iterate through every frame of the animation - for (uint j=0;jGetNumFrames();j++) { - // extend bounds by vertex positions at the frame - for (int i=0;iGetFrameTime(); - 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;iUpdate(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;iGetNumBones();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;im_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::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;iAddProp(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;im_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;iGetNumBones(); + 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;iGetNumVertices(); + SModelVertex* verts=m_pModelDef->GetVertices(); + + for (int i=0;iGetNumVertices(); + SModelVertex* verts=m_pModelDef->GetVertices(); + + // iterate through every frame of the animation + for (uint j=0;jGetNumFrames();j++) { + // extend bounds by vertex positions at the frame + for (int i=0;iGetFrameTime(); + 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;iUpdate(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;iGetNumBones();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;im_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::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;iAddProp(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;im_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); + } +} diff --git a/source/graphics/Model.h b/source/graphics/Model.h index 70def4ade1..677fd93b90 100755 --- a/source/graphics/Model.h +++ b/source/graphics/Model.h @@ -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& 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 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& 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 m_Props; +}; + +#endif diff --git a/source/graphics/ModelDef.cpp b/source/graphics/ModelDef.cpp index 75298d2585..d088f04670 100755 --- a/source/graphics/ModelDef.cpp +++ b/source/graphics/ModelDef.cpp @@ -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;im_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;im_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;im_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;im_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;im_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"); } - + diff --git a/source/graphics/ModelDef.h b/source/graphics/ModelDef.h index 738326f37a..316e615a4b 100755 --- a/source/graphics/ModelDef.h +++ b/source/graphics/ModelDef.h @@ -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; }; diff --git a/source/graphics/ObjectEntry.cpp b/source/graphics/ObjectEntry.cpp index f55ffd99e9..e5cd516dba 100755 --- a/source/graphics/ObjectEntry.cpp +++ b/source/graphics/ObjectEntry.cpp @@ -1,321 +1,321 @@ -#include "ObjectEntry.h" -#include "ObjectManager.h" -#include "Model.h" -#include "ModelDef.h" - -#include "UnitManager.h" - -// xerces XML stuff -#include -#include -#include -#include -#include - -// Gee's custom error handler -#include - -#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;iGetModelDef() : 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;pFindPropPoint((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& units=g_UnitMan.GetUnits(); - for (uint i=0;iGetModel(); - if (unitmodel->GetModelDef()==oldmodel) { - unitmodel->InitModel(m_Model->GetModelDef()); - - const std::vector& newprops=m_Model->GetProps(); - for (uint j=0;jAddProp(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; iitem(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; jgetLength(); ++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; jgetLength(); ++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,"\n\n"); - fprintf(fp,"\n\n"); - - // write the object itself - fprintf(fp,"\n"); - fprintf(fp,"\n"); - fprintf(fp,"\t%s\n",(const char*) m_Name); - fprintf(fp,"\t%s\n",(const char*) m_ModelName); - fprintf(fp,"\t%s\n",(const char*) m_TextureName); - if (m_Animations.size()>0) { - fprintf(fp,"\t\n"); - for (uint i=0;i \n",(const char*) m_Animations[i].m_AnimName,(const char*) m_Animations[i].m_FileName); - } - fprintf(fp,"\t\n"); - } - fprintf(fp,"\n"); - fclose(fp); - - return true; -} +#include "ObjectEntry.h" +#include "ObjectManager.h" +#include "Model.h" +#include "ModelDef.h" + +#include "UnitManager.h" + +// xerces XML stuff +#include +#include +#include +#include +#include + +// Gee's custom error handler +#include + +#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;iGetModelDef() : 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;pFindPropPoint((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& units=g_UnitMan.GetUnits(); + for (uint i=0;iGetModel(); + if (unitmodel->GetModelDef()==oldmodel) { + unitmodel->InitModel(m_Model->GetModelDef()); + + const std::vector& newprops=m_Model->GetProps(); + for (uint j=0;jAddProp(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; iitem(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; jgetLength(); ++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; jgetLength(); ++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,"\n\n"); + fprintf(fp,"\n\n"); + + // write the object itself + fprintf(fp,"\n"); + fprintf(fp,"\n"); + fprintf(fp,"\t%s\n",(const char*) m_Name); + fprintf(fp,"\t%s\n",(const char*) m_ModelName); + fprintf(fp,"\t%s\n",(const char*) m_TextureName); + if (m_Animations.size()>0) { + fprintf(fp,"\t\n"); + for (uint i=0;i \n",(const char*) m_Animations[i].m_AnimName,(const char*) m_Animations[i].m_FileName); + } + fprintf(fp,"\t\n"); + } + fprintf(fp,"\n"); + fclose(fp); + + return true; +} diff --git a/source/graphics/ObjectEntry.h b/source/graphics/ObjectEntry.h index 289ffe7026..6ea42181ff 100755 --- a/source/graphics/ObjectEntry.h +++ b/source/graphics/ObjectEntry.h @@ -1,65 +1,65 @@ -#ifndef _OBJECTENTRY_H -#define _OBJECTENTRY_H - -class CModel; -class CSkeletonAnim; - -#include -#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 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 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 +#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 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 m_Props; + // corresponding model + CModel* m_Model; + // type of object; index into object managers types array + int m_Type; +}; + + +#endif diff --git a/source/graphics/ObjectManager.cpp b/source/graphics/ObjectManager.cpp index 6766fe142e..49ce5a9227 100755 --- a/source/graphics/ObjectManager.cpp +++ b/source/graphics/ObjectManager.cpp @@ -8,15 +8,15 @@ CObjectManager::CObjectManager() : m_SelectedObject(0) m_ObjectTypes.reserve(32); } -CObjectManager::~CObjectManager() -{ - m_SelectedObject=0; - for (size_t i=0;i& objects=m_ObjectTypes[i].m_Objects; - - for (uint j=0;jm_Model) { - if (!objects[j]->BuildModel()) { - DeleteObject(objects[j]); - } - } - } - } + + // now build all the models + for (i=0;i& objects=m_ObjectTypes[i].m_Objects; + + for (uint j=0;jm_Model) { + if (!objects[j]->BuildModel()) { + DeleteObject(objects[j]); + } + } + } + } } void CObjectManager::BuildObjectTypes() diff --git a/source/graphics/ObjectManager.h b/source/graphics/ObjectManager.h index 1022a6f04c..ad170b530e 100755 --- a/source/graphics/ObjectManager.h +++ b/source/graphics/ObjectManager.h @@ -1,15 +1,15 @@ #ifndef _OBJECTMANAGER_H #define _OBJECTMANAGER_H -#include +#include #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 { public: @@ -23,10 +23,10 @@ public: std::vector m_Objects; }; -public: +public: // constructor, destructor CObjectManager(); - ~CObjectManager(); + ~CObjectManager(); void LoadObjects(); diff --git a/source/graphics/RenderableObject.h b/source/graphics/RenderableObject.h index d2d8690914..8cd264e3d4 100755 --- a/source/graphics/RenderableObject.h +++ b/source/graphics/RenderableObject.h @@ -1,104 +1,104 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Name: RenderableObject.h -// Author: Rich Cross -// Contact: rich@wildfiregames.com -// -/////////////////////////////////////////////////////////////////////////////// - -#ifndef _RENDERABLEOBJECT_H -#define _RENDERABLEOBJECT_H - -#include -#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 +#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 diff --git a/source/graphics/SkeletonAnim.h b/source/graphics/SkeletonAnim.h index 340aa5ab88..272abd04c8 100755 --- a/source/graphics/SkeletonAnim.h +++ b/source/graphics/SkeletonAnim.h @@ -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 \ No newline at end of file diff --git a/source/graphics/SkeletonAnimDef.h b/source/graphics/SkeletonAnimDef.h index 4bb408e466..342bec3c15 100755 --- a/source/graphics/SkeletonAnimDef.h +++ b/source/graphics/SkeletonAnimDef.h @@ -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 \ No newline at end of file diff --git a/source/graphics/SkeletonAnimManager.cpp b/source/graphics/SkeletonAnimManager.cpp index 2eee2583f3..44631f2cf2 100755 --- a/source/graphics/SkeletonAnimManager.cpp +++ b/source/graphics/SkeletonAnimManager.cpp @@ -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 - -/////////////////////////////////////////////////////////////////////////////// -// CSkeletonAnimManager constructor -CSkeletonAnimManager::CSkeletonAnimManager() -{ -} - -/////////////////////////////////////////////////////////////////////////////// -// CSkeletonAnimManager destructor -CSkeletonAnimManager::~CSkeletonAnimManager() -{ - typedef std::map::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::iterator iter=m_Animations.find(fname); - if (iter!=m_Animations.end()) { - // yes - return it - return iter->second; - } - - // already failed to load? - std::set::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 + +/////////////////////////////////////////////////////////////////////////////// +// CSkeletonAnimManager constructor +CSkeletonAnimManager::CSkeletonAnimManager() +{ +} + +/////////////////////////////////////////////////////////////////////////////// +// CSkeletonAnimManager destructor +CSkeletonAnimManager::~CSkeletonAnimManager() +{ + typedef std::map::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::iterator iter=m_Animations.find(fname); + if (iter!=m_Animations.end()) { + // yes - return it + return iter->second; + } + + // already failed to load? + std::set::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; + } +} diff --git a/source/graphics/SkeletonAnimManager.h b/source/graphics/SkeletonAnimManager.h index 2c155028c9..f2ebed119a 100755 --- a/source/graphics/SkeletonAnimManager.h +++ b/source/graphics/SkeletonAnimManager.h @@ -1,44 +1,44 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Name: SkeletonAnimManager.h -// Author: Rich Cross -// Contact: rich@wildfiregames.com -// -/////////////////////////////////////////////////////////////////////////////// - -#ifndef _SKELETONANIMMANAGER_H -#define _SKELETONANIMMANAGER_H - -#include -#include -#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 -{ -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 m_Animations; - // set of bad animation names - prevents multiple reloads of bad files - std::set m_BadAnimationFiles; -}; - +/////////////////////////////////////////////////////////////////////////////// +// +// Name: SkeletonAnimManager.h +// Author: Rich Cross +// Contact: rich@wildfiregames.com +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef _SKELETONANIMMANAGER_H +#define _SKELETONANIMMANAGER_H + +#include +#include +#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 +{ +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 m_Animations; + // set of bad animation names - prevents multiple reloads of bad files + std::set m_BadAnimationFiles; +}; + #endif \ No newline at end of file diff --git a/source/graphics/Sprite.cpp b/source/graphics/Sprite.cpp index d0b5efd61e..6c0b34403b 100755 --- a/source/graphics/Sprite.cpp +++ b/source/graphics/Sprite.cpp @@ -25,7 +25,7 @@ ==================================================================*/ #include "Sprite.h" -#include "Renderer.h" +#include "Renderer.h" #include "ogl.h" #include "res/tex.h" diff --git a/source/graphics/TextureManager.cpp b/source/graphics/TextureManager.cpp index 4ab8f15d3a..e3e509145f 100755 --- a/source/graphics/TextureManager.cpp +++ b/source/graphics/TextureManager.cpp @@ -16,15 +16,15 @@ CTextureManager::CTextureManager() { m_TerrainTextures.reserve(32); } - -CTextureManager::~CTextureManager() -{ - for (size_t i=0;i -#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 { public: @@ -24,10 +24,10 @@ public: std::vector m_Textures; }; -public: +public: // constructor, destructor CTextureManager(); - ~CTextureManager(); + ~CTextureManager(); void LoadTerrainTextures(); diff --git a/source/graphics/Unit.h b/source/graphics/Unit.h index ef5af04f56..6c58271a73 100755 --- a/source/graphics/Unit.h +++ b/source/graphics/Unit.h @@ -1,31 +1,31 @@ #ifndef _UNIT_H #define _UNIT_H - -#include + +#include #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; diff --git a/source/graphics/UnitManager.cpp b/source/graphics/UnitManager.cpp index 3861aa17fa..678df75446 100755 --- a/source/graphics/UnitManager.cpp +++ b/source/graphics/UnitManager.cpp @@ -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 - -/////////////////////////////////////////////////////////////////////////////// -// 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::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;iGetModel()->GetBounds().RayIntersect(origin,dir,tmin,tmax)) { - if (!hit || tmin + +/////////////////////////////////////////////////////////////////////////////// +// 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::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;iGetModel()->GetBounds().RayIntersect(origin,dir,tmin,tmax)) { + if (!hit || tmin -#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 -{ -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& 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 m_Units; -}; - +/////////////////////////////////////////////////////////////////////////////// +// +// Name: UnitManager.h +// Author: Rich Cross +// Contact: rich@wildfiregames.com +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef _UNITMANAGER_H +#define _UNITMANAGER_H + +#include +#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 +{ +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& 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 m_Units; +}; + #endif \ No newline at end of file diff --git a/source/lib/res/tex.cpp b/source/lib/res/tex.cpp index d5116fa6f8..55f0d109d8 100755 --- a/source/lib/res/tex.cpp +++ b/source/lib/res/tex.cpp @@ -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; diff --git a/source/lib/res/tex.h b/source/lib/res/tex.h index 7b0275dec7..4a0375c7f7 100755 --- a/source/lib/res/tex.h +++ b/source/lib/res/tex.h @@ -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); diff --git a/source/lib/sysdep/win/wposix.cpp b/source/lib/sysdep/win/wposix.cpp index 178ed7c542..0dbb8915df 100755 --- a/source/lib/sysdep/win/wposix.cpp +++ b/source/lib/sysdep/win/wposix.cpp @@ -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) diff --git a/source/main.cpp b/source/main.cpp index e9181d2836..911ed8857f 100755 --- a/source/main.cpp +++ b/source/main.cpp @@ -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& props=model->GetProps(); - for (uint i=0;i& props=model->GetProps(); + for (uint i=0;i& units=g_UnitMan.GetUnits(); for (uint i=0;iGetModel()->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? diff --git a/source/maths/Bound.cpp b/source/maths/Bound.cpp index 73aa735b69..fe811af984 100755 --- a/source/maths/Bound.cpp +++ b/source/maths/Bound.cpp @@ -1,162 +1,162 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Name: Bound.cpp -// Author: Rich Cross -// Contact: rich@wildfiregames.com -// -/////////////////////////////////////////////////////////////////////////////// - - -// necessary includes -#include -#include -#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[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[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[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[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 (t1tnear) - tnear = t1; - if (t2tfar || tfar<0) - return false; - } - - if (dir[2]==0 && (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 (t1tnear) - tnear = t1; - if (t2tfar || 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 +#include +#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[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[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[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[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 (t1tnear) + tnear = t1; + if (t2tfar || tfar<0) + return false; + } + + if (dir[2]==0 && (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 (t1tnear) + tnear = t1; + if (t2tfar || 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 diff --git a/source/maths/MathUtil.h b/source/maths/MathUtil.h index 935a1529da..f465c0e4a0 100755 --- a/source/maths/MathUtil.h +++ b/source/maths/MathUtil.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 diff --git a/source/maths/Matrix3D.cpp b/source/maths/Matrix3D.cpp index c4290f3719..209d2c6424 100755 --- a/source/maths/Matrix3D.cpp +++ b/source/maths/Matrix3D.cpp @@ -1,540 +1,540 @@ -//*********************************************************** -// -// Name: Matrix3D.Cpp -// Last Update: 31/1/02 -// Author: Poya Manouchehri -// -// Description: A Matrix class used for holding and -// manipulating transformation info. -// -//*********************************************************** - - -#include "Matrix3D.h" -#include "Quaternion.h" - -CMatrix3D::CMatrix3D () -{ -} - -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) -{ - _11=a11; - _12=a12; - _13=a13; - _14=a14; - - _21=a21; - _22=a22; - _23=a23; - _24=a24; - - _31=a31; - _32=a32; - _33=a33; - _34=a34; - - _41=a41; - _42=a42; - _43=a43; - _44=a44; -} - -//Matrix multiplication -CMatrix3D CMatrix3D::operator*(const CMatrix3D& matrix) const -{ - CMatrix3D Temp; - - Temp._11 = _11*matrix._11 + - _12*matrix._21 + - _13*matrix._31 + - _14*matrix._41; - - Temp._12 = _11*matrix._12 + - _12*matrix._22 + - _13*matrix._32 + - _14*matrix._42; - - Temp._13 = _11*matrix._13 + - _12*matrix._23 + - _13*matrix._33 + - _14*matrix._43; - - Temp._14 = _11*matrix._14 + - _12*matrix._24 + - _13*matrix._34 + - _14*matrix._44; - - Temp._21 = _21*matrix._11 + - _22*matrix._21 + - _23*matrix._31 + - _24*matrix._41; - - Temp._22 = _21*matrix._12 + - _22*matrix._22 + - _23*matrix._32 + - _24*matrix._42; - - Temp._23 = _21*matrix._13 + - _22*matrix._23 + - _23*matrix._33 + - _24*matrix._43; - - Temp._24 = _21*matrix._14 + - _22*matrix._24 + - _23*matrix._34 + - _24*matrix._44; - - Temp._31 = _31*matrix._11 + - _32*matrix._21 + - _33*matrix._31 + - _34*matrix._41; - - Temp._32 = _31*matrix._12 + - _32*matrix._22 + - _33*matrix._32 + - _34*matrix._42; - - Temp._33 = _31*matrix._13 + - _32*matrix._23 + - _33*matrix._33 + - _34*matrix._43; - - Temp._34 = _31*matrix._14 + - _32*matrix._24 + - _33*matrix._34 + - _34*matrix._44; - - Temp._41 = _41*matrix._11 + - _42*matrix._21 + - _43*matrix._31 + - _44*matrix._41; - - Temp._42 = _41*matrix._12 + - _42*matrix._22 + - _43*matrix._32 + - _44*matrix._42; - - Temp._43 = _41*matrix._13 + - _42*matrix._23 + - _43*matrix._33 + - _44*matrix._43; - - Temp._44 = _41*matrix._14 + - _42*matrix._24 + - _43*matrix._34 + - _44*matrix._44; - - return Temp; -} - -//Matrix multiplication/assignment -CMatrix3D& CMatrix3D::operator*=(const CMatrix3D& matrix) -{ - Concatenate(matrix); - return *this; -} - -//Matrix scaling -CMatrix3D CMatrix3D::operator*(float f) const -{ - CMatrix3D tmp; - for (int i=0;i<16;i++) { - tmp._data[i]=_data[i]*f; - } - return tmp; -} - -//Matrix scaling/assignment -CMatrix3D& CMatrix3D::operator*=(float f) -{ - for (int i=0;i<16;i++) { - _data[i]*=f; - } - return *this; -} - -//Matrix addition -CMatrix3D CMatrix3D::operator+(const CMatrix3D& m) const -{ - CMatrix3D tmp; - for (int i=0;i<16;i++) { - tmp._data[i]=_data[i]+m._data[i]; - } - return tmp; -} - -//Matrix addition/assignment -CMatrix3D& CMatrix3D::operator+=(const CMatrix3D& m) -{ - for (int i=0;i<16;i++) { - _data[i]+=m._data[i]; - } - return *this; -} - -//Sets the identity matrix -void CMatrix3D::SetIdentity () -{ - _11=1.0f; _12=0.0f; _13=0.0f; _14=0.0f; - _21=0.0f; _22=1.0f; _23=0.0f; _24=0.0f; - _31=0.0f; _32=0.0f; _33=1.0f; _34=0.0f; - _41=0.0f; _42=0.0f; _43=0.0f; _44=1.0f; -} - -//Sets the zero matrix -void CMatrix3D::SetZero () -{ - _11=0.0f; _12=0.0f; _13=0.0f; _14=0.0f; - _21=0.0f; _22=0.0f; _23=0.0f; _24=0.0f; - _31=0.0f; _32=0.0f; _33=0.0f; _34=0.0f; - _41=0.0f; _42=0.0f; _43=0.0f; _44=0.0f; -} - -//The following clear the matrix and set the -//rotation of each of the 3 axes - -void CMatrix3D::SetXRotation (float angle) -{ - float Cos = cosf (angle); - float Sin = sinf (angle); - - _11=1.0f; _12=0.0f; _13=0.0f; _14=0.0f; - _21=0.0f; _22=Cos; _23=-Sin; _24=0.0f; - _31=0.0f; _32=Sin; _33=Cos; _34=0.0f; - _41=0.0f; _42=0.0f; _43=0.0f; _44=1.0f; -} - -void CMatrix3D::SetYRotation (float angle) -{ - float Cos = cosf (angle); - float Sin = sinf (angle); - - _11=Cos; _12=0.0f; _13=Sin; _14=0.0f; - _21=0.0f; _22=1.0f; _23=0.0f; _24=0.0f; - _31=-Sin; _32=0.0f; _33=Cos; _34=0.0f; - _41=0.0f; _42=0.0f; _43=0.0f; _44=1.0f; -} - -void CMatrix3D::SetZRotation (float angle) -{ - float Cos = cosf (angle); - float Sin = sinf (angle); - - _11=Cos; _12=-Sin; _13=0.0f; _14=0.0f; - _21=Sin; _22=Cos; _23=0.0f; _24=0.0f; - _31=0.0f; _32=0.0f; _33=1.0f; _34=0.0f; - _41=0.0f; _42=0.0f; _43=0.0f; _44=1.0f; -} - -//The following apply a rotation to the matrix -//about each of the axes; - -void CMatrix3D::RotateX (float angle) -{ - CMatrix3D Temp; - Temp.SetXRotation (angle); - Concatenate(Temp); -} - -void CMatrix3D::RotateY (float angle) -{ - CMatrix3D Temp; - Temp.SetYRotation (angle); - Concatenate(Temp); -} - -void CMatrix3D::RotateZ (float angle) -{ - CMatrix3D Temp; - Temp.SetZRotation(angle); - Concatenate(Temp); -} - -//Sets the translation of the matrix -void CMatrix3D::SetTranslation (float x, float y, float z) -{ - _11=1.0f; _12=0.0f; _13=0.0f; _14=x; - _21=0.0f; _22=1.0f; _23=0.0f; _24=y; - _31=0.0f; _32=0.0f; _33=1.0f; _34=z; - _41=0.0f; _42=0.0f; _43=0.0f; _44=1.0f; -} - -void CMatrix3D::SetTranslation(const CVector3D& vector) -{ - SetTranslation(vector.X, vector.Y, vector.Z); -} - -//Applies a translation to the matrix -void CMatrix3D::Translate(float x, float y, float z) -{ - CMatrix3D Temp; - Temp.SetTranslation(x,y,z); - Concatenate(Temp); -} - -void CMatrix3D::Translate(const CVector3D &vector) -{ - Translate(vector.X,vector.Y,vector.Z); -} - -void CMatrix3D::Concatenate(const CMatrix3D& m) -{ - (*this)=m*(*this); -} - -CVector3D CMatrix3D::GetTranslation() const -{ - CVector3D Temp; - - Temp.X = _14; - Temp.Y = _24; - Temp.Z = _34; - - return Temp; -} - -//Clears and sets the scaling of the matrix -void CMatrix3D::SetScaling (float x_scale, float y_scale, float z_scale) -{ - _11=x_scale; _12=0.0f; _13=0.0f; _14=0.0f; - _21=0.0f; _22=y_scale; _23=0.0f; _24=0.0f; - _31=0.0f; _32=0.0f; _33=z_scale; _34=0.0f; - _41=0.0f; _42=0.0f; _43=0.0f; _44=1.0f; -} - -//Scales the matrix -void CMatrix3D::Scale (float x_scale, float y_scale, float z_scale) -{ - CMatrix3D Temp; - Temp.SetScaling(x_scale,y_scale,z_scale); - Concatenate(Temp); -} - -//Returns the transpose of the matrix. For orthonormal -//matrices, this is the same is the inverse matrix -void CMatrix3D::GetTranspose(CMatrix3D& result) const -{ - result._11 = _11; - result._21 = _12; - result._31 = _13; - result._41 = _14; - - result._12 = _21; - result._22 = _22; - result._32 = _23; - result._42 = _24; - - result._13 = _31; - result._23 = _32; - result._33 = _33; - result._43 = _34; - - result._14 = _41; - result._24 = _42; - result._34 = _43; - result._44 = _44; -} - - -//Get a vector which points to the left of the matrix -CVector3D CMatrix3D::GetLeft () const -{ - CVector3D Temp; - - Temp.X = -_11; - Temp.Y = -_21; - Temp.Z = -_31; - - return Temp; -} - -//Get a vector which points up from the matrix -CVector3D CMatrix3D::GetUp () const -{ - CVector3D Temp; - - Temp.X = _12; - Temp.Y = _22; - Temp.Z = _32; - - return Temp; -} - -//Get a vector which points to front of the matrix -CVector3D CMatrix3D::GetIn () const -{ - CVector3D Temp; - - Temp.X = _13; - Temp.Y = _23; - Temp.Z = _33; - - return Temp; -} - - -//Transform a vector by this matrix -CVector3D CMatrix3D::Transform (const CVector3D &vector) const -{ - CVector3D result; - Transform(vector,result); - return result; -} - -void CMatrix3D::Transform(const CVector3D& vector,CVector3D& result) const -{ - result.X = _11*vector.X + _12*vector.Y + _13*vector.Z + _14; - result.Y = _21*vector.X + _22*vector.Y + _23*vector.Z + _24; - result.Z = _31*vector.X + _32*vector.Y + _33*vector.Z + _34; -} - -//Transform a vector by this matrix -CVector4D CMatrix3D::Transform(const CVector4D &vector) const -{ - CVector4D result; - Transform(vector,result); - return result; -} - -void CMatrix3D::Transform(const CVector4D& vector,CVector4D& result) const -{ - result[0] = _11*vector[0] + _12*vector[1] + _13*vector[2] + _14*vector[3]; - result[1] = _21*vector[0] + _22*vector[1] + _23*vector[2] + _24*vector[3]; - result[2] = _31*vector[0] + _32*vector[1] + _33*vector[2] + _34*vector[3]; - result[3] = _41*vector[0] + _42*vector[1] + _43*vector[2] + _44*vector[3]; -} - -//Only rotate (not translate) a vector by this matrix -CVector3D CMatrix3D::Rotate(const CVector3D& vector) const -{ - CVector3D result; - Rotate(vector,result); - return result; -} - -void CMatrix3D::Rotate(const CVector3D& vector,CVector3D& result) const -{ - result.X = _11*vector.X + _12*vector.Y + _13*vector.Z; - result.Y = _21*vector.X + _22*vector.Y + _23*vector.Z; - result.Z = _31*vector.X + _32*vector.Y + _33*vector.Z; -} - -/////////////////////////////////////////////////////////////////////////////// -// RotateTransposed: rotate a vector by the transpose of this matrix -CVector3D CMatrix3D::RotateTransposed(const CVector3D& vector) const -{ - CVector3D result; - RotateTransposed(vector,result); - return result; -} - -/////////////////////////////////////////////////////////////////////////////// -// RotateTransposed: rotate a vector by the transpose of this matrix -void CMatrix3D::RotateTransposed(const CVector3D& vector,CVector3D& result) const -{ - result.X = _11*vector.X + _21*vector.Y + _31*vector.Z; - result.Y = _12*vector.X + _22*vector.Y + _32*vector.Z; - result.Z = _13*vector.X + _23*vector.Y + _33*vector.Z; -} - - -void CMatrix3D::GetInverse(CMatrix3D& dst) const -{ - float tmp[12]; // temp array for pairs - float src[16]; // array of transpose source matrix - float det; // determinant - - // transpose matrix - for (int i = 0; i < 4; ++i) { - src[i] = _data[i*4]; - src[i + 4] = _data[i*4 + 1]; - src[i + 8] = _data[i*4 + 2]; - src[i + 12] = _data[i*4 + 3]; - } - - // calculate pairs for first 8 elements (cofactors) - tmp[0] = src[10] * src[15]; - tmp[1] = src[11] * src[14]; - tmp[2] = src[9] * src[15]; - tmp[3] = src[11] * src[13]; - tmp[4] = src[9] * src[14]; - tmp[5] = src[10] * src[13]; - tmp[6] = src[8] * src[15]; - tmp[7] = src[11] * src[12]; - tmp[8] = src[8] * src[14]; - tmp[9] = src[10] * src[12]; - tmp[10] = src[8] * src[13]; - tmp[11] = src[9] * src[12]; - - // calculate first 8 elements (cofactors) - dst._data[0] = tmp[0]*src[5] + tmp[3]*src[6] + tmp[4]*src[7]; - dst._data[0] -= tmp[1]*src[5] + tmp[2]*src[6] + tmp[5]*src[7]; - dst._data[1] = tmp[1]*src[4] + tmp[6]*src[6] + tmp[9]*src[7]; - dst._data[1] -= tmp[0]*src[4] + tmp[7]*src[6] + tmp[8]*src[7]; - dst._data[2] = tmp[2]*src[4] + tmp[7]*src[5] + tmp[10]*src[7]; - dst._data[2] -= tmp[3]*src[4] + tmp[6]*src[5] + tmp[11]*src[7]; - dst._data[3] = tmp[5]*src[4] + tmp[8]*src[5] + tmp[11]*src[6]; - dst._data[3] -= tmp[4]*src[4] + tmp[9]*src[5] + tmp[10]*src[6]; - dst._data[4] = tmp[1]*src[1] + tmp[2]*src[2] + tmp[5]*src[3]; - dst._data[4] -= tmp[0]*src[1] + tmp[3]*src[2] + tmp[4]*src[3]; - dst._data[5] = tmp[0]*src[0] + tmp[7]*src[2] + tmp[8]*src[3]; - dst._data[5] -= tmp[1]*src[0] + tmp[6]*src[2] + tmp[9]*src[3]; - dst._data[6] = tmp[3]*src[0] + tmp[6]*src[1] + tmp[11]*src[3]; - dst._data[6] -= tmp[2]*src[0] + tmp[7]*src[1] + tmp[10]*src[3]; - dst._data[7] = tmp[4]*src[0] + tmp[9]*src[1] + tmp[10]*src[2]; - dst._data[7] -= tmp[5]*src[0] + tmp[8]*src[1] + tmp[11]*src[2]; - - // calculate pairs for second 8 elements (cofactors) - tmp[0] = src[2]*src[7]; - tmp[1] = src[3]*src[6]; - tmp[2] = src[1]*src[7]; - tmp[3] = src[3]*src[5]; - tmp[4] = src[1]*src[6]; - tmp[5] = src[2]*src[5]; - tmp[6] = src[0]*src[7]; - tmp[7] = src[3]*src[4]; - tmp[8] = src[0]*src[6]; - tmp[9] = src[2]*src[4]; - tmp[10] = src[0]*src[5]; - tmp[11] = src[1]*src[4]; - - // calculate second 8 elements (cofactors) - dst._data[8] = tmp[0]*src[13] + tmp[3]*src[14] + tmp[4]*src[15]; - dst._data[8] -= tmp[1]*src[13] + tmp[2]*src[14] + tmp[5]*src[15]; - dst._data[9] = tmp[1]*src[12] + tmp[6]*src[14] + tmp[9]*src[15]; - dst._data[9] -= tmp[0]*src[12] + tmp[7]*src[14] + tmp[8]*src[15]; - dst._data[10] = tmp[2]*src[12] + tmp[7]*src[13] + tmp[10]*src[15]; - dst._data[10]-= tmp[3]*src[12] + tmp[6]*src[13] + tmp[11]*src[15]; - dst._data[11] = tmp[5]*src[12] + tmp[8]*src[13] + tmp[11]*src[14]; - dst._data[11]-= tmp[4]*src[12] + tmp[9]*src[13] + tmp[10]*src[14]; - dst._data[12] = tmp[2]*src[10] + tmp[5]*src[11] + tmp[1]*src[9]; - dst._data[12]-= tmp[4]*src[11] + tmp[0]*src[9] + tmp[3]*src[10]; - dst._data[13] = tmp[8]*src[11] + tmp[0]*src[8] + tmp[7]*src[10]; - dst._data[13]-= tmp[6]*src[10] + tmp[9]*src[11] + tmp[1]*src[8]; - dst._data[14] = tmp[6]*src[9] + tmp[11]*src[11] + tmp[3]*src[8]; - dst._data[14]-= tmp[10]*src[11] + tmp[2]*src[8] + tmp[7]*src[9]; - dst._data[15] = tmp[10]*src[10] + tmp[4]*src[8] + tmp[9]*src[9]; - dst._data[15]-= tmp[8]*src[9] + tmp[11]*src[10] + tmp[5]*src[8]; - - // calculate matrix inverse - det=src[0]*dst._data[0]+src[1]*dst._data[1]+src[2]*dst._data[2]+src[3]*dst._data[3]; - det = 1/det; - for ( int j = 0; j < 16; j++) { - dst._data[j] *= det; - } -} - -void CMatrix3D::Rotate(const CQuaternion& quat) -{ - CMatrix3D rotationMatrix=quat.ToMatrix(); - Concatenate(rotationMatrix); -} - -void CMatrix3D::SetRotation(const CQuaternion& quat) -{ - quat.ToMatrix(*this); -} - - +//*********************************************************** +// +// Name: Matrix3D.Cpp +// Last Update: 31/1/02 +// Author: Poya Manouchehri +// +// Description: A Matrix class used for holding and +// manipulating transformation info. +// +//*********************************************************** + + +#include "Matrix3D.h" +#include "Quaternion.h" + +CMatrix3D::CMatrix3D () +{ +} + +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) +{ + _11=a11; + _12=a12; + _13=a13; + _14=a14; + + _21=a21; + _22=a22; + _23=a23; + _24=a24; + + _31=a31; + _32=a32; + _33=a33; + _34=a34; + + _41=a41; + _42=a42; + _43=a43; + _44=a44; +} + +//Matrix multiplication +CMatrix3D CMatrix3D::operator*(const CMatrix3D& matrix) const +{ + CMatrix3D Temp; + + Temp._11 = _11*matrix._11 + + _12*matrix._21 + + _13*matrix._31 + + _14*matrix._41; + + Temp._12 = _11*matrix._12 + + _12*matrix._22 + + _13*matrix._32 + + _14*matrix._42; + + Temp._13 = _11*matrix._13 + + _12*matrix._23 + + _13*matrix._33 + + _14*matrix._43; + + Temp._14 = _11*matrix._14 + + _12*matrix._24 + + _13*matrix._34 + + _14*matrix._44; + + Temp._21 = _21*matrix._11 + + _22*matrix._21 + + _23*matrix._31 + + _24*matrix._41; + + Temp._22 = _21*matrix._12 + + _22*matrix._22 + + _23*matrix._32 + + _24*matrix._42; + + Temp._23 = _21*matrix._13 + + _22*matrix._23 + + _23*matrix._33 + + _24*matrix._43; + + Temp._24 = _21*matrix._14 + + _22*matrix._24 + + _23*matrix._34 + + _24*matrix._44; + + Temp._31 = _31*matrix._11 + + _32*matrix._21 + + _33*matrix._31 + + _34*matrix._41; + + Temp._32 = _31*matrix._12 + + _32*matrix._22 + + _33*matrix._32 + + _34*matrix._42; + + Temp._33 = _31*matrix._13 + + _32*matrix._23 + + _33*matrix._33 + + _34*matrix._43; + + Temp._34 = _31*matrix._14 + + _32*matrix._24 + + _33*matrix._34 + + _34*matrix._44; + + Temp._41 = _41*matrix._11 + + _42*matrix._21 + + _43*matrix._31 + + _44*matrix._41; + + Temp._42 = _41*matrix._12 + + _42*matrix._22 + + _43*matrix._32 + + _44*matrix._42; + + Temp._43 = _41*matrix._13 + + _42*matrix._23 + + _43*matrix._33 + + _44*matrix._43; + + Temp._44 = _41*matrix._14 + + _42*matrix._24 + + _43*matrix._34 + + _44*matrix._44; + + return Temp; +} + +//Matrix multiplication/assignment +CMatrix3D& CMatrix3D::operator*=(const CMatrix3D& matrix) +{ + Concatenate(matrix); + return *this; +} + +//Matrix scaling +CMatrix3D CMatrix3D::operator*(float f) const +{ + CMatrix3D tmp; + for (int i=0;i<16;i++) { + tmp._data[i]=_data[i]*f; + } + return tmp; +} + +//Matrix scaling/assignment +CMatrix3D& CMatrix3D::operator*=(float f) +{ + for (int i=0;i<16;i++) { + _data[i]*=f; + } + return *this; +} + +//Matrix addition +CMatrix3D CMatrix3D::operator+(const CMatrix3D& m) const +{ + CMatrix3D tmp; + for (int i=0;i<16;i++) { + tmp._data[i]=_data[i]+m._data[i]; + } + return tmp; +} + +//Matrix addition/assignment +CMatrix3D& CMatrix3D::operator+=(const CMatrix3D& m) +{ + for (int i=0;i<16;i++) { + _data[i]+=m._data[i]; + } + return *this; +} + +//Sets the identity matrix +void CMatrix3D::SetIdentity () +{ + _11=1.0f; _12=0.0f; _13=0.0f; _14=0.0f; + _21=0.0f; _22=1.0f; _23=0.0f; _24=0.0f; + _31=0.0f; _32=0.0f; _33=1.0f; _34=0.0f; + _41=0.0f; _42=0.0f; _43=0.0f; _44=1.0f; +} + +//Sets the zero matrix +void CMatrix3D::SetZero () +{ + _11=0.0f; _12=0.0f; _13=0.0f; _14=0.0f; + _21=0.0f; _22=0.0f; _23=0.0f; _24=0.0f; + _31=0.0f; _32=0.0f; _33=0.0f; _34=0.0f; + _41=0.0f; _42=0.0f; _43=0.0f; _44=0.0f; +} + +//The following clear the matrix and set the +//rotation of each of the 3 axes + +void CMatrix3D::SetXRotation (float angle) +{ + float Cos = cosf (angle); + float Sin = sinf (angle); + + _11=1.0f; _12=0.0f; _13=0.0f; _14=0.0f; + _21=0.0f; _22=Cos; _23=-Sin; _24=0.0f; + _31=0.0f; _32=Sin; _33=Cos; _34=0.0f; + _41=0.0f; _42=0.0f; _43=0.0f; _44=1.0f; +} + +void CMatrix3D::SetYRotation (float angle) +{ + float Cos = cosf (angle); + float Sin = sinf (angle); + + _11=Cos; _12=0.0f; _13=Sin; _14=0.0f; + _21=0.0f; _22=1.0f; _23=0.0f; _24=0.0f; + _31=-Sin; _32=0.0f; _33=Cos; _34=0.0f; + _41=0.0f; _42=0.0f; _43=0.0f; _44=1.0f; +} + +void CMatrix3D::SetZRotation (float angle) +{ + float Cos = cosf (angle); + float Sin = sinf (angle); + + _11=Cos; _12=-Sin; _13=0.0f; _14=0.0f; + _21=Sin; _22=Cos; _23=0.0f; _24=0.0f; + _31=0.0f; _32=0.0f; _33=1.0f; _34=0.0f; + _41=0.0f; _42=0.0f; _43=0.0f; _44=1.0f; +} + +//The following apply a rotation to the matrix +//about each of the axes; + +void CMatrix3D::RotateX (float angle) +{ + CMatrix3D Temp; + Temp.SetXRotation (angle); + Concatenate(Temp); +} + +void CMatrix3D::RotateY (float angle) +{ + CMatrix3D Temp; + Temp.SetYRotation (angle); + Concatenate(Temp); +} + +void CMatrix3D::RotateZ (float angle) +{ + CMatrix3D Temp; + Temp.SetZRotation(angle); + Concatenate(Temp); +} + +//Sets the translation of the matrix +void CMatrix3D::SetTranslation (float x, float y, float z) +{ + _11=1.0f; _12=0.0f; _13=0.0f; _14=x; + _21=0.0f; _22=1.0f; _23=0.0f; _24=y; + _31=0.0f; _32=0.0f; _33=1.0f; _34=z; + _41=0.0f; _42=0.0f; _43=0.0f; _44=1.0f; +} + +void CMatrix3D::SetTranslation(const CVector3D& vector) +{ + SetTranslation(vector.X, vector.Y, vector.Z); +} + +//Applies a translation to the matrix +void CMatrix3D::Translate(float x, float y, float z) +{ + CMatrix3D Temp; + Temp.SetTranslation(x,y,z); + Concatenate(Temp); +} + +void CMatrix3D::Translate(const CVector3D &vector) +{ + Translate(vector.X,vector.Y,vector.Z); +} + +void CMatrix3D::Concatenate(const CMatrix3D& m) +{ + (*this)=m*(*this); +} + +CVector3D CMatrix3D::GetTranslation() const +{ + CVector3D Temp; + + Temp.X = _14; + Temp.Y = _24; + Temp.Z = _34; + + return Temp; +} + +//Clears and sets the scaling of the matrix +void CMatrix3D::SetScaling (float x_scale, float y_scale, float z_scale) +{ + _11=x_scale; _12=0.0f; _13=0.0f; _14=0.0f; + _21=0.0f; _22=y_scale; _23=0.0f; _24=0.0f; + _31=0.0f; _32=0.0f; _33=z_scale; _34=0.0f; + _41=0.0f; _42=0.0f; _43=0.0f; _44=1.0f; +} + +//Scales the matrix +void CMatrix3D::Scale (float x_scale, float y_scale, float z_scale) +{ + CMatrix3D Temp; + Temp.SetScaling(x_scale,y_scale,z_scale); + Concatenate(Temp); +} + +//Returns the transpose of the matrix. For orthonormal +//matrices, this is the same is the inverse matrix +void CMatrix3D::GetTranspose(CMatrix3D& result) const +{ + result._11 = _11; + result._21 = _12; + result._31 = _13; + result._41 = _14; + + result._12 = _21; + result._22 = _22; + result._32 = _23; + result._42 = _24; + + result._13 = _31; + result._23 = _32; + result._33 = _33; + result._43 = _34; + + result._14 = _41; + result._24 = _42; + result._34 = _43; + result._44 = _44; +} + + +//Get a vector which points to the left of the matrix +CVector3D CMatrix3D::GetLeft () const +{ + CVector3D Temp; + + Temp.X = -_11; + Temp.Y = -_21; + Temp.Z = -_31; + + return Temp; +} + +//Get a vector which points up from the matrix +CVector3D CMatrix3D::GetUp () const +{ + CVector3D Temp; + + Temp.X = _12; + Temp.Y = _22; + Temp.Z = _32; + + return Temp; +} + +//Get a vector which points to front of the matrix +CVector3D CMatrix3D::GetIn () const +{ + CVector3D Temp; + + Temp.X = _13; + Temp.Y = _23; + Temp.Z = _33; + + return Temp; +} + + +//Transform a vector by this matrix +CVector3D CMatrix3D::Transform (const CVector3D &vector) const +{ + CVector3D result; + Transform(vector,result); + return result; +} + +void CMatrix3D::Transform(const CVector3D& vector,CVector3D& result) const +{ + result.X = _11*vector.X + _12*vector.Y + _13*vector.Z + _14; + result.Y = _21*vector.X + _22*vector.Y + _23*vector.Z + _24; + result.Z = _31*vector.X + _32*vector.Y + _33*vector.Z + _34; +} + +//Transform a vector by this matrix +CVector4D CMatrix3D::Transform(const CVector4D &vector) const +{ + CVector4D result; + Transform(vector,result); + return result; +} + +void CMatrix3D::Transform(const CVector4D& vector,CVector4D& result) const +{ + result[0] = _11*vector[0] + _12*vector[1] + _13*vector[2] + _14*vector[3]; + result[1] = _21*vector[0] + _22*vector[1] + _23*vector[2] + _24*vector[3]; + result[2] = _31*vector[0] + _32*vector[1] + _33*vector[2] + _34*vector[3]; + result[3] = _41*vector[0] + _42*vector[1] + _43*vector[2] + _44*vector[3]; +} + +//Only rotate (not translate) a vector by this matrix +CVector3D CMatrix3D::Rotate(const CVector3D& vector) const +{ + CVector3D result; + Rotate(vector,result); + return result; +} + +void CMatrix3D::Rotate(const CVector3D& vector,CVector3D& result) const +{ + result.X = _11*vector.X + _12*vector.Y + _13*vector.Z; + result.Y = _21*vector.X + _22*vector.Y + _23*vector.Z; + result.Z = _31*vector.X + _32*vector.Y + _33*vector.Z; +} + +/////////////////////////////////////////////////////////////////////////////// +// RotateTransposed: rotate a vector by the transpose of this matrix +CVector3D CMatrix3D::RotateTransposed(const CVector3D& vector) const +{ + CVector3D result; + RotateTransposed(vector,result); + return result; +} + +/////////////////////////////////////////////////////////////////////////////// +// RotateTransposed: rotate a vector by the transpose of this matrix +void CMatrix3D::RotateTransposed(const CVector3D& vector,CVector3D& result) const +{ + result.X = _11*vector.X + _21*vector.Y + _31*vector.Z; + result.Y = _12*vector.X + _22*vector.Y + _32*vector.Z; + result.Z = _13*vector.X + _23*vector.Y + _33*vector.Z; +} + + +void CMatrix3D::GetInverse(CMatrix3D& dst) const +{ + float tmp[12]; // temp array for pairs + float src[16]; // array of transpose source matrix + float det; // determinant + + // transpose matrix + for (int i = 0; i < 4; ++i) { + src[i] = _data[i*4]; + src[i + 4] = _data[i*4 + 1]; + src[i + 8] = _data[i*4 + 2]; + src[i + 12] = _data[i*4 + 3]; + } + + // calculate pairs for first 8 elements (cofactors) + tmp[0] = src[10] * src[15]; + tmp[1] = src[11] * src[14]; + tmp[2] = src[9] * src[15]; + tmp[3] = src[11] * src[13]; + tmp[4] = src[9] * src[14]; + tmp[5] = src[10] * src[13]; + tmp[6] = src[8] * src[15]; + tmp[7] = src[11] * src[12]; + tmp[8] = src[8] * src[14]; + tmp[9] = src[10] * src[12]; + tmp[10] = src[8] * src[13]; + tmp[11] = src[9] * src[12]; + + // calculate first 8 elements (cofactors) + dst._data[0] = tmp[0]*src[5] + tmp[3]*src[6] + tmp[4]*src[7]; + dst._data[0] -= tmp[1]*src[5] + tmp[2]*src[6] + tmp[5]*src[7]; + dst._data[1] = tmp[1]*src[4] + tmp[6]*src[6] + tmp[9]*src[7]; + dst._data[1] -= tmp[0]*src[4] + tmp[7]*src[6] + tmp[8]*src[7]; + dst._data[2] = tmp[2]*src[4] + tmp[7]*src[5] + tmp[10]*src[7]; + dst._data[2] -= tmp[3]*src[4] + tmp[6]*src[5] + tmp[11]*src[7]; + dst._data[3] = tmp[5]*src[4] + tmp[8]*src[5] + tmp[11]*src[6]; + dst._data[3] -= tmp[4]*src[4] + tmp[9]*src[5] + tmp[10]*src[6]; + dst._data[4] = tmp[1]*src[1] + tmp[2]*src[2] + tmp[5]*src[3]; + dst._data[4] -= tmp[0]*src[1] + tmp[3]*src[2] + tmp[4]*src[3]; + dst._data[5] = tmp[0]*src[0] + tmp[7]*src[2] + tmp[8]*src[3]; + dst._data[5] -= tmp[1]*src[0] + tmp[6]*src[2] + tmp[9]*src[3]; + dst._data[6] = tmp[3]*src[0] + tmp[6]*src[1] + tmp[11]*src[3]; + dst._data[6] -= tmp[2]*src[0] + tmp[7]*src[1] + tmp[10]*src[3]; + dst._data[7] = tmp[4]*src[0] + tmp[9]*src[1] + tmp[10]*src[2]; + dst._data[7] -= tmp[5]*src[0] + tmp[8]*src[1] + tmp[11]*src[2]; + + // calculate pairs for second 8 elements (cofactors) + tmp[0] = src[2]*src[7]; + tmp[1] = src[3]*src[6]; + tmp[2] = src[1]*src[7]; + tmp[3] = src[3]*src[5]; + tmp[4] = src[1]*src[6]; + tmp[5] = src[2]*src[5]; + tmp[6] = src[0]*src[7]; + tmp[7] = src[3]*src[4]; + tmp[8] = src[0]*src[6]; + tmp[9] = src[2]*src[4]; + tmp[10] = src[0]*src[5]; + tmp[11] = src[1]*src[4]; + + // calculate second 8 elements (cofactors) + dst._data[8] = tmp[0]*src[13] + tmp[3]*src[14] + tmp[4]*src[15]; + dst._data[8] -= tmp[1]*src[13] + tmp[2]*src[14] + tmp[5]*src[15]; + dst._data[9] = tmp[1]*src[12] + tmp[6]*src[14] + tmp[9]*src[15]; + dst._data[9] -= tmp[0]*src[12] + tmp[7]*src[14] + tmp[8]*src[15]; + dst._data[10] = tmp[2]*src[12] + tmp[7]*src[13] + tmp[10]*src[15]; + dst._data[10]-= tmp[3]*src[12] + tmp[6]*src[13] + tmp[11]*src[15]; + dst._data[11] = tmp[5]*src[12] + tmp[8]*src[13] + tmp[11]*src[14]; + dst._data[11]-= tmp[4]*src[12] + tmp[9]*src[13] + tmp[10]*src[14]; + dst._data[12] = tmp[2]*src[10] + tmp[5]*src[11] + tmp[1]*src[9]; + dst._data[12]-= tmp[4]*src[11] + tmp[0]*src[9] + tmp[3]*src[10]; + dst._data[13] = tmp[8]*src[11] + tmp[0]*src[8] + tmp[7]*src[10]; + dst._data[13]-= tmp[6]*src[10] + tmp[9]*src[11] + tmp[1]*src[8]; + dst._data[14] = tmp[6]*src[9] + tmp[11]*src[11] + tmp[3]*src[8]; + dst._data[14]-= tmp[10]*src[11] + tmp[2]*src[8] + tmp[7]*src[9]; + dst._data[15] = tmp[10]*src[10] + tmp[4]*src[8] + tmp[9]*src[9]; + dst._data[15]-= tmp[8]*src[9] + tmp[11]*src[10] + tmp[5]*src[8]; + + // calculate matrix inverse + det=src[0]*dst._data[0]+src[1]*dst._data[1]+src[2]*dst._data[2]+src[3]*dst._data[3]; + det = 1/det; + for ( int j = 0; j < 16; j++) { + dst._data[j] *= det; + } +} + +void CMatrix3D::Rotate(const CQuaternion& quat) +{ + CMatrix3D rotationMatrix=quat.ToMatrix(); + Concatenate(rotationMatrix); +} + +void CMatrix3D::SetRotation(const CQuaternion& quat) +{ + quat.ToMatrix(*this); +} + + diff --git a/source/maths/Matrix3D.h b/source/maths/Matrix3D.h index 993ce900d4..b76a7db45c 100755 --- a/source/maths/Matrix3D.h +++ b/source/maths/Matrix3D.h @@ -1,123 +1,123 @@ -#ifndef __MATRIX3D_H -#define __MATRIX3D_H - -#include -#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 +#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 diff --git a/source/maths/Quaternion.cpp b/source/maths/Quaternion.cpp index 19ee1781d1..84ab317af7 100755 --- a/source/maths/Quaternion.cpp +++ b/source/maths/Quaternion.cpp @@ -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; +} diff --git a/source/maths/Quaternion.h b/source/maths/Quaternion.h index 260b27c879..81c5ff8d56 100755 --- a/source/maths/Quaternion.h +++ b/source/maths/Quaternion.h @@ -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); }; diff --git a/source/ps/Overlay.h b/source/ps/Overlay.h index 04986cb880..e45d1d949f 100755 --- a/source/ps/Overlay.h +++ b/source/ps/Overlay.h @@ -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; diff --git a/source/renderer/ModelRData.cpp b/source/renderer/ModelRData.cpp index 79643a6c04..6c12d72e10 100755 --- a/source/renderer/ModelRData.cpp +++ b/source/renderer/ModelRData.cpp @@ -1,261 +1,261 @@ -#include -#include -#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; jGetNumFaces(); 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 (xmax) 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 && iGetModelDef(); - - // 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; jGetBoneMatrices()); - 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; jGetNumVertices()*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 IntFloatPair; -static std::vector 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;im_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 +#include +#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; jGetNumFaces(); 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 (xmax) 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 && iGetModelDef(); + + // 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; jGetBoneMatrices()); + 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; jGetNumVertices()*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 IntFloatPair; +static std::vector 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;im_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 #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; }; diff --git a/source/renderer/PBuffer.cpp b/source/renderer/PBuffer.cpp index e07847327b..708ce7328e 100755 --- a/source/renderer/PBuffer.cpp +++ b/source/renderer/PBuffer.cpp @@ -1,385 +1,385 @@ -#include "pbuffer.h" - -#ifdef _WIN32 -#include -#include -#include -#include - -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 +#include +#include +#include + +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; +} diff --git a/source/renderer/PBuffer.h b/source/renderer/PBuffer.h index d70021f07e..61d5d921d3 100755 --- a/source/renderer/PBuffer.h +++ b/source/renderer/PBuffer.h @@ -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 diff --git a/source/renderer/PatchRData.cpp b/source/renderer/PatchRData.cpp index 608eb64bba..d32f2fc6c3 100755 --- a/source/renderer/PatchRData.cpp +++ b/source/renderer/PatchRData.cpp @@ -1,553 +1,553 @@ -#pragma warning(disable:4786) - -#include -#include -#include -#include "res/tex.h" -#include "Renderer.h" -#include "PatchRData.h" -#include "AlphaMapCalculator.h" - -const int BlendOffsets[8][2] = { - { 0, -1 }, - { -1, -1 }, - { -1, 0 }, - { -1, 1 }, - { 0, 1 }, - { 1, 1 }, - { 1, 0 }, - { 1, -1 } -}; - - -CPatchRData::CPatchRData(CPatch* patch) : m_Patch(patch), m_Vertices(0), m_VBBase(0), m_VBBlends(0) -{ - assert(patch); - Build(); -} - -CPatchRData::~CPatchRData() -{ - delete[] m_Vertices; - if (m_VBBase) glDeleteBuffersARB(1,(GLuint*) &m_VBBase); - if (m_VBBlends) glDeleteBuffersARB(1,(GLuint*) &m_VBBlends); -} - - -static Handle GetTerrainTileTexture(CTerrain* terrain,int gx,int gz) -{ - CMiniPatch* mp=terrain->GetTile(gx,gz); - return mp ? mp->Tex1 : 0; -} - -bool QueryAdjacency(int x,int y,Handle h,Handle* texgrid) -{ - for (int j=y-1;j<=y+1;j++) { - for (int i=x-1;i<=x+1;i++) { - if (i<0 || i>PATCH_SIZE+1 || j<0 || j>PATCH_SIZE+1) { - continue; - } - - if (texgrid[j*(PATCH_SIZE+2)+i]==h) { - return true; - } - } - } - return false; -} - -struct STmpSplat { - Handle m_Texture; - u16 m_Indices[4]; -}; - -void CPatchRData::BuildBlends() -{ - m_BlendIndices.clear(); - m_BlendSplats.clear(); - m_BlendVertices.clear(); - - // get index of this patch - int px=m_Patch->m_X; - int pz=m_Patch->m_Z; - - CTerrain* terrain=m_Patch->m_Parent; - - // temporary list of splats - std::vector splats; - // set of textures used for splats - std::set splatTextures; - - // for each tile in patch .. - for (int j=0;jm_MiniPatches[j][i]; - mp->GetTileIndex(gx,gz); - - // build list of textures of higher priority than current tile that are used by neighbouring tiles - std::vector neighbourTextures; - for (int m=-1;m<=1;m++) { - for (int k=-1;k<=1;k++) { - CMiniPatch* nmp=terrain->GetTile(gx+k,gz+m); - if (nmp) { - if (nmp->Tex1Priority>mp->Tex1Priority || (nmp->Tex1Priority==mp->Tex1Priority && nmp->Tex1>mp->Tex1)) { - STex tex; - tex.m_Handle=nmp->Tex1; - tex.m_Priority=nmp->Tex1Priority; - if (std::find(neighbourTextures.begin(),neighbourTextures.end(),tex)==neighbourTextures.end()) { - neighbourTextures.push_back(tex); - } - } - } - } - } - if (neighbourTextures.size()>0) { - u32 count=neighbourTextures.size(); - // sort textures from lowest to highest priority - std::sort(neighbourTextures.begin(),neighbourTextures.end()); - - // for each of the neighbouring textures .. - for (uint k=0;k::iterator iter=splatTextures.begin(); - for (;iter!=splatTextures.end();++iter) { - Handle tex=*iter; - - SSplat& splat=m_BlendSplats[splatCount]; - splat.m_IndexStart=m_BlendIndices.size(); - splat.m_Texture=tex; - - for (uint k=0;k textures; - Handle texgrid[PATCH_SIZE][PATCH_SIZE]; - for (int j=0;jm_MiniPatches[j][i].Tex1; - texgrid[j][i]=h; - if (std::find(textures.begin(),textures.end(),h)==textures.end()) { - textures.push_back(h); - } - } - } - - // now build base splats from interior textures - m_Splats.resize(textures.size()); - - for (uint i=0;imax) 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 void BuildHeightmapNormals(int size,u16 *heightmap,CVector3D* normals) -{ - int x, y; - int sm=size-1; - - for(y = 0;y < size; y++) - for(x = 0; x < size; x++) { - - // Access current normalmap grid point - CVector3D* N = &normals[y*size+x]; - - // Compute normal by using the height differential - u16 h1=(x==sm) ? heightmap[y*size+x] : heightmap[y*size+x+1]; - u16 h2=(y==sm) ? heightmap[y*size+x] : heightmap[(y+1)*size+x]; - u16 h3=(x==0) ? heightmap[y*size+x] : heightmap[y*size+x-1]; - u16 h4=(y==0) ? heightmap[y*size+x] : heightmap[(y-1)*size+x+1]; - N->X = (h3-h1)*HEIGHT_SCALE; - N->Y = CELL_SIZE; - N->Z = (h4-h2)*HEIGHT_SCALE; - - // Normalize it - float len=N->GetLength(); - if (len>0) { - (*N)*=1.0f/len; - } else { - *N=CVector3D(0,0,0); - } - } -} - -void CPatchRData::BuildVertices() -{ - // number of vertices in each direction in each patch - int vsize=PATCH_SIZE+1; - - if (!m_Vertices) { - m_Vertices=new SBaseVertex[vsize*vsize]; - } - SBaseVertex* vertices=m_Vertices; - - - // get index of this patch - u32 px=m_Patch->m_X; - u32 pz=m_Patch->m_Z; - - CTerrain* terrain=m_Patch->m_Parent; - u32 mapSize=terrain->GetVerticesPerSide(); - - // build vertices - for (int j=0; jCalcPosition(ix,iz,pos); - terrain->CalcNormal(ix,iz,normal); - - RGBColor c; - g_Renderer.m_SHCoeffsTerrain.Evaluate(normal,c); - - int v=(j*vsize)+i; - vertices[v].m_UVs[0]=i*0.125f; - vertices[v].m_UVs[1]=j*0.125f; - vertices[v].m_Color=ConvertColor(c); - vertices[v].m_Position=pos; - } - } - - if (g_Renderer.m_Caps.m_VBO) { - if (!m_VBBase) { - glGenBuffersARB(1,(GLuint*) &m_VBBase); - glBindBufferARB(GL_ARRAY_BUFFER_ARB,m_VBBase); - glBufferDataARB(GL_ARRAY_BUFFER_ARB,vsize*vsize*sizeof(SBaseVertex),0,GL_STATIC_DRAW_ARB); - } - glBindBufferARB(GL_ARRAY_BUFFER_ARB,m_VBBase); - glBufferSubDataARB(GL_ARRAY_BUFFER_ARB,0,vsize*vsize*sizeof(SBaseVertex),m_Vertices); - } -} - -void CPatchRData::Build() -{ - BuildVertices(); - BuildIndices(); - BuildBlends(); -} - -void CPatchRData::Update() -{ - if (m_UpdateFlags!=0) { - // TODO,RC 11/04/04 - need to only rebuild necessary bits of renderdata rather - // than everything; it's complicated slightly because the blends are dependent - // on both vertex and index data - BuildVertices(); - BuildIndices(); - BuildBlends(); - - m_UpdateFlags=0; - } -} - -void CPatchRData::RenderBase() -{ - assert(m_UpdateFlags==0); - - u8* base; - if (g_Renderer.m_Caps.m_VBO) { - glBindBufferARB(GL_ARRAY_BUFFER_ARB,m_VBBase); - base=0; - } else { - base=(u8*) &m_Vertices[0]; - } - - // setup data pointers - u32 stride=sizeof(SBaseVertex); - glVertexPointer(3,GL_FLOAT,stride,base+offsetof(SBaseVertex,m_Position)); - glColorPointer(4,GL_UNSIGNED_BYTE,stride,base+offsetof(SBaseVertex,m_Color)); - glTexCoordPointer(2,GL_FLOAT,stride,base+offsetof(SBaseVertex,m_UVs[0])); - - // render each splat - for (uint i=0;i +#include +#include +#include "res/tex.h" +#include "Renderer.h" +#include "PatchRData.h" +#include "AlphaMapCalculator.h" + +const int BlendOffsets[8][2] = { + { 0, -1 }, + { -1, -1 }, + { -1, 0 }, + { -1, 1 }, + { 0, 1 }, + { 1, 1 }, + { 1, 0 }, + { 1, -1 } +}; + + +CPatchRData::CPatchRData(CPatch* patch) : m_Patch(patch), m_Vertices(0), m_VBBase(0), m_VBBlends(0) +{ + assert(patch); + Build(); +} + +CPatchRData::~CPatchRData() +{ + delete[] m_Vertices; + if (m_VBBase) glDeleteBuffersARB(1,(GLuint*) &m_VBBase); + if (m_VBBlends) glDeleteBuffersARB(1,(GLuint*) &m_VBBlends); +} + + +static Handle GetTerrainTileTexture(CTerrain* terrain,int gx,int gz) +{ + CMiniPatch* mp=terrain->GetTile(gx,gz); + return mp ? mp->Tex1 : 0; +} + +bool QueryAdjacency(int x,int y,Handle h,Handle* texgrid) +{ + for (int j=y-1;j<=y+1;j++) { + for (int i=x-1;i<=x+1;i++) { + if (i<0 || i>PATCH_SIZE+1 || j<0 || j>PATCH_SIZE+1) { + continue; + } + + if (texgrid[j*(PATCH_SIZE+2)+i]==h) { + return true; + } + } + } + return false; +} + +struct STmpSplat { + Handle m_Texture; + u16 m_Indices[4]; +}; + +void CPatchRData::BuildBlends() +{ + m_BlendIndices.clear(); + m_BlendSplats.clear(); + m_BlendVertices.clear(); + + // get index of this patch + int px=m_Patch->m_X; + int pz=m_Patch->m_Z; + + CTerrain* terrain=m_Patch->m_Parent; + + // temporary list of splats + std::vector splats; + // set of textures used for splats + std::set splatTextures; + + // for each tile in patch .. + for (int j=0;jm_MiniPatches[j][i]; + mp->GetTileIndex(gx,gz); + + // build list of textures of higher priority than current tile that are used by neighbouring tiles + std::vector neighbourTextures; + for (int m=-1;m<=1;m++) { + for (int k=-1;k<=1;k++) { + CMiniPatch* nmp=terrain->GetTile(gx+k,gz+m); + if (nmp) { + if (nmp->Tex1Priority>mp->Tex1Priority || (nmp->Tex1Priority==mp->Tex1Priority && nmp->Tex1>mp->Tex1)) { + STex tex; + tex.m_Handle=nmp->Tex1; + tex.m_Priority=nmp->Tex1Priority; + if (std::find(neighbourTextures.begin(),neighbourTextures.end(),tex)==neighbourTextures.end()) { + neighbourTextures.push_back(tex); + } + } + } + } + } + if (neighbourTextures.size()>0) { + u32 count=neighbourTextures.size(); + // sort textures from lowest to highest priority + std::sort(neighbourTextures.begin(),neighbourTextures.end()); + + // for each of the neighbouring textures .. + for (uint k=0;k::iterator iter=splatTextures.begin(); + for (;iter!=splatTextures.end();++iter) { + Handle tex=*iter; + + SSplat& splat=m_BlendSplats[splatCount]; + splat.m_IndexStart=m_BlendIndices.size(); + splat.m_Texture=tex; + + for (uint k=0;k textures; + Handle texgrid[PATCH_SIZE][PATCH_SIZE]; + for (int j=0;jm_MiniPatches[j][i].Tex1; + texgrid[j][i]=h; + if (std::find(textures.begin(),textures.end(),h)==textures.end()) { + textures.push_back(h); + } + } + } + + // now build base splats from interior textures + m_Splats.resize(textures.size()); + + for (uint i=0;imax) 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 void BuildHeightmapNormals(int size,u16 *heightmap,CVector3D* normals) +{ + int x, y; + int sm=size-1; + + for(y = 0;y < size; y++) + for(x = 0; x < size; x++) { + + // Access current normalmap grid point + CVector3D* N = &normals[y*size+x]; + + // Compute normal by using the height differential + u16 h1=(x==sm) ? heightmap[y*size+x] : heightmap[y*size+x+1]; + u16 h2=(y==sm) ? heightmap[y*size+x] : heightmap[(y+1)*size+x]; + u16 h3=(x==0) ? heightmap[y*size+x] : heightmap[y*size+x-1]; + u16 h4=(y==0) ? heightmap[y*size+x] : heightmap[(y-1)*size+x+1]; + N->X = (h3-h1)*HEIGHT_SCALE; + N->Y = CELL_SIZE; + N->Z = (h4-h2)*HEIGHT_SCALE; + + // Normalize it + float len=N->GetLength(); + if (len>0) { + (*N)*=1.0f/len; + } else { + *N=CVector3D(0,0,0); + } + } +} + +void CPatchRData::BuildVertices() +{ + // number of vertices in each direction in each patch + int vsize=PATCH_SIZE+1; + + if (!m_Vertices) { + m_Vertices=new SBaseVertex[vsize*vsize]; + } + SBaseVertex* vertices=m_Vertices; + + + // get index of this patch + u32 px=m_Patch->m_X; + u32 pz=m_Patch->m_Z; + + CTerrain* terrain=m_Patch->m_Parent; + u32 mapSize=terrain->GetVerticesPerSide(); + + // build vertices + for (int j=0; jCalcPosition(ix,iz,pos); + terrain->CalcNormal(ix,iz,normal); + + RGBColor c; + g_Renderer.m_SHCoeffsTerrain.Evaluate(normal,c); + + int v=(j*vsize)+i; + vertices[v].m_UVs[0]=i*0.125f; + vertices[v].m_UVs[1]=j*0.125f; + vertices[v].m_Color=ConvertColor(c); + vertices[v].m_Position=pos; + } + } + + if (g_Renderer.m_Caps.m_VBO) { + if (!m_VBBase) { + glGenBuffersARB(1,(GLuint*) &m_VBBase); + glBindBufferARB(GL_ARRAY_BUFFER_ARB,m_VBBase); + glBufferDataARB(GL_ARRAY_BUFFER_ARB,vsize*vsize*sizeof(SBaseVertex),0,GL_STATIC_DRAW_ARB); + } + glBindBufferARB(GL_ARRAY_BUFFER_ARB,m_VBBase); + glBufferSubDataARB(GL_ARRAY_BUFFER_ARB,0,vsize*vsize*sizeof(SBaseVertex),m_Vertices); + } +} + +void CPatchRData::Build() +{ + BuildVertices(); + BuildIndices(); + BuildBlends(); +} + +void CPatchRData::Update() +{ + if (m_UpdateFlags!=0) { + // TODO,RC 11/04/04 - need to only rebuild necessary bits of renderdata rather + // than everything; it's complicated slightly because the blends are dependent + // on both vertex and index data + BuildVertices(); + BuildIndices(); + BuildBlends(); + + m_UpdateFlags=0; + } +} + +void CPatchRData::RenderBase() +{ + assert(m_UpdateFlags==0); + + u8* base; + if (g_Renderer.m_Caps.m_VBO) { + glBindBufferARB(GL_ARRAY_BUFFER_ARB,m_VBBase); + base=0; + } else { + base=(u8*) &m_Vertices[0]; + } + + // setup data pointers + u32 stride=sizeof(SBaseVertex); + glVertexPointer(3,GL_FLOAT,stride,base+offsetof(SBaseVertex,m_Position)); + glColorPointer(4,GL_UNSIGNED_BYTE,stride,base+offsetof(SBaseVertex,m_Color)); + glTexCoordPointer(2,GL_FLOAT,stride,base+offsetof(SBaseVertex,m_UVs[0])); + + // render each splat + for (uint i=0;i -#include -#include -#include "Renderer.h" -#include "TransparencyRenderer.h" -#include "Terrain.h" -#include "Matrix3D.h" -#include "Camera.h" -#include "PatchRData.h" -#include "Texture.h" -#include "LightEnv.h" - -#include "Model.h" -#include "ModelDef.h" - -#include "ogl.h" -#include "res/mem.h" -#include "res/tex.h" - -#ifdef _WIN32 -#include "pbuffer.h" -#endif - -struct TGAHeader { - // header stuff - unsigned char iif_size; - unsigned char cmap_type; - unsigned char image_type; - unsigned char pad[5]; - - // origin : unused - unsigned short d_x_origin; - unsigned short d_y_origin; - - // dimensions - unsigned short width; - unsigned short height; - - // bits per pixel : 16, 24 or 32 - unsigned char bpp; - - // image descriptor : Bits 3-0: size of alpha channel - // Bit 4: must be 0 (reserved) - // Bit 5: should be 0 (origin) - // Bits 6-7: should be 0 (interleaving) - unsigned char image_descriptor; -}; - -static bool saveTGA(const char* filename,int width,int height,unsigned char* data) -{ - FILE* fp=fopen(filename,"wb"); - if (!fp) return false; - - // fill file header - TGAHeader header; - header.iif_size=0; - header.cmap_type=0; - header.image_type=2; - memset(header.pad,0,sizeof(header.pad)); - header.d_x_origin=0; - header.d_y_origin=0; - header.width=width; - header.height=height; - header.bpp=24; - header.image_descriptor=0; - - if (fwrite(&header,sizeof(TGAHeader),1,fp)!=1) { - fclose(fp); - return false; - } - - // write data - if (fwrite(data,width*height*3,1,fp)!=1) { - fclose(fp); - return false; - } - - // return success .. - fclose(fp); - return true; -} - -extern CTerrain g_Terrain; - - -CRenderer::CRenderer () -{ - m_Width=0; - m_Height=0; - m_Depth=0; - m_FrameCounter=0; - m_TerrainRenderMode=SOLID; - m_ModelRenderMode=SOLID; - m_ClearColor[0]=m_ClearColor[1]=m_ClearColor[2]=m_ClearColor[3]=0; - m_ShadowMap=0; - m_Options.m_NoVBO=false; - m_Options.m_NoPBuffer=false; - m_Options.m_Shadows=false; - m_Options.m_ShadowColor=RGBColor(0.4f,0.4f,0.4f); -} - -CRenderer::~CRenderer () -{ -} - - -/////////////////////////////////////////////////////////////////////////////////// -// EnumCaps: build card cap bits -void CRenderer::EnumCaps() -{ - // assume support for nothing - m_Caps.m_VBO=false; - m_Caps.m_TextureBorderClamp=false; - m_Caps.m_PBuffer=false; - m_Caps.m_GenerateMipmaps=false; - - // now start querying extensions - if (!m_Options.m_NoVBO) { - if (oglExtAvail("GL_ARB_vertex_buffer_object")) { - m_Caps.m_VBO=true; - } - } - if (oglExtAvail("GL_ARB_texture_border_clamp")) { - m_Caps.m_TextureBorderClamp=true; - } - if (oglExtAvail("GL_SGIS_generate_mipmap")) { - m_Caps.m_GenerateMipmaps=true; - } - - if (!m_Options.m_NoPBuffer) { - extern bool PBufferQuery(); - if (PBufferQuery()) { - m_Caps.m_PBuffer=true; - } - } -} - -bool CRenderer::Open(int width, int height, int depth) -{ - m_Width = width; - m_Height = height; - m_Depth = depth; - - // set packing parameters - glPixelStorei(GL_PACK_ALIGNMENT,1); - glPixelStorei(GL_UNPACK_ALIGNMENT,1); - - // setup default state - glDepthFunc(GL_LEQUAL); - glEnable(GL_DEPTH_TEST); - glCullFace(GL_BACK); - glFrontFace(GL_CCW); - glEnable(GL_CULL_FACE); - glClearColor(0.0f,0.0f,0.0f,0.0f); - - // query card capabilities - EnumCaps(); - -#ifdef _WIN32 - if (m_Caps.m_PBuffer) { - // TODO, RC - query max pbuffer size - PBufferInit(1024,1024,0,32,16,0); - } -#endif - return true; -} - -void CRenderer::Close() -{ -} - -// resize renderer view -void CRenderer::Resize(int width,int height) -{ - m_Width = width; - m_Height = height; - if (m_ShadowMap) { - glDeleteTextures(1,(GLuint*) &m_ShadowMap); - m_ShadowMap=0; - } -} - -////////////////////////////////////////////////////////////////////////////////////////// -// SetOptionBool: set boolean renderer option -void CRenderer::SetOptionBool(enum Option opt,bool value) -{ - switch (opt) { - case OPT_NOVBO: - m_Options.m_NoVBO=value; - break; - case OPT_NOPBUFFER: - m_Options.m_NoPBuffer=value; - break; - case OPT_SHADOWS: - m_Options.m_Shadows=value; - break; - } -} - -////////////////////////////////////////////////////////////////////////////////////////// -// GetOptionBool: get boolean renderer option -bool CRenderer::GetOptionBool(enum Option opt) const -{ - switch (opt) { - case OPT_NOVBO: - return m_Options.m_NoVBO; - case OPT_NOPBUFFER: - return m_Options.m_NoPBuffer; - case OPT_SHADOWS: - return m_Options.m_Shadows; - } - - return false; -} - -////////////////////////////////////////////////////////////////////////////////////////// -// SetOptionColor: set color renderer option -void CRenderer::SetOptionColor(enum Option opt,const RGBColor& value) -{ - switch (opt) { - case OPT_SHADOWCOLOR: - m_Options.m_ShadowColor=value; - break; - } -} - -////////////////////////////////////////////////////////////////////////////////////////// -// GetOptionColor: get color renderer option -const RGBColor& CRenderer::GetOptionColor(enum Option opt) const -{ - static const RGBColor defaultColor(1.0f,1.0f,1.0f); - - switch (opt) { - case OPT_SHADOWCOLOR: - return m_Options.m_ShadowColor; - } - - return defaultColor; -} - -////////////////////////////////////////////////////////////////////////////////////////// -// BeginFrame: signal frame start -void CRenderer::BeginFrame() -{ - // bump frame counter - m_FrameCounter++; - - // zero out all the per-frame stats - m_Stats.Reset(); - - // calculate coefficients for terrain and unit lighting - m_SHCoeffsUnits.Clear(); - m_SHCoeffsTerrain.Clear(); - - if (m_LightEnv) { - CVector3D dirlight; - m_LightEnv->GetSunDirection(dirlight); - m_SHCoeffsUnits.AddDirectionalLight(dirlight,m_LightEnv->m_SunColor); - m_SHCoeffsTerrain.AddDirectionalLight(dirlight,m_LightEnv->m_SunColor); - - m_SHCoeffsUnits.AddAmbientLight(m_LightEnv->m_UnitsAmbientColor); - m_SHCoeffsTerrain.AddAmbientLight(m_LightEnv->m_TerrainAmbientColor); - } - - // init per frame stuff - m_ShadowRendered=false; -} - -////////////////////////////////////////////////////////////////////////////////////////// -// SetClearColor: set color used to clear screen in BeginFrame() -void CRenderer::SetClearColor(u32 color) -{ - m_ClearColor[0]=float(color & 0xff)/255.0f; - m_ClearColor[1]=float((color>>8) & 0xff)/255.0f; - m_ClearColor[2]=float((color>>16) & 0xff)/255.0f; - m_ClearColor[3]=float((color>>24) & 0xff)/255.0f; -} - -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; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////////////// -// BuildTransformation: build transformation matrix from a position and standard basis vectors -void CRenderer::BuildTransformation(const CVector3D& pos,const CVector3D& right,const CVector3D& up, - const CVector3D& dir,CMatrix3D& result) -{ - // build basis - result._11=right.X; - result._12=right.Y; - result._13=right.Z; - result._14=0; - - result._21=up.X; - result._22=up.Y; - result._23=up.Z; - result._24=0; - - result._31=dir.X; - result._32=dir.Y; - result._33=dir.Z; - result._34=0; - - result._41=0; - result._42=0; - result._43=0; - result._44=1; - - CMatrix3D trans; - trans.SetTranslation(-pos.X,-pos.Y,-pos.Z); - result=result*trans; -} - -/////////////////////////////////////////////////////////////////////////////////////////////////// -// ConstructLightTransform: build transformation matrix for light at given position casting in -// given direction -void CRenderer::ConstructLightTransform(const CVector3D& pos,const CVector3D& dir,CMatrix3D& result) -{ - CVector3D right,up; - - CVector3D viewdir=m_Camera.m_Orientation.GetIn(); - if (fabs(dir.Y)>0.01f) { - up=CVector3D(viewdir.X,(-dir.Z*viewdir.Z-dir.X*dir.X)/dir.Y,viewdir.Z); - } else { - up=CVector3D(0,0,1); - } - - up.Normalize(); - right=dir.Cross(up); - right.Normalize(); - BuildTransformation(pos,right,up,dir,result); -} - -/////////////////////////////////////////////////////////////////////////////////////////////////// -// CalcShadowMatrices: calculate required matrices for shadow map generation - the light's -// projection and transformation matrices -void CRenderer::CalcShadowMatrices() -{ - int i; - - // get bounds of shadow casting objects - CBound bounds; - CalcShadowBounds(bounds); - - // get centre of bounds - CVector3D centre; - bounds.GetCentre(centre); - - // get sunlight direction - CVector3D lightdir; - // ??? RC using matrix rotation to get sun direction? - m_LightEnv->GetSunDirection(lightdir); - // ??? RC more optimal light placement? - CVector3D lightpos=centre-(lightdir*1000); - - // make light transformation matrix - ConstructLightTransform(lightpos,lightdir,m_LightTransform); - - // transform shadow bounds to light space, calculate near and far bounds - CVector3D vp[8]; - m_LightTransform.Transform(CVector3D(bounds[0].X,bounds[0].Y,bounds[0].Z),vp[0]); - m_LightTransform.Transform(CVector3D(bounds[1].X,bounds[0].Y,bounds[0].Z),vp[1]); - m_LightTransform.Transform(CVector3D(bounds[0].X,bounds[1].Y,bounds[0].Z),vp[2]); - m_LightTransform.Transform(CVector3D(bounds[1].X,bounds[1].Y,bounds[0].Z),vp[3]); - m_LightTransform.Transform(CVector3D(bounds[0].X,bounds[0].Y,bounds[1].Z),vp[4]); - m_LightTransform.Transform(CVector3D(bounds[1].X,bounds[0].Y,bounds[1].Z),vp[5]); - m_LightTransform.Transform(CVector3D(bounds[0].X,bounds[1].Y,bounds[1].Z),vp[6]); - m_LightTransform.Transform(CVector3D(bounds[1].X,bounds[1].Y,bounds[1].Z),vp[7]); - - float left=vp[0].X; - float right=vp[0].X; - float top=vp[0].Y; - float bottom=vp[0].Y; - float znear=vp[0].Z; - float zfar=vp[0].Z; - - for (i=1;i<8;i++) { - if (vp[i].Xright) right=vp[i].X; - - if (vp[i].Ytop) top=vp[i].Y; - - if (vp[i].Zzfar) zfar=vp[i].Z; - } - - // shift near and far clip planes slightly to avoid artifacts with points - // exactly on the clip planes - znear-=0.01f; - zfar+=0.01f; - - m_LightProjection.SetZero(); - m_LightProjection._11=2/(right-left); - m_LightProjection._22=2/(top-bottom); - m_LightProjection._33=2/(zfar-znear); - m_LightProjection._14=-(right+left)/(right-left); - m_LightProjection._24=-(top+bottom)/(top-bottom); - m_LightProjection._34=-(zfar+znear)/(zfar-znear); - m_LightProjection._44=1; - -#if 0 - -#if 0 - // TODO, RC - trim against frustum? - // get points of view frustum in world space - CVector3D frustumPts[8]; - m_Camera.GetFrustumPoints(frustumPts); - - // transform to light space - for (i=0;i<8;i++) { - m_LightTransform.Transform(frustumPts[i],vp[i]); - } - - float left1=vp[0].X; - float right1=vp[0].X; - float top1=vp[0].Y; - float bottom1=vp[0].Y; - float znear1=vp[0].Z; - float zfar1=vp[0].Z; - - for (int i=1;i<8;i++) { - if (vp[i].Xright1) right1=vp[i].X; - - if (vp[i].Ytop1) top1=vp[i].Y; - - if (vp[i].Zzfar1) zfar1=vp[i].Z; - } - - left=max(left,left1); - right=min(right,right1); - top=min(top,top1); - bottom=max(bottom,bottom1); - znear=max(znear,znear1); - zfar=min(zfar,zfar1); -#endif - - // experimental stuff, do not use .. - // TODO, RC - desperately need to improve resolution here if we're using shadow maps; investigate - // feasibility of PSMs - - // transform light space bounds to image space - TODO, RC: safe to just use 3d transform here? - CVector4D vph[8]; - for (i=0;i<8;i++) { - CVector4D tmp(vp[i].X,vp[i].Y,vp[i].Z,1.0f); - m_LightProjection.Transform(tmp,vph[i]); - vph[i][0]/=vph[i][2]; - vph[i][1]/=vph[i][2]; - } - - // find the two points furthest apart - int p0,p1; - float maxdistsqrd=-1; - for (i=0;i<8;i++) { - for (int j=i+1;j<8;j++) { - float dx=vph[i][0]-vph[j][0]; - float dy=vph[i][1]-vph[j][1]; - float distsqrd=dx*dx+dy*dy; - if (distsqrd>maxdistsqrd) { - p0=i; - p1=j; - maxdistsqrd=distsqrd; - } - } - } - - // now we want to rotate the camera such that the longest axis lies the diagonal at 45 degrees - - // get angle between points - float angle=atan2(vph[p0][1]-vph[p1][1],vph[p0][0]-vph[p1][0]); - float rotation=-angle; - - // build rotation matrix - CQuaternion quat; - quat.FromAxisAngle(lightdir,rotation); - CMatrix3D m; - quat.ToMatrix(m); - - // rotate up vector by given rotation - CVector3D up(m_LightTransform._21,m_LightTransform._22,m_LightTransform._23); - up=m.Rotate(up); - up.Normalize(); // TODO, RC - required?? - - // rebuild right vector - CVector3D rightvec; - rightvec=lightdir.Cross(up); - rightvec.Normalize(); - BuildTransformation(lightpos,rightvec,up,lightdir,m_LightTransform); - - // retransform points - m_LightTransform.Transform(CVector3D(bounds[0].X,bounds[0].Y,bounds[0].Z),vp[0]); - m_LightTransform.Transform(CVector3D(bounds[1].X,bounds[0].Y,bounds[0].Z),vp[1]); - m_LightTransform.Transform(CVector3D(bounds[0].X,bounds[1].Y,bounds[0].Z),vp[2]); - m_LightTransform.Transform(CVector3D(bounds[1].X,bounds[1].Y,bounds[0].Z),vp[3]); - m_LightTransform.Transform(CVector3D(bounds[0].X,bounds[0].Y,bounds[1].Z),vp[4]); - m_LightTransform.Transform(CVector3D(bounds[1].X,bounds[0].Y,bounds[1].Z),vp[5]); - m_LightTransform.Transform(CVector3D(bounds[0].X,bounds[1].Y,bounds[1].Z),vp[6]); - m_LightTransform.Transform(CVector3D(bounds[1].X,bounds[1].Y,bounds[1].Z),vp[7]); - - // recalculate projection - left=vp[0].X; - right=vp[0].X; - top=vp[0].Y; - bottom=vp[0].Y; - znear=vp[0].Z; - zfar=vp[0].Z; - - for (i=1;i<8;i++) { - if (vp[i].Xright) right=vp[i].X; - - if (vp[i].Ytop) top=vp[i].Y; - - if (vp[i].Zzfar) zfar=vp[i].Z; - } - - // shift near and far clip planes slightly to avoid artifacts with points - // exactly on the clip planes - znear-=0.01f; - zfar+=0.01f; - - m_LightProjection.SetZero(); - m_LightProjection._11=2/(right-left); - m_LightProjection._22=2/(top-bottom); - m_LightProjection._33=2/(zfar-znear); - m_LightProjection._14=-(right+left)/(right-left); - m_LightProjection._24=-(top+bottom)/(top-bottom); - m_LightProjection._34=-(zfar+znear)/(zfar-znear); - m_LightProjection._44=1; -#endif -} - -/////////////////////////////////////////////////////////////////////////////////////////////////// -// CalcShadowBounds: calculate the bounding box encompassing all visible shadow casting -// objects -void CRenderer::CalcShadowBounds(CBound& bounds) -{ - bounds.SetEmpty(); - - for (uint i=0;iGetBounds(); - } -} - -void CRenderer::CreateShadowMap() -{ - // get shadow map size as next power of two down from minimum of view width and height - if (!m_Caps.m_PBuffer) { - m_ShadowMapSize=m_Width>=1; - } else { - m_ShadowMapSize=PBufferWidth(); - } - - // create texture object - glGenTextures(1,(GLuint*) &m_ShadowMap); - BindTexture(0,(GLuint) m_ShadowMap); - glTexImage2D(GL_TEXTURE_2D,0,m_Depth==16 ? GL_RGBA4 : GL_RGBA8,m_ShadowMapSize,m_ShadowMapSize,0,GL_RGBA,GL_UNSIGNED_BYTE,0); - - // set texture parameters - if (m_Caps.m_TextureBorderClamp) { - const float borderColour[4]={1,1,1,0}; - glTexParameterfv(GL_TEXTURE_2D,GL_TEXTURE_BORDER_COLOR,borderColour); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); - } else { - glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - } - glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); -} - -void CRenderer::RenderShadowMap() -{ - // create shadow map if we haven't already got one - if (!m_ShadowMap) CreateShadowMap(); - - if (m_Caps.m_PBuffer) { - PBufferMakeCurrent(); - } - - // clear buffers - glClearColor(1,1,1,1); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - // build required matrices - CalcShadowMatrices(); - - // setup viewport - glViewport(0,0,m_ShadowMapSize,m_ShadowMapSize); - - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glLoadMatrixf(&m_LightProjection._11); - - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - glLoadMatrixf(&m_LightTransform._11); - - if (0) - { - // debug aid - render actual bounds of shadow casting objects; helps see where - // the lights projection/transform can be optimised - glColor3f(1.0,0.0,0.0); - CBound bounds; - CalcShadowBounds(bounds); - - glBegin(GL_LINE_LOOP); - glVertex3f(bounds[0].X,bounds[0].Y,bounds[0].Z); - glVertex3f(bounds[0].X,bounds[0].Y,bounds[1].Z); - glVertex3f(bounds[0].X,bounds[1].Y,bounds[1].Z); - glVertex3f(bounds[0].X,bounds[1].Y,bounds[0].Z); - glEnd(); - - glBegin(GL_LINE_LOOP); - glVertex3f(bounds[1].X,bounds[0].Y,bounds[0].Z); - glVertex3f(bounds[1].X,bounds[0].Y,bounds[1].Z); - glVertex3f(bounds[1].X,bounds[1].Y,bounds[1].Z); - glVertex3f(bounds[1].X,bounds[1].Y,bounds[0].Z); - glEnd(); - - glBegin(GL_LINE_LOOP); - glVertex3f(bounds[0].X,bounds[0].Y,bounds[0].Z); - glVertex3f(bounds[0].X,bounds[0].Y,bounds[1].Z); - glVertex3f(bounds[1].X,bounds[0].Y,bounds[1].Z); - glVertex3f(bounds[1].X,bounds[0].Y,bounds[0].Z); - glEnd(); - - glBegin(GL_LINE_LOOP); - glVertex3f(bounds[0].X,bounds[1].Y,bounds[0].Z); - glVertex3f(bounds[0].X,bounds[1].Y,bounds[1].Z); - glVertex3f(bounds[1].X,bounds[1].Y,bounds[1].Z); - glVertex3f(bounds[1].X,bounds[1].Y,bounds[0].Z); - glEnd(); - } - - // setup client states - glEnableClientState(GL_VERTEX_ARRAY); - - if (!m_Caps.m_TextureBorderClamp) { - glEnable(GL_SCISSOR_TEST); - glScissor(1,1,m_ShadowMapSize-2,m_ShadowMapSize-2); - } - - 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_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_ONE); - glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA); - - glColor3fv(&m_Options.m_ShadowColor.X); - - // render models - RenderModelsStreams(STREAM_POS); - - // call on the transparency renderer to render all the transparent stuff - g_TransparencyRenderer.RenderShadows(); - - glColor3f(1.0f,1.0f,1.0f); - - if (!m_Caps.m_TextureBorderClamp) { - glDisable(GL_SCISSOR_TEST); - } - glDisableClientState(GL_VERTEX_ARRAY); - - // copy result into shadow map texture - BindTexture(0,m_ShadowMap); - glCopyTexSubImage2D(GL_TEXTURE_2D,0,0,0,0,0,m_ShadowMapSize,m_ShadowMapSize); - - // restore matrix stack - glPopMatrix(); - glMatrixMode(GL_PROJECTION); - glPopMatrix(); - glMatrixMode(GL_MODELVIEW); - - if (0) - { - // debug aid - dump generated shadow map to file; helps verify shadow map - // space being well used (no guarantee this'll work on pbuffer - may have a single buffered one) - unsigned char* data=new unsigned char[m_ShadowMapSize*m_ShadowMapSize*3]; - glReadBuffer(GL_BACK); - glReadPixels(0,0,m_ShadowMapSize,m_ShadowMapSize,GL_BGR_EXT,GL_UNSIGNED_BYTE,data); - saveTGA("d:\\test.tga",m_ShadowMapSize,m_ShadowMapSize,data); - delete[] data; - } - - if (m_Caps.m_PBuffer) { - PBufferMakeUncurrent(); - } - - // restore viewport - const SViewPort& vp=m_Camera.GetViewPort(); - glViewport(vp.m_X, vp.m_Y, vp.m_Width, vp.m_Height); -} - -void CRenderer::ApplyShadowMap() -{ - BindTexture(0,m_ShadowMap); - - 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_TEXTURE); - 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_ONE); - glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA); - - glColor3f(1,1,1); - - glEnable(GL_BLEND); - glBlendFunc(GL_DST_COLOR,GL_ZERO); - - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - - CMatrix3D tmp2; - CMatrix3D texturematrix; - - texturematrix.SetTranslation(0.5f,0.5f,0.5f); // transform (-0.5, 0.5) to (0,1) - texture space - tmp2.SetScaling(0.5f,0.5f,0.5f); // scale (-1,1) to (-0.5,0.5) - texturematrix=texturematrix*tmp2; - - texturematrix=texturematrix*m_LightProjection; // transform light -> projected light space (-1 to 1) - texturematrix=texturematrix*m_LightTransform; // transform world -> light space - - glMatrixMode(GL_TEXTURE); - glLoadMatrixf(&texturematrix._11); - glMatrixMode(GL_MODELVIEW); - - for (uint i=0;iGetRenderData(); - patchdata->RenderStreams(STREAM_POS|STREAM_POSTOUV0); - } - - glMatrixMode(GL_TEXTURE); - glLoadIdentity(); - glMatrixMode(GL_MODELVIEW); - - glDisable(GL_BLEND); - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); -} - -void CRenderer::RenderPatches() -{ - // switch on wireframe if we need it - if (m_TerrainRenderMode==WIREFRAME) { - glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); - } - - // render all the patches, including blend pass - RenderPatchSubmissions(); - - if (m_TerrainRenderMode==WIREFRAME) { - // switch wireframe off again - glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); - } else if (m_TerrainRenderMode==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); - SetTexture(0,0); - glColor4f(1,1,1,0.35f); - glLineWidth(2.0f); - - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); - - // .. and some client states - glEnableClientState(GL_VERTEX_ARRAY); - - uint i; - - // render each patch in wireframe - for (i=0;iGetRenderData(); - patchdata->RenderStreams(STREAM_POS); - } - - // set color for outline - glColor3f(0,0,1); - glLineWidth(4.0f); - - // render outline of each patch - for (i=0;iGetRenderData(); - patchdata->RenderOutline(); - } - - // .. 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); - } -} - -////////////////////////////////////////////////////////////////////////////////////////// -// RenderModelsStreams: recurse down given model rendering given streams on each model -void CRenderer::RenderModelsStreams(u32 streamflags) -{ - for (uint i=0;iGetTransform()._11); - - // render this model - CModelRData* modeldata=(CModelRData*) model->GetRenderData(); - modeldata->RenderStreams(streamflags); - - // pop transform off stack - glPopMatrix(); - } -} - -void CRenderer::RenderModelSubmissions() -{ - // 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); - - // setup client states - glClientActiveTexture(GL_TEXTURE0); - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_COLOR_ARRAY); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - - // render models - RenderModelsStreams(STREAM_POS|STREAM_COLOR|STREAM_UV0); - - // switch off client states - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_COLOR_ARRAY); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); -} - -void CRenderer::RenderModels() -{ - // switch on wireframe if we need it - if (m_ModelRenderMode==WIREFRAME) { - glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); - } - - // render all the models - RenderModelSubmissions(); - - if (m_ModelRenderMode==WIREFRAME) { - // switch wireframe off again - glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); - } else if (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); - 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 - RenderModelsStreams(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); - } -} - -/////////////////////////////////////////////////////////////////////////////////////////////////// -// SortModelsByTexture: sorting class used for batching models with identical textures -struct SortModelsByTexture { - typedef CModel* SortObj; - - bool operator()(const SortObj& lhs,const SortObj& rhs) { - return lhs->GetTexture()GetTexture() ? true : false; - } -}; - -/////////////////////////////////////////////////////////////////////////////////////////////////// -// FlushFrame: force rendering of any batched objects -void CRenderer::FlushFrame() -{ - // update renderdata of everything submitted - UpdateSubmittedObjectData(); - - // sort all the models by texture - std::sort(m_Models.begin(),m_Models.end(),SortModelsByTexture()); - - // sort all the transparent stuff - g_TransparencyRenderer.Sort(); - - if (!m_ShadowRendered) { - if (m_Models.size()>0 && m_Options.m_Shadows) RenderShadowMap(); - m_ShadowRendered=true; - // clear buffers - glClearColor(m_ClearColor[0],m_ClearColor[1],m_ClearColor[2],m_ClearColor[3]); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - } - - // render submitted patches and models - RenderPatches(); - if (m_Models.size()>0) { - if (m_Options.m_Shadows) ApplyShadowMap(); - RenderModels(); - // call on the transparency renderer to render all the transparent stuff - g_TransparencyRenderer.Render(); - } - - // empty lists - g_TransparencyRenderer.Clear(); - m_TerrainPatches.clear(); - m_Models.clear(); -} - -// signal frame end : implicitly flushes batched objects -void CRenderer::EndFrame() -{ - FlushFrame(); - g_Renderer.SetTexture(0,0); -} - -void CRenderer::SetCamera(CCamera& camera) -{ - CMatrix3D view; - camera.m_Orientation.GetInverse(view); - CMatrix3D proj = camera.GetProjection(); - - float gl_view[16] = {view._11, view._21, view._31, view._41, - view._12, view._22, view._32, view._42, - view._13, view._23, view._33, view._43, - view._14, view._24, view._34, view._44}; - - float gl_proj[16] = {proj._11, proj._21, proj._31, proj._41, - proj._12, proj._22, proj._32, proj._42, - proj._13, proj._23, proj._33, proj._43, - proj._14, proj._24, proj._34, proj._44}; - - - glMatrixMode(GL_PROJECTION); - glLoadMatrixf(gl_proj); - - glMatrixMode(GL_MODELVIEW); - glLoadMatrixf(gl_view); - - const SViewPort& vp = camera.GetViewPort(); - glViewport (vp.m_X, vp.m_Y, vp.m_Width, vp.m_Height); - - m_Camera=camera; -} - -void CRenderer::Submit(CPatch* patch) -{ - m_TerrainPatches.push_back(patch); -} - -void CRenderer::Submit(CModel* model) -{ - m_Models.push_back(model); -} - -void CRenderer::Submit(CSprite* sprite) -{ -} - -void CRenderer::Submit(CParticleSys* psys) -{ -} - -void CRenderer::Submit(COverlay* overlay) -{ -} - -void CRenderer::RenderPatchSubmissions() -{ - uint i; - - // set up client states for base pass - glClientActiveTexture(GL_TEXTURE0); - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_COLOR_ARRAY); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - - // set up texture environment for base pass - glActiveTexture(GL_TEXTURE0); - 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); - - glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE); - glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_ZERO); - glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_ONE_MINUS_SRC_ALPHA); - - // render base passes for each patch - for (i=0;iGetRenderData(); - patchdata->RenderBase(); - } - - // switch on the composite alpha map texture - BindTexture(1,m_CompositeAlphaMap); - - // setup additional texenv required by blend pass - 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); - 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_ONE_MINUS_SRC_ALPHA); - - // switch on blending - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); - - // no need to write to the depth buffer a second time - glDepthMask(0); - - glClientActiveTexture(GL_TEXTURE1); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - - // render blend passes for each patch - for (i=0;iGetRenderData(); - patchdata->RenderBlends(); - } - - glClientActiveTexture(GL_TEXTURE1); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - - // restore depth writes - glDepthMask(1); - - // restore default state: switch off blending - glDisable(GL_BLEND); - - // switch off texture unit 1, make unit 0 active texture - glActiveTexture(GL_TEXTURE1); - glDisable(GL_TEXTURE_2D); - glActiveTexture(GL_TEXTURE0); - - // switch off all client states - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_COLOR_ARRAY); - glClientActiveTexture(GL_TEXTURE0); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); -} - - - -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// LoadTexture: try and load the given texture; set clamp/repeat flags on texture object if necessary -bool CRenderer::LoadTexture(CTexture* texture,u32 wrapflags) -{ - Handle h=texture->GetHandle(); - if (h) { - // already tried to load this texture, nothing to do here - just return success according - // to whether this is a valid handle or not - return h==0xfffffff ? true : false; - } else { - h=tex_load(texture->GetName()); - if (!h) { - texture->SetHandle(0xffffffff); - return false; - } else { - tex_upload(h); - - BindTexture(0,tex_id(h)); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - - if (wrapflags) { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapflags); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapflags); - } - - texture->SetHandle(h); - return true; - } - } -} - -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// BindTexture: bind a GL texture object to given unit -void CRenderer::BindTexture(int unit,GLuint tex) -{ - glActiveTexture(GL_TEXTURE0+unit); -// if (tex==m_ActiveTextures[unit]) return; - - if (tex) { - glEnable(GL_TEXTURE_2D); - } else { - glDisable(GL_TEXTURE_2D); - } - glBindTexture(GL_TEXTURE_2D,tex); - m_ActiveTextures[unit]=tex; -} - -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// SetTexture: set the given unit to reference the given texture; pass a null texture to disable texturing on any unit -void CRenderer::SetTexture(int unit,CTexture* texture) -{ - if (texture) { - Handle h=texture->GetHandle(); - BindTexture(unit,tex_id(h)); - } else { - BindTexture(unit,0); - } -} - -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// IsTextureTransparent: return true if given texture is transparent, else false - note texture must be loaded -// beforehand -bool CRenderer::IsTextureTransparent(CTexture* texture) -{ - if (!texture) return false; - - Handle h=texture->GetHandle(); - if (h<=0) return false; - - int fmt; - int bpp; - - tex_info(h, NULL, NULL, &fmt, &bpp, NULL); - if (bpp==24 || fmt == GL_COMPRESSED_RGB_S3TC_DXT1_EXT) { - return false; - } - return true; -} - - - - -inline void CopyTriple(unsigned char* dst,const unsigned char* src) -{ - dst[0]=src[0]; - dst[1]=src[1]; - dst[2]=src[2]; -} - -/////////////////////////////////////////////////////////////////////////////////////////////////// -// LoadAlphaMaps: load the 14 default alpha maps, pack them into one composite texture and -// calculate the coordinate of each alphamap within this packed texture .. need to add -// validation that all maps are the same size -bool CRenderer::LoadAlphaMaps(const char* fnames[]) -{ - glActiveTexture(GL_TEXTURE0_ARB); - - Handle textures[NumAlphaMaps]; - - int i; - - for (i=0;iGetRenderData(); - assert(data); - if (data->GetFlags() & MODELRDATA_FLAG_TRANSPARENT) { - // add this mode to the transparency renderer for later processing - calculate - // transform matrix - g_TransparencyRenderer.Add(model); - } -} - - -///////////////////////////////////////////////////////////////////////////////////////////////////// -// UpdateModelDataRecursive: recurse down given model building renderdata for it -// and all it's children -void CRenderer::UpdateModelDataRecursive(CModel* model) -{ - CModelRData* data=(CModelRData*) model->GetRenderData(); - if (data==0) { - // no renderdata for model, create it now - data=new CModelRData(model); - model->SetRenderData(data); - } else { - data->Update(); - } -} - -///////////////////////////////////////////////////////////////////////////////////////////////////// -// UpdateSubmittedObjectData: ensure all submitted objects have renderdata and that it is up to date -// - call once before doing anything with any objects -void CRenderer::UpdateSubmittedObjectData() -{ - uint i; - - // ensure all patches have up to date renderdata built for them - for (i=0;iGetRenderData(); - if (data==0) { - // no renderdata for patch, create it now - data=new CPatchRData(patch); - patch->SetRenderData(data); - } else { - data->Update(); - } - } - - // ensure all models have up to date renderdata built for them - for (i=0;i +#include +#include +#include "Renderer.h" +#include "TransparencyRenderer.h" +#include "Terrain.h" +#include "Matrix3D.h" +#include "Camera.h" +#include "PatchRData.h" +#include "Texture.h" +#include "LightEnv.h" + +#include "Model.h" +#include "ModelDef.h" + +#include "ogl.h" +#include "res/mem.h" +#include "res/tex.h" + +#ifdef _WIN32 +#include "pbuffer.h" +#endif + +struct TGAHeader { + // header stuff + unsigned char iif_size; + unsigned char cmap_type; + unsigned char image_type; + unsigned char pad[5]; + + // origin : unused + unsigned short d_x_origin; + unsigned short d_y_origin; + + // dimensions + unsigned short width; + unsigned short height; + + // bits per pixel : 16, 24 or 32 + unsigned char bpp; + + // image descriptor : Bits 3-0: size of alpha channel + // Bit 4: must be 0 (reserved) + // Bit 5: should be 0 (origin) + // Bits 6-7: should be 0 (interleaving) + unsigned char image_descriptor; +}; + +static bool saveTGA(const char* filename,int width,int height,unsigned char* data) +{ + FILE* fp=fopen(filename,"wb"); + if (!fp) return false; + + // fill file header + TGAHeader header; + header.iif_size=0; + header.cmap_type=0; + header.image_type=2; + memset(header.pad,0,sizeof(header.pad)); + header.d_x_origin=0; + header.d_y_origin=0; + header.width=width; + header.height=height; + header.bpp=24; + header.image_descriptor=0; + + if (fwrite(&header,sizeof(TGAHeader),1,fp)!=1) { + fclose(fp); + return false; + } + + // write data + if (fwrite(data,width*height*3,1,fp)!=1) { + fclose(fp); + return false; + } + + // return success .. + fclose(fp); + return true; +} + +extern CTerrain g_Terrain; + + +CRenderer::CRenderer () +{ + m_Width=0; + m_Height=0; + m_Depth=0; + m_FrameCounter=0; + m_TerrainRenderMode=SOLID; + m_ModelRenderMode=SOLID; + m_ClearColor[0]=m_ClearColor[1]=m_ClearColor[2]=m_ClearColor[3]=0; + m_ShadowMap=0; + m_Options.m_NoVBO=false; + m_Options.m_NoPBuffer=false; + m_Options.m_Shadows=true; + m_Options.m_ShadowColor=RGBColor(0.4f,0.4f,0.4f); +} + +CRenderer::~CRenderer () +{ +} + + +/////////////////////////////////////////////////////////////////////////////////// +// EnumCaps: build card cap bits +void CRenderer::EnumCaps() +{ + // assume support for nothing + m_Caps.m_VBO=false; + m_Caps.m_TextureBorderClamp=false; + m_Caps.m_PBuffer=false; + m_Caps.m_GenerateMipmaps=false; + + // now start querying extensions + if (!m_Options.m_NoVBO) { + if (oglExtAvail("GL_ARB_vertex_buffer_object")) { + m_Caps.m_VBO=true; + } + } + if (oglExtAvail("GL_ARB_texture_border_clamp")) { + m_Caps.m_TextureBorderClamp=true; + } + if (oglExtAvail("GL_SGIS_generate_mipmap")) { + m_Caps.m_GenerateMipmaps=true; + } + + if (!m_Options.m_NoPBuffer) { + extern bool PBufferQuery(); + if (PBufferQuery()) { + m_Caps.m_PBuffer=true; + } + } +} + +bool CRenderer::Open(int width, int height, int depth) +{ + m_Width = width; + m_Height = height; + m_Depth = depth; + + // set packing parameters + glPixelStorei(GL_PACK_ALIGNMENT,1); + glPixelStorei(GL_UNPACK_ALIGNMENT,1); + + // setup default state + glDepthFunc(GL_LEQUAL); + glEnable(GL_DEPTH_TEST); + glCullFace(GL_BACK); + glFrontFace(GL_CCW); + glEnable(GL_CULL_FACE); + glClearColor(0.0f,0.0f,0.0f,0.0f); + + // query card capabilities + EnumCaps(); + +#ifdef _WIN32 + if (m_Caps.m_PBuffer) { + // TODO, RC - query max pbuffer size + PBufferInit(1024,1024,0,32,16,0); + } +#endif + return true; +} + +void CRenderer::Close() +{ +} + +// resize renderer view +void CRenderer::Resize(int width,int height) +{ + m_Width = width; + m_Height = height; + if (m_ShadowMap) { + glDeleteTextures(1,(GLuint*) &m_ShadowMap); + m_ShadowMap=0; + } +} + +////////////////////////////////////////////////////////////////////////////////////////// +// SetOptionBool: set boolean renderer option +void CRenderer::SetOptionBool(enum Option opt,bool value) +{ + switch (opt) { + case OPT_NOVBO: + m_Options.m_NoVBO=value; + break; + case OPT_NOPBUFFER: + m_Options.m_NoPBuffer=value; + break; + case OPT_SHADOWS: + m_Options.m_Shadows=value; + break; + } +} + +////////////////////////////////////////////////////////////////////////////////////////// +// GetOptionBool: get boolean renderer option +bool CRenderer::GetOptionBool(enum Option opt) const +{ + switch (opt) { + case OPT_NOVBO: + return m_Options.m_NoVBO; + case OPT_NOPBUFFER: + return m_Options.m_NoPBuffer; + case OPT_SHADOWS: + return m_Options.m_Shadows; + } + + return false; +} + +////////////////////////////////////////////////////////////////////////////////////////// +// SetOptionColor: set color renderer option +void CRenderer::SetOptionColor(enum Option opt,const RGBColor& value) +{ + switch (opt) { + case OPT_SHADOWCOLOR: + m_Options.m_ShadowColor=value; + break; + } +} + +////////////////////////////////////////////////////////////////////////////////////////// +// GetOptionColor: get color renderer option +const RGBColor& CRenderer::GetOptionColor(enum Option opt) const +{ + static const RGBColor defaultColor(1.0f,1.0f,1.0f); + + switch (opt) { + case OPT_SHADOWCOLOR: + return m_Options.m_ShadowColor; + } + + return defaultColor; +} + +////////////////////////////////////////////////////////////////////////////////////////// +// BeginFrame: signal frame start +void CRenderer::BeginFrame() +{ + // bump frame counter + m_FrameCounter++; + + // zero out all the per-frame stats + m_Stats.Reset(); + + // calculate coefficients for terrain and unit lighting + m_SHCoeffsUnits.Clear(); + m_SHCoeffsTerrain.Clear(); + + if (m_LightEnv) { + CVector3D dirlight; + m_LightEnv->GetSunDirection(dirlight); + m_SHCoeffsUnits.AddDirectionalLight(dirlight,m_LightEnv->m_SunColor); + m_SHCoeffsTerrain.AddDirectionalLight(dirlight,m_LightEnv->m_SunColor); + + m_SHCoeffsUnits.AddAmbientLight(m_LightEnv->m_UnitsAmbientColor); + m_SHCoeffsTerrain.AddAmbientLight(m_LightEnv->m_TerrainAmbientColor); + } + + // init per frame stuff + m_ShadowRendered=false; +} + +////////////////////////////////////////////////////////////////////////////////////////// +// SetClearColor: set color used to clear screen in BeginFrame() +void CRenderer::SetClearColor(u32 color) +{ + m_ClearColor[0]=float(color & 0xff)/255.0f; + m_ClearColor[1]=float((color>>8) & 0xff)/255.0f; + m_ClearColor[2]=float((color>>16) & 0xff)/255.0f; + m_ClearColor[3]=float((color>>24) & 0xff)/255.0f; +} + +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; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////// +// BuildTransformation: build transformation matrix from a position and standard basis vectors +void CRenderer::BuildTransformation(const CVector3D& pos,const CVector3D& right,const CVector3D& up, + const CVector3D& dir,CMatrix3D& result) +{ + // build basis + result._11=right.X; + result._12=right.Y; + result._13=right.Z; + result._14=0; + + result._21=up.X; + result._22=up.Y; + result._23=up.Z; + result._24=0; + + result._31=dir.X; + result._32=dir.Y; + result._33=dir.Z; + result._34=0; + + result._41=0; + result._42=0; + result._43=0; + result._44=1; + + CMatrix3D trans; + trans.SetTranslation(-pos.X,-pos.Y,-pos.Z); + result=result*trans; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// ConstructLightTransform: build transformation matrix for light at given position casting in +// given direction +void CRenderer::ConstructLightTransform(const CVector3D& pos,const CVector3D& dir,CMatrix3D& result) +{ + CVector3D right,up; + + CVector3D viewdir=m_Camera.m_Orientation.GetIn(); + if (fabs(dir.Y)>0.01f) { + up=CVector3D(viewdir.X,(-dir.Z*viewdir.Z-dir.X*dir.X)/dir.Y,viewdir.Z); + } else { + up=CVector3D(0,0,1); + } + + up.Normalize(); + right=dir.Cross(up); + right.Normalize(); + BuildTransformation(pos,right,up,dir,result); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// CalcShadowMatrices: calculate required matrices for shadow map generation - the light's +// projection and transformation matrices +void CRenderer::CalcShadowMatrices() +{ + int i; + + // get bounds of shadow casting objects + CBound bounds; + CalcShadowBounds(bounds); + + // get centre of bounds + CVector3D centre; + bounds.GetCentre(centre); + + // get sunlight direction + CVector3D lightdir; + // ??? RC using matrix rotation to get sun direction? + m_LightEnv->GetSunDirection(lightdir); + // ??? RC more optimal light placement? + CVector3D lightpos=centre-(lightdir*1000); + + // make light transformation matrix + ConstructLightTransform(lightpos,lightdir,m_LightTransform); + + // transform shadow bounds to light space, calculate near and far bounds + CVector3D vp[8]; + m_LightTransform.Transform(CVector3D(bounds[0].X,bounds[0].Y,bounds[0].Z),vp[0]); + m_LightTransform.Transform(CVector3D(bounds[1].X,bounds[0].Y,bounds[0].Z),vp[1]); + m_LightTransform.Transform(CVector3D(bounds[0].X,bounds[1].Y,bounds[0].Z),vp[2]); + m_LightTransform.Transform(CVector3D(bounds[1].X,bounds[1].Y,bounds[0].Z),vp[3]); + m_LightTransform.Transform(CVector3D(bounds[0].X,bounds[0].Y,bounds[1].Z),vp[4]); + m_LightTransform.Transform(CVector3D(bounds[1].X,bounds[0].Y,bounds[1].Z),vp[5]); + m_LightTransform.Transform(CVector3D(bounds[0].X,bounds[1].Y,bounds[1].Z),vp[6]); + m_LightTransform.Transform(CVector3D(bounds[1].X,bounds[1].Y,bounds[1].Z),vp[7]); + + float left=vp[0].X; + float right=vp[0].X; + float top=vp[0].Y; + float bottom=vp[0].Y; + float znear=vp[0].Z; + float zfar=vp[0].Z; + + for (i=1;i<8;i++) { + if (vp[i].Xright) right=vp[i].X; + + if (vp[i].Ytop) top=vp[i].Y; + + if (vp[i].Zzfar) zfar=vp[i].Z; + } + + // shift near and far clip planes slightly to avoid artifacts with points + // exactly on the clip planes + znear-=0.01f; + zfar+=0.01f; + + m_LightProjection.SetZero(); + m_LightProjection._11=2/(right-left); + m_LightProjection._22=2/(top-bottom); + m_LightProjection._33=2/(zfar-znear); + m_LightProjection._14=-(right+left)/(right-left); + m_LightProjection._24=-(top+bottom)/(top-bottom); + m_LightProjection._34=-(zfar+znear)/(zfar-znear); + m_LightProjection._44=1; + +#if 0 + +#if 0 + // TODO, RC - trim against frustum? + // get points of view frustum in world space + CVector3D frustumPts[8]; + m_Camera.GetFrustumPoints(frustumPts); + + // transform to light space + for (i=0;i<8;i++) { + m_LightTransform.Transform(frustumPts[i],vp[i]); + } + + float left1=vp[0].X; + float right1=vp[0].X; + float top1=vp[0].Y; + float bottom1=vp[0].Y; + float znear1=vp[0].Z; + float zfar1=vp[0].Z; + + for (int i=1;i<8;i++) { + if (vp[i].Xright1) right1=vp[i].X; + + if (vp[i].Ytop1) top1=vp[i].Y; + + if (vp[i].Zzfar1) zfar1=vp[i].Z; + } + + left=max(left,left1); + right=min(right,right1); + top=min(top,top1); + bottom=max(bottom,bottom1); + znear=max(znear,znear1); + zfar=min(zfar,zfar1); +#endif + + // experimental stuff, do not use .. + // TODO, RC - desperately need to improve resolution here if we're using shadow maps; investigate + // feasibility of PSMs + + // transform light space bounds to image space - TODO, RC: safe to just use 3d transform here? + CVector4D vph[8]; + for (i=0;i<8;i++) { + CVector4D tmp(vp[i].X,vp[i].Y,vp[i].Z,1.0f); + m_LightProjection.Transform(tmp,vph[i]); + vph[i][0]/=vph[i][2]; + vph[i][1]/=vph[i][2]; + } + + // find the two points furthest apart + int p0,p1; + float maxdistsqrd=-1; + for (i=0;i<8;i++) { + for (int j=i+1;j<8;j++) { + float dx=vph[i][0]-vph[j][0]; + float dy=vph[i][1]-vph[j][1]; + float distsqrd=dx*dx+dy*dy; + if (distsqrd>maxdistsqrd) { + p0=i; + p1=j; + maxdistsqrd=distsqrd; + } + } + } + + // now we want to rotate the camera such that the longest axis lies the diagonal at 45 degrees - + // get angle between points + float angle=atan2(vph[p0][1]-vph[p1][1],vph[p0][0]-vph[p1][0]); + float rotation=-angle; + + // build rotation matrix + CQuaternion quat; + quat.FromAxisAngle(lightdir,rotation); + CMatrix3D m; + quat.ToMatrix(m); + + // rotate up vector by given rotation + CVector3D up(m_LightTransform._21,m_LightTransform._22,m_LightTransform._23); + up=m.Rotate(up); + up.Normalize(); // TODO, RC - required?? + + // rebuild right vector + CVector3D rightvec; + rightvec=lightdir.Cross(up); + rightvec.Normalize(); + BuildTransformation(lightpos,rightvec,up,lightdir,m_LightTransform); + + // retransform points + m_LightTransform.Transform(CVector3D(bounds[0].X,bounds[0].Y,bounds[0].Z),vp[0]); + m_LightTransform.Transform(CVector3D(bounds[1].X,bounds[0].Y,bounds[0].Z),vp[1]); + m_LightTransform.Transform(CVector3D(bounds[0].X,bounds[1].Y,bounds[0].Z),vp[2]); + m_LightTransform.Transform(CVector3D(bounds[1].X,bounds[1].Y,bounds[0].Z),vp[3]); + m_LightTransform.Transform(CVector3D(bounds[0].X,bounds[0].Y,bounds[1].Z),vp[4]); + m_LightTransform.Transform(CVector3D(bounds[1].X,bounds[0].Y,bounds[1].Z),vp[5]); + m_LightTransform.Transform(CVector3D(bounds[0].X,bounds[1].Y,bounds[1].Z),vp[6]); + m_LightTransform.Transform(CVector3D(bounds[1].X,bounds[1].Y,bounds[1].Z),vp[7]); + + // recalculate projection + left=vp[0].X; + right=vp[0].X; + top=vp[0].Y; + bottom=vp[0].Y; + znear=vp[0].Z; + zfar=vp[0].Z; + + for (i=1;i<8;i++) { + if (vp[i].Xright) right=vp[i].X; + + if (vp[i].Ytop) top=vp[i].Y; + + if (vp[i].Zzfar) zfar=vp[i].Z; + } + + // shift near and far clip planes slightly to avoid artifacts with points + // exactly on the clip planes + znear-=0.01f; + zfar+=0.01f; + + m_LightProjection.SetZero(); + m_LightProjection._11=2/(right-left); + m_LightProjection._22=2/(top-bottom); + m_LightProjection._33=2/(zfar-znear); + m_LightProjection._14=-(right+left)/(right-left); + m_LightProjection._24=-(top+bottom)/(top-bottom); + m_LightProjection._34=-(zfar+znear)/(zfar-znear); + m_LightProjection._44=1; +#endif +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// CalcShadowBounds: calculate the bounding box encompassing all visible shadow casting +// objects +void CRenderer::CalcShadowBounds(CBound& bounds) +{ + bounds.SetEmpty(); + + for (uint i=0;iGetBounds(); + } +} + +void CRenderer::CreateShadowMap() +{ + // get shadow map size as next power of two down from minimum of view width and height + if (!m_Caps.m_PBuffer) { + m_ShadowMapSize=m_Width>=1; + } else { + m_ShadowMapSize=PBufferWidth(); + } + + // create texture object + glGenTextures(1,(GLuint*) &m_ShadowMap); + BindTexture(0,(GLuint) m_ShadowMap); + glTexImage2D(GL_TEXTURE_2D,0,m_Depth==16 ? GL_RGBA4 : GL_RGBA8,m_ShadowMapSize,m_ShadowMapSize,0,GL_RGBA,GL_UNSIGNED_BYTE,0); + + // set texture parameters + if (m_Caps.m_TextureBorderClamp) { + const float borderColour[4]={1,1,1,0}; + glTexParameterfv(GL_TEXTURE_2D,GL_TEXTURE_BORDER_COLOR,borderColour); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); + } else { + glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + } + glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); +} + +void CRenderer::RenderShadowMap() +{ + // create shadow map if we haven't already got one + if (!m_ShadowMap) CreateShadowMap(); + + if (m_Caps.m_PBuffer) { + PBufferMakeCurrent(); + } + + // clear buffers + glClearColor(1,1,1,1); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + // build required matrices + CalcShadowMatrices(); + + // setup viewport + glViewport(0,0,m_ShadowMapSize,m_ShadowMapSize); + + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadMatrixf(&m_LightProjection._11); + + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadMatrixf(&m_LightTransform._11); + + if (0) + { + // debug aid - render actual bounds of shadow casting objects; helps see where + // the lights projection/transform can be optimised + glColor3f(1.0,0.0,0.0); + CBound bounds; + CalcShadowBounds(bounds); + + glBegin(GL_LINE_LOOP); + glVertex3f(bounds[0].X,bounds[0].Y,bounds[0].Z); + glVertex3f(bounds[0].X,bounds[0].Y,bounds[1].Z); + glVertex3f(bounds[0].X,bounds[1].Y,bounds[1].Z); + glVertex3f(bounds[0].X,bounds[1].Y,bounds[0].Z); + glEnd(); + + glBegin(GL_LINE_LOOP); + glVertex3f(bounds[1].X,bounds[0].Y,bounds[0].Z); + glVertex3f(bounds[1].X,bounds[0].Y,bounds[1].Z); + glVertex3f(bounds[1].X,bounds[1].Y,bounds[1].Z); + glVertex3f(bounds[1].X,bounds[1].Y,bounds[0].Z); + glEnd(); + + glBegin(GL_LINE_LOOP); + glVertex3f(bounds[0].X,bounds[0].Y,bounds[0].Z); + glVertex3f(bounds[0].X,bounds[0].Y,bounds[1].Z); + glVertex3f(bounds[1].X,bounds[0].Y,bounds[1].Z); + glVertex3f(bounds[1].X,bounds[0].Y,bounds[0].Z); + glEnd(); + + glBegin(GL_LINE_LOOP); + glVertex3f(bounds[0].X,bounds[1].Y,bounds[0].Z); + glVertex3f(bounds[0].X,bounds[1].Y,bounds[1].Z); + glVertex3f(bounds[1].X,bounds[1].Y,bounds[1].Z); + glVertex3f(bounds[1].X,bounds[1].Y,bounds[0].Z); + glEnd(); + } + + // setup client states + glEnableClientState(GL_VERTEX_ARRAY); + + if (!m_Caps.m_TextureBorderClamp) { + glEnable(GL_SCISSOR_TEST); + glScissor(1,1,m_ShadowMapSize-2,m_ShadowMapSize-2); + } + + 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_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_ONE); + glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA); + + glColor3fv(&m_Options.m_ShadowColor.X); + + // render models + RenderModelsStreams(STREAM_POS); + + // call on the transparency renderer to render all the transparent stuff + g_TransparencyRenderer.RenderShadows(); + + glColor3f(1.0f,1.0f,1.0f); + + if (!m_Caps.m_TextureBorderClamp) { + glDisable(GL_SCISSOR_TEST); + } + glDisableClientState(GL_VERTEX_ARRAY); + + // copy result into shadow map texture + BindTexture(0,m_ShadowMap); + glCopyTexSubImage2D(GL_TEXTURE_2D,0,0,0,0,0,m_ShadowMapSize,m_ShadowMapSize); + + // restore matrix stack + glPopMatrix(); + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + + if (0) + { + // debug aid - dump generated shadow map to file; helps verify shadow map + // space being well used (no guarantee this'll work on pbuffer - may have a single buffered one) + unsigned char* data=new unsigned char[m_ShadowMapSize*m_ShadowMapSize*3]; + glReadBuffer(GL_BACK); + glReadPixels(0,0,m_ShadowMapSize,m_ShadowMapSize,GL_BGR_EXT,GL_UNSIGNED_BYTE,data); + saveTGA("d:\\test.tga",m_ShadowMapSize,m_ShadowMapSize,data); + delete[] data; + } + + if (m_Caps.m_PBuffer) { + PBufferMakeUncurrent(); + } + + // restore viewport + const SViewPort& vp=m_Camera.GetViewPort(); + glViewport(vp.m_X, vp.m_Y, vp.m_Width, vp.m_Height); +} + +void CRenderer::ApplyShadowMap() +{ + BindTexture(0,m_ShadowMap); + + 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_TEXTURE); + 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_ONE); + glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA); + + glColor3f(1,1,1); + + glEnable(GL_BLEND); + glBlendFunc(GL_DST_COLOR,GL_ZERO); + + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + + CMatrix3D tmp2; + CMatrix3D texturematrix; + + texturematrix.SetTranslation(0.5f,0.5f,0.5f); // transform (-0.5, 0.5) to (0,1) - texture space + tmp2.SetScaling(0.5f,0.5f,0.5f); // scale (-1,1) to (-0.5,0.5) + texturematrix=texturematrix*tmp2; + + texturematrix=texturematrix*m_LightProjection; // transform light -> projected light space (-1 to 1) + texturematrix=texturematrix*m_LightTransform; // transform world -> light space + + glMatrixMode(GL_TEXTURE); + glLoadMatrixf(&texturematrix._11); + glMatrixMode(GL_MODELVIEW); + + for (uint i=0;iGetRenderData(); + patchdata->RenderStreams(STREAM_POS|STREAM_POSTOUV0); + } + + glMatrixMode(GL_TEXTURE); + glLoadIdentity(); + glMatrixMode(GL_MODELVIEW); + + glDisable(GL_BLEND); + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); +} + +void CRenderer::RenderPatches() +{ + // switch on wireframe if we need it + if (m_TerrainRenderMode==WIREFRAME) { + glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); + } + + // render all the patches, including blend pass + RenderPatchSubmissions(); + + if (m_TerrainRenderMode==WIREFRAME) { + // switch wireframe off again + glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); + } else if (m_TerrainRenderMode==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); + SetTexture(0,0); + glColor4f(1,1,1,0.35f); + glLineWidth(2.0f); + + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); + + // .. and some client states + glEnableClientState(GL_VERTEX_ARRAY); + + uint i; + + // render each patch in wireframe + for (i=0;iGetRenderData(); + patchdata->RenderStreams(STREAM_POS); + } + + // set color for outline + glColor3f(0,0,1); + glLineWidth(4.0f); + + // render outline of each patch + for (i=0;iGetRenderData(); + patchdata->RenderOutline(); + } + + // .. 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); + } +} + +////////////////////////////////////////////////////////////////////////////////////////// +// RenderModelsStreams: recurse down given model rendering given streams on each model +void CRenderer::RenderModelsStreams(u32 streamflags) +{ + glMatrixMode(GL_MODELVIEW); + + for (uint i=0;iGetTransform()._11); + + // render this model + CModelRData* modeldata=(CModelRData*) model->GetRenderData(); + modeldata->RenderStreams(streamflags); + + // pop transform off stack + glPopMatrix(); + } +} + +void CRenderer::RenderModelSubmissions() +{ + // 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); + + // setup client states + glClientActiveTexture(GL_TEXTURE0); + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_COLOR_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + + // render models + RenderModelsStreams(STREAM_POS|STREAM_COLOR|STREAM_UV0); + + // switch off client states + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_COLOR_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); +} + +void CRenderer::RenderModels() +{ + // switch on wireframe if we need it + if (m_ModelRenderMode==WIREFRAME) { + glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); + } + + // render all the models + RenderModelSubmissions(); + + if (m_ModelRenderMode==WIREFRAME) { + // switch wireframe off again + glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); + } else if (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); + 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 + RenderModelsStreams(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); + } +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// SortModelsByTexture: sorting class used for batching models with identical textures +struct SortModelsByTexture { + typedef CModel* SortObj; + + bool operator()(const SortObj& lhs,const SortObj& rhs) { + return lhs->GetTexture()GetTexture() ? true : false; + } +}; + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// FlushFrame: force rendering of any batched objects +void CRenderer::FlushFrame() +{ + // update renderdata of everything submitted + UpdateSubmittedObjectData(); + + // sort all the models by texture + std::sort(m_Models.begin(),m_Models.end(),SortModelsByTexture()); + + // sort all the transparent stuff + g_TransparencyRenderer.Sort(); + + if (!m_ShadowRendered) { + if (m_Models.size()>0 && m_Options.m_Shadows) RenderShadowMap(); + m_ShadowRendered=true; + // clear buffers + glClearColor(m_ClearColor[0],m_ClearColor[1],m_ClearColor[2],m_ClearColor[3]); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + } + + // render submitted patches and models + RenderPatches(); + if (m_Models.size()>0) { + if (m_Options.m_Shadows) ApplyShadowMap(); + RenderModels(); + // call on the transparency renderer to render all the transparent stuff + g_TransparencyRenderer.Render(); + } + + // empty lists + g_TransparencyRenderer.Clear(); + m_TerrainPatches.clear(); + m_Models.clear(); +} + +// signal frame end : implicitly flushes batched objects +void CRenderer::EndFrame() +{ + FlushFrame(); + g_Renderer.SetTexture(0,0); +} + +void CRenderer::SetCamera(CCamera& camera) +{ + CMatrix3D view; + camera.m_Orientation.GetInverse(view); + CMatrix3D proj = camera.GetProjection(); + + float gl_view[16] = {view._11, view._21, view._31, view._41, + view._12, view._22, view._32, view._42, + view._13, view._23, view._33, view._43, + view._14, view._24, view._34, view._44}; + + float gl_proj[16] = {proj._11, proj._21, proj._31, proj._41, + proj._12, proj._22, proj._32, proj._42, + proj._13, proj._23, proj._33, proj._43, + proj._14, proj._24, proj._34, proj._44}; + + + glMatrixMode(GL_PROJECTION); + glLoadMatrixf(gl_proj); + + glMatrixMode(GL_MODELVIEW); + glLoadMatrixf(gl_view); + + const SViewPort& vp = camera.GetViewPort(); + glViewport (vp.m_X, vp.m_Y, vp.m_Width, vp.m_Height); + + m_Camera=camera; +} + +void CRenderer::Submit(CPatch* patch) +{ + m_TerrainPatches.push_back(patch); +} + +void CRenderer::Submit(CModel* model) +{ + m_Models.push_back(model); +} + +void CRenderer::Submit(CSprite* sprite) +{ +} + +void CRenderer::Submit(CParticleSys* psys) +{ +} + +void CRenderer::Submit(COverlay* overlay) +{ +} + +void CRenderer::RenderPatchSubmissions() +{ + uint i; + + // set up client states for base pass + glClientActiveTexture(GL_TEXTURE0); + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_COLOR_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + + // set up texture environment for base pass + glActiveTexture(GL_TEXTURE0); + 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); + + glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE); + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_ZERO); + glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_ONE_MINUS_SRC_ALPHA); + + // render base passes for each patch + for (i=0;iGetRenderData(); + patchdata->RenderBase(); + } + + // switch on the composite alpha map texture + BindTexture(1,m_CompositeAlphaMap); + + // setup additional texenv required by blend pass + 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); + 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_ONE_MINUS_SRC_ALPHA); + + // switch on blending + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); + + // no need to write to the depth buffer a second time + glDepthMask(0); + + glClientActiveTexture(GL_TEXTURE1); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + + // render blend passes for each patch + for (i=0;iGetRenderData(); + patchdata->RenderBlends(); + } + + glClientActiveTexture(GL_TEXTURE1); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + + // restore depth writes + glDepthMask(1); + + // restore default state: switch off blending + glDisable(GL_BLEND); + + // switch off texture unit 1, make unit 0 active texture + glActiveTexture(GL_TEXTURE1); + glDisable(GL_TEXTURE_2D); + glActiveTexture(GL_TEXTURE0); + + // switch off all client states + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_COLOR_ARRAY); + glClientActiveTexture(GL_TEXTURE0); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); +} + + + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// LoadTexture: try and load the given texture; set clamp/repeat flags on texture object if necessary +bool CRenderer::LoadTexture(CTexture* texture,u32 wrapflags) +{ + Handle h=texture->GetHandle(); + if (h) { + // already tried to load this texture, nothing to do here - just return success according + // to whether this is a valid handle or not + return h==0xfffffff ? true : false; + } else { + h=tex_load(texture->GetName()); + if (!h) { + texture->SetHandle(0xffffffff); + return false; + } else { + tex_upload(h); + + BindTexture(0,tex_id(h)); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + if (wrapflags) { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapflags); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapflags); + } + + texture->SetHandle(h); + return true; + } + } +} + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// BindTexture: bind a GL texture object to given unit +void CRenderer::BindTexture(int unit,GLuint tex) +{ + glActiveTexture(GL_TEXTURE0+unit); +// if (tex==m_ActiveTextures[unit]) return; + + if (tex) { + glEnable(GL_TEXTURE_2D); + } else { + glDisable(GL_TEXTURE_2D); + } + glBindTexture(GL_TEXTURE_2D,tex); + m_ActiveTextures[unit]=tex; +} + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// SetTexture: set the given unit to reference the given texture; pass a null texture to disable texturing on any unit +void CRenderer::SetTexture(int unit,CTexture* texture) +{ + if (texture) { + Handle h=texture->GetHandle(); + BindTexture(unit,tex_id(h)); + } else { + BindTexture(unit,0); + } +} + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// IsTextureTransparent: return true if given texture is transparent, else false - note texture must be loaded +// beforehand +bool CRenderer::IsTextureTransparent(CTexture* texture) +{ + if (!texture) return false; + + Handle h=texture->GetHandle(); + if (h<=0) return false; + + int fmt; + int bpp; + + tex_info(h, NULL, NULL, &fmt, &bpp, NULL); + if (bpp==24 || fmt == GL_COMPRESSED_RGB_S3TC_DXT1_EXT) { + return false; + } + return true; +} + + + + +inline void CopyTriple(unsigned char* dst,const unsigned char* src) +{ + dst[0]=src[0]; + dst[1]=src[1]; + dst[2]=src[2]; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// LoadAlphaMaps: load the 14 default alpha maps, pack them into one composite texture and +// calculate the coordinate of each alphamap within this packed texture .. need to add +// validation that all maps are the same size +bool CRenderer::LoadAlphaMaps(const char* fnames[]) +{ + glActiveTexture(GL_TEXTURE0_ARB); + + Handle textures[NumAlphaMaps]; + + int i; + + for (i=0;iGetRenderData(); + assert(data); + if (data->GetFlags() & MODELRDATA_FLAG_TRANSPARENT) { + // add this mode to the transparency renderer for later processing - calculate + // transform matrix + g_TransparencyRenderer.Add(model); + } +} + + +///////////////////////////////////////////////////////////////////////////////////////////////////// +// UpdateModelDataRecursive: recurse down given model building renderdata for it +// and all it's children +void CRenderer::UpdateModelDataRecursive(CModel* model) +{ + CModelRData* data=(CModelRData*) model->GetRenderData(); + if (data==0) { + // no renderdata for model, create it now + data=new CModelRData(model); + model->SetRenderData(data); + } else { + data->Update(); + } +} + +///////////////////////////////////////////////////////////////////////////////////////////////////// +// UpdateSubmittedObjectData: ensure all submitted objects have renderdata and that it is up to date +// - call once before doing anything with any objects +void CRenderer::UpdateSubmittedObjectData() +{ + uint i; + + // ensure all patches have up to date renderdata built for them + for (i=0;iGetRenderData(); + if (data==0) { + // no renderdata for patch, create it now + data=new CPatchRData(patch); + patch->SetRenderData(data); + } else { + data->Update(); + } + } + + // ensure all models have up to date renderdata built for them + for (i=0;i -#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 -{ -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 m_TerrainPatches; - std::vector m_Models; - std::vector m_Sprites; - std::vector m_ParticleSyses; - std::vector 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 +#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 +{ +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 m_TerrainPatches; + std::vector m_Models; + std::vector m_Sprites; + std::vector m_ParticleSyses; + std::vector 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 diff --git a/source/renderer/TransparencyRenderer.cpp b/source/renderer/TransparencyRenderer.cpp index 03a1072fa6..c44127d962 100755 --- a/source/renderer/TransparencyRenderer.cpp +++ b/source/renderer/TransparencyRenderer.cpp @@ -1,185 +1,185 @@ -#include -#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;iGetTransform()._11); - - CModelRData* modeldata=(CModelRData*) model->GetRenderData(); - modeldata->RenderStreams(streamflags,true); - - glPopMatrix(); - } +#include +#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;iGetTransform()._11); + + CModelRData* modeldata=(CModelRData*) model->GetRenderData(); + modeldata->RenderStreams(streamflags,true); + + glPopMatrix(); + } } \ No newline at end of file diff --git a/source/renderer/TransparencyRenderer.h b/source/renderer/TransparencyRenderer.h index 4415bb067c..cf418b65b7 100755 --- a/source/renderer/TransparencyRenderer.h +++ b/source/renderer/TransparencyRenderer.h @@ -1,39 +1,39 @@ -#ifndef __TRANSPARENCYRENDERER_H -#define __TRANSPARENCYRENDERER_H - -#include - -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 m_Objects; -}; - -extern CTransparencyRenderer g_TransparencyRenderer; - -#endif +#ifndef __TRANSPARENCYRENDERER_H +#define __TRANSPARENCYRENDERER_H + +#include + +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 m_Objects; +}; + +extern CTransparencyRenderer g_TransparencyRenderer; + +#endif diff --git a/source/sced/AlterElevationCommand.cpp b/source/sced/AlterElevationCommand.cpp index 39ffde3a7f..7b9006964b 100755 --- a/source/sced/AlterElevationCommand.cpp +++ b/source/sced/AlterElevationCommand.cpp @@ -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 (xmax) 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& 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;jCalcBounds(); - 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 (xmax) 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& 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;jCalcBounds(); + 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); +} diff --git a/source/sced/AlterElevationCommand.h b/source/sced/AlterElevationCommand.h index f53f095494..a6a5d31f70 100755 --- a/source/sced/AlterElevationCommand.h +++ b/source/sced/AlterElevationCommand.h @@ -1,45 +1,45 @@ -#ifndef _ALTERELEVATIONCOMMAND_H -#define _ALTERELEVATIONCOMMAND_H - -#include -#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& 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 m_DataIn; - // output data (final terrain heights) - CArray2D m_DataOut; -}; - -#endif +#ifndef _ALTERELEVATIONCOMMAND_H +#define _ALTERELEVATIONCOMMAND_H + +#include +#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& 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 m_DataIn; + // output data (final terrain heights) + CArray2D m_DataOut; +}; + +#endif diff --git a/source/sced/AlterLightEnvCommand.cpp b/source/sced/AlterLightEnvCommand.cpp index e12c3c4c14..cde1f76f86 100755 --- a/source/sced/AlterLightEnvCommand.cpp +++ b/source/sced/AlterLightEnvCommand.cpp @@ -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;jSetDirty(RENDERDATA_UPDATE_VERTICES); - } - } - - // dirty all models - const std::vector& units=g_UnitMan.GetUnits(); - for (i=0;iGetModel()->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;jSetDirty(RENDERDATA_UPDATE_VERTICES); + } + } + + // dirty all models + const std::vector& units=g_UnitMan.GetUnits(); + for (i=0;iGetModel()->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); +} diff --git a/source/sced/AlterLightEnvCommand.h b/source/sced/AlterLightEnvCommand.h index 82dbe1350e..c4be37365c 100755 --- a/source/sced/AlterLightEnvCommand.h +++ b/source/sced/AlterLightEnvCommand.h @@ -1,40 +1,40 @@ -#ifndef _ALTERLIGHTENVCOMMAND_H -#define _ALTERLIGHTENVCOMMAND_H - -#include -#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 +#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 diff --git a/source/sced/Array2D.h b/source/sced/Array2D.h index 330817182a..1d589061f1 100755 --- a/source/sced/Array2D.h +++ b/source/sced/Array2D.h @@ -1,202 +1,202 @@ -#ifndef _ARRAY2D_H -#define _ARRAY2D_H - -template -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 -#include - -template -CArray2D::CArray2D() : _usize(0), _vsize(0), _elements(0) -{ -} - -template -CArray2D::CArray2D(int usize,int vsize) - : _usize(usize), _vsize(vsize), _elements(0) -{ - allocate(); -} - -template -CArray2D::CArray2D(int usize,int vsize,const T* elements) - : _usize(usize), _vsize(vsize), _elements(0) -{ - assert(elements!=0); - - allocate(); - fill(elements); -} - -template -CArray2D::CArray2D(const CArray2D& rhs) - : _usize(rhs._usize), _vsize(rhs._vsize), _elements(0) -{ - allocate(); - fill(rhs._elements); -} - -template -CArray2D::~CArray2D() -{ - deallocate(); -} - -template -CArray2D& CArray2D::operator=(const CArray2D& rhs) -{ - if (this==&rhs) - return *this; - - deallocate(); - - _usize=rhs._usize; - _vsize=rhs._vsize; - - allocate(); - fill(rhs._elements); - - return *this; -} - -template -void CArray2D::allocate() -{ - assert(_elements==0); - _elements=new T[_usize*_vsize]; -} - -template -void CArray2D::deallocate() -{ - delete[] _elements; - _elements=0; -} - -template -int CArray2D::usize() const -{ - return _usize; -} - -template -int CArray2D::vsize() const -{ - return _vsize; -} - -template -void CArray2D::size(int& usize,int& vsize) const -{ - usize=_usize; - vsize=_vsize; -} - -template -void CArray2D::resize(int usize,int vsize) -{ - deallocate(); - - _usize=usize; - _vsize=vsize; - allocate(); -} - -template -void CArray2D::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 -T& CArray2D::operator()(int u,int v) -{ - assert(u>=0 && u<_usize); - assert(v>=0 && v<_vsize); - return _elements[(u*_vsize)+v]; -} - -template -const T& CArray2D::operator()(int u,int v) const -{ - assert(u>=0 && u<_usize); - assert(v>=0 && v<_vsize); - return _elements[(u*_vsize)+v]; -} - -template -T& CArray2D::at(int u,int v) -{ - assert(u>=0 && u<_usize); - assert(v>=0 && v<_vsize); - return _elements[(u*_vsize)+v]; -} - -template -const T& CArray2D::at(int u,int v) const -{ - assert(u>=0 && u<_usize); - assert(v>=0 && v<_vsize); - return _elements[(u*_vsize)+v]; -} - -template -CArray2D::operator T*() -{ - return _elements; -} - -template -CArray2D::operator const T*() const -{ - return _elements; -} - -/////////////////////////////////////////////////////////////////////////// - -#endif +#ifndef _ARRAY2D_H +#define _ARRAY2D_H + +template +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 +#include + +template +CArray2D::CArray2D() : _usize(0), _vsize(0), _elements(0) +{ +} + +template +CArray2D::CArray2D(int usize,int vsize) + : _usize(usize), _vsize(vsize), _elements(0) +{ + allocate(); +} + +template +CArray2D::CArray2D(int usize,int vsize,const T* elements) + : _usize(usize), _vsize(vsize), _elements(0) +{ + assert(elements!=0); + + allocate(); + fill(elements); +} + +template +CArray2D::CArray2D(const CArray2D& rhs) + : _usize(rhs._usize), _vsize(rhs._vsize), _elements(0) +{ + allocate(); + fill(rhs._elements); +} + +template +CArray2D::~CArray2D() +{ + deallocate(); +} + +template +CArray2D& CArray2D::operator=(const CArray2D& rhs) +{ + if (this==&rhs) + return *this; + + deallocate(); + + _usize=rhs._usize; + _vsize=rhs._vsize; + + allocate(); + fill(rhs._elements); + + return *this; +} + +template +void CArray2D::allocate() +{ + assert(_elements==0); + _elements=new T[_usize*_vsize]; +} + +template +void CArray2D::deallocate() +{ + delete[] _elements; + _elements=0; +} + +template +int CArray2D::usize() const +{ + return _usize; +} + +template +int CArray2D::vsize() const +{ + return _vsize; +} + +template +void CArray2D::size(int& usize,int& vsize) const +{ + usize=_usize; + vsize=_vsize; +} + +template +void CArray2D::resize(int usize,int vsize) +{ + deallocate(); + + _usize=usize; + _vsize=vsize; + allocate(); +} + +template +void CArray2D::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 +T& CArray2D::operator()(int u,int v) +{ + assert(u>=0 && u<_usize); + assert(v>=0 && v<_vsize); + return _elements[(u*_vsize)+v]; +} + +template +const T& CArray2D::operator()(int u,int v) const +{ + assert(u>=0 && u<_usize); + assert(v>=0 && v<_vsize); + return _elements[(u*_vsize)+v]; +} + +template +T& CArray2D::at(int u,int v) +{ + assert(u>=0 && u<_usize); + assert(v>=0 && v<_vsize); + return _elements[(u*_vsize)+v]; +} + +template +const T& CArray2D::at(int u,int v) const +{ + assert(u>=0 && u<_usize); + assert(v>=0 && v<_vsize); + return _elements[(u*_vsize)+v]; +} + +template +CArray2D::operator T*() +{ + return _elements; +} + +template +CArray2D::operator const T*() const +{ + return _elements; +} + +/////////////////////////////////////////////////////////////////////////// + +#endif diff --git a/source/sced/BrushShapeEditorDlgBar.cpp b/source/sced/BrushShapeEditorDlgBar.cpp index 0412d5ece7..4363fd7201 100755 --- a/source/sced/BrushShapeEditorDlgBar.cpp +++ b/source/sced/BrushShapeEditorDlgBar.cpp @@ -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(); +} diff --git a/source/sced/BrushShapeEditorDlgBar.h b/source/sced/BrushShapeEditorDlgBar.h index b74d1c891c..2dd95157ea 100755 --- a/source/sced/BrushShapeEditorDlgBar.h +++ b/source/sced/BrushShapeEditorDlgBar.h @@ -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 + diff --git a/source/sced/BrushShapeEditorTool.cpp b/source/sced/BrushShapeEditorTool.cpp index 0e895b7777..22d65abe44 100755 --- a/source/sced/BrushShapeEditorTool.cpp +++ b/source/sced/BrushShapeEditorTool.cpp @@ -1,86 +1,86 @@ -#include "BrushShapeEditorTool.h" - -#include -#include -#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;jm_BrushSize ? m_BrushSize : size; - for (u32 j=0;j +#include +#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;jm_BrushSize ? m_BrushSize : size; + for (u32 j=0;j - -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 + +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(); + } + } + } +} + diff --git a/source/sced/BrushTool.h b/source/sced/BrushTool.h index 4d84d1db49..8361d251de 100755 --- a/source/sced/BrushTool.h +++ b/source/sced/BrushTool.h @@ -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 diff --git a/source/sced/ColorButton.cpp b/source/sced/ColorButton.cpp index 52ff1241c8..257c6eca1c 100755 --- a/source/sced/ColorButton.cpp +++ b/source/sced/ColorButton.cpp @@ -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(); + } +} diff --git a/source/sced/ColorButton.h b/source/sced/ColorButton.h index c31fe1c2f5..5f307b7c84 100755 --- a/source/sced/ColorButton.h +++ b/source/sced/ColorButton.h @@ -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_) diff --git a/source/sced/Command.h b/source/sced/Command.h index 52a87fd7cf..2d13d3a57f 100755 --- a/source/sced/Command.h +++ b/source/sced/Command.h @@ -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 diff --git a/source/sced/CommandManager.cpp b/source/sced/CommandManager.cpp index 61b05fafa5..9ba6980ba4 100755 --- a/source/sced/CommandManager.cpp +++ b/source/sced/CommandManager.cpp @@ -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; + } +} diff --git a/source/sced/CommandManager.h b/source/sced/CommandManager.h index 14a6b55aeb..ad11ddfd14 100755 --- a/source/sced/CommandManager.h +++ b/source/sced/CommandManager.h @@ -1,39 +1,39 @@ -#ifndef _COMMANDMANAGER_H -#define _COMMANDMANAGER_H - -class CCommand; -#include -#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 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 +#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 CommandList; + + CommandList::iterator GetIterator(int pos); + CCommand* GetUndoCommand(); + CCommand* GetRedoCommand(); + + i32 m_HistoryPos; + u32 m_CommandHistoryLength; + CommandList m_CommandHistory; +}; + +extern CCommandManager g_CmdMan; + +#endif diff --git a/source/sced/DirectionButton.cpp b/source/sced/DirectionButton.cpp index 5cdc0fa605..0d0432e4a0 100755 --- a/source/sced/DirectionButton.cpp +++ b/source/sced/DirectionButton.cpp @@ -1,96 +1,96 @@ -// DirectionButton.cpp : implementation file -// - -#include -#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 +#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); +} diff --git a/source/sced/DirectionButton.h b/source/sced/DirectionButton.h index f1aec5d593..28f29fee6d 100755 --- a/source/sced/DirectionButton.h +++ b/source/sced/DirectionButton.h @@ -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_) diff --git a/source/sced/EditorData.cpp b/source/sced/EditorData.cpp index c8a7659744..fa6edae200 100755 --- a/source/sced/EditorData.cpp +++ b/source/sced/EditorData.cpp @@ -1,658 +1,658 @@ - - -#include "EditorData.h" -#include "UIGlobals.h" -#include "ToolManager.h" -#include "ObjectManager.h" -#include "UnitManager.h" -#include "TextureManager.h" -#include "Model.h" -#include "SkeletonAnimManager.h" - -#include "ogl.h" -#include "res/tex.h" -#include "time.h" - -#include "BaseEntityCollection.h" -#include "Entity.h" -#include "EntityHandles.h" -#include "EntityManager.h" - -const int NUM_ALPHA_MAPS = 14; -Handle AlphaMaps[NUM_ALPHA_MAPS]; - -CTerrain g_Terrain; -CLightEnv g_LightEnv; -CMiniMap g_MiniMap; -CEditorData g_EditorData; - -CEditorData::CEditorData() -{ - m_ModelMatrix.SetIdentity(); - m_ScenarioName="Scenario01"; -} - -void CEditorData::SetMode(EditMode mode) -{ - if (m_Mode==TEST_MODE && mode!=TEST_MODE) StopTestMode(); - m_Mode=mode; - if (m_Mode==TEST_MODE) StartTestMode(); -} - -bool CEditorData::InitScene() -{ - // setup default lighting environment - g_LightEnv.m_SunColor=RGBColor(1,1,1); - g_LightEnv.m_Rotation=DEGTORAD(270); - g_LightEnv.m_Elevation=DEGTORAD(45); - g_LightEnv.m_TerrainAmbientColor=RGBColor(0,0,0); - g_LightEnv.m_UnitsAmbientColor=RGBColor(0.4f,0.4f,0.4f); - g_Renderer.SetLightEnv(&g_LightEnv); - - // load the default - if (!LoadTerrain("terrain.raw")) return false; - - // get default texture to apply to terrain - CTextureEntry* texture=0; - for (uint i=0;im_MiniPatches[j][i].Tex1=texture ? texture->m_Handle : 0; - } - } - } - } - - // setup camera - InitCamera(); - - // build the terrain plane - float h=128*HEIGHT_SCALE; - u32 mapSize=g_Terrain.GetVerticesPerSide(); - CVector3D pt0(0,h,0),pt1(float(CELL_SIZE*mapSize),h,0),pt2(0,h,float(CELL_SIZE*mapSize)); - m_TerrainPlane.Set(pt0,pt1,pt2); - m_TerrainPlane.Normalize(); - - return true; -} - - -struct TGAHeader { - // header stuff - unsigned char iif_size; - unsigned char cmap_type; - unsigned char image_type; - unsigned char pad[5]; - - // origin : unused - unsigned short d_x_origin; - unsigned short d_y_origin; - - // dimensions - unsigned short width; - unsigned short height; - - // bits per pixel : 16, 24 or 32 - unsigned char bpp; - - // image descriptor : Bits 3-0: size of alpha channel - // Bit 4: must be 0 (reserved) - // Bit 5: should be 0 (origin) - // Bits 6-7: should be 0 (interleaving) - unsigned char image_descriptor; -}; - -static bool saveTGA(const char* filename,int width,int height,unsigned char* data) -{ - FILE* fp=fopen(filename,"wb"); - if (!fp) return false; - - // fill file header - TGAHeader header; - header.iif_size=0; - header.cmap_type=0; - header.image_type=2; - memset(header.pad,0,sizeof(header.pad)); - header.d_x_origin=0; - header.d_y_origin=0; - header.width=width; - header.height=height; - header.bpp=24; - header.image_descriptor=0; - - if (fwrite(&header,sizeof(TGAHeader),1,fp)!=1) { - fclose(fp); - return false; - } - - // write data - if (fwrite(data,width*height*3,1,fp)!=1) { - fclose(fp); - return false; - } - - // return success .. - fclose(fp); - return true; -} - -void CEditorData::LoadAlphaMaps() -{ - const char* fns[CRenderer::NumAlphaMaps] = { - "art/textures/terrain/alphamaps/special/blendcircle.png", - "art/textures/terrain/alphamaps/special/blendlshape.png", - "art/textures/terrain/alphamaps/special/blendedge.png", - "art/textures/terrain/alphamaps/special/blendedgecorner.png", - "art/textures/terrain/alphamaps/special/blendedgetwocorners.png", - "art/textures/terrain/alphamaps/special/blendfourcorners.png", - "art/textures/terrain/alphamaps/special/blendtwooppositecorners.png", - "art/textures/terrain/alphamaps/special/blendlshapecorner.png", - "art/textures/terrain/alphamaps/special/blendtwocorners.png", - "art/textures/terrain/alphamaps/special/blendcorner.png", - "art/textures/terrain/alphamaps/special/blendtwoedges.png", - "art/textures/terrain/alphamaps/special/blendthreecorners.png", - "art/textures/terrain/alphamaps/special/blendushape.png", - "art/textures/terrain/alphamaps/special/blendbad.png" - }; - - g_Renderer.LoadAlphaMaps(fns); -} - -void CEditorData::InitResources() -{ - g_TexMan.LoadTerrainTextures(); - LoadAlphaMaps(); - g_ObjMan.LoadObjects(); -} - -///////////////////////////////////////////////////////////////////////////////////////////////// -// InitSingletons: create and initialise required singletons -void CEditorData::InitSingletons() -{ - // create terrain related stuff - new CTextureManager; - - // create actor related stuff - new CSkeletonAnimManager; - new CObjectManager; - new CUnitManager; - - // create entity related stuff - new CBaseEntityCollection; - new CEntityManager; - g_EntityTemplateCollection.loadTemplates(); -} - -///////////////////////////////////////////////////////////////////////////////////////////////// -// Init: perform one time initialisation of the editor -bool CEditorData::Init() -{ - // create and initialise singletons - InitSingletons(); - - // load default textures - InitResources(); - - // create the scene - terrain, camera, light environment etc - if (!InitScene()) return false; - - // set up an empty minimap - g_MiniMap.Initialise(); - - // set up the info box - m_InfoBox.Initialise(); - - return true; -} - -///////////////////////////////////////////////////////////////////////////////////////////////// -// Terminate: close down the editor (destroy singletons in reverse order to construction) -void CEditorData::Terminate() -{ - // destroy entity related stuff - delete CEntityManager::GetSingletonPtr(); - delete CBaseEntityCollection::GetSingletonPtr(); - - // destroy actor related stuff - delete CUnitManager::GetSingletonPtr(); - delete CObjectManager::GetSingletonPtr(); - delete CSkeletonAnimManager::GetSingletonPtr(); - - // destroy terrain related stuff - delete CTextureManager::GetSingletonPtr(); -} - -void CEditorData::InitCamera() -{ - g_NaviCam.GetCamera().SetProjection(1.0f,10000.0f,DEGTORAD(90)); - g_NaviCam.GetCamera().m_Orientation.SetIdentity(); -#ifdef TOPDOWNVIEW - g_NaviCam.GetCamera().m_Orientation.RotateX(DEGTORAD(90)); - g_NaviCam.GetCamera().m_Orientation.Translate(CELL_SIZE*250*0.5, 80, CELL_SIZE*250*0.5); -#else - g_NaviCam.GetCamera().m_Orientation.RotateX(DEGTORAD(40)); - g_NaviCam.GetCamera().m_Orientation.RotateY(DEGTORAD(-45)); - g_NaviCam.GetCamera().m_Orientation.Translate(600, 200, 125); -#endif - - OnCameraChanged(); -} - -void CEditorData::OnCameraChanged() -{ - int width=g_Renderer.GetWidth(); - int height=g_Renderer.GetHeight(); - - // resize viewport - SViewPort viewport; - viewport.m_X=0; - viewport.m_Y=0; - viewport.m_Width=width; - viewport.m_Height=height; - g_NaviCam.GetCamera().SetViewPort(&viewport); - - // rebuild object camera - m_ObjectCamera.SetViewPort(&viewport); - m_ObjectCamera.SetProjection(1.0f,10000.0f,DEGTORAD(90)); - - - // recalculate projection matrix - g_NaviCam.GetCamera().SetProjection(1.0f,10000.0f,DEGTORAD(20)); - - // update viewing frustum - g_NaviCam.GetCamera().UpdateFrustum(); - - // calculate intersection of camera stabbing lines with terrain plane - - // get points of back plane of frustum in camera space - float aspect=height>0 ? float(width)/float(height) : 1.0f; - float zfar=g_NaviCam.GetCamera().GetFarPlane(); - CVector3D cPts[4]; - float x=zfar*float(tan(g_NaviCam.GetCamera().GetFOV()*aspect*0.5)); - float y=zfar*float(tan(g_NaviCam.GetCamera().GetFOV()*0.5)); - cPts[0].X=-x; - cPts[0].Y=-y; - cPts[0].Z=zfar; - cPts[1].X=x; - cPts[1].Y=-y; - cPts[1].Z=zfar; - cPts[2].X=x; - cPts[2].Y=y; - cPts[2].Z=zfar; - cPts[3].X=-x; - cPts[3].Y=y; - cPts[3].Z=zfar; - - // transform to world space - CVector3D wPts[4]; - for (int i=0;i<4;i++) { - wPts[i]=g_NaviCam.GetCamera().m_Orientation.Transform(cPts[i]); - } - - // now intersect a ray from the camera through each point - CVector3D rayOrigin=g_NaviCam.GetCamera().m_Orientation.GetTranslation(); - CVector3D rayDir=g_NaviCam.GetCamera().m_Orientation.GetIn(); - - CVector3D hitPt[4]; - for (i=0;i<4;i++) { - CVector3D rayDir=wPts[i]-rayOrigin; - rayDir.Normalize(); - - // get intersection point - m_TerrainPlane.FindRayIntersection(rayOrigin,rayDir,&hitPt[i]); - } - - for (i=0;i<4;i++) { - // convert to minimap space - float px=hitPt[i].X; - float pz=hitPt[i].Z; - g_MiniMap.m_ViewRect[i][0]=(197*px/float(CELL_SIZE*g_Terrain.GetVerticesPerSide())); - g_MiniMap.m_ViewRect[i][1]=197*pz/float(CELL_SIZE*g_Terrain.GetVerticesPerSide()); - } -} - -void CEditorData::RenderTerrain() -{ - CFrustum frustum=g_NaviCam.GetCamera().GetFustum(); - u32 patchesPerSide=g_Terrain.GetPatchesPerSide(); - for (uint j=0; jGetBounds())) { - g_Renderer.Submit(patch); - } - } - } -} - -void CEditorData::OnScreenShot(const char* filename) -{ - g_Renderer.SetClearColor(0); - g_Renderer.BeginFrame(); - g_Renderer.SetCamera(g_NaviCam.GetCamera()); - - RenderWorld(); - - g_Renderer.EndFrame(); - - int width=g_Renderer.GetWidth(); - int height=g_Renderer.GetHeight(); - unsigned char* data=new unsigned char[width*height*3]; - - glReadBuffer(GL_BACK); - glReadPixels(0,0,width,height,GL_BGR_EXT,GL_UNSIGNED_BYTE,data); - - saveTGA(filename,width,height,data); - - delete[] data; -} - -////////////////////////////////////////////////////////////////////////////////////////////////// -// 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& props=model->GetProps(); - for (uint i=0;i& units=g_UnitMan.GetUnits(); - for (i=0;iGetModel()); - } - - u32 patchesPerSide=g_Terrain.GetPatchesPerSide(); - for (j=0; j& units=g_UnitMan.GetUnits(); - uint i; - for (i=0;iGetModel()->GetBounds())) { - SubmitModelRecursive(units[i]->GetModel()); - } - } -} - -void CEditorData::RenderWorld() -{ - // render terrain - RenderTerrain(); - - // render all the units - RenderModels(); - - // flush prior to rendering overlays etc - g_Renderer.FlushFrame(); -} - -void CEditorData::RenderObEdGrid() -{ - int i; - const int numSteps=32; - const CVector3D start(-numSteps*CELL_SIZE/2,0,-numSteps*CELL_SIZE/2); - const CVector3D end(numSteps*CELL_SIZE/2,0,numSteps*CELL_SIZE/2); - - glDisable(GL_TEXTURE_2D); - - glDepthMask(0); - glColor4f(0.5f,0.5f,0.5f,0.35f); - glLineWidth(1.0f); - - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); - - glBegin(GL_LINES); - for (i=0;i<=numSteps;i++) { - if (i%8==0) continue; - CVector3D v0(start.X+(i*(end.X-start.X))/float(numSteps),start.Y,start.Z); - glVertex3fv(&v0.X); - - CVector3D v1(v0.X,end.Y,end.Z); - glVertex3fv(&v1.X); - } - - for (i=0;i<=numSteps;i++) { - if (i%8==0) continue; - CVector3D v0(start.X,start.Y,start.Z+(i*(end.Z-start.Z))/float(numSteps)); - glVertex3fv(&v0.X); - - CVector3D v1(end.X,end.Y,v0.Z); - glVertex3fv(&v1.X); - } - glEnd(); - - glDisable(GL_BLEND); - - glColor3f(0,0,0.5); - glLineWidth(2.0f); - - glBegin(GL_LINES); - for (i=0;i<=numSteps;i+=8) { - CVector3D v0(start.X+(i*(end.X-start.X))/float(numSteps),start.Y,start.Z); - glVertex3fv(&v0.X); - - CVector3D v1(v0.X,end.Y,end.Z); - glVertex3fv(&v1.X); - } - - for (i=0;i<=numSteps;i+=8) { - CVector3D v0(start.X,start.Y,start.Z+(i*(end.Z-start.Z))/float(numSteps)); - glVertex3fv(&v0.X); - - CVector3D v1(end.X,end.Y,v0.Z); - glVertex3fv(&v1.X); - } - glEnd(); - glDepthMask(1); -} - -void CEditorData::OnDraw() -{ - if (m_Mode==SCENARIO_EDIT || m_Mode==TEST_MODE) { - g_Renderer.SetClearColor(0); - g_Renderer.BeginFrame(); - - // setup camera - g_Renderer.SetCamera(g_NaviCam.GetCamera()); - - // render base terrain plus models - RenderWorld(); - - if (m_Mode!=TEST_MODE) { - // render the active tool - g_ToolMan.OnDraw(); - } - - // flush prior to rendering overlays .. - g_Renderer.FlushFrame(); - - // .. and here's the overlays - g_MiniMap.Render(); - m_InfoBox.Render(); - } else { - g_Renderer.SetClearColor(0x00453015); - g_Renderer.BeginFrame(); - - CObjectEntry* selobject=g_ObjMan.GetSelectedObject(); - if (selobject && selobject->m_Model) { - // setup camera such that object is in the centre of the viewport - m_ModelMatrix.SetIdentity(); - selobject->m_Model->SetTransform(m_ModelMatrix); - - const CBound& bound=selobject->m_Model->GetBounds(); - CVector3D pt((bound[0].X+bound[1].X)*0.5f,(bound[0].Y+bound[1].Y)*0.5f,bound[0].Z); - - float hfov=tan(DEGTORAD(45)); - float vfov=hfov/g_Renderer.GetAspect(); - float zx=(bound[1].X-bound[0].X)*0.5f/hfov; - float zy=(bound[1].Y-bound[0].Y)*0.5f/vfov; - float z=zx>zy ? zx : zy; - z=(z+1)*2; - - m_ObjectCamera.m_Orientation.SetIdentity(); - m_ObjectCamera.m_Orientation.Translate(pt.X,pt.Y,-z); - - g_Renderer.SetCamera(m_ObjectCamera); - - RenderObEdGrid(); - - g_Renderer.Submit(selobject->m_Model); - } - - // flush prior to rendering overlays .. - g_Renderer.FlushFrame(); - - // .. and here's the overlays - m_InfoBox.Render(); - } - - g_Renderer.EndFrame(); - - // notify info box frame is complete; gives it chance to accumulate stats, check - // fps, etc - m_InfoBox.OnFrameComplete(); -} - - -bool CEditorData::LoadTerrain(const char* filename) -{ - Handle h = tex_load(filename); - if(h<=0) { - char buf[1024]; - sprintf(buf,"Failed to load \"%s\"",filename); - ErrorBox(buf); - return false; - } else { - - int width=0; - int height=0; - int bpp=0; - void *ptr=0; - - int i=tex_info(h, &width, &height, NULL, &bpp, &ptr); - if (i) - { - printf("tex_info error: %d\n",i); - fflush(stdout); - } - - // rescale the texture to fit to the nearest of the 4 possible map sizes - u32 mapsize=9; // assume smallest map - if (width>11*16+1) mapsize=11; - if (width>13*16+1) mapsize=13; - if (width>17*16+1) mapsize=17; - - u32 targetsize=mapsize*16+1; - unsigned char* data=new unsigned char[targetsize*targetsize*bpp/8]; - u32 fmt=(bpp==8) ? GL_RED : ((bpp==24) ? GL_RGB : GL_RGBA); - gluScaleImage(fmt,width,height,GL_UNSIGNED_BYTE,ptr, - targetsize,targetsize,GL_UNSIGNED_BYTE,data); - - // build 16 bit heightmap from red channel of texture - u16* heightmap=new u16[targetsize*targetsize]; - int stride=bpp/8; - u16* hmptr=heightmap; - - // get src of copy - const u8* dataptr = (bpp==8) ? data : ((bpp==24) ? data+2 : data+3); - - // build heightmap - for (uint j=0;j& units=g_UnitMan.GetUnits(); - for (uint i=0;iGetModel()->Update(time); - } - if (m_Mode==TEST_MODE) { - g_EntityManager.updateAll( time ); - } - } else { - CObjectEntry* selobject=g_ObjMan.GetSelectedObject(); - if (selobject && selobject->m_Model) { - selobject->m_Model->Update(time); - } - } -} - -void CEditorData::StartTestMode() -{ - // initialise entities - g_EntityManager.dispatchAll( &CMessage( CMessage::EMSG_INIT ) ); -} - -void CEditorData::StopTestMode() -{ - // make all units idle again - const std::vector& units=g_UnitMan.GetUnits(); - for (uint i=0;iGetObject()->m_IdleAnim) { - units[i]->GetModel()->SetAnimation(units[i]->GetObject()->m_IdleAnim); - } - } + + +#include "EditorData.h" +#include "UIGlobals.h" +#include "ToolManager.h" +#include "ObjectManager.h" +#include "UnitManager.h" +#include "TextureManager.h" +#include "Model.h" +#include "SkeletonAnimManager.h" + +#include "ogl.h" +#include "res/tex.h" +#include "time.h" + +#include "BaseEntityCollection.h" +#include "Entity.h" +#include "EntityHandles.h" +#include "EntityManager.h" + +const int NUM_ALPHA_MAPS = 14; +Handle AlphaMaps[NUM_ALPHA_MAPS]; + +CTerrain g_Terrain; +CLightEnv g_LightEnv; +CMiniMap g_MiniMap; +CEditorData g_EditorData; + +CEditorData::CEditorData() +{ + m_ModelMatrix.SetIdentity(); + m_ScenarioName="Scenario01"; +} + +void CEditorData::SetMode(EditMode mode) +{ + if (m_Mode==TEST_MODE && mode!=TEST_MODE) StopTestMode(); + m_Mode=mode; + if (m_Mode==TEST_MODE) StartTestMode(); +} + +bool CEditorData::InitScene() +{ + // setup default lighting environment + g_LightEnv.m_SunColor=RGBColor(1,1,1); + g_LightEnv.m_Rotation=DEGTORAD(270); + g_LightEnv.m_Elevation=DEGTORAD(45); + g_LightEnv.m_TerrainAmbientColor=RGBColor(0,0,0); + g_LightEnv.m_UnitsAmbientColor=RGBColor(0.4f,0.4f,0.4f); + g_Renderer.SetLightEnv(&g_LightEnv); + + // load the default + if (!LoadTerrain("terrain.raw")) return false; + + // get default texture to apply to terrain + CTextureEntry* texture=0; + for (uint i=0;im_MiniPatches[j][i].Tex1=texture ? texture->m_Handle : 0; + } + } + } + } + + // setup camera + InitCamera(); + + // build the terrain plane + float h=128*HEIGHT_SCALE; + u32 mapSize=g_Terrain.GetVerticesPerSide(); + CVector3D pt0(0,h,0),pt1(float(CELL_SIZE*mapSize),h,0),pt2(0,h,float(CELL_SIZE*mapSize)); + m_TerrainPlane.Set(pt0,pt1,pt2); + m_TerrainPlane.Normalize(); + + return true; +} + + +struct TGAHeader { + // header stuff + unsigned char iif_size; + unsigned char cmap_type; + unsigned char image_type; + unsigned char pad[5]; + + // origin : unused + unsigned short d_x_origin; + unsigned short d_y_origin; + + // dimensions + unsigned short width; + unsigned short height; + + // bits per pixel : 16, 24 or 32 + unsigned char bpp; + + // image descriptor : Bits 3-0: size of alpha channel + // Bit 4: must be 0 (reserved) + // Bit 5: should be 0 (origin) + // Bits 6-7: should be 0 (interleaving) + unsigned char image_descriptor; +}; + +static bool saveTGA(const char* filename,int width,int height,unsigned char* data) +{ + FILE* fp=fopen(filename,"wb"); + if (!fp) return false; + + // fill file header + TGAHeader header; + header.iif_size=0; + header.cmap_type=0; + header.image_type=2; + memset(header.pad,0,sizeof(header.pad)); + header.d_x_origin=0; + header.d_y_origin=0; + header.width=width; + header.height=height; + header.bpp=24; + header.image_descriptor=0; + + if (fwrite(&header,sizeof(TGAHeader),1,fp)!=1) { + fclose(fp); + return false; + } + + // write data + if (fwrite(data,width*height*3,1,fp)!=1) { + fclose(fp); + return false; + } + + // return success .. + fclose(fp); + return true; +} + +void CEditorData::LoadAlphaMaps() +{ + const char* fns[CRenderer::NumAlphaMaps] = { + "art/textures/terrain/alphamaps/special/blendcircle.png", + "art/textures/terrain/alphamaps/special/blendlshape.png", + "art/textures/terrain/alphamaps/special/blendedge.png", + "art/textures/terrain/alphamaps/special/blendedgecorner.png", + "art/textures/terrain/alphamaps/special/blendedgetwocorners.png", + "art/textures/terrain/alphamaps/special/blendfourcorners.png", + "art/textures/terrain/alphamaps/special/blendtwooppositecorners.png", + "art/textures/terrain/alphamaps/special/blendlshapecorner.png", + "art/textures/terrain/alphamaps/special/blendtwocorners.png", + "art/textures/terrain/alphamaps/special/blendcorner.png", + "art/textures/terrain/alphamaps/special/blendtwoedges.png", + "art/textures/terrain/alphamaps/special/blendthreecorners.png", + "art/textures/terrain/alphamaps/special/blendushape.png", + "art/textures/terrain/alphamaps/special/blendbad.png" + }; + + g_Renderer.LoadAlphaMaps(fns); +} + +void CEditorData::InitResources() +{ + g_TexMan.LoadTerrainTextures(); + LoadAlphaMaps(); + g_ObjMan.LoadObjects(); +} + +///////////////////////////////////////////////////////////////////////////////////////////////// +// InitSingletons: create and initialise required singletons +void CEditorData::InitSingletons() +{ + // create terrain related stuff + new CTextureManager; + + // create actor related stuff + new CSkeletonAnimManager; + new CObjectManager; + new CUnitManager; + + // create entity related stuff + new CBaseEntityCollection; + new CEntityManager; + g_EntityTemplateCollection.loadTemplates(); +} + +///////////////////////////////////////////////////////////////////////////////////////////////// +// Init: perform one time initialisation of the editor +bool CEditorData::Init() +{ + // create and initialise singletons + InitSingletons(); + + // load default textures + InitResources(); + + // create the scene - terrain, camera, light environment etc + if (!InitScene()) return false; + + // set up an empty minimap + g_MiniMap.Initialise(); + + // set up the info box + m_InfoBox.Initialise(); + + return true; +} + +///////////////////////////////////////////////////////////////////////////////////////////////// +// Terminate: close down the editor (destroy singletons in reverse order to construction) +void CEditorData::Terminate() +{ + // destroy entity related stuff + delete CEntityManager::GetSingletonPtr(); + delete CBaseEntityCollection::GetSingletonPtr(); + + // destroy actor related stuff + delete CUnitManager::GetSingletonPtr(); + delete CObjectManager::GetSingletonPtr(); + delete CSkeletonAnimManager::GetSingletonPtr(); + + // destroy terrain related stuff + delete CTextureManager::GetSingletonPtr(); +} + +void CEditorData::InitCamera() +{ + g_NaviCam.GetCamera().SetProjection(1.0f,10000.0f,DEGTORAD(90)); + g_NaviCam.GetCamera().m_Orientation.SetIdentity(); +#ifdef TOPDOWNVIEW + g_NaviCam.GetCamera().m_Orientation.RotateX(DEGTORAD(90)); + g_NaviCam.GetCamera().m_Orientation.Translate(CELL_SIZE*250*0.5, 80, CELL_SIZE*250*0.5); +#else + g_NaviCam.GetCamera().m_Orientation.RotateX(DEGTORAD(40)); + g_NaviCam.GetCamera().m_Orientation.RotateY(DEGTORAD(-45)); + g_NaviCam.GetCamera().m_Orientation.Translate(600, 200, 125); +#endif + + OnCameraChanged(); +} + +void CEditorData::OnCameraChanged() +{ + int width=g_Renderer.GetWidth(); + int height=g_Renderer.GetHeight(); + + // resize viewport + SViewPort viewport; + viewport.m_X=0; + viewport.m_Y=0; + viewport.m_Width=width; + viewport.m_Height=height; + g_NaviCam.GetCamera().SetViewPort(&viewport); + + // rebuild object camera + m_ObjectCamera.SetViewPort(&viewport); + m_ObjectCamera.SetProjection(1.0f,10000.0f,DEGTORAD(90)); + + + // recalculate projection matrix + g_NaviCam.GetCamera().SetProjection(1.0f,10000.0f,DEGTORAD(20)); + + // update viewing frustum + g_NaviCam.GetCamera().UpdateFrustum(); + + // calculate intersection of camera stabbing lines with terrain plane + + // get points of back plane of frustum in camera space + float aspect=height>0 ? float(width)/float(height) : 1.0f; + float zfar=g_NaviCam.GetCamera().GetFarPlane(); + CVector3D cPts[4]; + float x=zfar*float(tan(g_NaviCam.GetCamera().GetFOV()*aspect*0.5)); + float y=zfar*float(tan(g_NaviCam.GetCamera().GetFOV()*0.5)); + cPts[0].X=-x; + cPts[0].Y=-y; + cPts[0].Z=zfar; + cPts[1].X=x; + cPts[1].Y=-y; + cPts[1].Z=zfar; + cPts[2].X=x; + cPts[2].Y=y; + cPts[2].Z=zfar; + cPts[3].X=-x; + cPts[3].Y=y; + cPts[3].Z=zfar; + + // transform to world space + CVector3D wPts[4]; + for (int i=0;i<4;i++) { + wPts[i]=g_NaviCam.GetCamera().m_Orientation.Transform(cPts[i]); + } + + // now intersect a ray from the camera through each point + CVector3D rayOrigin=g_NaviCam.GetCamera().m_Orientation.GetTranslation(); + CVector3D rayDir=g_NaviCam.GetCamera().m_Orientation.GetIn(); + + CVector3D hitPt[4]; + for (i=0;i<4;i++) { + CVector3D rayDir=wPts[i]-rayOrigin; + rayDir.Normalize(); + + // get intersection point + m_TerrainPlane.FindRayIntersection(rayOrigin,rayDir,&hitPt[i]); + } + + for (i=0;i<4;i++) { + // convert to minimap space + float px=hitPt[i].X; + float pz=hitPt[i].Z; + g_MiniMap.m_ViewRect[i][0]=(197*px/float(CELL_SIZE*g_Terrain.GetVerticesPerSide())); + g_MiniMap.m_ViewRect[i][1]=197*pz/float(CELL_SIZE*g_Terrain.GetVerticesPerSide()); + } +} + +void CEditorData::RenderTerrain() +{ + CFrustum frustum=g_NaviCam.GetCamera().GetFustum(); + u32 patchesPerSide=g_Terrain.GetPatchesPerSide(); + for (uint j=0; jGetBounds())) { + g_Renderer.Submit(patch); + } + } + } +} + +void CEditorData::OnScreenShot(const char* filename) +{ + g_Renderer.SetClearColor(0); + g_Renderer.BeginFrame(); + g_Renderer.SetCamera(g_NaviCam.GetCamera()); + + RenderWorld(); + + g_Renderer.EndFrame(); + + int width=g_Renderer.GetWidth(); + int height=g_Renderer.GetHeight(); + unsigned char* data=new unsigned char[width*height*3]; + + glReadBuffer(GL_BACK); + glReadPixels(0,0,width,height,GL_BGR_EXT,GL_UNSIGNED_BYTE,data); + + saveTGA(filename,width,height,data); + + delete[] data; +} + +////////////////////////////////////////////////////////////////////////////////////////////////// +// 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& props=model->GetProps(); + for (uint i=0;i& units=g_UnitMan.GetUnits(); + for (i=0;iGetModel()); + } + + u32 patchesPerSide=g_Terrain.GetPatchesPerSide(); + for (j=0; j& units=g_UnitMan.GetUnits(); + uint i; + for (i=0;iGetModel()->GetBounds())) { + SubmitModelRecursive(units[i]->GetModel()); + } + } +} + +void CEditorData::RenderWorld() +{ + // render terrain + RenderTerrain(); + + // render all the units + RenderModels(); + + // flush prior to rendering overlays etc + g_Renderer.FlushFrame(); +} + +void CEditorData::RenderObEdGrid() +{ + int i; + const int numSteps=32; + const CVector3D start(-numSteps*CELL_SIZE/2,0,-numSteps*CELL_SIZE/2); + const CVector3D end(numSteps*CELL_SIZE/2,0,numSteps*CELL_SIZE/2); + + glDisable(GL_TEXTURE_2D); + + glDepthMask(0); + glColor4f(0.5f,0.5f,0.5f,0.35f); + glLineWidth(1.0f); + + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); + + glBegin(GL_LINES); + for (i=0;i<=numSteps;i++) { + if (i%8==0) continue; + CVector3D v0(start.X+(i*(end.X-start.X))/float(numSteps),start.Y,start.Z); + glVertex3fv(&v0.X); + + CVector3D v1(v0.X,end.Y,end.Z); + glVertex3fv(&v1.X); + } + + for (i=0;i<=numSteps;i++) { + if (i%8==0) continue; + CVector3D v0(start.X,start.Y,start.Z+(i*(end.Z-start.Z))/float(numSteps)); + glVertex3fv(&v0.X); + + CVector3D v1(end.X,end.Y,v0.Z); + glVertex3fv(&v1.X); + } + glEnd(); + + glDisable(GL_BLEND); + + glColor3f(0,0,0.5); + glLineWidth(2.0f); + + glBegin(GL_LINES); + for (i=0;i<=numSteps;i+=8) { + CVector3D v0(start.X+(i*(end.X-start.X))/float(numSteps),start.Y,start.Z); + glVertex3fv(&v0.X); + + CVector3D v1(v0.X,end.Y,end.Z); + glVertex3fv(&v1.X); + } + + for (i=0;i<=numSteps;i+=8) { + CVector3D v0(start.X,start.Y,start.Z+(i*(end.Z-start.Z))/float(numSteps)); + glVertex3fv(&v0.X); + + CVector3D v1(end.X,end.Y,v0.Z); + glVertex3fv(&v1.X); + } + glEnd(); + glDepthMask(1); +} + +void CEditorData::OnDraw() +{ + if (m_Mode==SCENARIO_EDIT || m_Mode==TEST_MODE) { + g_Renderer.SetClearColor(0); + g_Renderer.BeginFrame(); + + // setup camera + g_Renderer.SetCamera(g_NaviCam.GetCamera()); + + // render base terrain plus models + RenderWorld(); + + if (m_Mode!=TEST_MODE) { + // render the active tool + g_ToolMan.OnDraw(); + } + + // flush prior to rendering overlays .. + g_Renderer.FlushFrame(); + + // .. and here's the overlays + g_MiniMap.Render(); + m_InfoBox.Render(); + } else { + g_Renderer.SetClearColor(0x00453015); + g_Renderer.BeginFrame(); + + CObjectEntry* selobject=g_ObjMan.GetSelectedObject(); + if (selobject && selobject->m_Model) { + // setup camera such that object is in the centre of the viewport + m_ModelMatrix.SetIdentity(); + selobject->m_Model->SetTransform(m_ModelMatrix); + + const CBound& bound=selobject->m_Model->GetBounds(); + CVector3D pt((bound[0].X+bound[1].X)*0.5f,(bound[0].Y+bound[1].Y)*0.5f,bound[0].Z); + + float hfov=tan(DEGTORAD(45)); + float vfov=hfov/g_Renderer.GetAspect(); + float zx=(bound[1].X-bound[0].X)*0.5f/hfov; + float zy=(bound[1].Y-bound[0].Y)*0.5f/vfov; + float z=zx>zy ? zx : zy; + z=(z+1)*2; + + m_ObjectCamera.m_Orientation.SetIdentity(); + m_ObjectCamera.m_Orientation.Translate(pt.X,pt.Y,-z); + + g_Renderer.SetCamera(m_ObjectCamera); + + RenderObEdGrid(); + + g_Renderer.Submit(selobject->m_Model); + } + + // flush prior to rendering overlays .. + g_Renderer.FlushFrame(); + + // .. and here's the overlays + m_InfoBox.Render(); + } + + g_Renderer.EndFrame(); + + // notify info box frame is complete; gives it chance to accumulate stats, check + // fps, etc + m_InfoBox.OnFrameComplete(); +} + + +bool CEditorData::LoadTerrain(const char* filename) +{ + Handle h = tex_load(filename); + if(h<=0) { + char buf[1024]; + sprintf(buf,"Failed to load \"%s\"",filename); + ErrorBox(buf); + return false; + } else { + + int width=0; + int height=0; + int bpp=0; + void *ptr=0; + + int i=tex_info(h, &width, &height, NULL, &bpp, &ptr); + if (i) + { + printf("tex_info error: %d\n",i); + fflush(stdout); + } + + // rescale the texture to fit to the nearest of the 4 possible map sizes + u32 mapsize=9; // assume smallest map + if (width>11*16+1) mapsize=11; + if (width>13*16+1) mapsize=13; + if (width>17*16+1) mapsize=17; + + u32 targetsize=mapsize*16+1; + unsigned char* data=new unsigned char[targetsize*targetsize*bpp/8]; + u32 fmt=(bpp==8) ? GL_RED : ((bpp==24) ? GL_RGB : GL_RGBA); + gluScaleImage(fmt,width,height,GL_UNSIGNED_BYTE,ptr, + targetsize,targetsize,GL_UNSIGNED_BYTE,data); + + // build 16 bit heightmap from red channel of texture + u16* heightmap=new u16[targetsize*targetsize]; + int stride=bpp/8; + u16* hmptr=heightmap; + + // get src of copy + const u8* dataptr = (bpp==8) ? data : ((bpp==24) ? data+2 : data+3); + + // build heightmap + for (uint j=0;j& units=g_UnitMan.GetUnits(); + for (uint i=0;iGetModel()->Update(time); + } + if (m_Mode==TEST_MODE) { + g_EntityManager.updateAll( time ); + } + } else { + CObjectEntry* selobject=g_ObjMan.GetSelectedObject(); + if (selobject && selobject->m_Model) { + selobject->m_Model->Update(time); + } + } +} + +void CEditorData::StartTestMode() +{ + // initialise entities + g_EntityManager.dispatchAll( &CMessage( CMessage::EMSG_INIT ) ); +} + +void CEditorData::StopTestMode() +{ + // make all units idle again + const std::vector& units=g_UnitMan.GetUnits(); + for (uint i=0;iGetObject()->m_IdleAnim) { + units[i]->GetModel()->SetAnimation(units[i]->GetObject()->m_IdleAnim); + } + } } \ No newline at end of file diff --git a/source/sced/EditorData.h b/source/sced/EditorData.h index ee55fd4038..3d4535db98 100755 --- a/source/sced/EditorData.h +++ b/source/sced/EditorData.h @@ -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 diff --git a/source/sced/ElevToolsDlgBar.cpp b/source/sced/ElevToolsDlgBar.cpp index 5198ac44f0..485bf78730 100755 --- a/source/sced/ElevToolsDlgBar.cpp +++ b/source/sced/ElevToolsDlgBar.cpp @@ -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; +} + diff --git a/source/sced/ElevToolsDlgBar.h b/source/sced/ElevToolsDlgBar.h index 9e8ad14e4a..8fe7cc8856 100755 --- a/source/sced/ElevToolsDlgBar.h +++ b/source/sced/ElevToolsDlgBar.h @@ -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 diff --git a/source/sced/ElevationButton.cpp b/source/sced/ElevationButton.cpp index ac1e9290c4..fb09666d97 100755 --- a/source/sced/ElevationButton.cpp +++ b/source/sced/ElevationButton.cpp @@ -1,98 +1,98 @@ -// ElevationButton.cpp : implementation file -// - -#include -#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 +#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); +} diff --git a/source/sced/ElevationButton.h b/source/sced/ElevationButton.h index 597182975c..8dd99b9faa 100755 --- a/source/sced/ElevationButton.h +++ b/source/sced/ElevationButton.h @@ -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_) diff --git a/source/sced/ImageListCtrl.cpp b/source/sced/ImageListCtrl.cpp index 630ec32d32..f34fee3da5 100755 --- a/source/sced/ImageListCtrl.cpp +++ b/source/sced/ImageListCtrl.cpp @@ -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) +{ +} diff --git a/source/sced/ImageListCtrl.h b/source/sced/ImageListCtrl.h index 07015f022d..695146b48e 100755 --- a/source/sced/ImageListCtrl.h +++ b/source/sced/ImageListCtrl.h @@ -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_) diff --git a/source/sced/InfoBox.cpp b/source/sced/InfoBox.cpp index ae2f36951b..e75dc61966 100755 --- a/source/sced/InfoBox.cpp +++ b/source/sced/InfoBox.cpp @@ -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;ichardata(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;ichardata(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(); + } } \ No newline at end of file diff --git a/source/sced/InfoBox.h b/source/sced/InfoBox.h index d700a84695..47ad4d893d 100755 --- a/source/sced/InfoBox.h +++ b/source/sced/InfoBox.h @@ -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 diff --git a/source/sced/LightSettingsDlg.cpp b/source/sced/LightSettingsDlg.cpp index 338e55b488..2cb6d779e8 100755 --- a/source/sced/LightSettingsDlg.cpp +++ b/source/sced/LightSettingsDlg.cpp @@ -1,170 +1,170 @@ -// LightSettingsDlg.cpp : implementation file -// - -#include "stdafx.h" -#include "ScEd.h" -#include "LightSettingsDlg.h" - -#include - -#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 + +#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); + } +} + diff --git a/source/sced/LightSettingsDlg.h b/source/sced/LightSettingsDlg.h index 983b543a45..88c4974217 100755 --- a/source/sced/LightSettingsDlg.h +++ b/source/sced/LightSettingsDlg.h @@ -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_) diff --git a/source/sced/MainFrameDlgBar.cpp b/source/sced/MainFrameDlgBar.cpp index bb3ff51f86..59e361affc 100755 --- a/source/sced/MainFrameDlgBar.cpp +++ b/source/sced/MainFrameDlgBar.cpp @@ -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 +} diff --git a/source/sced/MainFrameDlgBar.h b/source/sced/MainFrameDlgBar.h index de9f6a8f59..57beea76a6 100755 --- a/source/sced/MainFrameDlgBar.h +++ b/source/sced/MainFrameDlgBar.h @@ -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_) diff --git a/source/sced/MainFrm.cpp b/source/sced/MainFrm.cpp index 8e04def31c..f492a3f640 100755 --- a/source/sced/MainFrm.cpp +++ b/source/sced/MainFrm.cpp @@ -1,719 +1,719 @@ -// MainFrm.cpp : implementation of the CMainFrame class -// - -#include "stdafx.h" - -#include "ogl.h" -#include "res/tex.h" -#include "res/mem.h" -#include "res/vfs.h" - -#include "ScEd.h" -#include "ScEdView.h" -#include "MiniMap.h" -#include "MapReader.h" -#include "MapWriter.h" - -#include "UserConfig.h" - -#include "Unit.h" -#include "UnitManager.h" -#include "UIGlobals.h" -#include "MainFrm.h" -#include "OptionsPropSheet.h" -#include "LightSettingsDlg.h" -#include "MapSizeDlg.h" -#include "EditorData.h" -#include "ToolManager.h" -#include "CommandManager.h" - -#include "AlterLightEnvCommand.h" - -#include "LightEnv.h" -#include "Terrain.h" - -#include "PaintTextureTool.h" -#include "PaintObjectTool.h" -#include "RaiseElevationTool.h" -#include "BrushShapeEditorTool.h" - -extern CTerrain g_Terrain; -extern CLightEnv g_LightEnv; - -///////////////////////////////////////////////////////////////////////////// -// CMainFrame - - -IMPLEMENT_DYNCREATE(CMainFrame, CFrameWnd) - -BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd) - //{{AFX_MSG_MAP(CMainFrame) - ON_WM_CREATE() - ON_COMMAND(ID_TERRAIN_LOAD, OnTerrainLoad) - ON_COMMAND(ID_LIGHTING_SETTINGS, OnLightingSettings) - ON_COMMAND(ID_VIEW_SCREENSHOT, OnViewScreenshot) - ON_COMMAND(IDR_TEXTURE_TOOLS, OnTextureTools) - ON_COMMAND(ID_TOOLS_OPTIONS, OnToolsOptions) - ON_COMMAND(ID_EDIT_UNDO, OnEditUndo) - ON_UPDATE_COMMAND_UI(ID_EDIT_UNDO, OnUpdateEditUndo) - ON_COMMAND(ID_EDIT_REDO, OnEditRedo) - ON_UPDATE_COMMAND_UI(ID_EDIT_REDO, OnUpdateEditRedo) - ON_COMMAND(IDR_ELEVATION_TOOLS, OnElevationTools) - ON_COMMAND(IDR_RESIZE_MAP, OnResizeMap) - ON_COMMAND(ID_VIEW_TERRAIN_GRID, OnViewTerrainGrid) - ON_UPDATE_COMMAND_UI(ID_VIEW_TERRAIN_GRID, OnUpdateViewTerrainGrid) - ON_COMMAND(ID_VIEW_TERRAIN_SOLID, OnViewTerrainSolid) - ON_UPDATE_COMMAND_UI(ID_VIEW_TERRAIN_SOLID, OnUpdateViewTerrainSolid) - ON_COMMAND(ID_VIEW_TERRAIN_WIREFRAME, OnViewTerrainWireframe) - ON_UPDATE_COMMAND_UI(ID_VIEW_TERRAIN_WIREFRAME, OnUpdateViewTerrainWireframe) - ON_COMMAND(ID_VIEW_MODEL_GRID, OnViewModelGrid) - ON_UPDATE_COMMAND_UI(ID_VIEW_MODEL_GRID, OnUpdateViewModelGrid) - ON_COMMAND(ID_VIEW_MODEL_SOLID, OnViewModelSolid) - ON_UPDATE_COMMAND_UI(ID_VIEW_MODEL_SOLID, OnUpdateViewModelSolid) - ON_COMMAND(ID_VIEW_MODEL_WIREFRAME, OnViewModelWireframe) - ON_UPDATE_COMMAND_UI(ID_VIEW_MODEL_WIREFRAME, OnUpdateViewModelWireframe) - ON_COMMAND(ID_FILE_SAVEMAP, OnFileSaveMap) - ON_COMMAND(ID_FILE_LOADMAP, OnFileLoadMap) - ON_COMMAND(ID_VIEW_RENDERSTATS, OnViewRenderStats) - ON_UPDATE_COMMAND_UI(ID_VIEW_RENDERSTATS, OnUpdateViewRenderStats) - ON_MESSAGE(WM_MOUSEWHEEL,OnMouseWheel) - ON_COMMAND(IDR_UNIT_TOOLS, OnUnitTools) - ON_COMMAND(ID_TEST_GO, OnTestGo) - ON_UPDATE_COMMAND_UI(ID_TEST_GO, OnUpdateTestGo) - ON_COMMAND(ID_TEST_STOP, OnTestStop) - ON_UPDATE_COMMAND_UI(ID_TEST_STOP, OnUpdateTestStop) - //}}AFX_MSG_MAP -END_MESSAGE_MAP() - -static UINT indicators[] = -{ - ID_SEPARATOR, // status line indicator - ID_INDICATOR_CAPS, - ID_INDICATOR_NUM, - ID_INDICATOR_SCRL, -}; - - -///////////////////////////////////////////////////////////////////////////// -// CMainFrame construction/destruction - -CMainFrame::CMainFrame() -{ - // TODO: add member initialization code here - -} - -CMainFrame::~CMainFrame() -{ -} - -void CMainFrame::PostNcDestroy() -{ - CFrameWnd::PostNcDestroy(); -} - -int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) -{ - if (CFrameWnd::OnCreate(lpCreateStruct) == -1) - return -1; - - - if (!m_wndDlgBar.Create(this, IDR_MAINFRAME, - CBRS_ALIGN_TOP, AFX_IDW_DIALOGBAR)) - { - TRACE0("Failed to create dialogbar\n"); - return -1; // fail to create - } - m_wndDlgBar.SetWindowText("Toolbar"); - - // create status bar - if (!m_wndStatusBar.Create(this) || - !m_wndStatusBar.SetIndicators(indicators, - sizeof(indicators)/sizeof(UINT))) - { - TRACE0("Failed to create status bar\n"); - return -1; // fail to create - } - - - // create texture tools bar - if (!m_wndTexToolsBar.Create(this, IDD_DIALOGBAR_TEXTURETOOLS, - CBRS_ALIGN_LEFT | CBRS_GRIPPER, AFX_IDW_DIALOGBAR)) - { - TRACE0("Failed to create dialogbar\n"); - return -1; // fail to create - } - m_wndTexToolsBar.SetWindowText("TexTools"); - - // create elevation tools bar - if (!m_wndElevToolsBar.Create(this, IDD_DIALOGBAR_ELEVATIONTOOLS, - CBRS_ALIGN_LEFT | CBRS_GRIPPER, AFX_IDW_DIALOGBAR)) - { - TRACE0("Failed to create dialogbar\n"); - return -1; // fail to create - } - m_wndElevToolsBar.SetWindowText("ElevTools"); - - // create unit tools bar - if (!m_wndUnitToolsBar.Create(this, IDD_DIALOGBAR_UNITTOOLS, - CBRS_ALIGN_LEFT | CBRS_GRIPPER, AFX_IDW_DIALOGBAR)) - { - TRACE0("Failed to create dialogbar\n"); - return -1; // fail to create - } - m_wndUnitToolsBar.SetWindowText("UnitTools"); - - // create unit properties bar - if (!m_wndUnitPropsBar.Create(this, IDD_DIALOGBAR_UNITPROPERTIES, - CBRS_ALIGN_LEFT | CBRS_GRIPPER, AFX_IDW_DIALOGBAR)) - { - TRACE0("Failed to create dialogbar\n"); - return -1; // fail to create - } - m_wndUnitPropsBar.SetWindowText("UnitProperties"); - - // create brush shape editor bar - if (!m_wndBrushShapeEditorBar.Create(this, IDD_DIALOGBAR_BRUSHSHAPEEDITOR, - CBRS_ALIGN_LEFT | CBRS_GRIPPER, AFX_IDW_DIALOGBAR)) - { - TRACE0("Failed to create dialogbar\n"); - return -1; // fail to create - } - m_wndTexToolsBar.SetWindowText("BrushEditor"); - - // enable docking on main frame - EnableDocking(CBRS_ALIGN_TOP | CBRS_ALIGN_LEFT | CBRS_ALIGN_RIGHT | CBRS_ALIGN_BOTTOM); - -/* - // initially dock everything - m_wndTexToolsBar.EnableDocking(CBRS_ALIGN_LEFT | CBRS_ALIGN_RIGHT); - DockControlBar(&m_wndTexToolsBar); - m_wndElevToolsBar.EnableDocking(CBRS_ALIGN_LEFT | CBRS_ALIGN_RIGHT); - DockControlBar(&m_wndElevToolsBar); - m_wndUnitToolsBar.EnableDocking(CBRS_ALIGN_LEFT | CBRS_ALIGN_RIGHT); - DockControlBar(&m_wndUnitToolsBar); - m_wndUnitPropsBar.EnableDocking(CBRS_ALIGN_LEFT | CBRS_ALIGN_RIGHT); - DockControlBar(&m_wndUnitPropsBar); -*/ - // and start up with all tools deselected - DeselectTools(); - - return 0; -} - -BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs) -{ - if( !CFrameWnd::PreCreateWindow(cs) ) - return FALSE; - // TODO: Modify the Window class or styles here by modifying - // the CREATESTRUCT cs - - return TRUE; -} - -///////////////////////////////////////////////////////////////////////////// -// CMainFrame diagnostics - -#ifdef _DEBUG -void CMainFrame::AssertValid() const -{ - CFrameWnd::AssertValid(); -} - -void CMainFrame::Dump(CDumpContext& dc) const -{ - CFrameWnd::Dump(dc); -} - -#endif //_DEBUG - -///////////////////////////////////////////////////////////////////////////// -// CMainFrame message handlers - - -float rnd1() -{ - return float(rand())/float(RAND_MAX); -} - - -void CMainFrame::OnTerrainLoad() -{ - const char* filter="Targa Files|*.tga|RAW files|*.raw||"; - CFileDialog dlg(TRUE,"tga",0,OFN_FILEMUSTEXIST | OFN_NOCHANGEDIR,filter,0); - dlg.m_ofn.lpstrInitialDir=g_UserCfg.GetOptionString(CFG_TERRAINLOADDIR); - - if (dlg.DoModal()==IDOK) { - const char* filename=dlg.m_ofn.lpstrFile; - - CStr dir(filename); - dir=dir.Left(dlg.m_ofn.nFileOffset-1); - g_UserCfg.SetOptionString(CFG_TERRAINLOADDIR,(const char*) dir); - - g_EditorData.LoadTerrain(filename); - } -} - - - -void CMainFrame::OnLightingSettings() -{ - CLightSettingsDlg dlg; - RGBColorToColorRef(g_LightEnv.m_SunColor,dlg.m_SunColor.m_Color); - RGBColorToColorRef(g_LightEnv.m_TerrainAmbientColor,dlg.m_TerrainAmbientColor.m_Color); - RGBColorToColorRef(g_LightEnv.m_UnitsAmbientColor,dlg.m_UnitsAmbientColor.m_Color); - dlg.m_Elevation=int(RADTODEG(g_LightEnv.m_Elevation)+0.5f); - dlg.m_Direction=int(RADTODEG(g_LightEnv.m_Rotation)+0.5f); - - if (dlg.DoModal()==IDOK) { - // have we previously applied a lightenv? - if (dlg.m_PreviousPreview) { - // yes - undo it - g_CmdMan.Undo(); - } - - // build a lighting environment from the parameters - CLightEnv env; - env.m_Elevation=DEGTORAD(dlg.m_ElevationButton.m_Elevation); - env.m_Rotation=DEGTORAD(dlg.m_DirectionButton.m_Direction); - ColorRefToRGBColor(dlg.m_SunColor.m_Color,env.m_SunColor); - ColorRefToRGBColor(dlg.m_TerrainAmbientColor.m_Color,env.m_TerrainAmbientColor); - ColorRefToRGBColor(dlg.m_TerrainAmbientColor.m_Color,env.m_UnitsAmbientColor); - - // create and execute an AlterLightEnv command - CAlterLightEnvCommand* cmd=new CAlterLightEnvCommand(env); - g_CmdMan.Execute(cmd); - } else { - if (dlg.m_PreviousPreview) { - // undo the change - g_CmdMan.Undo(); - } - } - - AfxGetMainWnd()->Invalidate(); - AfxGetMainWnd()->UpdateWindow(); -} - -void CMainFrame::OnViewScreenshot() -{ - CScEdView* view=(CScEdView*) GetActiveView(); - view->OnScreenShot(); -} - - - -void CMainFrame::OnTextureTools() -{ - g_EditorData.SetMode(CEditorData::SCENARIO_EDIT); - - // swizzle around control bar visibility - DisableCtrlBars(); - ShowControlBar(&m_wndTexToolsBar,TRUE,FALSE); - ((CButton*) m_wndDlgBar.GetDlgItem(IDC_BUTTON_TEXTURETOOLS))->SetState(TRUE); - - // set active tool - g_ToolMan.SetActiveTool(CPaintTextureTool::GetTool()); -} - -void CMainFrame::OnElevationTools() -{ - g_EditorData.SetMode(CEditorData::SCENARIO_EDIT); - - // swizzle around control bar visibility - DisableCtrlBars(); - ShowControlBar(&m_wndElevToolsBar,TRUE,FALSE); - ((CButton*) m_wndDlgBar.GetDlgItem(IDC_BUTTON_ELEVATIONTOOLS))->SetState(TRUE); - - // notify window being shown so controls for correct mode (raise/smooth) are drawn, - // and correct tool is setup - m_wndElevToolsBar.OnShow(); -} - -void CMainFrame::OnUnitTools() -{ - g_EditorData.SetMode(CEditorData::SCENARIO_EDIT); - - // swizzle around control bar visibility - DisableCtrlBars(); - ShowControlBar(&m_wndUnitToolsBar,TRUE,FALSE); - ((CButton*) m_wndDlgBar.GetDlgItem(IDC_BUTTON_MODELTOOLS))->SetState(TRUE); - - // set modeactive tool - if (m_wndUnitToolsBar.m_Mode==CUnitToolsDlgBar::SELECT_MODE) { - m_wndUnitToolsBar.SetSelectMode(); - } else { - m_wndUnitToolsBar.SetAddUnitMode(); - } - - // ensure we're in the right editing mode - g_EditorData.SetMode(CEditorData::SCENARIO_EDIT); -} - -void CMainFrame::DisableCtrlBars() -{ - ShowControlBar(&m_wndTexToolsBar,FALSE,FALSE); - ShowControlBar(&m_wndElevToolsBar,FALSE,FALSE); - ShowControlBar(&m_wndUnitToolsBar,FALSE,FALSE); - ShowControlBar(&m_wndUnitPropsBar,FALSE,FALSE); - ShowControlBar(&m_wndBrushShapeEditorBar,FALSE,FALSE); - - // switch off corresponding short cut buttons - DisableToolbarButtons(); -} - -void CMainFrame::DisableToolbarButtons() -{ - ((CButton*) m_wndDlgBar.GetDlgItem(IDC_BUTTON_SELECT))->SetState(FALSE); - ((CButton*) m_wndDlgBar.GetDlgItem(IDC_BUTTON_TEXTURETOOLS))->SetState(FALSE); - ((CButton*) m_wndDlgBar.GetDlgItem(IDC_BUTTON_ELEVATIONTOOLS))->SetState(FALSE); - ((CButton*) m_wndDlgBar.GetDlgItem(IDC_BUTTON_MODELTOOLS))->SetState(FALSE); -} - -void CMainFrame::DeselectTools() -{ - // switch off all control bars - DisableCtrlBars(); - ((CButton*) m_wndDlgBar.GetDlgItem(IDC_BUTTON_SELECT))->SetState(TRUE); - - // deselect active tool - g_ToolMan.SetActiveTool(0); - - // ensure we're in the right editing mode - g_EditorData.SetMode(CEditorData::SCENARIO_EDIT); -} - -void CMainFrame::OnObjectProperties(CObjectEntry* obj) -{ - // swizzle around control bar visibility - DisableCtrlBars(); - ShowControlBar(&m_wndUnitPropsBar,TRUE,FALSE); - - m_wndUnitPropsBar.SetObject(obj); - - // set active tool - g_ToolMan.SetActiveTool(0); - - // ensure we're in the right editing mode - g_EditorData.SetMode(CEditorData::UNIT_EDIT); -} - -void CMainFrame::OnToolsOptions() -{ - COptionsPropSheet dlg("Options",this,0); - dlg.m_NavigatePage.m_ScrollSpeed=g_UserCfg.GetOptionInt(CFG_SCROLLSPEED); - - dlg.m_ShadowsPage.m_EnableShadows=g_Renderer.GetOptionBool(CRenderer::OPT_SHADOWS) ? TRUE : FALSE; - - COLORREF c; - RGBColorToColorRef(g_Renderer.GetOptionColor(CRenderer::OPT_SHADOWCOLOR),c); - dlg.m_ShadowsPage.m_ShadowColor.m_Color=c; - - if (dlg.DoModal()==IDOK) { - g_UserCfg.SetOptionInt(CFG_SCROLLSPEED,dlg.m_NavigatePage.m_ScrollSpeed); - g_Renderer.SetOptionBool(CRenderer::OPT_SHADOWS,dlg.m_ShadowsPage.m_EnableShadows ? true : false); - - RGBColor c; - ColorRefToRGBColor(dlg.m_ShadowsPage.m_ShadowColor.m_Color,c); - g_Renderer.SetOptionColor(CRenderer::OPT_SHADOWCOLOR,c); - } -} - -void CMainFrame::OnEditUndo() -{ - g_CmdMan.Undo(); -} - -void CMainFrame::OnUpdateEditUndo(CCmdUI* pCmdUI) -{ - const char* cmdName=g_CmdMan.GetUndoName(); - if (!cmdName) { - const char* undoText="&Undo"; - pCmdUI->SetText(undoText); - pCmdUI->Enable(FALSE); - } else { - const char* undoText="&Undo Ctrl+Z"; - char buf[64]; - strcpy(buf,undoText); - int len=strlen(cmdName); - if (len>32) len=32; - buf[6]='\"'; - strncpy(buf+7,cmdName,len); - buf[6+len+1]='\"'; - pCmdUI->SetText(buf); - pCmdUI->Enable(TRUE); - } -} - -void CMainFrame::OnEditRedo() -{ - g_CmdMan.Redo(); -} - -void CMainFrame::OnUpdateEditRedo(CCmdUI* pCmdUI) -{ - const char* cmdName=g_CmdMan.GetRedoName(); - if (!cmdName) { - const char* redoText="&Redo"; - pCmdUI->SetText(redoText); - pCmdUI->Enable(FALSE); - } else { - const char* redoText="&Redo Ctrl+Y"; - char buf[64]; - strcpy(buf,redoText); - int len=strlen(cmdName); - if (len>32) len=32; - buf[6]='\"'; - strncpy(buf+7,cmdName,len); - buf[6+len+1]='\"'; - pCmdUI->SetText(buf); - pCmdUI->Enable(TRUE); - } -} - - - -void CMainFrame::OnResizeMap() -{ - CMapSizeDlg dlg; - if (dlg.DoModal()==IDOK) { - // resize terrain to selected size - g_Terrain.Resize(dlg.m_MapSize); - - // reinitialise minimap to cope with terrain of different size - g_MiniMap.Initialise(); - } -} - -void CMainFrame::OnViewModelGrid() -{ - g_Renderer.SetModelRenderMode(EDGED_FACES); -} - -void CMainFrame::OnUpdateViewModelGrid(CCmdUI* pCmdUI) -{ - pCmdUI->SetCheck(g_Renderer.GetModelRenderMode()==EDGED_FACES); -} - -void CMainFrame::OnViewModelSolid() -{ - g_Renderer.SetModelRenderMode(SOLID); -} - -void CMainFrame::OnUpdateViewModelSolid(CCmdUI* pCmdUI) -{ - pCmdUI->SetCheck(g_Renderer.GetModelRenderMode()==SOLID); -} - -void CMainFrame::OnViewModelWireframe() -{ - g_Renderer.SetModelRenderMode(WIREFRAME); -} - -void CMainFrame::OnUpdateViewModelWireframe(CCmdUI* pCmdUI) -{ - pCmdUI->SetCheck(g_Renderer.GetModelRenderMode()==WIREFRAME); -} - -void CMainFrame::OnViewTerrainGrid() -{ - g_Renderer.SetTerrainRenderMode(EDGED_FACES); -} - -void CMainFrame::OnUpdateViewTerrainGrid(CCmdUI* pCmdUI) -{ - pCmdUI->SetCheck(g_Renderer.GetTerrainRenderMode()==EDGED_FACES); -} - -void CMainFrame::OnViewTerrainSolid() -{ - g_Renderer.SetTerrainRenderMode(SOLID); -} - -void CMainFrame::OnUpdateViewTerrainSolid(CCmdUI* pCmdUI) -{ - pCmdUI->SetCheck(g_Renderer.GetTerrainRenderMode()==SOLID); -} - -void CMainFrame::OnViewTerrainWireframe() -{ - g_Renderer.SetTerrainRenderMode(WIREFRAME); -} - -void CMainFrame::OnUpdateViewTerrainWireframe(CCmdUI* pCmdUI) -{ - pCmdUI->SetCheck(g_Renderer.GetTerrainRenderMode()==WIREFRAME); -} - -void CMainFrame::OnFileSaveMap() -{ - const char* filter="PMP Files|*.pmp||"; - CFileDialog savedlg(FALSE,"pmp","Untitled.pmp",OFN_OVERWRITEPROMPT | OFN_NOCHANGEDIR,filter,0); - savedlg.m_ofn.lpstrInitialDir=g_UserCfg.GetOptionString(CFG_MAPSAVEDIR); - if (savedlg.DoModal()==IDOK) { - const char* savename=savedlg.m_ofn.lpstrFile; - - CStr dir(savename); - dir=dir.Left(savedlg.m_ofn.nFileOffset-1); - g_UserCfg.SetOptionString(CFG_MAPSAVEDIR,(const char*) dir); - - CMapWriter writer; - try { - writer.SaveMap(savename); - - CStr filetitle=savedlg.m_ofn.lpstrFileTitle; - int index=filetitle.ReverseFind(CStr(".")); - CStr doctitle=(index==-1) ? filetitle : filetitle.GetSubstring(0,index); - g_EditorData.SetScenarioName((const char*) doctitle); - SetTitle(); - } catch (CFilePacker::CFileOpenError) { - char buf[256]; - sprintf(buf,"Failed to open \"%s\" for writing",savename); - MessageBox(buf,"Error",MB_OK); - } catch (CFilePacker::CFileWriteError) { - char buf[256]; - sprintf(buf,"Error trying to write to \"%s\"",savename); - MessageBox(buf,"Error",MB_OK); - } catch (...) { - char buf[256]; - sprintf(buf,"Error saving file \"%s\"",savename); - MessageBox(buf,"Error",MB_OK); - } - } -} - -void CMainFrame::OnFileLoadMap() -{ - g_EditorData.SetMode(CEditorData::SCENARIO_EDIT); - - const char* filter="PMP Files|*.pmp||"; - CFileDialog loaddlg(TRUE,"pmp",0,OFN_FILEMUSTEXIST | OFN_NOCHANGEDIR,filter,0); - loaddlg.m_ofn.lpstrInitialDir=g_UserCfg.GetOptionString(CFG_MAPLOADDIR); - - if (loaddlg.DoModal()==IDOK) { - const char* loadname=loaddlg.m_ofn.lpstrFile; - - CStr dir(loadname); - dir=dir.Left(loaddlg.m_ofn.nFileOffset-1); - g_UserCfg.SetOptionString(CFG_MAPLOADDIR,(const char*) dir); - - CMapReader reader; - try { - reader.LoadMap(loadname); - - CStr filetitle=loaddlg.m_ofn.lpstrFileTitle; - int index=filetitle.ReverseFind(CStr(".")); - CStr doctitle=(index==-1) ? filetitle : filetitle.GetSubstring(0,index); - g_EditorData.SetScenarioName((const char*) doctitle); - SetTitle(); - - // reinitialise minimap - g_MiniMap.Initialise(); - // render everything force asset load - g_EditorData.RenderNoCull(); - - // start everything idling - const std::vector& units=g_UnitMan.GetUnits(); - for (uint i=0;iGetObject()->m_IdleAnim) { - units[i]->GetModel()->SetAnimation(units[i]->GetObject()->m_IdleAnim); - } - } - } catch (CFileUnpacker::CFileOpenError) { - char buf[256]; - sprintf(buf,"Failed to open \"%s\" for reading",loadname); - MessageBox(buf,"Error",MB_OK); - } catch (CFileUnpacker::CFileReadError) { - char buf[256]; - sprintf(buf,"Error trying to read from \"%s\"",loadname); - MessageBox(buf,"Error",MB_OK); - } catch (CFileUnpacker::CFileEOFError) { - char buf[256]; - sprintf(buf,"Premature end of file error reading from \"%s\"",loadname); - MessageBox(buf,"Error",MB_OK); - } catch (CFileUnpacker::CFileVersionError) { - char buf[256]; - sprintf(buf,"Error reading from \"%s\" - version mismatch",loadname); - MessageBox(buf,"Error",MB_OK); - } catch (CFileUnpacker::CFileTypeError) { - char buf[256]; - sprintf(buf,"Error reading \"%s\" - doesn't seem to a PMP file",loadname); - MessageBox(buf,"Error",MB_OK); - } catch (...) { - char buf[256]; - sprintf(buf,"Error loading file \"%s\"",loadname); - MessageBox(buf,"Error",MB_OK); - } - } -} - -void CMainFrame::SetTitle() -{ - // set document title - if (GetActiveView()) { - GetActiveView()->GetDocument()->SetTitle(g_EditorData.GetScenarioName()); - } -} - -void CMainFrame::OnViewRenderStats() -{ - CInfoBox& infobox=g_EditorData.GetInfoBox(); - infobox.SetVisible(!infobox.GetVisible()); -} - -void CMainFrame::OnUpdateViewRenderStats(CCmdUI* pCmdUI) -{ - pCmdUI->SetCheck(g_EditorData.GetInfoBox().GetVisible()==true); -} - -void CMainFrame::OnToolsBrushShapeEditor() -{ - DeselectTools(); - ShowControlBar(&m_wndBrushShapeEditorBar,TRUE,FALSE); - - // set active tool - g_ToolMan.SetActiveTool(CBrushShapeEditorTool::GetTool()); - - // ensure we're in the right editing mode - g_EditorData.SetMode(CEditorData::SCENARIO_EDIT); -} - -LRESULT CMainFrame::OnMouseWheel(WPARAM wParam,LPARAM lParam) -{ - // Windows sucks: why the main frame is getting mouse wheel messages - // when mouse move messages are still going to the view is beyond - // my comprehension. Just duplicate the work CScEdView does. - int xPos = LOWORD(lParam); - int yPos = HIWORD(lParam); - SHORT fwKeys = LOWORD(wParam); - SHORT zDelta = HIWORD(wParam); - - g_NaviCam.OnMouseWheelScroll(0,xPos,yPos,float(zDelta)/120.0f); - - return 0; -} - -void CMainFrame::OnTestGo() -{ - g_EditorData.SetMode(CEditorData::TEST_MODE); -} - -void CMainFrame::OnUpdateTestGo(CCmdUI* pCmdUI) -{ - if (g_EditorData.GetMode()==CEditorData::TEST_MODE || g_EditorData.GetMode()!=CEditorData::SCENARIO_EDIT) - pCmdUI->Enable(FALSE); - else - pCmdUI->Enable(TRUE); -} - -void CMainFrame::OnTestStop() -{ - g_EditorData.SetMode(CEditorData::SCENARIO_EDIT); -} - -void CMainFrame::OnUpdateTestStop(CCmdUI* pCmdUI) -{ - if (g_EditorData.GetMode()==CEditorData::TEST_MODE) - pCmdUI->Enable(TRUE); - else - pCmdUI->Enable(FALSE); -} +// MainFrm.cpp : implementation of the CMainFrame class +// + +#include "stdafx.h" + +#include "ogl.h" +#include "res/tex.h" +#include "res/mem.h" +#include "res/vfs.h" + +#include "ScEd.h" +#include "ScEdView.h" +#include "MiniMap.h" +#include "MapReader.h" +#include "MapWriter.h" + +#include "UserConfig.h" + +#include "Unit.h" +#include "UnitManager.h" +#include "UIGlobals.h" +#include "MainFrm.h" +#include "OptionsPropSheet.h" +#include "LightSettingsDlg.h" +#include "MapSizeDlg.h" +#include "EditorData.h" +#include "ToolManager.h" +#include "CommandManager.h" + +#include "AlterLightEnvCommand.h" + +#include "LightEnv.h" +#include "Terrain.h" + +#include "PaintTextureTool.h" +#include "PaintObjectTool.h" +#include "RaiseElevationTool.h" +#include "BrushShapeEditorTool.h" + +extern CTerrain g_Terrain; +extern CLightEnv g_LightEnv; + +///////////////////////////////////////////////////////////////////////////// +// CMainFrame + + +IMPLEMENT_DYNCREATE(CMainFrame, CFrameWnd) + +BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd) + //{{AFX_MSG_MAP(CMainFrame) + ON_WM_CREATE() + ON_COMMAND(ID_TERRAIN_LOAD, OnTerrainLoad) + ON_COMMAND(ID_LIGHTING_SETTINGS, OnLightingSettings) + ON_COMMAND(ID_VIEW_SCREENSHOT, OnViewScreenshot) + ON_COMMAND(IDR_TEXTURE_TOOLS, OnTextureTools) + ON_COMMAND(ID_TOOLS_OPTIONS, OnToolsOptions) + ON_COMMAND(ID_EDIT_UNDO, OnEditUndo) + ON_UPDATE_COMMAND_UI(ID_EDIT_UNDO, OnUpdateEditUndo) + ON_COMMAND(ID_EDIT_REDO, OnEditRedo) + ON_UPDATE_COMMAND_UI(ID_EDIT_REDO, OnUpdateEditRedo) + ON_COMMAND(IDR_ELEVATION_TOOLS, OnElevationTools) + ON_COMMAND(IDR_RESIZE_MAP, OnResizeMap) + ON_COMMAND(ID_VIEW_TERRAIN_GRID, OnViewTerrainGrid) + ON_UPDATE_COMMAND_UI(ID_VIEW_TERRAIN_GRID, OnUpdateViewTerrainGrid) + ON_COMMAND(ID_VIEW_TERRAIN_SOLID, OnViewTerrainSolid) + ON_UPDATE_COMMAND_UI(ID_VIEW_TERRAIN_SOLID, OnUpdateViewTerrainSolid) + ON_COMMAND(ID_VIEW_TERRAIN_WIREFRAME, OnViewTerrainWireframe) + ON_UPDATE_COMMAND_UI(ID_VIEW_TERRAIN_WIREFRAME, OnUpdateViewTerrainWireframe) + ON_COMMAND(ID_VIEW_MODEL_GRID, OnViewModelGrid) + ON_UPDATE_COMMAND_UI(ID_VIEW_MODEL_GRID, OnUpdateViewModelGrid) + ON_COMMAND(ID_VIEW_MODEL_SOLID, OnViewModelSolid) + ON_UPDATE_COMMAND_UI(ID_VIEW_MODEL_SOLID, OnUpdateViewModelSolid) + ON_COMMAND(ID_VIEW_MODEL_WIREFRAME, OnViewModelWireframe) + ON_UPDATE_COMMAND_UI(ID_VIEW_MODEL_WIREFRAME, OnUpdateViewModelWireframe) + ON_COMMAND(ID_FILE_SAVEMAP, OnFileSaveMap) + ON_COMMAND(ID_FILE_LOADMAP, OnFileLoadMap) + ON_COMMAND(ID_VIEW_RENDERSTATS, OnViewRenderStats) + ON_UPDATE_COMMAND_UI(ID_VIEW_RENDERSTATS, OnUpdateViewRenderStats) + ON_MESSAGE(WM_MOUSEWHEEL,OnMouseWheel) + ON_COMMAND(IDR_UNIT_TOOLS, OnUnitTools) + ON_COMMAND(ID_TEST_GO, OnTestGo) + ON_UPDATE_COMMAND_UI(ID_TEST_GO, OnUpdateTestGo) + ON_COMMAND(ID_TEST_STOP, OnTestStop) + ON_UPDATE_COMMAND_UI(ID_TEST_STOP, OnUpdateTestStop) + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +static UINT indicators[] = +{ + ID_SEPARATOR, // status line indicator + ID_INDICATOR_CAPS, + ID_INDICATOR_NUM, + ID_INDICATOR_SCRL, +}; + + +///////////////////////////////////////////////////////////////////////////// +// CMainFrame construction/destruction + +CMainFrame::CMainFrame() +{ + // TODO: add member initialization code here + +} + +CMainFrame::~CMainFrame() +{ +} + +void CMainFrame::PostNcDestroy() +{ + CFrameWnd::PostNcDestroy(); +} + +int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) +{ + if (CFrameWnd::OnCreate(lpCreateStruct) == -1) + return -1; + + + if (!m_wndDlgBar.Create(this, IDR_MAINFRAME, + CBRS_ALIGN_TOP, AFX_IDW_DIALOGBAR)) + { + TRACE0("Failed to create dialogbar\n"); + return -1; // fail to create + } + m_wndDlgBar.SetWindowText("Toolbar"); + + // create status bar + if (!m_wndStatusBar.Create(this) || + !m_wndStatusBar.SetIndicators(indicators, + sizeof(indicators)/sizeof(UINT))) + { + TRACE0("Failed to create status bar\n"); + return -1; // fail to create + } + + + // create texture tools bar + if (!m_wndTexToolsBar.Create(this, IDD_DIALOGBAR_TEXTURETOOLS, + CBRS_ALIGN_LEFT | CBRS_GRIPPER, AFX_IDW_DIALOGBAR)) + { + TRACE0("Failed to create dialogbar\n"); + return -1; // fail to create + } + m_wndTexToolsBar.SetWindowText("TexTools"); + + // create elevation tools bar + if (!m_wndElevToolsBar.Create(this, IDD_DIALOGBAR_ELEVATIONTOOLS, + CBRS_ALIGN_LEFT | CBRS_GRIPPER, AFX_IDW_DIALOGBAR)) + { + TRACE0("Failed to create dialogbar\n"); + return -1; // fail to create + } + m_wndElevToolsBar.SetWindowText("ElevTools"); + + // create unit tools bar + if (!m_wndUnitToolsBar.Create(this, IDD_DIALOGBAR_UNITTOOLS, + CBRS_ALIGN_LEFT | CBRS_GRIPPER, AFX_IDW_DIALOGBAR)) + { + TRACE0("Failed to create dialogbar\n"); + return -1; // fail to create + } + m_wndUnitToolsBar.SetWindowText("UnitTools"); + + // create unit properties bar + if (!m_wndUnitPropsBar.Create(this, IDD_DIALOGBAR_UNITPROPERTIES, + CBRS_ALIGN_LEFT | CBRS_GRIPPER, AFX_IDW_DIALOGBAR)) + { + TRACE0("Failed to create dialogbar\n"); + return -1; // fail to create + } + m_wndUnitPropsBar.SetWindowText("UnitProperties"); + + // create brush shape editor bar + if (!m_wndBrushShapeEditorBar.Create(this, IDD_DIALOGBAR_BRUSHSHAPEEDITOR, + CBRS_ALIGN_LEFT | CBRS_GRIPPER, AFX_IDW_DIALOGBAR)) + { + TRACE0("Failed to create dialogbar\n"); + return -1; // fail to create + } + m_wndTexToolsBar.SetWindowText("BrushEditor"); + + // enable docking on main frame + EnableDocking(CBRS_ALIGN_TOP | CBRS_ALIGN_LEFT | CBRS_ALIGN_RIGHT | CBRS_ALIGN_BOTTOM); + +/* + // initially dock everything + m_wndTexToolsBar.EnableDocking(CBRS_ALIGN_LEFT | CBRS_ALIGN_RIGHT); + DockControlBar(&m_wndTexToolsBar); + m_wndElevToolsBar.EnableDocking(CBRS_ALIGN_LEFT | CBRS_ALIGN_RIGHT); + DockControlBar(&m_wndElevToolsBar); + m_wndUnitToolsBar.EnableDocking(CBRS_ALIGN_LEFT | CBRS_ALIGN_RIGHT); + DockControlBar(&m_wndUnitToolsBar); + m_wndUnitPropsBar.EnableDocking(CBRS_ALIGN_LEFT | CBRS_ALIGN_RIGHT); + DockControlBar(&m_wndUnitPropsBar); +*/ + // and start up with all tools deselected + DeselectTools(); + + return 0; +} + +BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs) +{ + if( !CFrameWnd::PreCreateWindow(cs) ) + return FALSE; + // TODO: Modify the Window class or styles here by modifying + // the CREATESTRUCT cs + + return TRUE; +} + +///////////////////////////////////////////////////////////////////////////// +// CMainFrame diagnostics + +#ifdef _DEBUG +void CMainFrame::AssertValid() const +{ + CFrameWnd::AssertValid(); +} + +void CMainFrame::Dump(CDumpContext& dc) const +{ + CFrameWnd::Dump(dc); +} + +#endif //_DEBUG + +///////////////////////////////////////////////////////////////////////////// +// CMainFrame message handlers + + +float rnd1() +{ + return float(rand())/float(RAND_MAX); +} + + +void CMainFrame::OnTerrainLoad() +{ + const char* filter="Targa Files|*.tga|RAW files|*.raw||"; + CFileDialog dlg(TRUE,"tga",0,OFN_FILEMUSTEXIST | OFN_NOCHANGEDIR,filter,0); + dlg.m_ofn.lpstrInitialDir=g_UserCfg.GetOptionString(CFG_TERRAINLOADDIR); + + if (dlg.DoModal()==IDOK) { + const char* filename=dlg.m_ofn.lpstrFile; + + CStr dir(filename); + dir=dir.Left(dlg.m_ofn.nFileOffset-1); + g_UserCfg.SetOptionString(CFG_TERRAINLOADDIR,(const char*) dir); + + g_EditorData.LoadTerrain(filename); + } +} + + + +void CMainFrame::OnLightingSettings() +{ + CLightSettingsDlg dlg; + RGBColorToColorRef(g_LightEnv.m_SunColor,dlg.m_SunColor.m_Color); + RGBColorToColorRef(g_LightEnv.m_TerrainAmbientColor,dlg.m_TerrainAmbientColor.m_Color); + RGBColorToColorRef(g_LightEnv.m_UnitsAmbientColor,dlg.m_UnitsAmbientColor.m_Color); + dlg.m_Elevation=int(RADTODEG(g_LightEnv.m_Elevation)+0.5f); + dlg.m_Direction=int(RADTODEG(g_LightEnv.m_Rotation)+0.5f); + + if (dlg.DoModal()==IDOK) { + // have we previously applied a lightenv? + if (dlg.m_PreviousPreview) { + // yes - undo it + g_CmdMan.Undo(); + } + + // build a lighting environment from the parameters + CLightEnv env; + env.m_Elevation=DEGTORAD(dlg.m_ElevationButton.m_Elevation); + env.m_Rotation=DEGTORAD(dlg.m_DirectionButton.m_Direction); + ColorRefToRGBColor(dlg.m_SunColor.m_Color,env.m_SunColor); + ColorRefToRGBColor(dlg.m_TerrainAmbientColor.m_Color,env.m_TerrainAmbientColor); + ColorRefToRGBColor(dlg.m_TerrainAmbientColor.m_Color,env.m_UnitsAmbientColor); + + // create and execute an AlterLightEnv command + CAlterLightEnvCommand* cmd=new CAlterLightEnvCommand(env); + g_CmdMan.Execute(cmd); + } else { + if (dlg.m_PreviousPreview) { + // undo the change + g_CmdMan.Undo(); + } + } + + AfxGetMainWnd()->Invalidate(); + AfxGetMainWnd()->UpdateWindow(); +} + +void CMainFrame::OnViewScreenshot() +{ + CScEdView* view=(CScEdView*) GetActiveView(); + view->OnScreenShot(); +} + + + +void CMainFrame::OnTextureTools() +{ + g_EditorData.SetMode(CEditorData::SCENARIO_EDIT); + + // swizzle around control bar visibility + DisableCtrlBars(); + ShowControlBar(&m_wndTexToolsBar,TRUE,FALSE); + ((CButton*) m_wndDlgBar.GetDlgItem(IDC_BUTTON_TEXTURETOOLS))->SetState(TRUE); + + // set active tool + g_ToolMan.SetActiveTool(CPaintTextureTool::GetTool()); +} + +void CMainFrame::OnElevationTools() +{ + g_EditorData.SetMode(CEditorData::SCENARIO_EDIT); + + // swizzle around control bar visibility + DisableCtrlBars(); + ShowControlBar(&m_wndElevToolsBar,TRUE,FALSE); + ((CButton*) m_wndDlgBar.GetDlgItem(IDC_BUTTON_ELEVATIONTOOLS))->SetState(TRUE); + + // notify window being shown so controls for correct mode (raise/smooth) are drawn, + // and correct tool is setup + m_wndElevToolsBar.OnShow(); +} + +void CMainFrame::OnUnitTools() +{ + g_EditorData.SetMode(CEditorData::SCENARIO_EDIT); + + // swizzle around control bar visibility + DisableCtrlBars(); + ShowControlBar(&m_wndUnitToolsBar,TRUE,FALSE); + ((CButton*) m_wndDlgBar.GetDlgItem(IDC_BUTTON_MODELTOOLS))->SetState(TRUE); + + // set modeactive tool + if (m_wndUnitToolsBar.m_Mode==CUnitToolsDlgBar::SELECT_MODE) { + m_wndUnitToolsBar.SetSelectMode(); + } else { + m_wndUnitToolsBar.SetAddUnitMode(); + } + + // ensure we're in the right editing mode + g_EditorData.SetMode(CEditorData::SCENARIO_EDIT); +} + +void CMainFrame::DisableCtrlBars() +{ + ShowControlBar(&m_wndTexToolsBar,FALSE,FALSE); + ShowControlBar(&m_wndElevToolsBar,FALSE,FALSE); + ShowControlBar(&m_wndUnitToolsBar,FALSE,FALSE); + ShowControlBar(&m_wndUnitPropsBar,FALSE,FALSE); + ShowControlBar(&m_wndBrushShapeEditorBar,FALSE,FALSE); + + // switch off corresponding short cut buttons + DisableToolbarButtons(); +} + +void CMainFrame::DisableToolbarButtons() +{ + ((CButton*) m_wndDlgBar.GetDlgItem(IDC_BUTTON_SELECT))->SetState(FALSE); + ((CButton*) m_wndDlgBar.GetDlgItem(IDC_BUTTON_TEXTURETOOLS))->SetState(FALSE); + ((CButton*) m_wndDlgBar.GetDlgItem(IDC_BUTTON_ELEVATIONTOOLS))->SetState(FALSE); + ((CButton*) m_wndDlgBar.GetDlgItem(IDC_BUTTON_MODELTOOLS))->SetState(FALSE); +} + +void CMainFrame::DeselectTools() +{ + // switch off all control bars + DisableCtrlBars(); + ((CButton*) m_wndDlgBar.GetDlgItem(IDC_BUTTON_SELECT))->SetState(TRUE); + + // deselect active tool + g_ToolMan.SetActiveTool(0); + + // ensure we're in the right editing mode + g_EditorData.SetMode(CEditorData::SCENARIO_EDIT); +} + +void CMainFrame::OnObjectProperties(CObjectEntry* obj) +{ + // swizzle around control bar visibility + DisableCtrlBars(); + ShowControlBar(&m_wndUnitPropsBar,TRUE,FALSE); + + m_wndUnitPropsBar.SetObject(obj); + + // set active tool + g_ToolMan.SetActiveTool(0); + + // ensure we're in the right editing mode + g_EditorData.SetMode(CEditorData::UNIT_EDIT); +} + +void CMainFrame::OnToolsOptions() +{ + COptionsPropSheet dlg("Options",this,0); + dlg.m_NavigatePage.m_ScrollSpeed=g_UserCfg.GetOptionInt(CFG_SCROLLSPEED); + + dlg.m_ShadowsPage.m_EnableShadows=g_Renderer.GetOptionBool(CRenderer::OPT_SHADOWS) ? TRUE : FALSE; + + COLORREF c; + RGBColorToColorRef(g_Renderer.GetOptionColor(CRenderer::OPT_SHADOWCOLOR),c); + dlg.m_ShadowsPage.m_ShadowColor.m_Color=c; + + if (dlg.DoModal()==IDOK) { + g_UserCfg.SetOptionInt(CFG_SCROLLSPEED,dlg.m_NavigatePage.m_ScrollSpeed); + g_Renderer.SetOptionBool(CRenderer::OPT_SHADOWS,dlg.m_ShadowsPage.m_EnableShadows ? true : false); + + RGBColor c; + ColorRefToRGBColor(dlg.m_ShadowsPage.m_ShadowColor.m_Color,c); + g_Renderer.SetOptionColor(CRenderer::OPT_SHADOWCOLOR,c); + } +} + +void CMainFrame::OnEditUndo() +{ + g_CmdMan.Undo(); +} + +void CMainFrame::OnUpdateEditUndo(CCmdUI* pCmdUI) +{ + const char* cmdName=g_CmdMan.GetUndoName(); + if (!cmdName) { + const char* undoText="&Undo"; + pCmdUI->SetText(undoText); + pCmdUI->Enable(FALSE); + } else { + const char* undoText="&Undo Ctrl+Z"; + char buf[64]; + strcpy(buf,undoText); + int len=strlen(cmdName); + if (len>32) len=32; + buf[6]='\"'; + strncpy(buf+7,cmdName,len); + buf[6+len+1]='\"'; + pCmdUI->SetText(buf); + pCmdUI->Enable(TRUE); + } +} + +void CMainFrame::OnEditRedo() +{ + g_CmdMan.Redo(); +} + +void CMainFrame::OnUpdateEditRedo(CCmdUI* pCmdUI) +{ + const char* cmdName=g_CmdMan.GetRedoName(); + if (!cmdName) { + const char* redoText="&Redo"; + pCmdUI->SetText(redoText); + pCmdUI->Enable(FALSE); + } else { + const char* redoText="&Redo Ctrl+Y"; + char buf[64]; + strcpy(buf,redoText); + int len=strlen(cmdName); + if (len>32) len=32; + buf[6]='\"'; + strncpy(buf+7,cmdName,len); + buf[6+len+1]='\"'; + pCmdUI->SetText(buf); + pCmdUI->Enable(TRUE); + } +} + + + +void CMainFrame::OnResizeMap() +{ + CMapSizeDlg dlg; + if (dlg.DoModal()==IDOK) { + // resize terrain to selected size + g_Terrain.Resize(dlg.m_MapSize); + + // reinitialise minimap to cope with terrain of different size + g_MiniMap.Initialise(); + } +} + +void CMainFrame::OnViewModelGrid() +{ + g_Renderer.SetModelRenderMode(EDGED_FACES); +} + +void CMainFrame::OnUpdateViewModelGrid(CCmdUI* pCmdUI) +{ + pCmdUI->SetCheck(g_Renderer.GetModelRenderMode()==EDGED_FACES); +} + +void CMainFrame::OnViewModelSolid() +{ + g_Renderer.SetModelRenderMode(SOLID); +} + +void CMainFrame::OnUpdateViewModelSolid(CCmdUI* pCmdUI) +{ + pCmdUI->SetCheck(g_Renderer.GetModelRenderMode()==SOLID); +} + +void CMainFrame::OnViewModelWireframe() +{ + g_Renderer.SetModelRenderMode(WIREFRAME); +} + +void CMainFrame::OnUpdateViewModelWireframe(CCmdUI* pCmdUI) +{ + pCmdUI->SetCheck(g_Renderer.GetModelRenderMode()==WIREFRAME); +} + +void CMainFrame::OnViewTerrainGrid() +{ + g_Renderer.SetTerrainRenderMode(EDGED_FACES); +} + +void CMainFrame::OnUpdateViewTerrainGrid(CCmdUI* pCmdUI) +{ + pCmdUI->SetCheck(g_Renderer.GetTerrainRenderMode()==EDGED_FACES); +} + +void CMainFrame::OnViewTerrainSolid() +{ + g_Renderer.SetTerrainRenderMode(SOLID); +} + +void CMainFrame::OnUpdateViewTerrainSolid(CCmdUI* pCmdUI) +{ + pCmdUI->SetCheck(g_Renderer.GetTerrainRenderMode()==SOLID); +} + +void CMainFrame::OnViewTerrainWireframe() +{ + g_Renderer.SetTerrainRenderMode(WIREFRAME); +} + +void CMainFrame::OnUpdateViewTerrainWireframe(CCmdUI* pCmdUI) +{ + pCmdUI->SetCheck(g_Renderer.GetTerrainRenderMode()==WIREFRAME); +} + +void CMainFrame::OnFileSaveMap() +{ + const char* filter="PMP Files|*.pmp||"; + CFileDialog savedlg(FALSE,"pmp","Untitled.pmp",OFN_OVERWRITEPROMPT | OFN_NOCHANGEDIR,filter,0); + savedlg.m_ofn.lpstrInitialDir=g_UserCfg.GetOptionString(CFG_MAPSAVEDIR); + if (savedlg.DoModal()==IDOK) { + const char* savename=savedlg.m_ofn.lpstrFile; + + CStr dir(savename); + dir=dir.Left(savedlg.m_ofn.nFileOffset-1); + g_UserCfg.SetOptionString(CFG_MAPSAVEDIR,(const char*) dir); + + CMapWriter writer; + try { + writer.SaveMap(savename); + + CStr filetitle=savedlg.m_ofn.lpstrFileTitle; + int index=filetitle.ReverseFind(CStr(".")); + CStr doctitle=(index==-1) ? filetitle : filetitle.GetSubstring(0,index); + g_EditorData.SetScenarioName((const char*) doctitle); + SetTitle(); + } catch (CFilePacker::CFileOpenError) { + char buf[256]; + sprintf(buf,"Failed to open \"%s\" for writing",savename); + MessageBox(buf,"Error",MB_OK); + } catch (CFilePacker::CFileWriteError) { + char buf[256]; + sprintf(buf,"Error trying to write to \"%s\"",savename); + MessageBox(buf,"Error",MB_OK); + } catch (...) { + char buf[256]; + sprintf(buf,"Error saving file \"%s\"",savename); + MessageBox(buf,"Error",MB_OK); + } + } +} + +void CMainFrame::OnFileLoadMap() +{ + g_EditorData.SetMode(CEditorData::SCENARIO_EDIT); + + const char* filter="PMP Files|*.pmp||"; + CFileDialog loaddlg(TRUE,"pmp",0,OFN_FILEMUSTEXIST | OFN_NOCHANGEDIR,filter,0); + loaddlg.m_ofn.lpstrInitialDir=g_UserCfg.GetOptionString(CFG_MAPLOADDIR); + + if (loaddlg.DoModal()==IDOK) { + const char* loadname=loaddlg.m_ofn.lpstrFile; + + CStr dir(loadname); + dir=dir.Left(loaddlg.m_ofn.nFileOffset-1); + g_UserCfg.SetOptionString(CFG_MAPLOADDIR,(const char*) dir); + + CMapReader reader; + try { + reader.LoadMap(loadname); + + CStr filetitle=loaddlg.m_ofn.lpstrFileTitle; + int index=filetitle.ReverseFind(CStr(".")); + CStr doctitle=(index==-1) ? filetitle : filetitle.GetSubstring(0,index); + g_EditorData.SetScenarioName((const char*) doctitle); + SetTitle(); + + // reinitialise minimap + g_MiniMap.Initialise(); + // render everything force asset load + g_EditorData.RenderNoCull(); + + // start everything idling + const std::vector& units=g_UnitMan.GetUnits(); + for (uint i=0;iGetObject()->m_IdleAnim) { + units[i]->GetModel()->SetAnimation(units[i]->GetObject()->m_IdleAnim); + } + } + } catch (CFileUnpacker::CFileOpenError) { + char buf[256]; + sprintf(buf,"Failed to open \"%s\" for reading",loadname); + MessageBox(buf,"Error",MB_OK); + } catch (CFileUnpacker::CFileReadError) { + char buf[256]; + sprintf(buf,"Error trying to read from \"%s\"",loadname); + MessageBox(buf,"Error",MB_OK); + } catch (CFileUnpacker::CFileEOFError) { + char buf[256]; + sprintf(buf,"Premature end of file error reading from \"%s\"",loadname); + MessageBox(buf,"Error",MB_OK); + } catch (CFileUnpacker::CFileVersionError) { + char buf[256]; + sprintf(buf,"Error reading from \"%s\" - version mismatch",loadname); + MessageBox(buf,"Error",MB_OK); + } catch (CFileUnpacker::CFileTypeError) { + char buf[256]; + sprintf(buf,"Error reading \"%s\" - doesn't seem to a PMP file",loadname); + MessageBox(buf,"Error",MB_OK); + } catch (...) { + char buf[256]; + sprintf(buf,"Error loading file \"%s\"",loadname); + MessageBox(buf,"Error",MB_OK); + } + } +} + +void CMainFrame::SetTitle() +{ + // set document title + if (GetActiveView()) { + GetActiveView()->GetDocument()->SetTitle(g_EditorData.GetScenarioName()); + } +} + +void CMainFrame::OnViewRenderStats() +{ + CInfoBox& infobox=g_EditorData.GetInfoBox(); + infobox.SetVisible(!infobox.GetVisible()); +} + +void CMainFrame::OnUpdateViewRenderStats(CCmdUI* pCmdUI) +{ + pCmdUI->SetCheck(g_EditorData.GetInfoBox().GetVisible()==true); +} + +void CMainFrame::OnToolsBrushShapeEditor() +{ + DeselectTools(); + ShowControlBar(&m_wndBrushShapeEditorBar,TRUE,FALSE); + + // set active tool + g_ToolMan.SetActiveTool(CBrushShapeEditorTool::GetTool()); + + // ensure we're in the right editing mode + g_EditorData.SetMode(CEditorData::SCENARIO_EDIT); +} + +LRESULT CMainFrame::OnMouseWheel(WPARAM wParam,LPARAM lParam) +{ + // Windows sucks: why the main frame is getting mouse wheel messages + // when mouse move messages are still going to the view is beyond + // my comprehension. Just duplicate the work CScEdView does. + int xPos = LOWORD(lParam); + int yPos = HIWORD(lParam); + SHORT fwKeys = LOWORD(wParam); + SHORT zDelta = HIWORD(wParam); + + g_NaviCam.OnMouseWheelScroll(0,xPos,yPos,float(zDelta)/120.0f); + + return 0; +} + +void CMainFrame::OnTestGo() +{ + g_EditorData.SetMode(CEditorData::TEST_MODE); +} + +void CMainFrame::OnUpdateTestGo(CCmdUI* pCmdUI) +{ + if (g_EditorData.GetMode()==CEditorData::TEST_MODE || g_EditorData.GetMode()!=CEditorData::SCENARIO_EDIT) + pCmdUI->Enable(FALSE); + else + pCmdUI->Enable(TRUE); +} + +void CMainFrame::OnTestStop() +{ + g_EditorData.SetMode(CEditorData::SCENARIO_EDIT); +} + +void CMainFrame::OnUpdateTestStop(CCmdUI* pCmdUI) +{ + if (g_EditorData.GetMode()==CEditorData::TEST_MODE) + pCmdUI->Enable(TRUE); + else + pCmdUI->Enable(FALSE); +} diff --git a/source/sced/MainFrm.h b/source/sced/MainFrm.h index 0cc6d68e53..47314c416c 100755 --- a/source/sced/MainFrm.h +++ b/source/sced/MainFrm.h @@ -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_) diff --git a/source/sced/MapSizeDlg.cpp b/source/sced/MapSizeDlg.cpp index 4357f4febb..15e1e3015d 100755 --- a/source/sced/MapSizeDlg.cpp +++ b/source/sced/MapSizeDlg.cpp @@ -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; +} diff --git a/source/sced/MapSizeDlg.h b/source/sced/MapSizeDlg.h index 80cc687a9b..68874d2c67 100755 --- a/source/sced/MapSizeDlg.h +++ b/source/sced/MapSizeDlg.h @@ -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_) diff --git a/source/sced/MiniMap.cpp b/source/sced/MiniMap.cpp index 438d42acbb..fc331fb677 100755 --- a/source/sced/MiniMap.cpp +++ b/source/sced/MiniMap.cpp @@ -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>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; pjTex1 ? 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>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>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; pjTex1 ? 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>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; +} diff --git a/source/sced/MiniMap.h b/source/sced/MiniMap.h index 971f261904..b1b5accad2 100755 --- a/source/sced/MiniMap.h +++ b/source/sced/MiniMap.h @@ -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 diff --git a/source/sced/NaviCam.cpp b/source/sced/NaviCam.cpp index 140f47bc77..8ec953fdfc 100755 --- a/source/sced/NaviCam.cpp +++ b/source/sced/NaviCam.cpp @@ -1,68 +1,68 @@ -#include "stdafx.h" -#include "NaviCam.h" -#include "EditorData.h" -#include - -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 (h1500) { - // 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 + +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 (h1500) { + // 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) +{ +} diff --git a/source/sced/NaviCam.h b/source/sced/NaviCam.h index 83a711bfb5..f093deca17 100755 --- a/source/sced/NaviCam.h +++ b/source/sced/NaviCam.h @@ -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 diff --git a/source/sced/NavigatePropPage.cpp b/source/sced/NavigatePropPage.cpp index 8775891419..d8fd8703ef 100755 --- a/source/sced/NavigatePropPage.cpp +++ b/source/sced/NavigatePropPage.cpp @@ -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 diff --git a/source/sced/NavigatePropPage.h b/source/sced/NavigatePropPage.h index 2fd9d51755..b84987938f 100755 --- a/source/sced/NavigatePropPage.h +++ b/source/sced/NavigatePropPage.h @@ -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_) diff --git a/source/sced/OptionsDlg.cpp b/source/sced/OptionsDlg.cpp index 9dae09e207..9c08bbf466 100755 --- a/source/sced/OptionsDlg.cpp +++ b/source/sced/OptionsDlg.cpp @@ -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 +} diff --git a/source/sced/OptionsDlg.h b/source/sced/OptionsDlg.h index c18dae0d2f..ceb14a96bb 100755 --- a/source/sced/OptionsDlg.h +++ b/source/sced/OptionsDlg.h @@ -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_) diff --git a/source/sced/OptionsPropSheet.cpp b/source/sced/OptionsPropSheet.cpp index db45e1af2a..f26e54333b 100755 --- a/source/sced/OptionsPropSheet.cpp +++ b/source/sced/OptionsPropSheet.cpp @@ -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; +} diff --git a/source/sced/OptionsPropSheet.h b/source/sced/OptionsPropSheet.h index 7e60697b82..1b9b24db2a 100755 --- a/source/sced/OptionsPropSheet.h +++ b/source/sced/OptionsPropSheet.h @@ -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_) diff --git a/source/sced/PaintObjectCommand.cpp b/source/sced/PaintObjectCommand.cpp index 8366d32712..0246f22823 100755 --- a/source/sced/PaintObjectCommand.cpp +++ b/source/sced/PaintObjectCommand.cpp @@ -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); +} diff --git a/source/sced/PaintObjectCommand.h b/source/sced/PaintObjectCommand.h index 616271826a..88d172c662 100755 --- a/source/sced/PaintObjectCommand.h +++ b/source/sced/PaintObjectCommand.h @@ -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 diff --git a/source/sced/PaintObjectTool.cpp b/source/sced/PaintObjectTool.cpp index 8013b4e331..553ad744b9 100755 --- a/source/sced/PaintObjectTool.cpp +++ b/source/sced/PaintObjectTool.cpp @@ -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); +} diff --git a/source/sced/PaintObjectTool.h b/source/sced/PaintObjectTool.h index 594f6b4a96..4336b703e6 100755 --- a/source/sced/PaintObjectTool.h +++ b/source/sced/PaintObjectTool.h @@ -1,57 +1,57 @@ -#ifndef _PAINTOBJECTTOOL_H -#define _PAINTOBJECTTOOL_H - -#include -#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 +#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 diff --git a/source/sced/PaintTextureCommand.cpp b/source/sced/PaintTextureCommand.cpp index 13ad320a31..5d36f28705 100755 --- a/source/sced/PaintTextureCommand.cpp +++ b/source/sced/PaintTextureCommand.cpp @@ -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 (xmax) 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;jSetDirty(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& 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 (xmax) 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;jSetDirty(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& data) +{ +} diff --git a/source/sced/PaintTextureCommand.h b/source/sced/PaintTextureCommand.h index b4d3372560..1da106b1f6 100755 --- a/source/sced/PaintTextureCommand.h +++ b/source/sced/PaintTextureCommand.h @@ -1,68 +1,68 @@ -#ifndef _PAINTTEXTURECOMMAND_H -#define _PAINTTEXTURECOMMAND_H - -#include -#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& 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=0 && iy& 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 m_DataIn; - // output data (new textures applied to the selection after painting) - CArray2D m_DataOut; -}; - -#endif +#ifndef _PAINTTEXTURECOMMAND_H +#define _PAINTTEXTURECOMMAND_H + +#include +#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& 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=0 && iy& 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 m_DataIn; + // output data (new textures applied to the selection after painting) + CArray2D m_DataOut; +}; + +#endif diff --git a/source/sced/PaintTextureTool.cpp b/source/sced/PaintTextureTool.cpp index 0de8a8b82a..67839a1cef 100755 --- a/source/sced/PaintTextureTool.cpp +++ b/source/sced/PaintTextureTool.cpp @@ -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); +} + + diff --git a/source/sced/PaintTextureTool.h b/source/sced/PaintTextureTool.h index e2c8eae20c..5656a8ee18 100755 --- a/source/sced/PaintTextureTool.h +++ b/source/sced/PaintTextureTool.h @@ -1,43 +1,43 @@ -#ifndef _PAINTTEXTURETOOL_H -#define _PAINTTEXTURETOOL_H - -#include -#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 +#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 diff --git a/source/sced/RaiseElevationCommand.cpp b/source/sced/RaiseElevationCommand.cpp index b38f8fa952..7805674a82 100755 --- a/source/sced/RaiseElevationCommand.cpp +++ b/source/sced/RaiseElevationCommand.cpp @@ -1,36 +1,36 @@ -#include "RaiseElevationCommand.h" -#include "Terrain.h" - -extern CTerrain g_Terrain; - -inline int clamp(int x,int min,int max) -{ - if (xmax) 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 (xmax) 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; + } + } +} diff --git a/source/sced/RaiseElevationCommand.h b/source/sced/RaiseElevationCommand.h index bec66e3aac..1803b5e6e0 100755 --- a/source/sced/RaiseElevationCommand.h +++ b/source/sced/RaiseElevationCommand.h @@ -1,24 +1,24 @@ -#ifndef _RAISEELEVATIONCOMMAND_H -#define _RAISEELEVATIONCOMMAND_H - -#include "AlterElevationCommand.h" - -class CRaiseElevationCommand : public CAlterElevationCommand -{ -public: - // constructor, destructor - CRaiseElevationCommand(int deltaheight,int brushSize,int selectionCentre[2]); - ~CRaiseElevationCommand(); - - // return the texture name of this command - const char* GetName() const { return m_DeltaHeight<0 ? "Lower Elevation" : "Raise Elevation"; } - - // calculate output data - void CalcDataOut(int x0,int x1,int z0,int z1); - -private: - // change in elevation, signed - int m_DeltaHeight; -}; - -#endif +#ifndef _RAISEELEVATIONCOMMAND_H +#define _RAISEELEVATIONCOMMAND_H + +#include "AlterElevationCommand.h" + +class CRaiseElevationCommand : public CAlterElevationCommand +{ +public: + // constructor, destructor + CRaiseElevationCommand(int deltaheight,int brushSize,int selectionCentre[2]); + ~CRaiseElevationCommand(); + + // return the texture name of this command + const char* GetName() const { return m_DeltaHeight<0 ? "Lower Elevation" : "Raise Elevation"; } + + // calculate output data + void CalcDataOut(int x0,int x1,int z0,int z1); + +private: + // change in elevation, signed + int m_DeltaHeight; +}; + +#endif diff --git a/source/sced/RaiseElevationTool.cpp b/source/sced/RaiseElevationTool.cpp index f6bd5d5779..77f572daff 100755 --- a/source/sced/RaiseElevationTool.cpp +++ b/source/sced/RaiseElevationTool.cpp @@ -1,79 +1,79 @@ -#include "CommandManager.h" -#include "RaiseElevationTool.h" -#include "RaiseElevationCommand.h" - -#include "timer.h" - -// default tool instance -CRaiseElevationTool CRaiseElevationTool::m_RaiseElevationTool; - - -CRaiseElevationTool::CRaiseElevationTool() : m_Speed(MAX_SPEED) -{ -} - -// callback for left button down event -void CRaiseElevationTool::OnLButtonDown(u32 flags,int px,int py) -{ - // store trigger time - m_LastTriggerTime=get_time(); - // give base class a shout to do some work - CBrushTool::OnLButtonDown(flags,px,py); -} - -// callback for left button up event -void CRaiseElevationTool::OnLButtonUp(u32 flags,int px,int py) -{ - // force a trigger - OnTriggerLeft(); - // give base class a shout to do some work - CBrushTool::OnLButtonUp(flags,px,py); -} - -// callback for right button down event -void CRaiseElevationTool::OnRButtonDown(u32 flags,int px,int py) -{ - // store trigger time - m_LastTriggerTime=get_time(); - // give base class a shout to do some work - CBrushTool::OnRButtonDown(flags,px,py); -} - -// callback for right button up event -void CRaiseElevationTool::OnRButtonUp(u32 flags,int px,int py) -{ - // force a trigger - OnTriggerRight(); - // give base class a shout to do some work - CBrushTool::OnRButtonUp(flags,px,py); -} - -void CRaiseElevationTool::AlterSelectionHeight(int32 amount) -{ - CRaiseElevationCommand* alterCmd=new CRaiseElevationCommand(amount,m_BrushSize,m_SelectionCentre); - g_CmdMan.Execute(alterCmd); -} - -int32 CRaiseElevationTool::CalcDistSinceLastTrigger() -{ - double curtime=get_time(); - double elapsed=curtime-m_LastTriggerTime; - int32 dist=int32(elapsed*m_Speed); - - m_LastTriggerTime+=dist/m_Speed; - - return dist; -} - -// tool triggered by left mouse button; raise selected terrain -void CRaiseElevationTool::OnTriggerLeft() -{ - AlterSelectionHeight(CalcDistSinceLastTrigger()); -} - -// tool triggered by right mouse button; lower selected terrain -void CRaiseElevationTool::OnTriggerRight() -{ - AlterSelectionHeight(-CalcDistSinceLastTrigger()); -} - +#include "CommandManager.h" +#include "RaiseElevationTool.h" +#include "RaiseElevationCommand.h" + +#include "timer.h" + +// default tool instance +CRaiseElevationTool CRaiseElevationTool::m_RaiseElevationTool; + + +CRaiseElevationTool::CRaiseElevationTool() : m_Speed(MAX_SPEED) +{ +} + +// callback for left button down event +void CRaiseElevationTool::OnLButtonDown(u32 flags,int px,int py) +{ + // store trigger time + m_LastTriggerTime=get_time(); + // give base class a shout to do some work + CBrushTool::OnLButtonDown(flags,px,py); +} + +// callback for left button up event +void CRaiseElevationTool::OnLButtonUp(u32 flags,int px,int py) +{ + // force a trigger + OnTriggerLeft(); + // give base class a shout to do some work + CBrushTool::OnLButtonUp(flags,px,py); +} + +// callback for right button down event +void CRaiseElevationTool::OnRButtonDown(u32 flags,int px,int py) +{ + // store trigger time + m_LastTriggerTime=get_time(); + // give base class a shout to do some work + CBrushTool::OnRButtonDown(flags,px,py); +} + +// callback for right button up event +void CRaiseElevationTool::OnRButtonUp(u32 flags,int px,int py) +{ + // force a trigger + OnTriggerRight(); + // give base class a shout to do some work + CBrushTool::OnRButtonUp(flags,px,py); +} + +void CRaiseElevationTool::AlterSelectionHeight(int32 amount) +{ + CRaiseElevationCommand* alterCmd=new CRaiseElevationCommand(amount,m_BrushSize,m_SelectionCentre); + g_CmdMan.Execute(alterCmd); +} + +int32 CRaiseElevationTool::CalcDistSinceLastTrigger() +{ + double curtime=get_time(); + double elapsed=curtime-m_LastTriggerTime; + int32 dist=int32(elapsed*m_Speed); + + m_LastTriggerTime+=dist/m_Speed; + + return dist; +} + +// tool triggered by left mouse button; raise selected terrain +void CRaiseElevationTool::OnTriggerLeft() +{ + AlterSelectionHeight(CalcDistSinceLastTrigger()); +} + +// tool triggered by right mouse button; lower selected terrain +void CRaiseElevationTool::OnTriggerRight() +{ + AlterSelectionHeight(-CalcDistSinceLastTrigger()); +} + diff --git a/source/sced/RaiseElevationTool.h b/source/sced/RaiseElevationTool.h index 980da311ae..c81a17d1b8 100755 --- a/source/sced/RaiseElevationTool.h +++ b/source/sced/RaiseElevationTool.h @@ -1,60 +1,60 @@ -#ifndef _RAISEELEVATIONTOOL_H -#define _RAISEELEVATIONTOOL_H - -#include -#include "res/res.h" -#include "BrushTool.h" - -class CRaiseElevationTool : public CBrushTool -{ -public: - enum { MAX_BRUSH_SIZE=8 }; - enum { MAX_SPEED=255 }; - -public: - CRaiseElevationTool(); - - // tool triggered by left mouse button; raise selected terrain - void OnTriggerLeft(); - // tool triggered by right mouse button; lower selected terrain - void OnTriggerRight(); - - // callback for left button down event - void OnLButtonDown(u32 flags,int px,int py); - // callback for left button up event - void OnLButtonUp(u32 flags,int px,int py); - // callback for right button down event - void OnRButtonDown(u32 flags,int px,int py); - // callback for right button up event - void OnRButtonUp(u32 flags,int px,int py); - - // set change in elevation on tool being triggered - void SetSpeed(int delta) { m_Speed=delta; } - // get change in elevation on tool being triggered - int GetSpeed() const { return m_Speed; } - - // allow multiple triggers by click and drag - bool SupportDragTrigger() { return true; } - - // get tool instance - static CRaiseElevationTool* GetTool() { return &m_RaiseElevationTool; } - -private: - // raise/lower the currently selected terrain tiles by given amount - void AlterSelectionHeight(int32 amount); - - // calculate distance terrain has moved since last trigger; adjust last trigger - // time appropriately to avoid rounding errors - int32 CalcDistSinceLastTrigger(); - - // number of units to raise/lower selected terrain tiles per second - int m_Speed; - - // time of last trigger - double m_LastTriggerTime; - - // default tool instance - static CRaiseElevationTool m_RaiseElevationTool; -}; - -#endif +#ifndef _RAISEELEVATIONTOOL_H +#define _RAISEELEVATIONTOOL_H + +#include +#include "res/res.h" +#include "BrushTool.h" + +class CRaiseElevationTool : public CBrushTool +{ +public: + enum { MAX_BRUSH_SIZE=8 }; + enum { MAX_SPEED=255 }; + +public: + CRaiseElevationTool(); + + // tool triggered by left mouse button; raise selected terrain + void OnTriggerLeft(); + // tool triggered by right mouse button; lower selected terrain + void OnTriggerRight(); + + // callback for left button down event + void OnLButtonDown(u32 flags,int px,int py); + // callback for left button up event + void OnLButtonUp(u32 flags,int px,int py); + // callback for right button down event + void OnRButtonDown(u32 flags,int px,int py); + // callback for right button up event + void OnRButtonUp(u32 flags,int px,int py); + + // set change in elevation on tool being triggered + void SetSpeed(int delta) { m_Speed=delta; } + // get change in elevation on tool being triggered + int GetSpeed() const { return m_Speed; } + + // allow multiple triggers by click and drag + bool SupportDragTrigger() { return true; } + + // get tool instance + static CRaiseElevationTool* GetTool() { return &m_RaiseElevationTool; } + +private: + // raise/lower the currently selected terrain tiles by given amount + void AlterSelectionHeight(int32 amount); + + // calculate distance terrain has moved since last trigger; adjust last trigger + // time appropriately to avoid rounding errors + int32 CalcDistSinceLastTrigger(); + + // number of units to raise/lower selected terrain tiles per second + int m_Speed; + + // time of last trigger + double m_LastTriggerTime; + + // default tool instance + static CRaiseElevationTool m_RaiseElevationTool; +}; + +#endif diff --git a/source/sced/ScEd.cpp b/source/sced/ScEd.cpp index 005f6e5eaa..051a8cbe00 100755 --- a/source/sced/ScEd.cpp +++ b/source/sced/ScEd.cpp @@ -1,217 +1,217 @@ -// ScEd.cpp : Defines the class behaviors for the application. -// - -#include "stdafx.h" -#include "ScEd.h" - -#include "MainFrm.h" -#include "ScEdDoc.h" -#include "ScEdView.h" -#include "WebLinkButton.h" -#include "UIGlobals.h" - -#include "lib.h" -#ifdef _M_IX86 -#include "sysdep/ia32.h" -#endif -#include "detect.h" - -///////////////////////////////////////////////////////////////////////////// -// CScEdApp - -BEGIN_MESSAGE_MAP(CScEdApp, CWinApp) - //{{AFX_MSG_MAP(CScEdApp) - ON_COMMAND(ID_APP_ABOUT, OnAppAbout) - // NOTE - the ClassWizard will add and remove mapping macros here. - // DO NOT EDIT what you see in these blocks of generated code! - //}}AFX_MSG_MAP - // Standard file based document commands - ON_COMMAND(ID_FILE_NEW, CWinApp::OnFileNew) - ON_COMMAND(ID_FILE_OPEN, CWinApp::OnFileOpen) -END_MESSAGE_MAP() - -///////////////////////////////////////////////////////////////////////////// -// CScEdApp construction - -CScEdApp::CScEdApp() -{ -} - -///////////////////////////////////////////////////////////////////////////// -// The one and only CScEdApp object - -CScEdApp theApp; - -///////////////////////////////////////////////////////////////////////////// -// CScEdApp initialization - -BOOL CScEdApp::InitInstance() -{ - AfxEnableControlContainer(); - - // Standard initialization - // If you are not using these features and wish to reduce the size - // of your final executable, you should remove from the following - // the specific initialization routines you do not need. - -#ifdef _AFXDLL - Enable3dControls(); // Call this when using MFC in a shared DLL -#else - Enable3dControlsStatic(); // Call this when linking to MFC statically -#endif - - // Change the registry key under which our settings are stored. - // TODO: You should modify this string to be something appropriate - // such as the name of your company or organization. - SetRegistryKey(_T("Local AppWizard-Generated Applications")); - - LoadStdProfileSettings(); // Load standard INI file options (including MRU) - - // Register the application's document templates. Document templates - // serve as the connection between documents, frame windows and views. - - CSingleDocTemplate* pDocTemplate; - pDocTemplate = new CSingleDocTemplate( - IDR_MAINFRAME, - RUNTIME_CLASS(CScEdDoc), - RUNTIME_CLASS(CMainFrame), // main SDI frame window - RUNTIME_CLASS(CScEdView)); - AddDocTemplate(pDocTemplate); - - // Parse command line for standard shell commands, DDE, file open - CCommandLineInfo cmdInfo; - ParseCommandLine(cmdInfo); - - // Dispatch commands specified on the command line - if (!ProcessShellCommand(cmdInfo)) - return FALSE; - - ((CMainFrame*)m_pMainWnd)->SetTitle(); - - // The one and only window has been initialized, so show and update it. - m_pMainWnd->ShowWindow(SW_SHOWMAXIMIZED); - m_pMainWnd->UpdateWindow(); - - return TRUE; -} - - -///////////////////////////////////////////////////////////////////////////// -// CAboutDlg dialog used for App About - -class CAboutDlg : public CDialog -{ -public: - CAboutDlg(); - -// Dialog Data - //{{AFX_DATA(CAboutDlg) - enum { IDD = IDD_ABOUTBOX }; - CWebLinkButton m_WFGLinkButton; - //}}AFX_DATA - - // ClassWizard generated virtual function overrides - //{{AFX_VIRTUAL(CAboutDlg) - protected: - virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support - //}}AFX_VIRTUAL - -// Implementation -protected: - //{{AFX_MSG(CAboutDlg) - virtual BOOL OnInitDialog(); - //}}AFX_MSG - DECLARE_MESSAGE_MAP() -}; - -CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) -{ - //{{AFX_DATA_INIT(CAboutDlg) - //}}AFX_DATA_INIT -} - -void CAboutDlg::DoDataExchange(CDataExchange* pDX) -{ - CDialog::DoDataExchange(pDX); - //{{AFX_DATA_MAP(CAboutDlg) - DDX_Control(pDX, IDC_BUTTON_LAUNCHWFG, m_WFGLinkButton); - //}}AFX_DATA_MAP -} - -BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) - //{{AFX_MSG_MAP(CAboutDlg) - //}}AFX_MSG_MAP -END_MESSAGE_MAP() - -// App command to run the dialog -void CScEdApp::OnAppAbout() -{ - CAboutDlg aboutDlg; - aboutDlg.DoModal(); -} - -///////////////////////////////////////////////////////////////////////////// -// CScEdApp message handlers - -BOOL CAboutDlg::OnInitDialog() -{ - CDialog::OnInitDialog(); - - char buf[64]; - GetVersionString(buf); - - CWnd* wnd=GetDlgItem(IDC_STATIC_VERSION); - wnd->SetWindowText(buf); - - m_WFGLinkButton.m_Address="www.wildfiregames.com"; - - return TRUE; // return TRUE unless you set the focus to a control - // EXCEPTION: OCX Property Pages should return FALSE -} - -int CScEdApp::Run() -{ - // acquire and dispatch messages until a WM_QUIT message is received - while (1) { - // process windows messages - while (::PeekMessage(&m_msgCur, NULL, NULL, NULL, PM_NOREMOVE)) { - // pump message, but quit on WM_QUIT - if (!PumpMessage()) - return ExitInstance(); - } - // do idle time processing - CMainFrame* mainfrm=(CMainFrame*) AfxGetMainWnd(); - if (mainfrm) { - CScEdView* view=(CScEdView*) mainfrm->GetActiveView(); - if (view) { - view->IdleTimeProcess(); - } - } - } - - // shouldn't get here - return 0; -} - -#if 0 -int AFXAPI AfxWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, - LPTSTR lpCmdLine, int nCmdShow); - -extern void pre_main_init(); - -int main(int argc, char *argv[]) -{ - pre_main_init(); - lib_init(); - - // set 24 bit (float) FPU precision for faster divides / sqrts -#ifdef _M_IX86 - _control87(_PC_24, _MCW_PC); -#endif - - detect(); - - AfxInitialize(); - return AfxWinMain(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0); -} +// ScEd.cpp : Defines the class behaviors for the application. +// + +#include "stdafx.h" +#include "ScEd.h" + +#include "MainFrm.h" +#include "ScEdDoc.h" +#include "ScEdView.h" +#include "WebLinkButton.h" +#include "UIGlobals.h" + +#include "lib.h" +#ifdef _M_IX86 +#include "sysdep/ia32.h" +#endif +#include "detect.h" + +///////////////////////////////////////////////////////////////////////////// +// CScEdApp + +BEGIN_MESSAGE_MAP(CScEdApp, CWinApp) + //{{AFX_MSG_MAP(CScEdApp) + ON_COMMAND(ID_APP_ABOUT, OnAppAbout) + // NOTE - the ClassWizard will add and remove mapping macros here. + // DO NOT EDIT what you see in these blocks of generated code! + //}}AFX_MSG_MAP + // Standard file based document commands + ON_COMMAND(ID_FILE_NEW, CWinApp::OnFileNew) + ON_COMMAND(ID_FILE_OPEN, CWinApp::OnFileOpen) +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CScEdApp construction + +CScEdApp::CScEdApp() +{ +} + +///////////////////////////////////////////////////////////////////////////// +// The one and only CScEdApp object + +CScEdApp theApp; + +///////////////////////////////////////////////////////////////////////////// +// CScEdApp initialization + +BOOL CScEdApp::InitInstance() +{ + AfxEnableControlContainer(); + + // Standard initialization + // If you are not using these features and wish to reduce the size + // of your final executable, you should remove from the following + // the specific initialization routines you do not need. + +#ifdef _AFXDLL + Enable3dControls(); // Call this when using MFC in a shared DLL +#else + Enable3dControlsStatic(); // Call this when linking to MFC statically +#endif + + // Change the registry key under which our settings are stored. + // TODO: You should modify this string to be something appropriate + // such as the name of your company or organization. + SetRegistryKey(_T("Local AppWizard-Generated Applications")); + + LoadStdProfileSettings(); // Load standard INI file options (including MRU) + + // Register the application's document templates. Document templates + // serve as the connection between documents, frame windows and views. + + CSingleDocTemplate* pDocTemplate; + pDocTemplate = new CSingleDocTemplate( + IDR_MAINFRAME, + RUNTIME_CLASS(CScEdDoc), + RUNTIME_CLASS(CMainFrame), // main SDI frame window + RUNTIME_CLASS(CScEdView)); + AddDocTemplate(pDocTemplate); + + // Parse command line for standard shell commands, DDE, file open + CCommandLineInfo cmdInfo; + ParseCommandLine(cmdInfo); + + // Dispatch commands specified on the command line + if (!ProcessShellCommand(cmdInfo)) + return FALSE; + + ((CMainFrame*)m_pMainWnd)->SetTitle(); + + // The one and only window has been initialized, so show and update it. + m_pMainWnd->ShowWindow(SW_SHOWMAXIMIZED); + m_pMainWnd->UpdateWindow(); + + return TRUE; +} + + +///////////////////////////////////////////////////////////////////////////// +// CAboutDlg dialog used for App About + +class CAboutDlg : public CDialog +{ +public: + CAboutDlg(); + +// Dialog Data + //{{AFX_DATA(CAboutDlg) + enum { IDD = IDD_ABOUTBOX }; + CWebLinkButton m_WFGLinkButton; + //}}AFX_DATA + + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CAboutDlg) + protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + //{{AFX_MSG(CAboutDlg) + virtual BOOL OnInitDialog(); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) +{ + //{{AFX_DATA_INIT(CAboutDlg) + //}}AFX_DATA_INIT +} + +void CAboutDlg::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(CAboutDlg) + DDX_Control(pDX, IDC_BUTTON_LAUNCHWFG, m_WFGLinkButton); + //}}AFX_DATA_MAP +} + +BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) + //{{AFX_MSG_MAP(CAboutDlg) + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +// App command to run the dialog +void CScEdApp::OnAppAbout() +{ + CAboutDlg aboutDlg; + aboutDlg.DoModal(); +} + +///////////////////////////////////////////////////////////////////////////// +// CScEdApp message handlers + +BOOL CAboutDlg::OnInitDialog() +{ + CDialog::OnInitDialog(); + + char buf[64]; + GetVersionString(buf); + + CWnd* wnd=GetDlgItem(IDC_STATIC_VERSION); + wnd->SetWindowText(buf); + + m_WFGLinkButton.m_Address="www.wildfiregames.com"; + + return TRUE; // return TRUE unless you set the focus to a control + // EXCEPTION: OCX Property Pages should return FALSE +} + +int CScEdApp::Run() +{ + // acquire and dispatch messages until a WM_QUIT message is received + while (1) { + // process windows messages + while (::PeekMessage(&m_msgCur, NULL, NULL, NULL, PM_NOREMOVE)) { + // pump message, but quit on WM_QUIT + if (!PumpMessage()) + return ExitInstance(); + } + // do idle time processing + CMainFrame* mainfrm=(CMainFrame*) AfxGetMainWnd(); + if (mainfrm) { + CScEdView* view=(CScEdView*) mainfrm->GetActiveView(); + if (view) { + view->IdleTimeProcess(); + } + } + } + + // shouldn't get here + return 0; +} + +#if 0 +int AFXAPI AfxWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, + LPTSTR lpCmdLine, int nCmdShow); + +extern void pre_main_init(); + +int main(int argc, char *argv[]) +{ + pre_main_init(); + lib_init(); + + // set 24 bit (float) FPU precision for faster divides / sqrts +#ifdef _M_IX86 + _control87(_PC_24, _MCW_PC); +#endif + + detect(); + + AfxInitialize(); + return AfxWinMain(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0); +} #endif \ No newline at end of file diff --git a/source/sced/ScEd.h b/source/sced/ScEd.h index 5a8768c96c..22be6b21b5 100755 --- a/source/sced/ScEd.h +++ b/source/sced/ScEd.h @@ -1,50 +1,50 @@ -// ScEd.h : main header file for the SCED application -// - -#if !defined(AFX_SCED_H__7CE13472_02D4_450E_8F31_B08FBE733ED6__INCLUDED_) -#define AFX_SCED_H__7CE13472_02D4_450E_8F31_B08FBE733ED6__INCLUDED_ - -#if _MSC_VER > 1000 -#pragma once -#endif // _MSC_VER > 1000 - -#ifndef __AFXWIN_H__ - #error include 'stdafx.h' before including this file for PCH -#endif - -#include "resource.h" // main symbols - -///////////////////////////////////////////////////////////////////////////// -// CScEdApp: -// See ScEd.cpp for the implementation of this class -// - -class CScEdApp : public CWinApp -{ -public: - CScEdApp(); - -// Overrides - // ClassWizard generated virtual function overrides - //{{AFX_VIRTUAL(CScEdApp) - public: - virtual BOOL InitInstance(); - virtual int Run(); - //}}AFX_VIRTUAL - -// Implementation - //{{AFX_MSG(CScEdApp) - afx_msg void OnAppAbout(); - // NOTE - the ClassWizard will add and remove member functions here. - // DO NOT EDIT what you see in these blocks of generated code ! - //}}AFX_MSG - DECLARE_MESSAGE_MAP() -}; - - -///////////////////////////////////////////////////////////////////////////// - -//{{AFX_INSERT_LOCATION}} -// Microsoft Visual C++ will insert additional declarations immediately before the previous line. - -#endif // !defined(AFX_SCED_H__7CE13472_02D4_450E_8F31_B08FBE733ED6__INCLUDED_) +// ScEd.h : main header file for the SCED application +// + +#if !defined(AFX_SCED_H__7CE13472_02D4_450E_8F31_B08FBE733ED6__INCLUDED_) +#define AFX_SCED_H__7CE13472_02D4_450E_8F31_B08FBE733ED6__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +#ifndef __AFXWIN_H__ + #error include 'stdafx.h' before including this file for PCH +#endif + +#include "resource.h" // main symbols + +///////////////////////////////////////////////////////////////////////////// +// CScEdApp: +// See ScEd.cpp for the implementation of this class +// + +class CScEdApp : public CWinApp +{ +public: + CScEdApp(); + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CScEdApp) + public: + virtual BOOL InitInstance(); + virtual int Run(); + //}}AFX_VIRTUAL + +// Implementation + //{{AFX_MSG(CScEdApp) + afx_msg void OnAppAbout(); + // NOTE - the ClassWizard will add and remove member functions here. + // DO NOT EDIT what you see in these blocks of generated code ! + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + + +///////////////////////////////////////////////////////////////////////////// + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_SCED_H__7CE13472_02D4_450E_8F31_B08FBE733ED6__INCLUDED_) diff --git a/source/sced/ScEdDoc.cpp b/source/sced/ScEdDoc.cpp index f55fcac018..dac1d98231 100755 --- a/source/sced/ScEdDoc.cpp +++ b/source/sced/ScEdDoc.cpp @@ -1,78 +1,78 @@ -// ScEdDoc.cpp : implementation of the CScEdDoc class -// - -#include "stdafx.h" -#include "ScEd.h" - -#include "ScEdDoc.h" - -///////////////////////////////////////////////////////////////////////////// -// CScEdDoc - -IMPLEMENT_DYNCREATE(CScEdDoc, CDocument) - -BEGIN_MESSAGE_MAP(CScEdDoc, CDocument) - //{{AFX_MSG_MAP(CScEdDoc) - // NOTE - the ClassWizard will add and remove mapping macros here. - // DO NOT EDIT what you see in these blocks of generated code! - //}}AFX_MSG_MAP -END_MESSAGE_MAP() - -///////////////////////////////////////////////////////////////////////////// -// CScEdDoc construction/destruction - -CScEdDoc::CScEdDoc() -{ - // TODO: add one-time construction code here - m_bAutoDelete = FALSE; -} - -CScEdDoc::~CScEdDoc() -{ -} - -BOOL CScEdDoc::OnNewDocument() -{ - if (!CDocument::OnNewDocument()) - return FALSE; - - // TODO: add reinitialization code here - // (SDI documents will reuse this document) - - return TRUE; -} - - - -///////////////////////////////////////////////////////////////////////////// -// CScEdDoc serialization - -void CScEdDoc::Serialize(CArchive& ar) -{ - if (ar.IsStoring()) - { - // TODO: add storing code here - } - else - { - // TODO: add loading code here - } -} - -///////////////////////////////////////////////////////////////////////////// -// CScEdDoc diagnostics - -#ifdef _DEBUG -void CScEdDoc::AssertValid() const -{ - CDocument::AssertValid(); -} - -void CScEdDoc::Dump(CDumpContext& dc) const -{ - CDocument::Dump(dc); -} -#endif //_DEBUG - -///////////////////////////////////////////////////////////////////////////// -// CScEdDoc commands +// ScEdDoc.cpp : implementation of the CScEdDoc class +// + +#include "stdafx.h" +#include "ScEd.h" + +#include "ScEdDoc.h" + +///////////////////////////////////////////////////////////////////////////// +// CScEdDoc + +IMPLEMENT_DYNCREATE(CScEdDoc, CDocument) + +BEGIN_MESSAGE_MAP(CScEdDoc, CDocument) + //{{AFX_MSG_MAP(CScEdDoc) + // NOTE - the ClassWizard will add and remove mapping macros here. + // DO NOT EDIT what you see in these blocks of generated code! + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CScEdDoc construction/destruction + +CScEdDoc::CScEdDoc() +{ + // TODO: add one-time construction code here + m_bAutoDelete = FALSE; +} + +CScEdDoc::~CScEdDoc() +{ +} + +BOOL CScEdDoc::OnNewDocument() +{ + if (!CDocument::OnNewDocument()) + return FALSE; + + // TODO: add reinitialization code here + // (SDI documents will reuse this document) + + return TRUE; +} + + + +///////////////////////////////////////////////////////////////////////////// +// CScEdDoc serialization + +void CScEdDoc::Serialize(CArchive& ar) +{ + if (ar.IsStoring()) + { + // TODO: add storing code here + } + else + { + // TODO: add loading code here + } +} + +///////////////////////////////////////////////////////////////////////////// +// CScEdDoc diagnostics + +#ifdef _DEBUG +void CScEdDoc::AssertValid() const +{ + CDocument::AssertValid(); +} + +void CScEdDoc::Dump(CDumpContext& dc) const +{ + CDocument::Dump(dc); +} +#endif //_DEBUG + +///////////////////////////////////////////////////////////////////////////// +// CScEdDoc commands diff --git a/source/sced/ScEdDoc.h b/source/sced/ScEdDoc.h index 25cd72b256..e9dc558bb7 100755 --- a/source/sced/ScEdDoc.h +++ b/source/sced/ScEdDoc.h @@ -1,57 +1,57 @@ -// ScEdDoc.h : interface of the CScEdDoc class -// -///////////////////////////////////////////////////////////////////////////// - -#if !defined(AFX_SCEDDOC_H__6242BDFF_C79F_4830_8E45_7433106317DB__INCLUDED_) -#define AFX_SCEDDOC_H__6242BDFF_C79F_4830_8E45_7433106317DB__INCLUDED_ - -#if _MSC_VER > 1000 -#pragma once -#endif // _MSC_VER > 1000 - - -class CScEdDoc : public CDocument -{ -protected: // create from serialization only - CScEdDoc(); - DECLARE_DYNCREATE(CScEdDoc) - -// Attributes -public: - -// Operations -public: - -// Overrides - // ClassWizard generated virtual function overrides - //{{AFX_VIRTUAL(CScEdDoc) - public: - virtual BOOL OnNewDocument(); - virtual void Serialize(CArchive& ar); - //}}AFX_VIRTUAL - -// Implementation -public: - virtual ~CScEdDoc(); -#ifdef _DEBUG - virtual void AssertValid() const; - virtual void Dump(CDumpContext& dc) const; -#endif - -protected: - -// Generated message map functions -protected: - //{{AFX_MSG(CScEdDoc) - // NOTE - the ClassWizard will add and remove member functions here. - // DO NOT EDIT what you see in these blocks of generated code ! - //}}AFX_MSG - DECLARE_MESSAGE_MAP() -}; - -///////////////////////////////////////////////////////////////////////////// - -//{{AFX_INSERT_LOCATION}} -// Microsoft Visual C++ will insert additional declarations immediately before the previous line. - -#endif // !defined(AFX_SCEDDOC_H__6242BDFF_C79F_4830_8E45_7433106317DB__INCLUDED_) +// ScEdDoc.h : interface of the CScEdDoc class +// +///////////////////////////////////////////////////////////////////////////// + +#if !defined(AFX_SCEDDOC_H__6242BDFF_C79F_4830_8E45_7433106317DB__INCLUDED_) +#define AFX_SCEDDOC_H__6242BDFF_C79F_4830_8E45_7433106317DB__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + + +class CScEdDoc : public CDocument +{ +protected: // create from serialization only + CScEdDoc(); + DECLARE_DYNCREATE(CScEdDoc) + +// Attributes +public: + +// Operations +public: + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CScEdDoc) + public: + virtual BOOL OnNewDocument(); + virtual void Serialize(CArchive& ar); + //}}AFX_VIRTUAL + +// Implementation +public: + virtual ~CScEdDoc(); +#ifdef _DEBUG + virtual void AssertValid() const; + virtual void Dump(CDumpContext& dc) const; +#endif + +protected: + +// Generated message map functions +protected: + //{{AFX_MSG(CScEdDoc) + // NOTE - the ClassWizard will add and remove member functions here. + // DO NOT EDIT what you see in these blocks of generated code ! + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +///////////////////////////////////////////////////////////////////////////// + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_SCEDDOC_H__6242BDFF_C79F_4830_8E45_7433106317DB__INCLUDED_) diff --git a/source/sced/ScEdView.cpp b/source/sced/ScEdView.cpp index d23a5a3402..4e1c69faa3 100755 --- a/source/sced/ScEdView.cpp +++ b/source/sced/ScEdView.cpp @@ -1,580 +1,580 @@ -// ScEdView.cpp : implementation of the CScEdView class -// - -#include "stdafx.h" -#include "ScEd.h" - -#include "ScEdDoc.h" -#include "ScEdView.h" -#include "ToolManager.h" -#include "EditorData.h" -#include "UserConfig.h" -#include "MainFrm.h" - -#include "timer.h" -#include "ogl.h" -#include "res/vfs.h" - -int g_ClickMode=0; - -static unsigned int GetModifierKeyFlags() -{ - unsigned int flags=0; - if (::GetAsyncKeyState(VK_MENU) & 0x8000) flags|=TOOL_MOUSEFLAG_ALTDOWN; - if (::GetAsyncKeyState(VK_SHIFT) & 0x8000) flags|=TOOL_MOUSEFLAG_SHIFTDOWN; - if (::GetAsyncKeyState(VK_CONTROL) & 0x8000) flags|=TOOL_MOUSEFLAG_CTRLDOWN; - return flags; -} - - -///////////////////////////////////////////////////////////////////////////// -// CScEdView - -IMPLEMENT_DYNCREATE(CScEdView, CView) - -BEGIN_MESSAGE_MAP(CScEdView, CView) - //{{AFX_MSG_MAP(CScEdView) - ON_WM_ERASEBKGND() - ON_WM_CREATE() - ON_WM_DESTROY() - ON_WM_SIZE() - ON_WM_MOUSEMOVE() - ON_WM_LBUTTONDOWN() - ON_WM_LBUTTONUP() - ON_WM_RBUTTONDOWN() - ON_WM_RBUTTONUP() - ON_WM_MBUTTONDOWN() - ON_WM_MBUTTONUP() - ON_MESSAGE(WM_MOUSEWHEEL,OnMouseWheel) - //}}AFX_MSG_MAP -END_MESSAGE_MAP() - -///////////////////////////////////////////////////////////////////////////// -// CScEdView construction/destruction - -CScEdView::CScEdView() : m_hGLRC(0), m_LastTickTime(-1.0f), m_LastFrameDuration(-1.0f) -{ -} - -CScEdView::~CScEdView() -{ -} - -BOOL CScEdView::PreCreateWindow(CREATESTRUCT& cs) -{ - cs.lpszClass = ::AfxRegisterWndClass(CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS | CS_OWNDC, - ::LoadCursor(NULL, IDC_ARROW), NULL, NULL); - cs.style |= WS_CLIPSIBLINGS | WS_CLIPCHILDREN; - return CView::PreCreateWindow(cs); -} - -///////////////////////////////////////////////////////////////////////////// -// CScEdView drawing - - - -void CScEdView::OnDraw(CDC* pDC) -{ - HWND hWnd = GetSafeHwnd(); - HDC hDC = ::GetDC(hWnd); - wglMakeCurrent(hDC,m_hGLRC); - - g_EditorData.OnDraw(); - - SwapBuffers(hDC); -} - -///////////////////////////////////////////////////////////////////////////// -// CScEdView diagnostics - -#ifdef _DEBUG -void CScEdView::AssertValid() const -{ - CView::AssertValid(); -} - -void CScEdView::Dump(CDumpContext& dc) const -{ - CView::Dump(dc); -} - -CScEdDoc* CScEdView::GetDocument() // non-debug version is inline -{ - ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CScEdDoc))); - return (CScEdDoc*)m_pDocument; -} -#endif //_DEBUG - -///////////////////////////////////////////////////////////////////////////// -// CScEdView message handlers - -BOOL CScEdView::OnEraseBkgnd(CDC* pDC) -{ - return TRUE; -} - -int CScEdView::OnCreate(LPCREATESTRUCT lpCreateStruct) -{ - // base initialisation first - if (CView::OnCreate(lpCreateStruct) == -1) - return -1; - - // get device context for this window - HDC dc=::GetDC(m_hWnd); - - // try and setup a default pixel format - if (!SetupPixelFormat(dc)) { - return -1; - } - - // create context, make it current - m_hGLRC=wglCreateContext(dc); - wglMakeCurrent(dc,m_hGLRC); - - // initialise gl stuff (extensions, etc) - oglInit(); - - // check for minimum requirements - if(!oglExtAvail("GL_ARB_multitexture") || !oglExtAvail("GL_ARB_texture_env_combine")) { - const char* err="No graphics card support for multitexturing found; please visit the 0AD Forums for more information."; - ::MessageBox(0,err,"Error",MB_OK); - exit(0); - } - - - // initialise VFS paths - char path[256]; - ::GetModuleFileName(0,path,256); - file_rel_chdir(path, "../data"); - vfs_mount("", "mods/official", 0); - - // create renderer related stuff - new CRenderer; - - // start up the renderer - g_Renderer.Open(0,0,::GetDeviceCaps(dc,BITSPIXEL)); - - // initialise document data - if (!g_EditorData.Init()) return -1; - - // store current mouse pos - ::GetCursorPos(&m_LastMousePos); - - return 0; -} - -void CScEdView::OnDestroy() -{ - // close down editor resources - g_EditorData.Terminate(); - - // destroy renderer related stuff - delete CRenderer::GetSingletonPtr(); - - // release rendering context - if (m_hGLRC) { - wglMakeCurrent(0,0); - wglDeleteContext(m_hGLRC); - m_hGLRC=0; - } - - // base destruction - CView::OnDestroy(); -} - -void CScEdView::OnSize(UINT nType, int cx, int cy) -{ - // give base class a shout .. - CView::OnSize(nType, cx, cy); - - m_Width=cx; - m_Height=cy; - g_Renderer.Resize(m_Width,m_Height); - - g_EditorData.OnCameraChanged(); -} - -bool CScEdView::SetupPixelFormat(HDC dc) -{ - int bpp=::GetDeviceCaps(dc,BITSPIXEL); - PIXELFORMATDESCRIPTOR pfd = { - sizeof(PIXELFORMATDESCRIPTOR), // size of this pfd - 1, // version number - PFD_DRAW_TO_WINDOW | // support window - PFD_SUPPORT_OPENGL | // support OpenGL - PFD_DOUBLEBUFFER, // double buffered - PFD_TYPE_RGBA, // RGBA type - bpp==16 ? 16 : 24, // 16/24 bit color depth - 0, 0, 0, 0, 0, 0, // color bits ignored - bpp==16 ? 0 : 8, // 16/24 bit color depth - 0, // shift bit ignored - 0, // no accumulation buffer - 0, 0, 0, 0, // accum bits ignored - 24, // 24-bit z-buffer - 8, // 8-bit stencil buffer - 0, // no auxiliary buffer - PFD_MAIN_PLANE, // main layer - 0, // reserved - 0, 0, 0 // layer masks ignored - }; - - int format=::ChoosePixelFormat(dc,&pfd); - if (format==0) { - // ack - can't choose format; bail out - return false; - } - if(::SetPixelFormat(dc,format,&pfd) == false) { - // ugh - still can't get anything; bail out - return false; - } - - // check we've got an accelerated format available - if (::DescribePixelFormat(dc,format,sizeof(pfd),&pfd)) { - if (pfd.dwFlags & PFD_GENERIC_FORMAT) { - const char* err="No hardware accelerated graphics support found; please visit the 0AD Forums for more information."; - ::MessageBox(0,err,"Error",MB_OK); - exit(0); - } - } - - return true; -} - - -static CPoint lastClientMousePos; - -void CScEdView::OnMouseLeave(const CPoint& point) -{ -} - -void CScEdView::OnMouseEnter(const CPoint& point) -{ - unsigned int flags=GetModifierKeyFlags(); - - // trigger left button up and right button up events as required - if (!(::GetAsyncKeyState(VK_LBUTTON) & 0x8000)) { - g_ToolMan.OnLButtonUp(flags,point.x,point.y); - } - - if (!(::GetAsyncKeyState(VK_RBUTTON) & 0x8000)) { - g_ToolMan.OnRButtonUp(flags,point.x,point.y); - } -} - -void CScEdView::OnMouseMove(UINT nFlags, CPoint point) -{ - SetFocus(); - - if (nFlags & MK_MBUTTON) { - // middle mouse down .. forward move to the navicam and - // we're done - u32 flags=GetModifierKeyFlags(); - g_NaviCam.OnMouseMove(flags,point.x,point.y); - return; - } - - static bool mouseInView=false; - - // get view rect - CRect rect; - GetClientRect(rect); - - // inside? - if(rect.PtInRect(point)) { - // yes - previously inside? - if (!mouseInView) { - // nope - enable mouse capture - SetCapture(); - // run any necessary mouse leave code - OnMouseEnter(point); - } - mouseInView=true; - // store mouse position - lastClientMousePos=point; - - // now actually handle everything required for the actual move event - - // assume we want to update tile selection on mouse move - bool updateSelection=true; - - // check for left mouse down on minimap following click on minimap - if (nFlags & MK_LBUTTON) { - if (g_ClickMode==0) { - if (point.x>m_Width-200 && point.y>m_Height-200) { - AdjustCameraViaMinimapClick(point); - - // minimap moved, so don't update selection - updateSelection=false; - } - } - } - - if (updateSelection) { - unsigned int flags=GetModifierKeyFlags(); - g_ToolMan.OnMouseMove(flags,point.x,point.y); - } - - // store this position as last - m_LastMousePos=point; - - } else { - // previously inside view? - if (mouseInView) { - // yes - run any necessary mouse leave code - OnMouseLeave(point); - // release capture - ReleaseCapture(); - } - // note mouse no longer in view - mouseInView=false; - } - -} - - -void CScEdView::OnScreenShot() -{ - static int counter=1; - - // generate filename, create directory if required - char buf[512]; - sprintf(buf,"../screenshots"); - mkdir(buf,0); - sprintf(buf,"%s/%08d.tga",buf,counter++); - - // make context current - HWND hWnd = GetSafeHwnd(); - HDC hDC = ::GetDC(hWnd); - wglMakeCurrent(hDC,m_hGLRC); - - // call on editor to make screenshot - g_EditorData.OnScreenShot(buf); -} - - -void CScEdView::OnRButtonUp(UINT nFlags, CPoint point) -{ - g_ClickMode=1; - - unsigned int flags=GetModifierKeyFlags(); - g_ToolMan.OnRButtonUp(flags,point.x,point.y); -} - -void CScEdView::OnRButtonDown(UINT nFlags, CPoint point) -{ - if (point.x>m_Width-200 && point.y>m_Height-200) { - } else { - g_ClickMode=1; - unsigned int flags=GetModifierKeyFlags(); - g_ToolMan.OnRButtonDown(flags,point.x,point.y); - } -} - - -void CScEdView::OnLButtonUp(UINT nFlags, CPoint point) -{ - g_ClickMode=1; - - unsigned int flags=GetModifierKeyFlags(); - g_ToolMan.OnLButtonUp(flags,point.x,point.y); -} - -void CScEdView::OnLButtonDown(UINT nFlags, CPoint point) -{ - if (point.x>m_Width-200 && point.y>m_Height-200) { - g_ClickMode=0; - AdjustCameraViaMinimapClick(point); - } else { - g_ClickMode=1; - unsigned int flags=GetModifierKeyFlags(); - g_ToolMan.OnLButtonDown(flags,point.x,point.y); - } -} - -void CScEdView::AdjustCameraViaMinimapClick(CPoint point) -{ - // convert from screen space point back to world space point representating intersection of - // ray with terrain plane - CVector3D pos; - pos.X=float(CELL_SIZE*g_Terrain.GetVerticesPerSide())*float(point.x+200-m_Width)/200.0f; - pos.Y=-g_EditorData.m_TerrainPlane.m_Dist; - pos.Z=float(CELL_SIZE*g_Terrain.GetVerticesPerSide())*float(m_Height-point.y)/197.0f; - - // calculate desired camera point from this - CVector3D startpos=g_NaviCam.GetCamera().m_Orientation.GetTranslation(); - CVector3D rayDir=g_NaviCam.GetCamera().m_Orientation.GetIn(); - - float distToPlane=g_EditorData.m_TerrainPlane.DistanceToPlane(startpos); - float dot=rayDir.Dot(g_EditorData.m_TerrainPlane.m_Norm); - CVector3D endpos=pos+(rayDir*(distToPlane/dot)); - - // translate camera from old point to new - CVector3D trans=endpos-startpos; - g_NaviCam.GetCamera().m_Orientation.Translate(trans); - - g_EditorData.OnCameraChanged(); -} - -bool CScEdView::AppHasFocus() -{ - CWnd* wnd=AfxGetMainWnd(); - if (!wnd) return false; - - CWnd* focuswnd=GetFocus(); - - while (focuswnd) { - if (focuswnd==wnd) return true; - focuswnd=focuswnd->GetParent(); - } - - return false; -} - -void CScEdView::IdleTimeProcess() -{ - if (m_LastTickTime==-1) { - m_LastTickTime=get_time(); - return; - } - - // fake a mouse move from current position if either mouse button is down - unsigned int flags=0; - if ((::GetAsyncKeyState(VK_LBUTTON) & 0x8000) || (::GetAsyncKeyState(VK_RBUTTON) & 0x8000)) { - unsigned int flags=GetModifierKeyFlags(); - g_ToolMan.OnMouseMove(flags,m_LastMousePos.x,m_LastMousePos.y); - } - - double curtime=get_time(); - double diff=curtime-m_LastTickTime; - - if (m_LastFrameDuration>0) { - - g_EditorData.UpdateWorld(float(m_LastFrameDuration)); - - // check app has focus - if (AppHasFocus()) { - POINT pt; - if (GetCursorPos(&pt)) { - // want to scroll? - int scrollspeed=g_UserCfg.GetOptionInt(CFG_SCROLLSPEED); - if (scrollspeed>0) { - RECT rect; - AfxGetMainWnd()->GetWindowRect(&rect); - - // scale translation by distance from terrain - float h=g_NaviCam.GetCamera().m_Orientation.GetTranslation().Y; - float speed=h*0.1f; - - // scale translation to account for fact that we might not be running at the same rate as the timer - speed*=float(diff); - - // scale by user requested speed - speed*=scrollspeed; - - bool changed=false; - if (pt.xrect.right-16) { - CVector3D left=g_NaviCam.GetCamera().m_Orientation.GetLeft(); - // strip vertical movement, to prevent moving into/away from terrain plane - left.Y=0; - left.Normalize(); - g_NaviCam.GetCamera().m_Orientation.Translate(left*(-speed)); - changed=true; - } - - if (pt.y>rect.bottom-16) { - CVector3D up=g_NaviCam.GetCamera().m_Orientation.GetUp(); - // strip vertical movement, to prevent moving into/away from terrain plane - up.Y=0; - up.Normalize(); - g_NaviCam.GetCamera().m_Orientation.Translate(up*(-speed)); - changed=true; - } else if (pt.ymessage >= WM_KEYFIRST && pMsg->message <= WM_KEYLAST) { - if (pMsg->message==WM_KEYDOWN) { - int key=(int) pMsg->wParam; - CMainFrame* mainfrm=(CMainFrame*)AfxGetApp()->m_pMainWnd; - switch (key) { - case VK_F1: - mainfrm->OnViewRenderStats(); - break; - case VK_F9: - mainfrm->OnViewScreenshot(); - break; - case 'Z': - if (GetAsyncKeyState(VK_CONTROL)) - mainfrm->OnEditUndo(); - break; - case 'Y': - if (GetAsyncKeyState(VK_CONTROL)) - mainfrm->OnEditRedo(); - break; - } - } - return 1; - } else { - return CView::PreTranslateMessage(pMsg); - } -} +// ScEdView.cpp : implementation of the CScEdView class +// + +#include "stdafx.h" +#include "ScEd.h" + +#include "ScEdDoc.h" +#include "ScEdView.h" +#include "ToolManager.h" +#include "EditorData.h" +#include "UserConfig.h" +#include "MainFrm.h" + +#include "timer.h" +#include "ogl.h" +#include "res/vfs.h" + +int g_ClickMode=0; + +static unsigned int GetModifierKeyFlags() +{ + unsigned int flags=0; + if (::GetAsyncKeyState(VK_MENU) & 0x8000) flags|=TOOL_MOUSEFLAG_ALTDOWN; + if (::GetAsyncKeyState(VK_SHIFT) & 0x8000) flags|=TOOL_MOUSEFLAG_SHIFTDOWN; + if (::GetAsyncKeyState(VK_CONTROL) & 0x8000) flags|=TOOL_MOUSEFLAG_CTRLDOWN; + return flags; +} + + +///////////////////////////////////////////////////////////////////////////// +// CScEdView + +IMPLEMENT_DYNCREATE(CScEdView, CView) + +BEGIN_MESSAGE_MAP(CScEdView, CView) + //{{AFX_MSG_MAP(CScEdView) + ON_WM_ERASEBKGND() + ON_WM_CREATE() + ON_WM_DESTROY() + ON_WM_SIZE() + ON_WM_MOUSEMOVE() + ON_WM_LBUTTONDOWN() + ON_WM_LBUTTONUP() + ON_WM_RBUTTONDOWN() + ON_WM_RBUTTONUP() + ON_WM_MBUTTONDOWN() + ON_WM_MBUTTONUP() + ON_MESSAGE(WM_MOUSEWHEEL,OnMouseWheel) + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CScEdView construction/destruction + +CScEdView::CScEdView() : m_hGLRC(0), m_LastTickTime(-1.0f), m_LastFrameDuration(-1.0f) +{ +} + +CScEdView::~CScEdView() +{ +} + +BOOL CScEdView::PreCreateWindow(CREATESTRUCT& cs) +{ + cs.lpszClass = ::AfxRegisterWndClass(CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS | CS_OWNDC, + ::LoadCursor(NULL, IDC_ARROW), NULL, NULL); + cs.style |= WS_CLIPSIBLINGS | WS_CLIPCHILDREN; + return CView::PreCreateWindow(cs); +} + +///////////////////////////////////////////////////////////////////////////// +// CScEdView drawing + + + +void CScEdView::OnDraw(CDC* pDC) +{ + HWND hWnd = GetSafeHwnd(); + HDC hDC = ::GetDC(hWnd); + wglMakeCurrent(hDC,m_hGLRC); + + g_EditorData.OnDraw(); + + SwapBuffers(hDC); +} + +///////////////////////////////////////////////////////////////////////////// +// CScEdView diagnostics + +#ifdef _DEBUG +void CScEdView::AssertValid() const +{ + CView::AssertValid(); +} + +void CScEdView::Dump(CDumpContext& dc) const +{ + CView::Dump(dc); +} + +CScEdDoc* CScEdView::GetDocument() // non-debug version is inline +{ + ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CScEdDoc))); + return (CScEdDoc*)m_pDocument; +} +#endif //_DEBUG + +///////////////////////////////////////////////////////////////////////////// +// CScEdView message handlers + +BOOL CScEdView::OnEraseBkgnd(CDC* pDC) +{ + return TRUE; +} + +int CScEdView::OnCreate(LPCREATESTRUCT lpCreateStruct) +{ + // base initialisation first + if (CView::OnCreate(lpCreateStruct) == -1) + return -1; + + // get device context for this window + HDC dc=::GetDC(m_hWnd); + + // try and setup a default pixel format + if (!SetupPixelFormat(dc)) { + return -1; + } + + // create context, make it current + m_hGLRC=wglCreateContext(dc); + wglMakeCurrent(dc,m_hGLRC); + + // initialise gl stuff (extensions, etc) + oglInit(); + + // check for minimum requirements + if(!oglExtAvail("GL_ARB_multitexture") || !oglExtAvail("GL_ARB_texture_env_combine")) { + const char* err="No graphics card support for multitexturing found; please visit the 0AD Forums for more information."; + ::MessageBox(0,err,"Error",MB_OK); + exit(0); + } + + + // initialise VFS paths + char path[256]; + ::GetModuleFileName(0,path,256); + file_rel_chdir(path, "../data"); + vfs_mount("", "mods/official", 0); + + // create renderer related stuff + new CRenderer; + + // start up the renderer + g_Renderer.Open(0,0,::GetDeviceCaps(dc,BITSPIXEL)); + + // initialise document data + if (!g_EditorData.Init()) return -1; + + // store current mouse pos + ::GetCursorPos(&m_LastMousePos); + + return 0; +} + +void CScEdView::OnDestroy() +{ + // close down editor resources + g_EditorData.Terminate(); + + // destroy renderer related stuff + delete CRenderer::GetSingletonPtr(); + + // release rendering context + if (m_hGLRC) { + wglMakeCurrent(0,0); + wglDeleteContext(m_hGLRC); + m_hGLRC=0; + } + + // base destruction + CView::OnDestroy(); +} + +void CScEdView::OnSize(UINT nType, int cx, int cy) +{ + // give base class a shout .. + CView::OnSize(nType, cx, cy); + + m_Width=cx; + m_Height=cy; + g_Renderer.Resize(m_Width,m_Height); + + g_EditorData.OnCameraChanged(); +} + +bool CScEdView::SetupPixelFormat(HDC dc) +{ + int bpp=::GetDeviceCaps(dc,BITSPIXEL); + PIXELFORMATDESCRIPTOR pfd = { + sizeof(PIXELFORMATDESCRIPTOR), // size of this pfd + 1, // version number + PFD_DRAW_TO_WINDOW | // support window + PFD_SUPPORT_OPENGL | // support OpenGL + PFD_DOUBLEBUFFER, // double buffered + PFD_TYPE_RGBA, // RGBA type + bpp==16 ? 16 : 24, // 16/24 bit color depth + 0, 0, 0, 0, 0, 0, // color bits ignored + bpp==16 ? 0 : 8, // 16/24 bit color depth + 0, // shift bit ignored + 0, // no accumulation buffer + 0, 0, 0, 0, // accum bits ignored + 24, // 24-bit z-buffer + 8, // 8-bit stencil buffer + 0, // no auxiliary buffer + PFD_MAIN_PLANE, // main layer + 0, // reserved + 0, 0, 0 // layer masks ignored + }; + + int format=::ChoosePixelFormat(dc,&pfd); + if (format==0) { + // ack - can't choose format; bail out + return false; + } + if(::SetPixelFormat(dc,format,&pfd) == false) { + // ugh - still can't get anything; bail out + return false; + } + + // check we've got an accelerated format available + if (::DescribePixelFormat(dc,format,sizeof(pfd),&pfd)) { + if (pfd.dwFlags & PFD_GENERIC_FORMAT) { + const char* err="No hardware accelerated graphics support found; please visit the 0AD Forums for more information."; + ::MessageBox(0,err,"Error",MB_OK); + exit(0); + } + } + + return true; +} + + +static CPoint lastClientMousePos; + +void CScEdView::OnMouseLeave(const CPoint& point) +{ +} + +void CScEdView::OnMouseEnter(const CPoint& point) +{ + unsigned int flags=GetModifierKeyFlags(); + + // trigger left button up and right button up events as required + if (!(::GetAsyncKeyState(VK_LBUTTON) & 0x8000)) { + g_ToolMan.OnLButtonUp(flags,point.x,point.y); + } + + if (!(::GetAsyncKeyState(VK_RBUTTON) & 0x8000)) { + g_ToolMan.OnRButtonUp(flags,point.x,point.y); + } +} + +void CScEdView::OnMouseMove(UINT nFlags, CPoint point) +{ + SetFocus(); + + if (nFlags & MK_MBUTTON) { + // middle mouse down .. forward move to the navicam and + // we're done + u32 flags=GetModifierKeyFlags(); + g_NaviCam.OnMouseMove(flags,point.x,point.y); + return; + } + + static bool mouseInView=false; + + // get view rect + CRect rect; + GetClientRect(rect); + + // inside? + if(rect.PtInRect(point)) { + // yes - previously inside? + if (!mouseInView) { + // nope - enable mouse capture + SetCapture(); + // run any necessary mouse leave code + OnMouseEnter(point); + } + mouseInView=true; + // store mouse position + lastClientMousePos=point; + + // now actually handle everything required for the actual move event + + // assume we want to update tile selection on mouse move + bool updateSelection=true; + + // check for left mouse down on minimap following click on minimap + if (nFlags & MK_LBUTTON) { + if (g_ClickMode==0) { + if (point.x>m_Width-200 && point.y>m_Height-200) { + AdjustCameraViaMinimapClick(point); + + // minimap moved, so don't update selection + updateSelection=false; + } + } + } + + if (updateSelection) { + unsigned int flags=GetModifierKeyFlags(); + g_ToolMan.OnMouseMove(flags,point.x,point.y); + } + + // store this position as last + m_LastMousePos=point; + + } else { + // previously inside view? + if (mouseInView) { + // yes - run any necessary mouse leave code + OnMouseLeave(point); + // release capture + ReleaseCapture(); + } + // note mouse no longer in view + mouseInView=false; + } + +} + + +void CScEdView::OnScreenShot() +{ + static int counter=1; + + // generate filename, create directory if required + char buf[512]; + sprintf(buf,"../screenshots"); + mkdir(buf,0); + sprintf(buf,"%s/%08d.tga",buf,counter++); + + // make context current + HWND hWnd = GetSafeHwnd(); + HDC hDC = ::GetDC(hWnd); + wglMakeCurrent(hDC,m_hGLRC); + + // call on editor to make screenshot + g_EditorData.OnScreenShot(buf); +} + + +void CScEdView::OnRButtonUp(UINT nFlags, CPoint point) +{ + g_ClickMode=1; + + unsigned int flags=GetModifierKeyFlags(); + g_ToolMan.OnRButtonUp(flags,point.x,point.y); +} + +void CScEdView::OnRButtonDown(UINT nFlags, CPoint point) +{ + if (point.x>m_Width-200 && point.y>m_Height-200) { + } else { + g_ClickMode=1; + unsigned int flags=GetModifierKeyFlags(); + g_ToolMan.OnRButtonDown(flags,point.x,point.y); + } +} + + +void CScEdView::OnLButtonUp(UINT nFlags, CPoint point) +{ + g_ClickMode=1; + + unsigned int flags=GetModifierKeyFlags(); + g_ToolMan.OnLButtonUp(flags,point.x,point.y); +} + +void CScEdView::OnLButtonDown(UINT nFlags, CPoint point) +{ + if (point.x>m_Width-200 && point.y>m_Height-200) { + g_ClickMode=0; + AdjustCameraViaMinimapClick(point); + } else { + g_ClickMode=1; + unsigned int flags=GetModifierKeyFlags(); + g_ToolMan.OnLButtonDown(flags,point.x,point.y); + } +} + +void CScEdView::AdjustCameraViaMinimapClick(CPoint point) +{ + // convert from screen space point back to world space point representating intersection of + // ray with terrain plane + CVector3D pos; + pos.X=float(CELL_SIZE*g_Terrain.GetVerticesPerSide())*float(point.x+200-m_Width)/200.0f; + pos.Y=-g_EditorData.m_TerrainPlane.m_Dist; + pos.Z=float(CELL_SIZE*g_Terrain.GetVerticesPerSide())*float(m_Height-point.y)/197.0f; + + // calculate desired camera point from this + CVector3D startpos=g_NaviCam.GetCamera().m_Orientation.GetTranslation(); + CVector3D rayDir=g_NaviCam.GetCamera().m_Orientation.GetIn(); + + float distToPlane=g_EditorData.m_TerrainPlane.DistanceToPlane(startpos); + float dot=rayDir.Dot(g_EditorData.m_TerrainPlane.m_Norm); + CVector3D endpos=pos+(rayDir*(distToPlane/dot)); + + // translate camera from old point to new + CVector3D trans=endpos-startpos; + g_NaviCam.GetCamera().m_Orientation.Translate(trans); + + g_EditorData.OnCameraChanged(); +} + +bool CScEdView::AppHasFocus() +{ + CWnd* wnd=AfxGetMainWnd(); + if (!wnd) return false; + + CWnd* focuswnd=GetFocus(); + + while (focuswnd) { + if (focuswnd==wnd) return true; + focuswnd=focuswnd->GetParent(); + } + + return false; +} + +void CScEdView::IdleTimeProcess() +{ + if (m_LastTickTime==-1) { + m_LastTickTime=get_time(); + return; + } + + // fake a mouse move from current position if either mouse button is down + unsigned int flags=0; + if ((::GetAsyncKeyState(VK_LBUTTON) & 0x8000) || (::GetAsyncKeyState(VK_RBUTTON) & 0x8000)) { + unsigned int flags=GetModifierKeyFlags(); + g_ToolMan.OnMouseMove(flags,m_LastMousePos.x,m_LastMousePos.y); + } + + double curtime=get_time(); + double diff=curtime-m_LastTickTime; + + if (m_LastFrameDuration>0) { + + g_EditorData.UpdateWorld(float(m_LastFrameDuration)); + + // check app has focus + if (AppHasFocus()) { + POINT pt; + if (GetCursorPos(&pt)) { + // want to scroll? + int scrollspeed=g_UserCfg.GetOptionInt(CFG_SCROLLSPEED); + if (scrollspeed>0) { + RECT rect; + AfxGetMainWnd()->GetWindowRect(&rect); + + // scale translation by distance from terrain + float h=g_NaviCam.GetCamera().m_Orientation.GetTranslation().Y; + float speed=h*0.1f; + + // scale translation to account for fact that we might not be running at the same rate as the timer + speed*=float(diff); + + // scale by user requested speed + speed*=scrollspeed; + + bool changed=false; + if (pt.xrect.right-16) { + CVector3D left=g_NaviCam.GetCamera().m_Orientation.GetLeft(); + // strip vertical movement, to prevent moving into/away from terrain plane + left.Y=0; + left.Normalize(); + g_NaviCam.GetCamera().m_Orientation.Translate(left*(-speed)); + changed=true; + } + + if (pt.y>rect.bottom-16) { + CVector3D up=g_NaviCam.GetCamera().m_Orientation.GetUp(); + // strip vertical movement, to prevent moving into/away from terrain plane + up.Y=0; + up.Normalize(); + g_NaviCam.GetCamera().m_Orientation.Translate(up*(-speed)); + changed=true; + } else if (pt.ymessage >= WM_KEYFIRST && pMsg->message <= WM_KEYLAST) { + if (pMsg->message==WM_KEYDOWN) { + int key=(int) pMsg->wParam; + CMainFrame* mainfrm=(CMainFrame*)AfxGetApp()->m_pMainWnd; + switch (key) { + case VK_F1: + mainfrm->OnViewRenderStats(); + break; + case VK_F9: + mainfrm->OnViewScreenshot(); + break; + case 'Z': + if (GetAsyncKeyState(VK_CONTROL)) + mainfrm->OnEditUndo(); + break; + case 'Y': + if (GetAsyncKeyState(VK_CONTROL)) + mainfrm->OnEditRedo(); + break; + } + } + return 1; + } else { + return CView::PreTranslateMessage(pMsg); + } +} diff --git a/source/sced/ScEdView.h b/source/sced/ScEdView.h index e274771da8..fbbebf0687 100755 --- a/source/sced/ScEdView.h +++ b/source/sced/ScEdView.h @@ -1,101 +1,101 @@ -// ScEdView.h : interface of the CScEdView class -// -///////////////////////////////////////////////////////////////////////////// - -#if !defined(AFX_SCEDVIEW_H__8E15B3D6_0CEA_4B52_95AC_64B15600ADE8__INCLUDED_) -#define AFX_SCEDVIEW_H__8E15B3D6_0CEA_4B52_95AC_64B15600ADE8__INCLUDED_ - -#if _MSC_VER > 1000 -#pragma once -#endif // _MSC_VER > 1000 - - -// forward declarations -class CScEdDoc; - - -class CScEdView : public CView -{ -protected: // create from serialization only - CScEdView(); - DECLARE_DYNCREATE(CScEdView) - -// Attributes -public: - CScEdDoc* GetDocument(); - void OnScreenShot(); - -// Operations -public: - -// Overrides - // ClassWizard generated virtual function overrides - //{{AFX_VIRTUAL(CScEdView) - public: - virtual void OnDraw(CDC* pDC); // overridden to draw this view - virtual BOOL PreCreateWindow(CREATESTRUCT& cs); - virtual BOOL PreTranslateMessage(MSG* pMsg); - //}}AFX_VIRTUAL - -// Implementation -public: - virtual ~CScEdView(); -#ifdef _DEBUG - virtual void AssertValid() const; - virtual void Dump(CDumpContext& dc) const; -#endif - - - void IdleTimeProcess(); - - // current size of view - int m_Width,m_Height; - -protected: - void AdjustCameraViaMinimapClick(CPoint point); - bool AppHasFocus(); - - // GL rendering context - HGLRC m_hGLRC; - // last known position of mouse - CPoint m_LastMousePos; - // setup pixel format on given DC - bool SetupPixelFormat(HDC dc); - // last tick time - double m_LastTickTime; - // duration of last frame - double m_LastFrameDuration; - - void OnMouseLeave(const CPoint& point); - void OnMouseEnter(const CPoint& point); - -// Generated message map functions -protected: - //{{AFX_MSG(CScEdView) - afx_msg BOOL OnEraseBkgnd(CDC* pDC); - afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); - afx_msg void OnDestroy(); - afx_msg void OnSize(UINT nType, int cx, int cy); - afx_msg void OnMouseMove(UINT nFlags, CPoint point); - afx_msg void OnLButtonDown(UINT nFlags, CPoint point); - afx_msg void OnLButtonUp(UINT nFlags, CPoint point); - afx_msg void OnRButtonDown(UINT nFlags, CPoint point); - afx_msg void OnRButtonUp(UINT nFlags, CPoint point); - afx_msg void OnMButtonDown(UINT nFlags, CPoint point); - afx_msg void OnMButtonUp(UINT nFlags, CPoint point); - afx_msg LRESULT OnMouseWheel(WPARAM wParam,LPARAM lParam); - //}}AFX_MSG - DECLARE_MESSAGE_MAP() -}; - -#ifndef _DEBUG // debug version in ScEdView.cpp -inline CScEdDoc* CScEdView::GetDocument() - { return (CScEdDoc*)m_pDocument; } -#endif - -///////////////////////////////////////////////////////////////////////////// - -//{{AFX_INSERT_LOCATION}} -// Microsoft Visual C++ will insert additional declarations immediately before the previous line. - -#endif // !defined(AFX_SCEDVIEW_H__8E15B3D6_0CEA_4B52_95AC_64B15600ADE8__INCLUDED_) +// ScEdView.h : interface of the CScEdView class +// +///////////////////////////////////////////////////////////////////////////// + +#if !defined(AFX_SCEDVIEW_H__8E15B3D6_0CEA_4B52_95AC_64B15600ADE8__INCLUDED_) +#define AFX_SCEDVIEW_H__8E15B3D6_0CEA_4B52_95AC_64B15600ADE8__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + + +// forward declarations +class CScEdDoc; + + +class CScEdView : public CView +{ +protected: // create from serialization only + CScEdView(); + DECLARE_DYNCREATE(CScEdView) + +// Attributes +public: + CScEdDoc* GetDocument(); + void OnScreenShot(); + +// Operations +public: + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CScEdView) + public: + virtual void OnDraw(CDC* pDC); // overridden to draw this view + virtual BOOL PreCreateWindow(CREATESTRUCT& cs); + virtual BOOL PreTranslateMessage(MSG* pMsg); + //}}AFX_VIRTUAL + +// Implementation +public: + virtual ~CScEdView(); +#ifdef _DEBUG + virtual void AssertValid() const; + virtual void Dump(CDumpContext& dc) const; +#endif + + + void IdleTimeProcess(); + + // current size of view + int m_Width,m_Height; + +protected: + void AdjustCameraViaMinimapClick(CPoint point); + bool AppHasFocus(); + + // GL rendering context + HGLRC m_hGLRC; + // last known position of mouse + CPoint m_LastMousePos; + // setup pixel format on given DC + bool SetupPixelFormat(HDC dc); + // last tick time + double m_LastTickTime; + // duration of last frame + double m_LastFrameDuration; + + void OnMouseLeave(const CPoint& point); + void OnMouseEnter(const CPoint& point); + +// Generated message map functions +protected: + //{{AFX_MSG(CScEdView) + afx_msg BOOL OnEraseBkgnd(CDC* pDC); + afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); + afx_msg void OnDestroy(); + afx_msg void OnSize(UINT nType, int cx, int cy); + afx_msg void OnMouseMove(UINT nFlags, CPoint point); + afx_msg void OnLButtonDown(UINT nFlags, CPoint point); + afx_msg void OnLButtonUp(UINT nFlags, CPoint point); + afx_msg void OnRButtonDown(UINT nFlags, CPoint point); + afx_msg void OnRButtonUp(UINT nFlags, CPoint point); + afx_msg void OnMButtonDown(UINT nFlags, CPoint point); + afx_msg void OnMButtonUp(UINT nFlags, CPoint point); + afx_msg LRESULT OnMouseWheel(WPARAM wParam,LPARAM lParam); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +#ifndef _DEBUG // debug version in ScEdView.cpp +inline CScEdDoc* CScEdView::GetDocument() + { return (CScEdDoc*)m_pDocument; } +#endif + +///////////////////////////////////////////////////////////////////////////// + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_SCEDVIEW_H__8E15B3D6_0CEA_4B52_95AC_64B15600ADE8__INCLUDED_) diff --git a/source/sced/SelectObjectTool.cpp b/source/sced/SelectObjectTool.cpp index 92839cddf7..19dbb2ec9d 100755 --- a/source/sced/SelectObjectTool.cpp +++ b/source/sced/SelectObjectTool.cpp @@ -1,112 +1,112 @@ -#include "CommandManager.h" -#include "Unit.h" -#include "Model.h" -#include "ObjectEntry.h" -#include "Terrain.h" -#include "Renderer.h" -#include "UnitManager.h" -#include "SelectObjectTool.h" -#include - -// default tool instance -CSelectObjectTool CSelectObjectTool::m_SelectObjectTool; - -CSelectObjectTool::CSelectObjectTool() -{ - m_BrushSize=0; -} - -void CSelectObjectTool::OnDraw() -{ - glColor3f(1,0,0); - - for (uint i=0;i::iterator Iter; - Iter iter=std::find(m_SelectedUnits.begin(),m_SelectedUnits.end(),hit); - if (iter!=m_SelectedUnits.end()) { - m_SelectedUnits.erase(iter); - } - } else { - // just set hit as sole selection - m_SelectedUnits.clear(); - m_SelectedUnits.push_back(hit); - } - } else { - // clear selection unless some modifier begin applied - if (!(flags & TOOL_MOUSEFLAG_CTRLDOWN) && !(flags & TOOL_MOUSEFLAG_ALTDOWN)) { - m_SelectedUnits.clear(); - } - } -} - -///////////////////////////////////////////////////////////////////////////////////////////////// -// RenderUnitBounds: render a bounding box round given unit -void CSelectObjectTool::RenderUnitBounds(CUnit* unit) -{ - glPushMatrix(); - const CMatrix3D& transform=unit->GetModel()->GetTransform(); - glMultMatrixf(&transform._11); - - const CBound& bounds=unit->GetModel()->GetObjectBounds(); - - glBegin(GL_LINE_LOOP); - glVertex3f(bounds[0].X,bounds[0].Y,bounds[0].Z); - glVertex3f(bounds[0].X,bounds[0].Y,bounds[1].Z); - glVertex3f(bounds[0].X,bounds[1].Y,bounds[1].Z); - glVertex3f(bounds[0].X,bounds[1].Y,bounds[0].Z); - glEnd(); - - glBegin(GL_LINE_LOOP); - glVertex3f(bounds[1].X,bounds[0].Y,bounds[0].Z); - glVertex3f(bounds[1].X,bounds[0].Y,bounds[1].Z); - glVertex3f(bounds[1].X,bounds[1].Y,bounds[1].Z); - glVertex3f(bounds[1].X,bounds[1].Y,bounds[0].Z); - glEnd(); - - glBegin(GL_LINE_LOOP); - glVertex3f(bounds[0].X,bounds[0].Y,bounds[0].Z); - glVertex3f(bounds[0].X,bounds[0].Y,bounds[1].Z); - glVertex3f(bounds[1].X,bounds[0].Y,bounds[1].Z); - glVertex3f(bounds[1].X,bounds[0].Y,bounds[0].Z); - glEnd(); - - glBegin(GL_LINE_LOOP); - glVertex3f(bounds[0].X,bounds[1].Y,bounds[0].Z); - glVertex3f(bounds[0].X,bounds[1].Y,bounds[1].Z); - glVertex3f(bounds[1].X,bounds[1].Y,bounds[1].Z); - glVertex3f(bounds[1].X,bounds[1].Y,bounds[0].Z); - glEnd(); - - glPopMatrix(); -} - +#include "CommandManager.h" +#include "Unit.h" +#include "Model.h" +#include "ObjectEntry.h" +#include "Terrain.h" +#include "Renderer.h" +#include "UnitManager.h" +#include "SelectObjectTool.h" +#include + +// default tool instance +CSelectObjectTool CSelectObjectTool::m_SelectObjectTool; + +CSelectObjectTool::CSelectObjectTool() +{ + m_BrushSize=0; +} + +void CSelectObjectTool::OnDraw() +{ + glColor3f(1,0,0); + + for (uint i=0;i::iterator Iter; + Iter iter=std::find(m_SelectedUnits.begin(),m_SelectedUnits.end(),hit); + if (iter!=m_SelectedUnits.end()) { + m_SelectedUnits.erase(iter); + } + } else { + // just set hit as sole selection + m_SelectedUnits.clear(); + m_SelectedUnits.push_back(hit); + } + } else { + // clear selection unless some modifier begin applied + if (!(flags & TOOL_MOUSEFLAG_CTRLDOWN) && !(flags & TOOL_MOUSEFLAG_ALTDOWN)) { + m_SelectedUnits.clear(); + } + } +} + +///////////////////////////////////////////////////////////////////////////////////////////////// +// RenderUnitBounds: render a bounding box round given unit +void CSelectObjectTool::RenderUnitBounds(CUnit* unit) +{ + glPushMatrix(); + const CMatrix3D& transform=unit->GetModel()->GetTransform(); + glMultMatrixf(&transform._11); + + const CBound& bounds=unit->GetModel()->GetObjectBounds(); + + glBegin(GL_LINE_LOOP); + glVertex3f(bounds[0].X,bounds[0].Y,bounds[0].Z); + glVertex3f(bounds[0].X,bounds[0].Y,bounds[1].Z); + glVertex3f(bounds[0].X,bounds[1].Y,bounds[1].Z); + glVertex3f(bounds[0].X,bounds[1].Y,bounds[0].Z); + glEnd(); + + glBegin(GL_LINE_LOOP); + glVertex3f(bounds[1].X,bounds[0].Y,bounds[0].Z); + glVertex3f(bounds[1].X,bounds[0].Y,bounds[1].Z); + glVertex3f(bounds[1].X,bounds[1].Y,bounds[1].Z); + glVertex3f(bounds[1].X,bounds[1].Y,bounds[0].Z); + glEnd(); + + glBegin(GL_LINE_LOOP); + glVertex3f(bounds[0].X,bounds[0].Y,bounds[0].Z); + glVertex3f(bounds[0].X,bounds[0].Y,bounds[1].Z); + glVertex3f(bounds[1].X,bounds[0].Y,bounds[1].Z); + glVertex3f(bounds[1].X,bounds[0].Y,bounds[0].Z); + glEnd(); + + glBegin(GL_LINE_LOOP); + glVertex3f(bounds[0].X,bounds[1].Y,bounds[0].Z); + glVertex3f(bounds[0].X,bounds[1].Y,bounds[1].Z); + glVertex3f(bounds[1].X,bounds[1].Y,bounds[1].Z); + glVertex3f(bounds[1].X,bounds[1].Y,bounds[0].Z); + glEnd(); + + glPopMatrix(); +} + diff --git a/source/sced/SelectObjectTool.h b/source/sced/SelectObjectTool.h index bb9f6f5f26..ff08c9b40f 100755 --- a/source/sced/SelectObjectTool.h +++ b/source/sced/SelectObjectTool.h @@ -1,41 +1,41 @@ -#ifndef _SELECTOBJECTTOOL_H -#define _SELECTOBJECTTOOL_H - -#include -#include "res/res.h" - -#include "BrushTool.h" -#include "Vector3D.h" -#include "Matrix3D.h" -#include "Model.h" - -class CUnit; - -class CSelectObjectTool : public CBrushTool -{ -public: - CSelectObjectTool(); - - void OnDraw(); - - // tool triggered via left mouse button; paint current selection - void OnLButtonDown(unsigned int flags,int px,int py) { SelectObject(flags,px,py); } - - // get the default select object instance - static CSelectObjectTool* GetTool() { return &m_SelectObjectTool; } - -private: - // try and select the object under the cursor - void SelectObject(unsigned int flags,int px,int py); - - // render bounding box round given unit - void RenderUnitBounds(CUnit* unit); - - // list of currently selected units - std::vector m_SelectedUnits; - - // default tool instance - static CSelectObjectTool m_SelectObjectTool; -}; - -#endif +#ifndef _SELECTOBJECTTOOL_H +#define _SELECTOBJECTTOOL_H + +#include +#include "res/res.h" + +#include "BrushTool.h" +#include "Vector3D.h" +#include "Matrix3D.h" +#include "Model.h" + +class CUnit; + +class CSelectObjectTool : public CBrushTool +{ +public: + CSelectObjectTool(); + + void OnDraw(); + + // tool triggered via left mouse button; paint current selection + void OnLButtonDown(unsigned int flags,int px,int py) { SelectObject(flags,px,py); } + + // get the default select object instance + static CSelectObjectTool* GetTool() { return &m_SelectObjectTool; } + +private: + // try and select the object under the cursor + void SelectObject(unsigned int flags,int px,int py); + + // render bounding box round given unit + void RenderUnitBounds(CUnit* unit); + + // list of currently selected units + std::vector m_SelectedUnits; + + // default tool instance + static CSelectObjectTool m_SelectObjectTool; +}; + +#endif diff --git a/source/sced/ShadowsPropPage.cpp b/source/sced/ShadowsPropPage.cpp index 56d49a42c7..0b960963de 100755 --- a/source/sced/ShadowsPropPage.cpp +++ b/source/sced/ShadowsPropPage.cpp @@ -1,47 +1,47 @@ -// ShadowsPropPage.cpp : implementation file -// - -#include "stdafx.h" -#include "ScEd.h" -#include "ShadowsPropPage.h" - -#ifdef _DEBUG -#define new DEBUG_NEW -#undef THIS_FILE -static char THIS_FILE[] = __FILE__; -#endif - -///////////////////////////////////////////////////////////////////////////// -// CShadowsPropPage property page - -IMPLEMENT_DYNCREATE(CShadowsPropPage, CPropertyPage) - -CShadowsPropPage::CShadowsPropPage() : CPropertyPage(CShadowsPropPage::IDD) -{ - //{{AFX_DATA_INIT(CShadowsPropPage) - m_EnableShadows = FALSE; - //}}AFX_DATA_INIT -} - -CShadowsPropPage::~CShadowsPropPage() -{ -} - -void CShadowsPropPage::DoDataExchange(CDataExchange* pDX) -{ - CPropertyPage::DoDataExchange(pDX); - //{{AFX_DATA_MAP(CShadowsPropPage) - DDX_Control(pDX, IDC_BUTTON_SHADOWCOLOR, m_ShadowColor); - DDX_Check(pDX, IDC_CHECK_SHADOWS, m_EnableShadows); - //}}AFX_DATA_MAP -} - - -BEGIN_MESSAGE_MAP(CShadowsPropPage, CPropertyPage) - //{{AFX_MSG_MAP(CShadowsPropPage) - // NOTE: the ClassWizard will add message map macros here - //}}AFX_MSG_MAP -END_MESSAGE_MAP() - -///////////////////////////////////////////////////////////////////////////// -// CShadowsPropPage message handlers +// ShadowsPropPage.cpp : implementation file +// + +#include "stdafx.h" +#include "ScEd.h" +#include "ShadowsPropPage.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CShadowsPropPage property page + +IMPLEMENT_DYNCREATE(CShadowsPropPage, CPropertyPage) + +CShadowsPropPage::CShadowsPropPage() : CPropertyPage(CShadowsPropPage::IDD) +{ + //{{AFX_DATA_INIT(CShadowsPropPage) + m_EnableShadows = FALSE; + //}}AFX_DATA_INIT +} + +CShadowsPropPage::~CShadowsPropPage() +{ +} + +void CShadowsPropPage::DoDataExchange(CDataExchange* pDX) +{ + CPropertyPage::DoDataExchange(pDX); + //{{AFX_DATA_MAP(CShadowsPropPage) + DDX_Control(pDX, IDC_BUTTON_SHADOWCOLOR, m_ShadowColor); + DDX_Check(pDX, IDC_CHECK_SHADOWS, m_EnableShadows); + //}}AFX_DATA_MAP +} + + +BEGIN_MESSAGE_MAP(CShadowsPropPage, CPropertyPage) + //{{AFX_MSG_MAP(CShadowsPropPage) + // NOTE: the ClassWizard will add message map macros here + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CShadowsPropPage message handlers diff --git a/source/sced/ShadowsPropPage.h b/source/sced/ShadowsPropPage.h index e281dc1c4b..b969a1969a 100755 --- a/source/sced/ShadowsPropPage.h +++ b/source/sced/ShadowsPropPage.h @@ -1,52 +1,52 @@ -#if !defined(AFX_SHADOWSPROPPAGE_H__49CB83C3_EFFA_4D6B_8EAC_A728D4F85963__INCLUDED_) -#define AFX_SHADOWSPROPPAGE_H__49CB83C3_EFFA_4D6B_8EAC_A728D4F85963__INCLUDED_ - -#if _MSC_VER > 1000 -#pragma once -#endif // _MSC_VER > 1000 -// ShadowsPropPage.h : header file -// - -#include "ColorButton.h" - -///////////////////////////////////////////////////////////////////////////// -// CShadowsPropPage dialog - -class CShadowsPropPage : public CPropertyPage -{ - DECLARE_DYNCREATE(CShadowsPropPage) - -// Construction -public: - CShadowsPropPage(); - ~CShadowsPropPage(); - -// Dialog Data - //{{AFX_DATA(CShadowsPropPage) - enum { IDD = IDD_PROPPAGE_SHADOWS }; - CColorButton m_ShadowColor; - BOOL m_EnableShadows; - //}}AFX_DATA - - -// Overrides - // ClassWizard generate virtual function overrides - //{{AFX_VIRTUAL(CShadowsPropPage) - protected: - virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support - //}}AFX_VIRTUAL - -// Implementation -protected: - // Generated message map functions - //{{AFX_MSG(CShadowsPropPage) - // 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_SHADOWSPROPPAGE_H__49CB83C3_EFFA_4D6B_8EAC_A728D4F85963__INCLUDED_) +#if !defined(AFX_SHADOWSPROPPAGE_H__49CB83C3_EFFA_4D6B_8EAC_A728D4F85963__INCLUDED_) +#define AFX_SHADOWSPROPPAGE_H__49CB83C3_EFFA_4D6B_8EAC_A728D4F85963__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 +// ShadowsPropPage.h : header file +// + +#include "ColorButton.h" + +///////////////////////////////////////////////////////////////////////////// +// CShadowsPropPage dialog + +class CShadowsPropPage : public CPropertyPage +{ + DECLARE_DYNCREATE(CShadowsPropPage) + +// Construction +public: + CShadowsPropPage(); + ~CShadowsPropPage(); + +// Dialog Data + //{{AFX_DATA(CShadowsPropPage) + enum { IDD = IDD_PROPPAGE_SHADOWS }; + CColorButton m_ShadowColor; + BOOL m_EnableShadows; + //}}AFX_DATA + + +// Overrides + // ClassWizard generate virtual function overrides + //{{AFX_VIRTUAL(CShadowsPropPage) + protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + // Generated message map functions + //{{AFX_MSG(CShadowsPropPage) + // 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_SHADOWSPROPPAGE_H__49CB83C3_EFFA_4D6B_8EAC_A728D4F85963__INCLUDED_) diff --git a/source/sced/SimpleEdit.cpp b/source/sced/SimpleEdit.cpp index 1c88f16024..2ef4d7e2dd 100755 --- a/source/sced/SimpleEdit.cpp +++ b/source/sced/SimpleEdit.cpp @@ -1,52 +1,52 @@ -// SimpleEdit.cpp : implementation file -// - -#include "stdafx.h" -#include "ScEd.h" -#include "SimpleEdit.h" - -///////////////////////////////////////////////////////////////////////////// -// CSimpleEdit dialog - - -CSimpleEdit::CSimpleEdit(const char* title,CWnd* pParent /*=NULL*/) - : m_Title(title), CDialog(CSimpleEdit::IDD, pParent) -{ - //{{AFX_DATA_INIT(CSimpleEdit) - m_Text = _T(""); - //}}AFX_DATA_INIT -} - - -void CSimpleEdit::DoDataExchange(CDataExchange* pDX) -{ - CDialog::DoDataExchange(pDX); - //{{AFX_DATA_MAP(CSimpleEdit) - DDX_Text(pDX, IDC_EDIT1, m_Text); - DDV_MaxChars(pDX, m_Text, 64); - //}}AFX_DATA_MAP -} - - -BEGIN_MESSAGE_MAP(CSimpleEdit, CDialog) - //{{AFX_MSG_MAP(CSimpleEdit) - //}}AFX_MSG_MAP -END_MESSAGE_MAP() - -///////////////////////////////////////////////////////////////////////////// -// CSimpleEdit message handlers - -BOOL CSimpleEdit::OnInitDialog() -{ - CDialog::OnInitDialog(); - - SetWindowText((const char*) m_Title); - - CWnd* edit=GetDlgItem(IDC_EDIT1); - if (edit) { - edit->SetFocus(); - return FALSE; - } - - return TRUE; -} +// SimpleEdit.cpp : implementation file +// + +#include "stdafx.h" +#include "ScEd.h" +#include "SimpleEdit.h" + +///////////////////////////////////////////////////////////////////////////// +// CSimpleEdit dialog + + +CSimpleEdit::CSimpleEdit(const char* title,CWnd* pParent /*=NULL*/) + : m_Title(title), CDialog(CSimpleEdit::IDD, pParent) +{ + //{{AFX_DATA_INIT(CSimpleEdit) + m_Text = _T(""); + //}}AFX_DATA_INIT +} + + +void CSimpleEdit::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(CSimpleEdit) + DDX_Text(pDX, IDC_EDIT1, m_Text); + DDV_MaxChars(pDX, m_Text, 64); + //}}AFX_DATA_MAP +} + + +BEGIN_MESSAGE_MAP(CSimpleEdit, CDialog) + //{{AFX_MSG_MAP(CSimpleEdit) + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CSimpleEdit message handlers + +BOOL CSimpleEdit::OnInitDialog() +{ + CDialog::OnInitDialog(); + + SetWindowText((const char*) m_Title); + + CWnd* edit=GetDlgItem(IDC_EDIT1); + if (edit) { + edit->SetFocus(); + return FALSE; + } + + return TRUE; +} diff --git a/source/sced/SimpleEdit.h b/source/sced/SimpleEdit.h index 8023201615..cde126df54 100755 --- a/source/sced/SimpleEdit.h +++ b/source/sced/SimpleEdit.h @@ -1,47 +1,47 @@ -#if !defined(AFX_SIMPLEEDIT_H__190C3373_D31B_4037_9851_2C3255DFEA53__INCLUDED_) -#define AFX_SIMPLEEDIT_H__190C3373_D31B_4037_9851_2C3255DFEA53__INCLUDED_ - -#if _MSC_VER > 1000 -#pragma once -#endif // _MSC_VER > 1000 -// SimpleEdit.h : header file -// - -///////////////////////////////////////////////////////////////////////////// -// CSimpleEdit dialog - -class CSimpleEdit : public CDialog -{ -// Construction -public: - CSimpleEdit(const char* title,CWnd* pParent = NULL); // standard constructor - -// Dialog Data - //{{AFX_DATA(CSimpleEdit) - enum { IDD = IDD_DIALOG_SIMPLEEDIT }; - CString m_Text; - CString m_Title; - //}}AFX_DATA - - -// Overrides - // ClassWizard generated virtual function overrides - //{{AFX_VIRTUAL(CSimpleEdit) - protected: - virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support - //}}AFX_VIRTUAL - -// Implementation -protected: - - // Generated message map functions - //{{AFX_MSG(CSimpleEdit) - 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_SIMPLEEDIT_H__190C3373_D31B_4037_9851_2C3255DFEA53__INCLUDED_) +#if !defined(AFX_SIMPLEEDIT_H__190C3373_D31B_4037_9851_2C3255DFEA53__INCLUDED_) +#define AFX_SIMPLEEDIT_H__190C3373_D31B_4037_9851_2C3255DFEA53__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 +// SimpleEdit.h : header file +// + +///////////////////////////////////////////////////////////////////////////// +// CSimpleEdit dialog + +class CSimpleEdit : public CDialog +{ +// Construction +public: + CSimpleEdit(const char* title,CWnd* pParent = NULL); // standard constructor + +// Dialog Data + //{{AFX_DATA(CSimpleEdit) + enum { IDD = IDD_DIALOG_SIMPLEEDIT }; + CString m_Text; + CString m_Title; + //}}AFX_DATA + + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CSimpleEdit) + protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + + // Generated message map functions + //{{AFX_MSG(CSimpleEdit) + 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_SIMPLEEDIT_H__190C3373_D31B_4037_9851_2C3255DFEA53__INCLUDED_) diff --git a/source/sced/SmoothElevationCommand.cpp b/source/sced/SmoothElevationCommand.cpp index e4d3f67c2c..9f657454b6 100755 --- a/source/sced/SmoothElevationCommand.cpp +++ b/source/sced/SmoothElevationCommand.cpp @@ -1,67 +1,67 @@ -#include "SmoothElevationCommand.h" -#include "Terrain.h" - -#include - -extern CTerrain g_Terrain; - -inline int clamp(int x,int min,int max) -{ - if (xmax) return max; - else return x; -} - - -CSmoothElevationCommand::CSmoothElevationCommand(float smoothpower,int brushSize,int selectionCentre[2]) - : CAlterElevationCommand(brushSize,selectionCentre), m_SmoothPower(smoothpower) -{ -} - - -CSmoothElevationCommand::~CSmoothElevationCommand() -{ -} - -void CSmoothElevationCommand::CalcDataOut(int x0,int x1,int z0,int z1) -{ - u32 mapSize=g_Terrain.GetVerticesPerSide(); - - // get valid filter vertex indices - int fxmin=clamp(x0-2,0,mapSize-1); - int fxmax=clamp(x1+2,0,mapSize-1); - int fzmin=clamp(z0-2,0,mapSize-1); - int fzmax=clamp(z1+2,0,mapSize-1); - - int i,j; - for (j=z0;j<=z1;j++) { - for (i=x0;i<=x1;i++) { - // calculate output height at this pixel by filtering across neighbouring vertices - float accum=0; - float totalWeight=0; - - // iterate through each vertex in selection - int r=2; - for (int k=-r;k<=r;k++) { - for (int m=-r;m<=r;m++) { - if (i+m>=fxmin && i+m<=fxmax && j+k>=fzmin && j+k<=fzmax) { - float dist=sqrt(float((k*k)+(m*m))); - float weight=1-(dist/(r+1)); - accum+=weight*g_Terrain.GetHeightMap()[(j+k)*mapSize+(i+m)]; - totalWeight+=weight; - } - } - } - - if (1 || totalWeight>0) { - float t=0.5f;//m_SmoothPower/32.0f; - float inputHeight=g_Terrain.GetHeightMap()[j*mapSize+i]; - accum/=totalWeight; - m_DataOut(i-x0,j-z0)=clamp(int((inputHeight*(1-t))+accum*t),0,65535); - } else { - m_DataOut(i-x0,j-z0)=g_Terrain.GetHeightMap()[j*mapSize+i]; - } - } - } -} - +#include "SmoothElevationCommand.h" +#include "Terrain.h" + +#include + +extern CTerrain g_Terrain; + +inline int clamp(int x,int min,int max) +{ + if (xmax) return max; + else return x; +} + + +CSmoothElevationCommand::CSmoothElevationCommand(float smoothpower,int brushSize,int selectionCentre[2]) + : CAlterElevationCommand(brushSize,selectionCentre), m_SmoothPower(smoothpower) +{ +} + + +CSmoothElevationCommand::~CSmoothElevationCommand() +{ +} + +void CSmoothElevationCommand::CalcDataOut(int x0,int x1,int z0,int z1) +{ + u32 mapSize=g_Terrain.GetVerticesPerSide(); + + // get valid filter vertex indices + int fxmin=clamp(x0-2,0,mapSize-1); + int fxmax=clamp(x1+2,0,mapSize-1); + int fzmin=clamp(z0-2,0,mapSize-1); + int fzmax=clamp(z1+2,0,mapSize-1); + + int i,j; + for (j=z0;j<=z1;j++) { + for (i=x0;i<=x1;i++) { + // calculate output height at this pixel by filtering across neighbouring vertices + float accum=0; + float totalWeight=0; + + // iterate through each vertex in selection + int r=2; + for (int k=-r;k<=r;k++) { + for (int m=-r;m<=r;m++) { + if (i+m>=fxmin && i+m<=fxmax && j+k>=fzmin && j+k<=fzmax) { + float dist=sqrt(float((k*k)+(m*m))); + float weight=1-(dist/(r+1)); + accum+=weight*g_Terrain.GetHeightMap()[(j+k)*mapSize+(i+m)]; + totalWeight+=weight; + } + } + } + + if (1 || totalWeight>0) { + float t=0.5f;//m_SmoothPower/32.0f; + float inputHeight=g_Terrain.GetHeightMap()[j*mapSize+i]; + accum/=totalWeight; + m_DataOut(i-x0,j-z0)=clamp(int((inputHeight*(1-t))+accum*t),0,65535); + } else { + m_DataOut(i-x0,j-z0)=g_Terrain.GetHeightMap()[j*mapSize+i]; + } + } + } +} + diff --git a/source/sced/SmoothElevationCommand.h b/source/sced/SmoothElevationCommand.h index 56ff15f86a..cba5a1c013 100755 --- a/source/sced/SmoothElevationCommand.h +++ b/source/sced/SmoothElevationCommand.h @@ -1,24 +1,24 @@ -#ifndef _SMOOTHELEVATIONCOMMAND_H -#define _SMOOTHELEVATIONCOMMAND_H - -#include "AlterElevationCommand.h" - -class CSmoothElevationCommand : public CAlterElevationCommand -{ -public: - // constructor, destructor - CSmoothElevationCommand(float smoothpower,int brushSize,int selectionCentre[2]); - ~CSmoothElevationCommand(); - - // return the texture name of this command - const char* GetName() const { return "Smooth Elevation"; } - - // calculate output data - void CalcDataOut(int x0,int x1,int z0,int z1); - -private: - // smoothing power - higher powers have greater smoothing effect - float m_SmoothPower; -}; - -#endif +#ifndef _SMOOTHELEVATIONCOMMAND_H +#define _SMOOTHELEVATIONCOMMAND_H + +#include "AlterElevationCommand.h" + +class CSmoothElevationCommand : public CAlterElevationCommand +{ +public: + // constructor, destructor + CSmoothElevationCommand(float smoothpower,int brushSize,int selectionCentre[2]); + ~CSmoothElevationCommand(); + + // return the texture name of this command + const char* GetName() const { return "Smooth Elevation"; } + + // calculate output data + void CalcDataOut(int x0,int x1,int z0,int z1); + +private: + // smoothing power - higher powers have greater smoothing effect + float m_SmoothPower; +}; + +#endif diff --git a/source/sced/SmoothElevationTool.cpp b/source/sced/SmoothElevationTool.cpp index fdf677908b..19d9d623ea 100755 --- a/source/sced/SmoothElevationTool.cpp +++ b/source/sced/SmoothElevationTool.cpp @@ -1,49 +1,49 @@ -#include "timer.h" -#include "CommandManager.h" -#include "SmoothElevationTool.h" -#include "SmoothElevationCommand.h" - -// default tool instance -CSmoothElevationTool CSmoothElevationTool::m_SmoothElevationTool; - -// maximum smoothing power -const float CSmoothElevationTool::MAX_SMOOTH_POWER=32.0f; - -CSmoothElevationTool::CSmoothElevationTool() : m_SmoothPower(16.0f) -{ -} - - -void CSmoothElevationTool::SmoothSelection() -{ - double curtime=1000*get_time(); - double elapsed=(curtime-m_LastTriggerTime); - - while (elapsed>=m_SmoothPower) { - CSmoothElevationCommand* smoothCmd=new CSmoothElevationCommand(MAX_SMOOTH_POWER,m_BrushSize,m_SelectionCentre); - g_CmdMan.Execute(smoothCmd); - elapsed-=m_SmoothPower; - } - m_LastTriggerTime=curtime-elapsed; -} - - -// callback for left button down event -void CSmoothElevationTool::OnLButtonDown(unsigned int flags,int px,int py) -{ - // store trigger time - m_LastTriggerTime=1000*get_time(); - // give base class a shout to do some work - CBrushTool::OnLButtonDown(flags,px,py); -} - -// callback for left button up event -void CSmoothElevationTool::OnLButtonUp(unsigned int flags,int px,int py) -{ - // force a trigger - OnTriggerLeft(); - // give base class a shout to do some work - CBrushTool::OnLButtonUp(flags,px,py); -} - - +#include "timer.h" +#include "CommandManager.h" +#include "SmoothElevationTool.h" +#include "SmoothElevationCommand.h" + +// default tool instance +CSmoothElevationTool CSmoothElevationTool::m_SmoothElevationTool; + +// maximum smoothing power +const float CSmoothElevationTool::MAX_SMOOTH_POWER=32.0f; + +CSmoothElevationTool::CSmoothElevationTool() : m_SmoothPower(16.0f) +{ +} + + +void CSmoothElevationTool::SmoothSelection() +{ + double curtime=1000*get_time(); + double elapsed=(curtime-m_LastTriggerTime); + + while (elapsed>=m_SmoothPower) { + CSmoothElevationCommand* smoothCmd=new CSmoothElevationCommand(MAX_SMOOTH_POWER,m_BrushSize,m_SelectionCentre); + g_CmdMan.Execute(smoothCmd); + elapsed-=m_SmoothPower; + } + m_LastTriggerTime=curtime-elapsed; +} + + +// callback for left button down event +void CSmoothElevationTool::OnLButtonDown(unsigned int flags,int px,int py) +{ + // store trigger time + m_LastTriggerTime=1000*get_time(); + // give base class a shout to do some work + CBrushTool::OnLButtonDown(flags,px,py); +} + +// callback for left button up event +void CSmoothElevationTool::OnLButtonUp(unsigned int flags,int px,int py) +{ + // force a trigger + OnTriggerLeft(); + // give base class a shout to do some work + CBrushTool::OnLButtonUp(flags,px,py); +} + + diff --git a/source/sced/SmoothElevationTool.h b/source/sced/SmoothElevationTool.h index dd0c9a5e0f..c621d4dba2 100755 --- a/source/sced/SmoothElevationTool.h +++ b/source/sced/SmoothElevationTool.h @@ -1,50 +1,50 @@ -#ifndef _SMOOTHELEVATIONTOOL_H -#define _SMOOTHELEVATIONTOOL_H - -#include -#include "res/res.h" -#include "BrushTool.h" - -class CSmoothElevationTool : public CBrushTool -{ -public: - enum { MAX_BRUSH_SIZE=8 }; - static const float MAX_SMOOTH_POWER; - -public: - CSmoothElevationTool(); - - // tool triggered by left mouse button; smooth selected terrain - void OnTriggerLeft() { SmoothSelection(); } - - // callback for left button down event - void OnLButtonDown(unsigned int flags,int px,int py); - // callback for left button up event - void OnLButtonUp(unsigned int flags,int px,int py); - - // set smoothing power - void SetSmoothPower(float power) { m_SmoothPower=power; } - // get smoothing power - float GetSmoothPower() const { return m_SmoothPower; } - - // allow multiple triggers by click and drag - bool SupportDragTrigger() { return true; } - - // get tool instance - static CSmoothElevationTool* GetTool() { return &m_SmoothElevationTool; } - -private: - // smooth the currently selected terrain tiles - void SmoothSelection(); - - // time of last trigger - double m_LastTriggerTime; - - // amount to smooth selected terrain tiles - float m_SmoothPower; - - // default tool instance - static CSmoothElevationTool m_SmoothElevationTool; -}; - -#endif +#ifndef _SMOOTHELEVATIONTOOL_H +#define _SMOOTHELEVATIONTOOL_H + +#include +#include "res/res.h" +#include "BrushTool.h" + +class CSmoothElevationTool : public CBrushTool +{ +public: + enum { MAX_BRUSH_SIZE=8 }; + static const float MAX_SMOOTH_POWER; + +public: + CSmoothElevationTool(); + + // tool triggered by left mouse button; smooth selected terrain + void OnTriggerLeft() { SmoothSelection(); } + + // callback for left button down event + void OnLButtonDown(unsigned int flags,int px,int py); + // callback for left button up event + void OnLButtonUp(unsigned int flags,int px,int py); + + // set smoothing power + void SetSmoothPower(float power) { m_SmoothPower=power; } + // get smoothing power + float GetSmoothPower() const { return m_SmoothPower; } + + // allow multiple triggers by click and drag + bool SupportDragTrigger() { return true; } + + // get tool instance + static CSmoothElevationTool* GetTool() { return &m_SmoothElevationTool; } + +private: + // smooth the currently selected terrain tiles + void SmoothSelection(); + + // time of last trigger + double m_LastTriggerTime; + + // amount to smooth selected terrain tiles + float m_SmoothPower; + + // default tool instance + static CSmoothElevationTool m_SmoothElevationTool; +}; + +#endif diff --git a/source/sced/StdAfx.cpp b/source/sced/StdAfx.cpp index ecda1a69ba..ff29ae8c41 100755 --- a/source/sced/StdAfx.cpp +++ b/source/sced/StdAfx.cpp @@ -1,8 +1,8 @@ -// stdafx.cpp : source file that includes just the standard includes -// ScEd.pch will be the pre-compiled header -// stdafx.obj will contain the pre-compiled type information - -#include "stdafx.h" - - - +// stdafx.cpp : source file that includes just the standard includes +// ScEd.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + + + diff --git a/source/sced/StdAfx.h b/source/sced/StdAfx.h index d01d3a6ee0..193c180b99 100755 --- a/source/sced/StdAfx.h +++ b/source/sced/StdAfx.h @@ -1,38 +1,38 @@ -// stdafx.h : include file for standard system include files, -// or project specific include files that are used frequently, but -// are changed infrequently -// - -#if !defined(AFX_STDAFX_H__806A78B8_0008_491A_9FB6_5FF892838693__INCLUDED_) -#define AFX_STDAFX_H__806A78B8_0008_491A_9FB6_5FF892838693__INCLUDED_ - -#if _MSC_VER > 1000 -#pragma once -#endif // _MSC_VER > 1000 - -#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers - -#define _SIZE_T_DEFINED -#include "posix.h" -#include "CStr.h" - -#undef _WINDOWS_ -#undef UNUSED -#undef _T -#undef _istspace -#undef _totlower - -#include // MFC core and standard components -#include // MFC extensions -#include // MFC Automation classes -#include // MFC support for Internet Explorer 4 Common Controls -#ifndef _AFX_NO_AFXCMN_SUPPORT -#include // MFC support for Windows Common Controls -#endif // _AFX_NO_AFXCMN_SUPPORT - -#include "resource.h" - -//{{AFX_INSERT_LOCATION}} -// Microsoft Visual C++ will insert additional declarations immediately before the previous line. - -#endif // !defined(AFX_STDAFX_H__806A78B8_0008_491A_9FB6_5FF892838693__INCLUDED_) +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently +// + +#if !defined(AFX_STDAFX_H__806A78B8_0008_491A_9FB6_5FF892838693__INCLUDED_) +#define AFX_STDAFX_H__806A78B8_0008_491A_9FB6_5FF892838693__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers + +#define _SIZE_T_DEFINED +#include "posix.h" +#include "CStr.h" + +#undef _WINDOWS_ +#undef UNUSED +#undef _T +#undef _istspace +#undef _totlower + +#include // MFC core and standard components +#include // MFC extensions +#include // MFC Automation classes +#include // MFC support for Internet Explorer 4 Common Controls +#ifndef _AFX_NO_AFXCMN_SUPPORT +#include // MFC support for Windows Common Controls +#endif // _AFX_NO_AFXCMN_SUPPORT + +#include "resource.h" + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_STDAFX_H__806A78B8_0008_491A_9FB6_5FF892838693__INCLUDED_) diff --git a/source/sced/TexToolsDlgBar.cpp b/source/sced/TexToolsDlgBar.cpp index 97e86e09e7..242d94ed43 100755 --- a/source/sced/TexToolsDlgBar.cpp +++ b/source/sced/TexToolsDlgBar.cpp @@ -1,291 +1,291 @@ -#include "stdafx.h" -#include "TexToolsDlgBar.h" -#include "TextureManager.h" -#include "PaintTextureTool.h" -#include "Renderer.h" - -#include "ogl.h" -#include "res/tex.h" -#include "res/vfs.h" - -BEGIN_MESSAGE_MAP(CTexToolsDlgBar, CDialogBar) - //{{AFX_MSG_MAP(CTexToolsDlgBar) - // NOTE - the ClassWizard will add and remove mapping macros here. - //}}AFX_MSG_MAP - ON_NOTIFY(NM_CLICK, IDC_LIST_TEXTUREBROWSER, OnClickListTextureBrowser) - ON_CBN_SELCHANGE(IDC_COMBO_TERRAINTYPES, OnSelChangeTerrainTypes) - ON_NOTIFY(NM_RELEASEDCAPTURE, IDC_SLIDER_BRUSHSIZE, OnReleasedCaptureSliderBrushSize) -END_MESSAGE_MAP() - - -CTexToolsDlgBar::CTexToolsDlgBar() -{ -} - -CTexToolsDlgBar::~CTexToolsDlgBar() -{ -} - -BOOL CTexToolsDlgBar::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 CTexToolsDlgBar::Create(CWnd * pParentWnd, UINT nIDTemplate,UINT nStyle, UINT nID) -{ - if (!Create(pParentWnd, MAKEINTRESOURCE(nIDTemplate), nStyle, nID)) { - return FALSE; - } - - return TRUE; -} - -void CTexToolsDlgBar::Select(CTextureEntry* entry) -{ - CStatic* curbmp=(CStatic*) GetDlgItem(IDC_STATIC_CURRENTTEXTURE); - CBitmap* bmp=(CBitmap*) (entry ? entry->m_Bitmap : 0); - curbmp->SetBitmap((HBITMAP) (*bmp)); - CPaintTextureTool::GetTool()->SetSelectedTexture(entry); -} - -// 32 bit colour data struct -struct Color8888 { - unsigned char r; - unsigned char g; - unsigned char b; - unsigned char a; -}; - -// 24 bit colour data struct -struct Color888 { - unsigned char r; - unsigned char g; - unsigned char b; -}; - -// 16-bit colour data struct -struct Color565 { - unsigned r : 5; - unsigned g : 6; - unsigned b : 5; -}; - -static void ConvertColor(const Color8888* src,Color565* dst) -{ - dst->r=(src->r>>3); - dst->g=(src->g>>2); - dst->b=(src->b>>3); -} - -static void ConvertColor(const Color8888* src,Color888* dst) -{ - dst->r=src->r; - dst->g=src->g; - dst->b=src->b; -} - -int CTexToolsDlgBar::GetCurrentTerrainType() -{ - CComboBox* terraintypes=(CComboBox*) GetDlgItem(IDC_COMBO_TERRAINTYPES); - return terraintypes->GetCurSel(); -} - -BOOL CTexToolsDlgBar::BuildImageListIcon(CTextureEntry* texentry) -{ - // bind to texture - g_Renderer.BindTexture(0,tex_id(texentry->m_Handle)); - - // get image data in BGRA format - int w,h; - glGetTexLevelParameteriv(GL_TEXTURE_2D,0,GL_TEXTURE_WIDTH,&w); - glGetTexLevelParameteriv(GL_TEXTURE_2D,0,GL_TEXTURE_HEIGHT,&h); - - unsigned char* texdata=new unsigned char[w*h*4]; - glGetTexImage(GL_TEXTURE_2D,0,GL_BGRA_EXT,GL_UNSIGNED_BYTE,texdata); - - // generate scaled bitmap of correct size - int bmpsize=32*32*4; - unsigned int bmpdata[32*32]; - gluScaleImage(GL_BGRA_EXT,w,h,GL_UNSIGNED_BYTE,texdata,32,32,GL_UNSIGNED_BYTE,bmpdata); - - // create the actual CBitmap object - BOOL success=TRUE; - CDC* dc=GetDC(); - CBitmap* bmp=new CBitmap; - texentry->m_Bitmap=bmp; - - if (bmp->CreateCompatibleBitmap(dc,32,32)) { - - // query bpp of bitmap - BITMAP bm; - if (bmp->GetBitmap(&bm)) { - int bpp=bm.bmBitsPixel; - if (bpp==16) { - // build 16 bit image - unsigned short* tmp=new unsigned short[32*32]; - for (int i=0;i<32*32;i++) { - ConvertColor((Color8888*) &bmpdata[i],(Color565*) &tmp[i]); - } - bmp->SetBitmapBits(32*32*2,tmp); - delete[] tmp; - } else if (bpp==24) { - // ditch alpha from image - unsigned short* tmp=new unsigned short[32*32]; - for (int i=0;i<32*32;i++) { - ConvertColor((Color8888*) &bmpdata[i],(Color888*) &tmp[i]); - } - bmp->SetBitmapBits(32*32*3,tmp); - delete[] tmp; - } else if (bpp==32) { - // upload original image - bmp->SetBitmapBits(bmpsize,bmpdata); - } - - // now add to image list - m_ImageList.Add(bmp,RGB(255,255,255)); - - // success; note this - success=TRUE; - } - } - - // clean up - delete[] texdata; - ReleaseDC(dc); - - return success; -} - -BOOL CTexToolsDlgBar::AddImageListIcon(CTextureEntry* texentry) -{ - // get a bitmap for imagelist yet? - if (!texentry->m_Bitmap) { - // nope; create one now - BuildImageListIcon(texentry); - } - - // add bitmap to imagelist - m_ImageList.Add((CBitmap*) texentry->m_Bitmap,RGB(255,255,255)); - - return TRUE; -} - -BOOL CTexToolsDlgBar::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); - - m_ImageList.Create(32,32,ILC_COLORDDB,0,16); - m_ImageList.SetBkColor(RGB(255,255,255)); - - // build combo box for terrain types - CComboBox* terraintypes=(CComboBox*) GetDlgItem(IDC_COMBO_TERRAINTYPES); - - const std::vector& ttypes=g_TexMan.m_TerrainTextures; - for (uint i=0;iAddString((const char*) ttypes[i].m_Name); - } - if (ttypes.size()>0) { - // select first type - terraintypes->SetCurSel(0); - } - - CListCtrl* listctrl=(CListCtrl*) GetDlgItem(IDC_LIST_TEXTUREBROWSER); - // set lists images - listctrl->SetImageList(&m_ImageList,LVSIL_NORMAL); - - // build icons for existing textures - if (ttypes.size()) { - const std::vector& textures=ttypes[0].m_Textures; - for (uint i=0;iGetItemCount(); - listctrl->InsertItem(index,(const char*) textures[i]->m_Name,index); - } - - // select first entry if we've got any entries - if (textures.size()>0) { - Select(textures[0]); - } else { - Select(0); - } - } - - OnSelChangeTerrainTypes(); - - // set up brush size slider - CSliderCtrl* sliderctrl=(CSliderCtrl*) GetDlgItem(IDC_SLIDER_BRUSHSIZE); - sliderctrl->SetRange(0,CPaintTextureTool::MAX_BRUSH_SIZE); - sliderctrl->SetPos(CPaintTextureTool::GetTool()->GetBrushSize()); - - return TRUE; -} - -void CTexToolsDlgBar::OnUpdateCmdUI(CFrameWnd* pTarget, BOOL bDisableIfNoHndler) -{ - bDisableIfNoHndler = FALSE; - CDialogBar::OnUpdateCmdUI(pTarget,bDisableIfNoHndler); -} - -void CTexToolsDlgBar::OnClickListTextureBrowser(NMHDR* pNMHDR, LRESULT* pResult) -{ - CListCtrl* listctrl=(CListCtrl*) GetDlgItem(IDC_LIST_TEXTUREBROWSER); - - POSITION pos=listctrl->GetFirstSelectedItemPosition(); - if (!pos) return; - - int index=listctrl->GetNextSelectedItem(pos); - Select(g_TexMan.m_TerrainTextures[GetCurrentTerrainType()].m_Textures[index]); - - *pResult = 0; -} - -void CTexToolsDlgBar::OnReleasedCaptureSliderBrushSize(NMHDR* pNMHDR, LRESULT* pResult) -{ - CSliderCtrl* sliderctrl=(CSliderCtrl*) GetDlgItem(IDC_SLIDER_BRUSHSIZE); - CPaintTextureTool::GetTool()->SetBrushSize(sliderctrl->GetPos()); - *pResult = 0; -} - - -void CTexToolsDlgBar::OnSelChangeTerrainTypes() -{ - // clear out the old image list - int i; - int count=m_ImageList.GetImageCount(); - for (i=count-1;i>=0;--i) { - m_ImageList.Remove(i); - } - - // clear out the listctrl - CListCtrl* listctrl=(CListCtrl*) GetDlgItem(IDC_LIST_TEXTUREBROWSER); - listctrl->DeleteAllItems(); - - // add icons to image list from new selected terrain types - if (GetCurrentTerrainType()!=CB_ERR) - { - std::vector& textures=g_TexMan.m_TerrainTextures[GetCurrentTerrainType()].m_Textures; - for (uint j=0;jInsertItem(j,(const char*) textures[j]->m_Name,j); - } - } +#include "stdafx.h" +#include "TexToolsDlgBar.h" +#include "TextureManager.h" +#include "PaintTextureTool.h" +#include "Renderer.h" + +#include "ogl.h" +#include "res/tex.h" +#include "res/vfs.h" + +BEGIN_MESSAGE_MAP(CTexToolsDlgBar, CDialogBar) + //{{AFX_MSG_MAP(CTexToolsDlgBar) + // NOTE - the ClassWizard will add and remove mapping macros here. + //}}AFX_MSG_MAP + ON_NOTIFY(NM_CLICK, IDC_LIST_TEXTUREBROWSER, OnClickListTextureBrowser) + ON_CBN_SELCHANGE(IDC_COMBO_TERRAINTYPES, OnSelChangeTerrainTypes) + ON_NOTIFY(NM_RELEASEDCAPTURE, IDC_SLIDER_BRUSHSIZE, OnReleasedCaptureSliderBrushSize) +END_MESSAGE_MAP() + + +CTexToolsDlgBar::CTexToolsDlgBar() +{ +} + +CTexToolsDlgBar::~CTexToolsDlgBar() +{ +} + +BOOL CTexToolsDlgBar::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 CTexToolsDlgBar::Create(CWnd * pParentWnd, UINT nIDTemplate,UINT nStyle, UINT nID) +{ + if (!Create(pParentWnd, MAKEINTRESOURCE(nIDTemplate), nStyle, nID)) { + return FALSE; + } + + return TRUE; +} + +void CTexToolsDlgBar::Select(CTextureEntry* entry) +{ + CStatic* curbmp=(CStatic*) GetDlgItem(IDC_STATIC_CURRENTTEXTURE); + CBitmap* bmp=(CBitmap*) (entry ? entry->m_Bitmap : 0); + curbmp->SetBitmap((HBITMAP) (*bmp)); + CPaintTextureTool::GetTool()->SetSelectedTexture(entry); +} + +// 32 bit colour data struct +struct Color8888 { + unsigned char r; + unsigned char g; + unsigned char b; + unsigned char a; +}; + +// 24 bit colour data struct +struct Color888 { + unsigned char r; + unsigned char g; + unsigned char b; +}; + +// 16-bit colour data struct +struct Color565 { + unsigned r : 5; + unsigned g : 6; + unsigned b : 5; +}; + +static void ConvertColor(const Color8888* src,Color565* dst) +{ + dst->r=(src->r>>3); + dst->g=(src->g>>2); + dst->b=(src->b>>3); +} + +static void ConvertColor(const Color8888* src,Color888* dst) +{ + dst->r=src->r; + dst->g=src->g; + dst->b=src->b; +} + +int CTexToolsDlgBar::GetCurrentTerrainType() +{ + CComboBox* terraintypes=(CComboBox*) GetDlgItem(IDC_COMBO_TERRAINTYPES); + return terraintypes->GetCurSel(); +} + +BOOL CTexToolsDlgBar::BuildImageListIcon(CTextureEntry* texentry) +{ + // bind to texture + g_Renderer.BindTexture(0,tex_id(texentry->m_Handle)); + + // get image data in BGRA format + int w,h; + glGetTexLevelParameteriv(GL_TEXTURE_2D,0,GL_TEXTURE_WIDTH,&w); + glGetTexLevelParameteriv(GL_TEXTURE_2D,0,GL_TEXTURE_HEIGHT,&h); + + unsigned char* texdata=new unsigned char[w*h*4]; + glGetTexImage(GL_TEXTURE_2D,0,GL_BGRA_EXT,GL_UNSIGNED_BYTE,texdata); + + // generate scaled bitmap of correct size + int bmpsize=32*32*4; + unsigned int bmpdata[32*32]; + gluScaleImage(GL_BGRA_EXT,w,h,GL_UNSIGNED_BYTE,texdata,32,32,GL_UNSIGNED_BYTE,bmpdata); + + // create the actual CBitmap object + BOOL success=TRUE; + CDC* dc=GetDC(); + CBitmap* bmp=new CBitmap; + texentry->m_Bitmap=bmp; + + if (bmp->CreateCompatibleBitmap(dc,32,32)) { + + // query bpp of bitmap + BITMAP bm; + if (bmp->GetBitmap(&bm)) { + int bpp=bm.bmBitsPixel; + if (bpp==16) { + // build 16 bit image + unsigned short* tmp=new unsigned short[32*32]; + for (int i=0;i<32*32;i++) { + ConvertColor((Color8888*) &bmpdata[i],(Color565*) &tmp[i]); + } + bmp->SetBitmapBits(32*32*2,tmp); + delete[] tmp; + } else if (bpp==24) { + // ditch alpha from image + unsigned short* tmp=new unsigned short[32*32]; + for (int i=0;i<32*32;i++) { + ConvertColor((Color8888*) &bmpdata[i],(Color888*) &tmp[i]); + } + bmp->SetBitmapBits(32*32*3,tmp); + delete[] tmp; + } else if (bpp==32) { + // upload original image + bmp->SetBitmapBits(bmpsize,bmpdata); + } + + // now add to image list + m_ImageList.Add(bmp,RGB(255,255,255)); + + // success; note this + success=TRUE; + } + } + + // clean up + delete[] texdata; + ReleaseDC(dc); + + return success; +} + +BOOL CTexToolsDlgBar::AddImageListIcon(CTextureEntry* texentry) +{ + // get a bitmap for imagelist yet? + if (!texentry->m_Bitmap) { + // nope; create one now + BuildImageListIcon(texentry); + } + + // add bitmap to imagelist + m_ImageList.Add((CBitmap*) texentry->m_Bitmap,RGB(255,255,255)); + + return TRUE; +} + +BOOL CTexToolsDlgBar::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); + + m_ImageList.Create(32,32,ILC_COLORDDB,0,16); + m_ImageList.SetBkColor(RGB(255,255,255)); + + // build combo box for terrain types + CComboBox* terraintypes=(CComboBox*) GetDlgItem(IDC_COMBO_TERRAINTYPES); + + const std::vector& ttypes=g_TexMan.m_TerrainTextures; + for (uint i=0;iAddString((const char*) ttypes[i].m_Name); + } + if (ttypes.size()>0) { + // select first type + terraintypes->SetCurSel(0); + } + + CListCtrl* listctrl=(CListCtrl*) GetDlgItem(IDC_LIST_TEXTUREBROWSER); + // set lists images + listctrl->SetImageList(&m_ImageList,LVSIL_NORMAL); + + // build icons for existing textures + if (ttypes.size()) { + const std::vector& textures=ttypes[0].m_Textures; + for (uint i=0;iGetItemCount(); + listctrl->InsertItem(index,(const char*) textures[i]->m_Name,index); + } + + // select first entry if we've got any entries + if (textures.size()>0) { + Select(textures[0]); + } else { + Select(0); + } + } + + OnSelChangeTerrainTypes(); + + // set up brush size slider + CSliderCtrl* sliderctrl=(CSliderCtrl*) GetDlgItem(IDC_SLIDER_BRUSHSIZE); + sliderctrl->SetRange(0,CPaintTextureTool::MAX_BRUSH_SIZE); + sliderctrl->SetPos(CPaintTextureTool::GetTool()->GetBrushSize()); + + return TRUE; +} + +void CTexToolsDlgBar::OnUpdateCmdUI(CFrameWnd* pTarget, BOOL bDisableIfNoHndler) +{ + bDisableIfNoHndler = FALSE; + CDialogBar::OnUpdateCmdUI(pTarget,bDisableIfNoHndler); +} + +void CTexToolsDlgBar::OnClickListTextureBrowser(NMHDR* pNMHDR, LRESULT* pResult) +{ + CListCtrl* listctrl=(CListCtrl*) GetDlgItem(IDC_LIST_TEXTUREBROWSER); + + POSITION pos=listctrl->GetFirstSelectedItemPosition(); + if (!pos) return; + + int index=listctrl->GetNextSelectedItem(pos); + Select(g_TexMan.m_TerrainTextures[GetCurrentTerrainType()].m_Textures[index]); + + *pResult = 0; +} + +void CTexToolsDlgBar::OnReleasedCaptureSliderBrushSize(NMHDR* pNMHDR, LRESULT* pResult) +{ + CSliderCtrl* sliderctrl=(CSliderCtrl*) GetDlgItem(IDC_SLIDER_BRUSHSIZE); + CPaintTextureTool::GetTool()->SetBrushSize(sliderctrl->GetPos()); + *pResult = 0; +} + + +void CTexToolsDlgBar::OnSelChangeTerrainTypes() +{ + // clear out the old image list + int i; + int count=m_ImageList.GetImageCount(); + for (i=count-1;i>=0;--i) { + m_ImageList.Remove(i); + } + + // clear out the listctrl + CListCtrl* listctrl=(CListCtrl*) GetDlgItem(IDC_LIST_TEXTUREBROWSER); + listctrl->DeleteAllItems(); + + // add icons to image list from new selected terrain types + if (GetCurrentTerrainType()!=CB_ERR) + { + std::vector& textures=g_TexMan.m_TerrainTextures[GetCurrentTerrainType()].m_Textures; + for (uint j=0;jInsertItem(j,(const char*) textures[j]->m_Name,j); + } + } } \ No newline at end of file diff --git a/source/sced/TexToolsDlgBar.h b/source/sced/TexToolsDlgBar.h index aab4298635..a9d1ab5e90 100755 --- a/source/sced/TexToolsDlgBar.h +++ b/source/sced/TexToolsDlgBar.h @@ -1,38 +1,38 @@ -#ifndef _TEXTOOLSDLGBAR_H -#define _TEXTOOLSDLGBAR_H - -#include "TextureEntry.h" - -class CTexToolsDlgBar : public CDialogBar -{ -// DECLARE_DYNAMIC(CInitDialogBar) -public: - CTexToolsDlgBar(); - ~CTexToolsDlgBar(); - - 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: - CImageList m_ImageList; - - int GetCurrentTerrainType(); - - void Select(CTextureEntry* entry); - BOOL BuildImageListIcon(CTextureEntry* texentry); - BOOL AddImageListIcon(CTextureEntry* entry); - BOOL OnInitDialog(); - - // Generated message map functions - //{{AFX_MSG(CTexToolsDlgBar) - afx_msg void OnClickListTextureBrowser(NMHDR* pNMHDR, LRESULT* pResult); - afx_msg void OnReleasedCaptureSliderBrushSize(NMHDR* pNMHDR, LRESULT* pResult); - afx_msg void OnSelChangeTerrainTypes(); - //}}AFX_MSG - DECLARE_MESSAGE_MAP() -}; - - -#endif - +#ifndef _TEXTOOLSDLGBAR_H +#define _TEXTOOLSDLGBAR_H + +#include "TextureEntry.h" + +class CTexToolsDlgBar : public CDialogBar +{ +// DECLARE_DYNAMIC(CInitDialogBar) +public: + CTexToolsDlgBar(); + ~CTexToolsDlgBar(); + + 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: + CImageList m_ImageList; + + int GetCurrentTerrainType(); + + void Select(CTextureEntry* entry); + BOOL BuildImageListIcon(CTextureEntry* texentry); + BOOL AddImageListIcon(CTextureEntry* entry); + BOOL OnInitDialog(); + + // Generated message map functions + //{{AFX_MSG(CTexToolsDlgBar) + afx_msg void OnClickListTextureBrowser(NMHDR* pNMHDR, LRESULT* pResult); + afx_msg void OnReleasedCaptureSliderBrushSize(NMHDR* pNMHDR, LRESULT* pResult); + afx_msg void OnSelChangeTerrainTypes(); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + + +#endif + diff --git a/source/sced/Tool.h b/source/sced/Tool.h index 7bb22ed23d..3513b43278 100755 --- a/source/sced/Tool.h +++ b/source/sced/Tool.h @@ -1,30 +1,30 @@ -#ifndef _TOOL_H -#define _TOOL_H - -// flags for mouse events -#define TOOL_MOUSEFLAG_ALTDOWN 0x04 -#define TOOL_MOUSEFLAG_CTRLDOWN 0x08 -#define TOOL_MOUSEFLAG_SHIFTDOWN 0x10 - -class CTool -{ -public: - // virtual destructor - virtual ~CTool() {} - - // 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) {} -}; - - -#endif +#ifndef _TOOL_H +#define _TOOL_H + +// flags for mouse events +#define TOOL_MOUSEFLAG_ALTDOWN 0x04 +#define TOOL_MOUSEFLAG_CTRLDOWN 0x08 +#define TOOL_MOUSEFLAG_SHIFTDOWN 0x10 + +class CTool +{ +public: + // virtual destructor + virtual ~CTool() {} + + // 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) {} +}; + + +#endif diff --git a/source/sced/ToolManager.cpp b/source/sced/ToolManager.cpp index a39cc6f39e..9535e4bc7f 100755 --- a/source/sced/ToolManager.cpp +++ b/source/sced/ToolManager.cpp @@ -1,3 +1,3 @@ -#include "ToolManager.h" - -CToolManager g_ToolMan; +#include "ToolManager.h" + +CToolManager g_ToolMan; diff --git a/source/sced/ToolManager.h b/source/sced/ToolManager.h index 680db7805e..b47222ac1e 100755 --- a/source/sced/ToolManager.h +++ b/source/sced/ToolManager.h @@ -1,52 +1,52 @@ -#ifndef _TOOLMANAGER_H -#define _TOOLMANAGER_H - -#include "Tool.h" - -class CToolManager -{ -public: - CToolManager() : m_ActiveTool(0) {} - - // draw the visual representation of active tool, if any - void OnDraw() { - if (m_ActiveTool) m_ActiveTool->OnDraw(); - } - - // callback for left button down event - void OnLButtonDown(unsigned int flags,int px,int py) { - if (m_ActiveTool) m_ActiveTool->OnLButtonDown(flags,px,py); - } - - // callback for left button up event - void OnLButtonUp(unsigned int flags,int px,int py) { - if (m_ActiveTool) m_ActiveTool->OnLButtonUp(flags,px,py); - } - - // callback for right button down event - void OnRButtonDown(unsigned int flags,int px,int py) { - if (m_ActiveTool) m_ActiveTool->OnRButtonDown(flags,px,py); - } - - // callback for right button up event - void OnRButtonUp(unsigned int flags,int px,int py) { - if (m_ActiveTool) m_ActiveTool->OnRButtonUp(flags,px,py); - } - - // callback for mouse move event - void OnMouseMove(unsigned int flags,int px,int py) { - if (m_ActiveTool) m_ActiveTool->OnMouseMove(flags,px,py); - } - - // set currently active tool, or pass 0 to deactive all tools - void SetActiveTool(CTool* tool) { m_ActiveTool=tool; } - // get currently active tool, if any - CTool* GetActiveTool() const { return m_ActiveTool; } - -private: - CTool* m_ActiveTool; -}; - -extern CToolManager g_ToolMan; - -#endif +#ifndef _TOOLMANAGER_H +#define _TOOLMANAGER_H + +#include "Tool.h" + +class CToolManager +{ +public: + CToolManager() : m_ActiveTool(0) {} + + // draw the visual representation of active tool, if any + void OnDraw() { + if (m_ActiveTool) m_ActiveTool->OnDraw(); + } + + // callback for left button down event + void OnLButtonDown(unsigned int flags,int px,int py) { + if (m_ActiveTool) m_ActiveTool->OnLButtonDown(flags,px,py); + } + + // callback for left button up event + void OnLButtonUp(unsigned int flags,int px,int py) { + if (m_ActiveTool) m_ActiveTool->OnLButtonUp(flags,px,py); + } + + // callback for right button down event + void OnRButtonDown(unsigned int flags,int px,int py) { + if (m_ActiveTool) m_ActiveTool->OnRButtonDown(flags,px,py); + } + + // callback for right button up event + void OnRButtonUp(unsigned int flags,int px,int py) { + if (m_ActiveTool) m_ActiveTool->OnRButtonUp(flags,px,py); + } + + // callback for mouse move event + void OnMouseMove(unsigned int flags,int px,int py) { + if (m_ActiveTool) m_ActiveTool->OnMouseMove(flags,px,py); + } + + // set currently active tool, or pass 0 to deactive all tools + void SetActiveTool(CTool* tool) { m_ActiveTool=tool; } + // get currently active tool, if any + CTool* GetActiveTool() const { return m_ActiveTool; } + +private: + CTool* m_ActiveTool; +}; + +extern CToolManager g_ToolMan; + +#endif diff --git a/source/sced/UIGlobals.cpp b/source/sced/UIGlobals.cpp index 31dffe48c4..f6acf3ad20 100755 --- a/source/sced/UIGlobals.cpp +++ b/source/sced/UIGlobals.cpp @@ -1,37 +1,37 @@ -#include "stdafx.h" -#include "UIGlobals.h" - -void GetVersionString(char* buf) -{ - // null version in case API calls fail for some reason - int version[4]; - version[0]=version[1]=version[2]=version[3]=0; - - // get filename of process currently running - char filename[256]; - ::GetModuleFileName(0,filename,256); - - DWORD unused; - DWORD len=::GetFileVersionInfoSize(filename,&unused); - if (len>0) { - char* versioninfo=new char[len]; - GetFileVersionInfo(filename,0,len,versioninfo); - - VS_FIXEDFILEINFO* fileinfo; - UINT size; - if (VerQueryValue(versioninfo,"\\",(LPVOID*) &fileinfo,&size)) { - version[0]=HIWORD(fileinfo->dwFileVersionMS); - version[1]=LOWORD(fileinfo->dwFileVersionMS); - version[2]=HIWORD(fileinfo->dwFileVersionLS); - version[3]=LOWORD(fileinfo->dwFileVersionLS); - } - - delete[] versioninfo; - } - sprintf(buf,"Version: %d.%d.%d.%d",version[0],version[1],version[2],version[3]); -} - -void ErrorBox(const char* errstr) -{ - ::MessageBox(0,errstr,"Error",MB_OK); +#include "stdafx.h" +#include "UIGlobals.h" + +void GetVersionString(char* buf) +{ + // null version in case API calls fail for some reason + int version[4]; + version[0]=version[1]=version[2]=version[3]=0; + + // get filename of process currently running + char filename[256]; + ::GetModuleFileName(0,filename,256); + + DWORD unused; + DWORD len=::GetFileVersionInfoSize(filename,&unused); + if (len>0) { + char* versioninfo=new char[len]; + GetFileVersionInfo(filename,0,len,versioninfo); + + VS_FIXEDFILEINFO* fileinfo; + UINT size; + if (VerQueryValue(versioninfo,"\\",(LPVOID*) &fileinfo,&size)) { + version[0]=HIWORD(fileinfo->dwFileVersionMS); + version[1]=LOWORD(fileinfo->dwFileVersionMS); + version[2]=HIWORD(fileinfo->dwFileVersionLS); + version[3]=LOWORD(fileinfo->dwFileVersionLS); + } + + delete[] versioninfo; + } + sprintf(buf,"Version: %d.%d.%d.%d",version[0],version[1],version[2],version[3]); +} + +void ErrorBox(const char* errstr) +{ + ::MessageBox(0,errstr,"Error",MB_OK); } \ No newline at end of file diff --git a/source/sced/UIGlobals.h b/source/sced/UIGlobals.h index c07f0d50cc..a49de08889 100755 --- a/source/sced/UIGlobals.h +++ b/source/sced/UIGlobals.h @@ -1,18 +1,18 @@ -#ifndef _UIGLOBALS_H -#define _UIGLOBALS_H - -/////////////////////////////////////////////////////////////////////////////// -// UIGlobals.h: miscellaneous functions for interface the editor to "UI" -// elements -/////////////////////////////////////////////////////////////////////////////// - - -/////////////////////////////////////////////////////////////////////////////// -// -// GetVersionString: fill version string into given buffer -extern void GetVersionString(char* buf); -// ErrorBox: show an error message box with given string -extern void ErrorBox(const char* errstr); - - -#endif +#ifndef _UIGLOBALS_H +#define _UIGLOBALS_H + +/////////////////////////////////////////////////////////////////////////////// +// UIGlobals.h: miscellaneous functions for interface the editor to "UI" +// elements +/////////////////////////////////////////////////////////////////////////////// + + +/////////////////////////////////////////////////////////////////////////////// +// +// GetVersionString: fill version string into given buffer +extern void GetVersionString(char* buf); +// ErrorBox: show an error message box with given string +extern void ErrorBox(const char* errstr); + + +#endif diff --git a/source/sced/UnitPropertiesAnimationsTab.cpp b/source/sced/UnitPropertiesAnimationsTab.cpp index c7f5bd7b0b..cb4eb3e771 100755 --- a/source/sced/UnitPropertiesAnimationsTab.cpp +++ b/source/sced/UnitPropertiesAnimationsTab.cpp @@ -1,43 +1,43 @@ -// UnitPropertiesAnimationsTab.cpp : implementation file -// - -#include "stdafx.h" -#include "ScEd.h" -#include "UnitPropertiesAnimationsTab.h" - -#ifdef _DEBUG -#define new DEBUG_NEW -#undef THIS_FILE -static char THIS_FILE[] = __FILE__; -#endif - -///////////////////////////////////////////////////////////////////////////// -// CUnitPropertiesAnimationsTab dialog - - -CUnitPropertiesAnimationsTab::CUnitPropertiesAnimationsTab(CWnd* pParent /*=NULL*/) - : CDialog(CUnitPropertiesAnimationsTab::IDD, pParent) -{ - //{{AFX_DATA_INIT(CUnitPropertiesAnimationsTab) - // NOTE: the ClassWizard will add member initialization here - //}}AFX_DATA_INIT -} - - -void CUnitPropertiesAnimationsTab::DoDataExchange(CDataExchange* pDX) -{ - CDialog::DoDataExchange(pDX); - //{{AFX_DATA_MAP(CUnitPropertiesAnimationsTab) - // NOTE: the ClassWizard will add DDX and DDV calls here - //}}AFX_DATA_MAP -} - - -BEGIN_MESSAGE_MAP(CUnitPropertiesAnimationsTab, CDialog) - //{{AFX_MSG_MAP(CUnitPropertiesAnimationsTab) - // NOTE: the ClassWizard will add message map macros here - //}}AFX_MSG_MAP -END_MESSAGE_MAP() - -///////////////////////////////////////////////////////////////////////////// -// CUnitPropertiesAnimationsTab message handlers +// UnitPropertiesAnimationsTab.cpp : implementation file +// + +#include "stdafx.h" +#include "ScEd.h" +#include "UnitPropertiesAnimationsTab.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CUnitPropertiesAnimationsTab dialog + + +CUnitPropertiesAnimationsTab::CUnitPropertiesAnimationsTab(CWnd* pParent /*=NULL*/) + : CDialog(CUnitPropertiesAnimationsTab::IDD, pParent) +{ + //{{AFX_DATA_INIT(CUnitPropertiesAnimationsTab) + // NOTE: the ClassWizard will add member initialization here + //}}AFX_DATA_INIT +} + + +void CUnitPropertiesAnimationsTab::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(CUnitPropertiesAnimationsTab) + // NOTE: the ClassWizard will add DDX and DDV calls here + //}}AFX_DATA_MAP +} + + +BEGIN_MESSAGE_MAP(CUnitPropertiesAnimationsTab, CDialog) + //{{AFX_MSG_MAP(CUnitPropertiesAnimationsTab) + // NOTE: the ClassWizard will add message map macros here + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CUnitPropertiesAnimationsTab message handlers diff --git a/source/sced/UnitPropertiesAnimationsTab.h b/source/sced/UnitPropertiesAnimationsTab.h index a3ad4ea771..66b2199159 100755 --- a/source/sced/UnitPropertiesAnimationsTab.h +++ b/source/sced/UnitPropertiesAnimationsTab.h @@ -1,46 +1,46 @@ -#if !defined(AFX_UNITPROPERTIESANIMATIONSTAB_H__EFA556CF_E800_419B_8438_4CCB00217B1A__INCLUDED_) -#define AFX_UNITPROPERTIESANIMATIONSTAB_H__EFA556CF_E800_419B_8438_4CCB00217B1A__INCLUDED_ - -#if _MSC_VER > 1000 -#pragma once -#endif // _MSC_VER > 1000 -// UnitPropertiesAnimationsTab.h : header file -// - -///////////////////////////////////////////////////////////////////////////// -// CUnitPropertiesAnimationsTab dialog - -class CUnitPropertiesAnimationsTab : public CDialog -{ -// Construction -public: - CUnitPropertiesAnimationsTab(CWnd* pParent = NULL); // standard constructor - -// Dialog Data - //{{AFX_DATA(CUnitPropertiesAnimationsTab) - enum { IDD = IDD_UNITPROPERTIES_ANIMATIONS }; - // NOTE: the ClassWizard will add data members here - //}}AFX_DATA - - -// Overrides - // ClassWizard generated virtual function overrides - //{{AFX_VIRTUAL(CUnitPropertiesAnimationsTab) - protected: - virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support - //}}AFX_VIRTUAL - -// Implementation -protected: - - // Generated message map functions - //{{AFX_MSG(CUnitPropertiesAnimationsTab) - // 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_UNITPROPERTIESANIMATIONSTAB_H__EFA556CF_E800_419B_8438_4CCB00217B1A__INCLUDED_) +#if !defined(AFX_UNITPROPERTIESANIMATIONSTAB_H__EFA556CF_E800_419B_8438_4CCB00217B1A__INCLUDED_) +#define AFX_UNITPROPERTIESANIMATIONSTAB_H__EFA556CF_E800_419B_8438_4CCB00217B1A__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 +// UnitPropertiesAnimationsTab.h : header file +// + +///////////////////////////////////////////////////////////////////////////// +// CUnitPropertiesAnimationsTab dialog + +class CUnitPropertiesAnimationsTab : public CDialog +{ +// Construction +public: + CUnitPropertiesAnimationsTab(CWnd* pParent = NULL); // standard constructor + +// Dialog Data + //{{AFX_DATA(CUnitPropertiesAnimationsTab) + enum { IDD = IDD_UNITPROPERTIES_ANIMATIONS }; + // NOTE: the ClassWizard will add data members here + //}}AFX_DATA + + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CUnitPropertiesAnimationsTab) + protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + + // Generated message map functions + //{{AFX_MSG(CUnitPropertiesAnimationsTab) + // 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_UNITPROPERTIESANIMATIONSTAB_H__EFA556CF_E800_419B_8438_4CCB00217B1A__INCLUDED_) diff --git a/source/sced/UnitPropertiesDlgBar.cpp b/source/sced/UnitPropertiesDlgBar.cpp index 999de8d693..3113b2088a 100755 --- a/source/sced/UnitPropertiesDlgBar.cpp +++ b/source/sced/UnitPropertiesDlgBar.cpp @@ -1,271 +1,271 @@ -#include "stdafx.h" -#include "UserConfig.h" -#include "MainFrm.h" -#include "Model.h" -#include "Unit.h" -#include "UnitManager.h" -#include "ObjectManager.h" -#include "UnitPropertiesDlgBar.h" - -#include "EditorData.h" -#include "UIGlobals.h" - -BEGIN_MESSAGE_MAP(CUnitPropertiesDlgBar, CDialogBar) - //{{AFX_MSG_MAP(CUnitPropertiesDlgBar) - // 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_REFRESH, OnButtonRefresh) - ON_BN_CLICKED(IDC_BUTTON_MODELBROWSE, OnButtonModelBrowse) - ON_BN_CLICKED(IDC_BUTTON_TEXTUREBROWSE, OnButtonTextureBrowse) - ON_BN_CLICKED(IDC_BUTTON_ANIMATIONBROWSE, OnButtonAnimationBrowse) -END_MESSAGE_MAP() - -////////////////////////////////////////////////////////////////////////////////// -// MakeRelativeFileName: adjust the given filename to return the filename -// relative to the mods/official directory - also swizzle backslashes -// to forward slashes -// TODO, RC: need to make this work with other root directories -static CStr MakeRelativeFileName(const char* fname) -{ - CStr result; - const char* ptr=strstr(fname,"mods\\official\\"); - if (!ptr) { - result=fname; - } else { - result=ptr+strlen("mods\\official\\"); - } - int len=result.Length(); - for (int i=0;iInsertItem(0, "Tab 1", 0); // add some test pages to the tab - tabCtrl->InsertItem(1, "Tab 2", 1); - tabCtrl->InsertItem(2, "Tab 3", 2); - tabCtrl->InsertItem(3, "Tab 4", 3); -*/ - // initialise data from editor data - UpdatePropertiesDlg(); - - return TRUE; -} - -void CUnitPropertiesDlgBar::OnUpdateCmdUI(CFrameWnd* pTarget, BOOL bDisableIfNoHndler) -{ - bDisableIfNoHndler = FALSE; - CDialogBar::OnUpdateCmdUI(pTarget,bDisableIfNoHndler); -} - -void CUnitPropertiesDlgBar::OnButtonBack() -{ - // save current object (if we've got one) before going back - if (m_Object) { - - CStr filename("data/mods/official/art/actors/"); - filename+=g_ObjMan.m_ObjectTypes[m_Object->m_Type].m_Name; - filename+="/"; - filename+=m_Object->m_Name; - filename+=".xml"; - m_Object->Save((const char*) filename); - - // and rebuild the model - UpdateEditorData(); - } - - CMainFrame* mainfrm=(CMainFrame*) AfxGetMainWnd(); - mainfrm->OnUnitTools(); -} - -void CUnitPropertiesDlgBar::OnButtonRefresh() -{ - UpdateEditorData(); -} - -void CUnitPropertiesDlgBar::OnButtonTextureBrowse() -{ - const char* filter="DDS Files|*.dds|PNG Files|*.png||"; - CFileDialog dlg(TRUE,g_UserCfg.GetOptionString(CFG_TEXTUREEXT),0,OFN_FILEMUSTEXIST | OFN_NOCHANGEDIR,filter,0); - dlg.m_ofn.lpstrInitialDir=g_UserCfg.GetOptionString(CFG_MODELTEXLOADDIR); - - if (dlg.DoModal()==IDOK) { - CStr filename=MakeRelativeFileName(dlg.m_ofn.lpstrFile); - - CStr dir(dlg.m_ofn.lpstrFile); - dir=dir.Left(dlg.m_ofn.nFileOffset-1); - g_UserCfg.SetOptionString(CFG_MODELTEXLOADDIR,(const char*) dir); - - CWnd* texture=GetDlgItem(IDC_EDIT_TEXTURE); - texture->SetWindowText(filename); - } -} - -void CUnitPropertiesDlgBar::OnButtonAnimationBrowse() -{ - const char* filter="PSA Files|*.psa||"; - CFileDialog dlg(TRUE,"psa",0,OFN_FILEMUSTEXIST | OFN_NOCHANGEDIR,filter,0); - dlg.m_ofn.lpstrInitialDir=g_UserCfg.GetOptionString(CFG_MODELANIMATIONDIR); - - if (dlg.DoModal()==IDOK) { - CStr filename=MakeRelativeFileName(dlg.m_ofn.lpstrFile); - - CStr dir(dlg.m_ofn.lpstrFile); - dir=dir.Left(dlg.m_ofn.nFileOffset-1); - g_UserCfg.SetOptionString(CFG_MODELANIMATIONDIR,(const char*) dir); - - CWnd* animation=GetDlgItem(IDC_EDIT_ANIMATION); - animation->SetWindowText(filename); - } -} - -void CUnitPropertiesDlgBar::OnButtonModelBrowse() -{ - const char* filter="PMD Files|*.pmd|0ADM Files|*.0adm||"; - CFileDialog dlg(TRUE,"pmd",0,OFN_FILEMUSTEXIST | OFN_NOCHANGEDIR,filter,0); - dlg.m_ofn.lpstrInitialDir=g_UserCfg.GetOptionString(CFG_MODELLOADDIR); - - if (dlg.DoModal()==IDOK) { - CStr filename=MakeRelativeFileName(dlg.m_ofn.lpstrFile); - - CStr dir(dlg.m_ofn.lpstrFile); - dir=dir.Left(dlg.m_ofn.nFileOffset-1); - g_UserCfg.SetOptionString(CFG_MODELLOADDIR,(const char*) dir); - - CWnd* texture=GetDlgItem(IDC_EDIT_MODEL); - texture->SetWindowText(filename); - } -} - -void CUnitPropertiesDlgBar::UpdateEditorData() -{ - if (!m_Object) { - g_ObjMan.SetSelectedObject(0); - return; - } - - CString str; - - CWnd* name=GetDlgItem(IDC_EDIT_NAME); - name->GetWindowText(str); - m_Object->m_Name=str; - - CWnd* model=GetDlgItem(IDC_EDIT_MODEL); - model->GetWindowText(str); - m_Object->m_ModelName=str; - - CWnd* texture=GetDlgItem(IDC_EDIT_TEXTURE); - texture->GetWindowText(str); - m_Object->m_TextureName=str; - - CWnd* animation=GetDlgItem(IDC_EDIT_ANIMATION); - animation->GetWindowText(str); - if (m_Object->m_Animations.size()==0) { - m_Object->m_Animations.resize(1); - m_Object->m_Animations[0].m_AnimName="Idle"; - } - m_Object->m_Animations[0].m_FileName=str; - - std::vector animupdatelist; - const std::vector& units=g_UnitMan.GetUnits(); - for (uint i=0;iGetModel()->GetModelDef()==m_Object->m_Model->GetModelDef()) { - animupdatelist.push_back(units[i]); - } - } - if (m_Object->BuildModel()) { - g_ObjMan.SetSelectedObject(m_Object); - CSkeletonAnim* anim=m_Object->m_Model->GetAnimation(); - if (anim) { - for (uint i=0;iGetModel()->SetAnimation(anim); - } - } - } else { - g_ObjMan.SetSelectedObject(0); - } -} - -void CUnitPropertiesDlgBar::UpdatePropertiesDlg() -{ - if (!m_Object) return; - - CWnd* name=GetDlgItem(IDC_EDIT_NAME); - if (name) { - name->SetWindowText(m_Object->m_Name); - } - - CWnd* model=GetDlgItem(IDC_EDIT_MODEL); - if (model) { - model->SetWindowText(m_Object->m_ModelName); - } - - CWnd* texture=GetDlgItem(IDC_EDIT_TEXTURE); - if (texture) { - texture->SetWindowText(m_Object->m_TextureName); - } - - CWnd* animation=GetDlgItem(IDC_EDIT_ANIMATION); - if (animation) { - if (m_Object->m_Animations.size()>0) { - animation->SetWindowText(m_Object->m_Animations[0].m_FileName); - } - } -} - - -void CUnitPropertiesDlgBar::SetObject(CObjectEntry* obj) -{ - m_Object=obj; - if (m_Object) { - if (m_Object->BuildModel()) { - g_ObjMan.SetSelectedObject(m_Object); - } else { - g_ObjMan.SetSelectedObject(0); - } - } - UpdatePropertiesDlg(); -} +#include "stdafx.h" +#include "UserConfig.h" +#include "MainFrm.h" +#include "Model.h" +#include "Unit.h" +#include "UnitManager.h" +#include "ObjectManager.h" +#include "UnitPropertiesDlgBar.h" + +#include "EditorData.h" +#include "UIGlobals.h" + +BEGIN_MESSAGE_MAP(CUnitPropertiesDlgBar, CDialogBar) + //{{AFX_MSG_MAP(CUnitPropertiesDlgBar) + // 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_REFRESH, OnButtonRefresh) + ON_BN_CLICKED(IDC_BUTTON_MODELBROWSE, OnButtonModelBrowse) + ON_BN_CLICKED(IDC_BUTTON_TEXTUREBROWSE, OnButtonTextureBrowse) + ON_BN_CLICKED(IDC_BUTTON_ANIMATIONBROWSE, OnButtonAnimationBrowse) +END_MESSAGE_MAP() + +////////////////////////////////////////////////////////////////////////////////// +// MakeRelativeFileName: adjust the given filename to return the filename +// relative to the mods/official directory - also swizzle backslashes +// to forward slashes +// TODO, RC: need to make this work with other root directories +static CStr MakeRelativeFileName(const char* fname) +{ + CStr result; + const char* ptr=strstr(fname,"mods\\official\\"); + if (!ptr) { + result=fname; + } else { + result=ptr+strlen("mods\\official\\"); + } + int len=result.Length(); + for (int i=0;iInsertItem(0, "Tab 1", 0); // add some test pages to the tab + tabCtrl->InsertItem(1, "Tab 2", 1); + tabCtrl->InsertItem(2, "Tab 3", 2); + tabCtrl->InsertItem(3, "Tab 4", 3); +*/ + // initialise data from editor data + UpdatePropertiesDlg(); + + return TRUE; +} + +void CUnitPropertiesDlgBar::OnUpdateCmdUI(CFrameWnd* pTarget, BOOL bDisableIfNoHndler) +{ + bDisableIfNoHndler = FALSE; + CDialogBar::OnUpdateCmdUI(pTarget,bDisableIfNoHndler); +} + +void CUnitPropertiesDlgBar::OnButtonBack() +{ + // save current object (if we've got one) before going back + if (m_Object) { + + CStr filename("data/mods/official/art/actors/"); + filename+=g_ObjMan.m_ObjectTypes[m_Object->m_Type].m_Name; + filename+="/"; + filename+=m_Object->m_Name; + filename+=".xml"; + m_Object->Save((const char*) filename); + + // and rebuild the model + UpdateEditorData(); + } + + CMainFrame* mainfrm=(CMainFrame*) AfxGetMainWnd(); + mainfrm->OnUnitTools(); +} + +void CUnitPropertiesDlgBar::OnButtonRefresh() +{ + UpdateEditorData(); +} + +void CUnitPropertiesDlgBar::OnButtonTextureBrowse() +{ + const char* filter="DDS Files|*.dds|PNG Files|*.png||"; + CFileDialog dlg(TRUE,g_UserCfg.GetOptionString(CFG_TEXTUREEXT),0,OFN_FILEMUSTEXIST | OFN_NOCHANGEDIR,filter,0); + dlg.m_ofn.lpstrInitialDir=g_UserCfg.GetOptionString(CFG_MODELTEXLOADDIR); + + if (dlg.DoModal()==IDOK) { + CStr filename=MakeRelativeFileName(dlg.m_ofn.lpstrFile); + + CStr dir(dlg.m_ofn.lpstrFile); + dir=dir.Left(dlg.m_ofn.nFileOffset-1); + g_UserCfg.SetOptionString(CFG_MODELTEXLOADDIR,(const char*) dir); + + CWnd* texture=GetDlgItem(IDC_EDIT_TEXTURE); + texture->SetWindowText(filename); + } +} + +void CUnitPropertiesDlgBar::OnButtonAnimationBrowse() +{ + const char* filter="PSA Files|*.psa||"; + CFileDialog dlg(TRUE,"psa",0,OFN_FILEMUSTEXIST | OFN_NOCHANGEDIR,filter,0); + dlg.m_ofn.lpstrInitialDir=g_UserCfg.GetOptionString(CFG_MODELANIMATIONDIR); + + if (dlg.DoModal()==IDOK) { + CStr filename=MakeRelativeFileName(dlg.m_ofn.lpstrFile); + + CStr dir(dlg.m_ofn.lpstrFile); + dir=dir.Left(dlg.m_ofn.nFileOffset-1); + g_UserCfg.SetOptionString(CFG_MODELANIMATIONDIR,(const char*) dir); + + CWnd* animation=GetDlgItem(IDC_EDIT_ANIMATION); + animation->SetWindowText(filename); + } +} + +void CUnitPropertiesDlgBar::OnButtonModelBrowse() +{ + const char* filter="PMD Files|*.pmd|0ADM Files|*.0adm||"; + CFileDialog dlg(TRUE,"pmd",0,OFN_FILEMUSTEXIST | OFN_NOCHANGEDIR,filter,0); + dlg.m_ofn.lpstrInitialDir=g_UserCfg.GetOptionString(CFG_MODELLOADDIR); + + if (dlg.DoModal()==IDOK) { + CStr filename=MakeRelativeFileName(dlg.m_ofn.lpstrFile); + + CStr dir(dlg.m_ofn.lpstrFile); + dir=dir.Left(dlg.m_ofn.nFileOffset-1); + g_UserCfg.SetOptionString(CFG_MODELLOADDIR,(const char*) dir); + + CWnd* texture=GetDlgItem(IDC_EDIT_MODEL); + texture->SetWindowText(filename); + } +} + +void CUnitPropertiesDlgBar::UpdateEditorData() +{ + if (!m_Object) { + g_ObjMan.SetSelectedObject(0); + return; + } + + CString str; + + CWnd* name=GetDlgItem(IDC_EDIT_NAME); + name->GetWindowText(str); + m_Object->m_Name=str; + + CWnd* model=GetDlgItem(IDC_EDIT_MODEL); + model->GetWindowText(str); + m_Object->m_ModelName=str; + + CWnd* texture=GetDlgItem(IDC_EDIT_TEXTURE); + texture->GetWindowText(str); + m_Object->m_TextureName=str; + + CWnd* animation=GetDlgItem(IDC_EDIT_ANIMATION); + animation->GetWindowText(str); + if (m_Object->m_Animations.size()==0) { + m_Object->m_Animations.resize(1); + m_Object->m_Animations[0].m_AnimName="Idle"; + } + m_Object->m_Animations[0].m_FileName=str; + + std::vector animupdatelist; + const std::vector& units=g_UnitMan.GetUnits(); + for (uint i=0;iGetModel()->GetModelDef()==m_Object->m_Model->GetModelDef()) { + animupdatelist.push_back(units[i]); + } + } + if (m_Object->BuildModel()) { + g_ObjMan.SetSelectedObject(m_Object); + CSkeletonAnim* anim=m_Object->m_Model->GetAnimation(); + if (anim) { + for (uint i=0;iGetModel()->SetAnimation(anim); + } + } + } else { + g_ObjMan.SetSelectedObject(0); + } +} + +void CUnitPropertiesDlgBar::UpdatePropertiesDlg() +{ + if (!m_Object) return; + + CWnd* name=GetDlgItem(IDC_EDIT_NAME); + if (name) { + name->SetWindowText(m_Object->m_Name); + } + + CWnd* model=GetDlgItem(IDC_EDIT_MODEL); + if (model) { + model->SetWindowText(m_Object->m_ModelName); + } + + CWnd* texture=GetDlgItem(IDC_EDIT_TEXTURE); + if (texture) { + texture->SetWindowText(m_Object->m_TextureName); + } + + CWnd* animation=GetDlgItem(IDC_EDIT_ANIMATION); + if (animation) { + if (m_Object->m_Animations.size()>0) { + animation->SetWindowText(m_Object->m_Animations[0].m_FileName); + } + } +} + + +void CUnitPropertiesDlgBar::SetObject(CObjectEntry* obj) +{ + m_Object=obj; + if (m_Object) { + if (m_Object->BuildModel()) { + g_ObjMan.SetSelectedObject(m_Object); + } else { + g_ObjMan.SetSelectedObject(0); + } + } + UpdatePropertiesDlg(); +} diff --git a/source/sced/UnitPropertiesDlgBar.h b/source/sced/UnitPropertiesDlgBar.h index 32fc500ee9..f6d029203e 100755 --- a/source/sced/UnitPropertiesDlgBar.h +++ b/source/sced/UnitPropertiesDlgBar.h @@ -1,40 +1,40 @@ -#ifndef _UNITPROPERTIESDLGBAR_H -#define _UNITPROPERTIESDLGBAR_H - -#include "ObjectEntry.h" - -class CUnitPropertiesDlgBar : public CDialogBar -{ -public: - CUnitPropertiesDlgBar(); - ~CUnitPropertiesDlgBar(); - - 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 SetObject(CObjectEntry* obj); - - -protected: - BOOL OnInitDialog(); - - void UpdateEditorData(); - void UpdatePropertiesDlg(); - - // object being edited - CObjectEntry* m_Object; - - // Generated message map functions - //{{AFX_MSG(CUnitPropertiesDlgBar) - afx_msg void OnButtonBack(); - afx_msg void OnButtonRefresh(); - afx_msg void OnButtonTextureBrowse(); - afx_msg void OnButtonModelBrowse(); - afx_msg void OnButtonAnimationBrowse(); - //}}AFX_MSG - DECLARE_MESSAGE_MAP() -}; - - -#endif +#ifndef _UNITPROPERTIESDLGBAR_H +#define _UNITPROPERTIESDLGBAR_H + +#include "ObjectEntry.h" + +class CUnitPropertiesDlgBar : public CDialogBar +{ +public: + CUnitPropertiesDlgBar(); + ~CUnitPropertiesDlgBar(); + + 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 SetObject(CObjectEntry* obj); + + +protected: + BOOL OnInitDialog(); + + void UpdateEditorData(); + void UpdatePropertiesDlg(); + + // object being edited + CObjectEntry* m_Object; + + // Generated message map functions + //{{AFX_MSG(CUnitPropertiesDlgBar) + afx_msg void OnButtonBack(); + afx_msg void OnButtonRefresh(); + afx_msg void OnButtonTextureBrowse(); + afx_msg void OnButtonModelBrowse(); + afx_msg void OnButtonAnimationBrowse(); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + + +#endif diff --git a/source/sced/UnitPropertiesTabCtrl.cpp b/source/sced/UnitPropertiesTabCtrl.cpp index 5d51eef0aa..0e7e785c2f 100755 --- a/source/sced/UnitPropertiesTabCtrl.cpp +++ b/source/sced/UnitPropertiesTabCtrl.cpp @@ -1,82 +1,82 @@ -// UnitPropertiesTabCtrl.cpp : implementation file -// - -#include "stdafx.h" -#include "ScEd.h" -#include "UnitPropertiesTabCtrl.h" - -#ifdef _DEBUG -#define new DEBUG_NEW -#undef THIS_FILE -static char THIS_FILE[] = __FILE__; -#endif - -///////////////////////////////////////////////////////////////////////////// -// CUnitPropertiesTabCtrl - -CUnitPropertiesTabCtrl::CUnitPropertiesTabCtrl() -{ - m_TexturesTab=new CUnitPropertiesTexturesTab; - m_AnimationsTab=new CUnitPropertiesAnimationsTab; - m_tabPages[0]=m_TexturesTab; - m_tabPages[1]=m_AnimationsTab; - m_nNumberOfPages=2; -} - -CUnitPropertiesTabCtrl::~CUnitPropertiesTabCtrl() -{ - delete m_TexturesTab; - delete m_AnimationsTab; -} - - -BEGIN_MESSAGE_MAP(CUnitPropertiesTabCtrl, CTabCtrl) - //{{AFX_MSG_MAP(CUnitPropertiesTabCtrl) - //}}AFX_MSG_MAP -END_MESSAGE_MAP() - -///////////////////////////////////////////////////////////////////////////// -// CUnitPropertiesTabCtrl message handlers - -void CUnitPropertiesTabCtrl::Init() -{ - m_tabCurrent=0; - - PSTR pszTabItems[] = { - "Textures", - "Animations", - NULL - }; - - TC_ITEM tcItem; - for(INT i = 0; pszTabItems[i] != NULL; i++) - { - tcItem.mask = TCIF_TEXT; - tcItem.pszText = pszTabItems[i]; - tcItem.cchTextMax = strlen(pszTabItems[i]); - InsertItem(i,&tcItem); - } - - m_TexturesTab->Create(IDD_UNITPROPERTIES_TEXTURES,this); - m_AnimationsTab->Create(IDD_UNITPROPERTIES_ANIMATIONS,this); - - m_TexturesTab->ShowWindow(SW_SHOW); - m_AnimationsTab->ShowWindow(SW_HIDE); - - - CRect tabRect, itemRect; - int nX, nY, nXc, nYc; - - GetClientRect(&tabRect); - GetItemRect(0, &itemRect); - - nX=itemRect.left; - nY=itemRect.bottom+1; - nXc=tabRect.right-itemRect.left-1; - nYc=tabRect.bottom-nY-1; - - m_tabPages[0]->SetWindowPos(&wndTop, nX, nY, nXc, nYc, SWP_SHOWWINDOW); - for(int nCount=1; nCount < m_nNumberOfPages; nCount++){ - m_tabPages[nCount]->SetWindowPos(&wndTop, nX, nY, nXc, nYc, SWP_HIDEWINDOW); - } -} +// UnitPropertiesTabCtrl.cpp : implementation file +// + +#include "stdafx.h" +#include "ScEd.h" +#include "UnitPropertiesTabCtrl.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CUnitPropertiesTabCtrl + +CUnitPropertiesTabCtrl::CUnitPropertiesTabCtrl() +{ + m_TexturesTab=new CUnitPropertiesTexturesTab; + m_AnimationsTab=new CUnitPropertiesAnimationsTab; + m_tabPages[0]=m_TexturesTab; + m_tabPages[1]=m_AnimationsTab; + m_nNumberOfPages=2; +} + +CUnitPropertiesTabCtrl::~CUnitPropertiesTabCtrl() +{ + delete m_TexturesTab; + delete m_AnimationsTab; +} + + +BEGIN_MESSAGE_MAP(CUnitPropertiesTabCtrl, CTabCtrl) + //{{AFX_MSG_MAP(CUnitPropertiesTabCtrl) + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CUnitPropertiesTabCtrl message handlers + +void CUnitPropertiesTabCtrl::Init() +{ + m_tabCurrent=0; + + PSTR pszTabItems[] = { + "Textures", + "Animations", + NULL + }; + + TC_ITEM tcItem; + for(INT i = 0; pszTabItems[i] != NULL; i++) + { + tcItem.mask = TCIF_TEXT; + tcItem.pszText = pszTabItems[i]; + tcItem.cchTextMax = strlen(pszTabItems[i]); + InsertItem(i,&tcItem); + } + + m_TexturesTab->Create(IDD_UNITPROPERTIES_TEXTURES,this); + m_AnimationsTab->Create(IDD_UNITPROPERTIES_ANIMATIONS,this); + + m_TexturesTab->ShowWindow(SW_SHOW); + m_AnimationsTab->ShowWindow(SW_HIDE); + + + CRect tabRect, itemRect; + int nX, nY, nXc, nYc; + + GetClientRect(&tabRect); + GetItemRect(0, &itemRect); + + nX=itemRect.left; + nY=itemRect.bottom+1; + nXc=tabRect.right-itemRect.left-1; + nYc=tabRect.bottom-nY-1; + + m_tabPages[0]->SetWindowPos(&wndTop, nX, nY, nXc, nYc, SWP_SHOWWINDOW); + for(int nCount=1; nCount < m_nNumberOfPages; nCount++){ + m_tabPages[nCount]->SetWindowPos(&wndTop, nX, nY, nXc, nYc, SWP_HIDEWINDOW); + } +} diff --git a/source/sced/UnitPropertiesTabCtrl.h b/source/sced/UnitPropertiesTabCtrl.h index 2dbf148baa..3b6efcb04b 100755 --- a/source/sced/UnitPropertiesTabCtrl.h +++ b/source/sced/UnitPropertiesTabCtrl.h @@ -1,58 +1,58 @@ -#if !defined(AFX_UNITPROPERTIESTABCTRL_H__65018BF5_3893_4430_AA1D_743F79904748__INCLUDED_) -#define AFX_UNITPROPERTIESTABCTRL_H__65018BF5_3893_4430_AA1D_743F79904748__INCLUDED_ - -#if _MSC_VER > 1000 -#pragma once -#endif // _MSC_VER > 1000 -// UnitPropertiesTabCtrl.h : header file -// - -#include "UnitPropertiesTexturesTab.h" -#include "UnitPropertiesAnimationsTab.h" - -///////////////////////////////////////////////////////////////////////////// -// CUnitPropertiesTabCtrl window - -class CUnitPropertiesTabCtrl : public CTabCtrl -{ -// Construction -public: - CUnitPropertiesTabCtrl(); - - CDialog *m_tabPages[2]; - int m_tabCurrent; - int m_nNumberOfPages; - - void Init(); - -// Attributes -public: - CUnitPropertiesTexturesTab* m_TexturesTab; - CUnitPropertiesAnimationsTab* m_AnimationsTab; - -// Operations -public: - -// Overrides - // ClassWizard generated virtual function overrides - //{{AFX_VIRTUAL(CUnitPropertiesTabCtrl) - //}}AFX_VIRTUAL - -// Implementation -public: - virtual ~CUnitPropertiesTabCtrl(); - - // Generated message map functions -protected: - //{{AFX_MSG(CUnitPropertiesTabCtrl) - //}}AFX_MSG - - DECLARE_MESSAGE_MAP() -}; - -///////////////////////////////////////////////////////////////////////////// - -//{{AFX_INSERT_LOCATION}} -// Microsoft Visual C++ will insert additional declarations immediately before the previous line. - -#endif // !defined(AFX_UNITPROPERTIESTABCTRL_H__65018BF5_3893_4430_AA1D_743F79904748__INCLUDED_) +#if !defined(AFX_UNITPROPERTIESTABCTRL_H__65018BF5_3893_4430_AA1D_743F79904748__INCLUDED_) +#define AFX_UNITPROPERTIESTABCTRL_H__65018BF5_3893_4430_AA1D_743F79904748__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 +// UnitPropertiesTabCtrl.h : header file +// + +#include "UnitPropertiesTexturesTab.h" +#include "UnitPropertiesAnimationsTab.h" + +///////////////////////////////////////////////////////////////////////////// +// CUnitPropertiesTabCtrl window + +class CUnitPropertiesTabCtrl : public CTabCtrl +{ +// Construction +public: + CUnitPropertiesTabCtrl(); + + CDialog *m_tabPages[2]; + int m_tabCurrent; + int m_nNumberOfPages; + + void Init(); + +// Attributes +public: + CUnitPropertiesTexturesTab* m_TexturesTab; + CUnitPropertiesAnimationsTab* m_AnimationsTab; + +// Operations +public: + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CUnitPropertiesTabCtrl) + //}}AFX_VIRTUAL + +// Implementation +public: + virtual ~CUnitPropertiesTabCtrl(); + + // Generated message map functions +protected: + //{{AFX_MSG(CUnitPropertiesTabCtrl) + //}}AFX_MSG + + DECLARE_MESSAGE_MAP() +}; + +///////////////////////////////////////////////////////////////////////////// + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_UNITPROPERTIESTABCTRL_H__65018BF5_3893_4430_AA1D_743F79904748__INCLUDED_) diff --git a/source/sced/UnitPropertiesTexturesTab.cpp b/source/sced/UnitPropertiesTexturesTab.cpp index f8e2c9a4b0..b79beb1483 100755 --- a/source/sced/UnitPropertiesTexturesTab.cpp +++ b/source/sced/UnitPropertiesTexturesTab.cpp @@ -1,43 +1,43 @@ -// UnitPropertiesTexturesTab.cpp : implementation file -// - -#include "stdafx.h" -#include "ScEd.h" -#include "UnitPropertiesTexturesTab.h" - -#ifdef _DEBUG -#define new DEBUG_NEW -#undef THIS_FILE -static char THIS_FILE[] = __FILE__; -#endif - -///////////////////////////////////////////////////////////////////////////// -// CUnitPropertiesTexturesTab dialog - - -CUnitPropertiesTexturesTab::CUnitPropertiesTexturesTab(CWnd* pParent /*=NULL*/) - : CDialog(CUnitPropertiesTexturesTab::IDD, pParent) -{ - //{{AFX_DATA_INIT(CUnitPropertiesTexturesTab) - // NOTE: the ClassWizard will add member initialization here - //}}AFX_DATA_INIT -} - - -void CUnitPropertiesTexturesTab::DoDataExchange(CDataExchange* pDX) -{ - CDialog::DoDataExchange(pDX); - //{{AFX_DATA_MAP(CUnitPropertiesTexturesTab) - // NOTE: the ClassWizard will add DDX and DDV calls here - //}}AFX_DATA_MAP -} - - -BEGIN_MESSAGE_MAP(CUnitPropertiesTexturesTab, CDialog) - //{{AFX_MSG_MAP(CUnitPropertiesTexturesTab) - // NOTE: the ClassWizard will add message map macros here - //}}AFX_MSG_MAP -END_MESSAGE_MAP() - -///////////////////////////////////////////////////////////////////////////// -// CUnitPropertiesTexturesTab message handlers +// UnitPropertiesTexturesTab.cpp : implementation file +// + +#include "stdafx.h" +#include "ScEd.h" +#include "UnitPropertiesTexturesTab.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CUnitPropertiesTexturesTab dialog + + +CUnitPropertiesTexturesTab::CUnitPropertiesTexturesTab(CWnd* pParent /*=NULL*/) + : CDialog(CUnitPropertiesTexturesTab::IDD, pParent) +{ + //{{AFX_DATA_INIT(CUnitPropertiesTexturesTab) + // NOTE: the ClassWizard will add member initialization here + //}}AFX_DATA_INIT +} + + +void CUnitPropertiesTexturesTab::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(CUnitPropertiesTexturesTab) + // NOTE: the ClassWizard will add DDX and DDV calls here + //}}AFX_DATA_MAP +} + + +BEGIN_MESSAGE_MAP(CUnitPropertiesTexturesTab, CDialog) + //{{AFX_MSG_MAP(CUnitPropertiesTexturesTab) + // NOTE: the ClassWizard will add message map macros here + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CUnitPropertiesTexturesTab message handlers diff --git a/source/sced/UnitPropertiesTexturesTab.h b/source/sced/UnitPropertiesTexturesTab.h index 0072b8535f..701f1a489e 100755 --- a/source/sced/UnitPropertiesTexturesTab.h +++ b/source/sced/UnitPropertiesTexturesTab.h @@ -1,46 +1,46 @@ -#if !defined(AFX_UNITPROPERTIESTEXTURESTAB_H__5F56FF68_6305_4E2E_BC75_6CF208ED2DBB__INCLUDED_) -#define AFX_UNITPROPERTIESTEXTURESTAB_H__5F56FF68_6305_4E2E_BC75_6CF208ED2DBB__INCLUDED_ - -#if _MSC_VER > 1000 -#pragma once -#endif // _MSC_VER > 1000 -// UnitPropertiesTexturesTab.h : header file -// - -///////////////////////////////////////////////////////////////////////////// -// CUnitPropertiesTexturesTab dialog - -class CUnitPropertiesTexturesTab : public CDialog -{ -// Construction -public: - CUnitPropertiesTexturesTab(CWnd* pParent = NULL); // standard constructor - -// Dialog Data - //{{AFX_DATA(CUnitPropertiesTexturesTab) - enum { IDD = IDD_UNITPROPERTIES_TEXTURES }; - // NOTE: the ClassWizard will add data members here - //}}AFX_DATA - - -// Overrides - // ClassWizard generated virtual function overrides - //{{AFX_VIRTUAL(CUnitPropertiesTexturesTab) - protected: - virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support - //}}AFX_VIRTUAL - -// Implementation -protected: - - // Generated message map functions - //{{AFX_MSG(CUnitPropertiesTexturesTab) - // 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_UNITPROPERTIESTEXTURESTAB_H__5F56FF68_6305_4E2E_BC75_6CF208ED2DBB__INCLUDED_) +#if !defined(AFX_UNITPROPERTIESTEXTURESTAB_H__5F56FF68_6305_4E2E_BC75_6CF208ED2DBB__INCLUDED_) +#define AFX_UNITPROPERTIESTEXTURESTAB_H__5F56FF68_6305_4E2E_BC75_6CF208ED2DBB__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 +// UnitPropertiesTexturesTab.h : header file +// + +///////////////////////////////////////////////////////////////////////////// +// CUnitPropertiesTexturesTab dialog + +class CUnitPropertiesTexturesTab : public CDialog +{ +// Construction +public: + CUnitPropertiesTexturesTab(CWnd* pParent = NULL); // standard constructor + +// Dialog Data + //{{AFX_DATA(CUnitPropertiesTexturesTab) + enum { IDD = IDD_UNITPROPERTIES_TEXTURES }; + // NOTE: the ClassWizard will add data members here + //}}AFX_DATA + + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CUnitPropertiesTexturesTab) + protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + + // Generated message map functions + //{{AFX_MSG(CUnitPropertiesTexturesTab) + // 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_UNITPROPERTIESTEXTURESTAB_H__5F56FF68_6305_4E2E_BC75_6CF208ED2DBB__INCLUDED_) diff --git a/source/sced/UnitToolsDlgBar.cpp b/source/sced/UnitToolsDlgBar.cpp index 755bbd4e2c..63818ca086 100755 --- a/source/sced/UnitToolsDlgBar.cpp +++ b/source/sced/UnitToolsDlgBar.cpp @@ -1,226 +1,226 @@ -#include "stdafx.h" -#include "MainFrm.h" -#include "SimpleEdit.h" -#include "ObjectManager.h" -#include "UnitToolsDlgBar.h" -#include "PaintObjectTool.h" -#include "SelectObjectTool.h" -#include "ToolManager.h" - -BEGIN_MESSAGE_MAP(CUnitToolsDlgBar, CDialogBar) - //{{AFX_MSG_MAP(CUnitToolsDlgBar) - // NOTE - the ClassWizard will add and remove mapping macros here. - //}}AFX_MSG_MAP - ON_BN_CLICKED(IDC_BUTTON_SELECT, OnButtonSelect) - ON_BN_CLICKED(IDC_BUTTON_ADDUNIT, OnButtonAddUnit) - ON_BN_CLICKED(IDC_BUTTON_ADD, OnButtonAdd) - ON_BN_CLICKED(IDC_BUTTON_EDIT, OnButtonEdit) - ON_NOTIFY(NM_CLICK, IDC_LIST_OBJECTBROWSER, OnClickListObjectBrowser) - ON_CBN_SELCHANGE(IDC_COMBO_OBJECTTYPES, OnSelChangeObjectTypes) -END_MESSAGE_MAP() - - -CUnitToolsDlgBar::CUnitToolsDlgBar() -{ -} - -CUnitToolsDlgBar::~CUnitToolsDlgBar() -{ -} - -BOOL CUnitToolsDlgBar::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 CUnitToolsDlgBar::Create(CWnd * pParentWnd, UINT nIDTemplate,UINT nStyle, UINT nID) -{ - if (!Create(pParentWnd, MAKEINTRESOURCE(nIDTemplate), nStyle, nID)) { - return FALSE; - } - - return TRUE; -} - - -BOOL CUnitToolsDlgBar::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); - - // setup the list ctrl - CListCtrl* listctrl=(CListCtrl*) GetDlgItem(IDC_LIST_OBJECTBROWSER); - listctrl->GetClientRect(&rect); - listctrl->InsertColumn(0,_T("Item Name"),LVCFMT_LEFT,rect.Width()); - - - // build combo box for object types - CComboBox* objecttypes=(CComboBox*) GetDlgItem(IDC_COMBO_OBJECTTYPES); - - const std::vector& types=g_ObjMan.m_ObjectTypes; - for (uint i=0;iAddString((const char*) types[i].m_Name); - } - if (types.size()>0) { - // select first type - objecttypes->SetCurSel(0); - - // set initial list contents - if (types.size()) { - const std::vector& objects=types[0].m_Objects; - for (uint i=0;iInsertItem(i,(const char*) objects[i]->m_Name,i); - } - } - } - - CButton* addunit=(CButton*) GetDlgItem(IDC_BUTTON_ADDUNIT); - addunit->SetBitmap(::LoadBitmap(::GetModuleHandle(0),MAKEINTRESOURCE(IDB_BITMAP_ADDUNIT))); - - CButton* selectunit=(CButton*) GetDlgItem(IDC_BUTTON_SELECT); - selectunit->SetBitmap(::LoadBitmap(::GetModuleHandle(0),MAKEINTRESOURCE(IDB_BITMAP_SELECTUNIT))); - - OnButtonSelect(); - - return TRUE; -} - -void CUnitToolsDlgBar::OnUpdateCmdUI(CFrameWnd* pTarget, BOOL bDisableIfNoHndler) -{ - bDisableIfNoHndler = FALSE; - CDialogBar::OnUpdateCmdUI(pTarget,bDisableIfNoHndler); -} - -void CUnitToolsDlgBar::OnButtonAdd() -{ - bool foundname=false; - CSimpleEdit dlg("Enter Object Name"); - while (!foundname && dlg.DoModal()==IDOK) { - // get object name - CString& name=dlg.m_Text; - if (name.GetLength()==0) { - MessageBox("Bad name","Error"); - } else if (g_ObjMan.FindObject(name)!=0) { - MessageBox("Object with that name already exists","Error"); - } else { - // add to list ctrl - CListCtrl* listctrl=(CListCtrl*) GetDlgItem(IDC_LIST_OBJECTBROWSER); - int index=listctrl->GetItemCount(); - listctrl->InsertItem(index,(const char*) name,index); - - // deselect current selection in list ctrl, if any - POSITION pos=listctrl->GetFirstSelectedItemPosition(); - if (pos) { - int oldindex=listctrl->GetNextSelectedItem(pos); - listctrl->SetItemState(oldindex, 0, LVIS_SELECTED); - } - - // select new entry - listctrl->SetItemState(index, LVIS_SELECTED, LVIS_SELECTED); - - // now enter edit mode - CObjectEntry* obj=new CObjectEntry(GetCurrentObjectType()); - obj->m_Name=name; - g_ObjMan.AddObject(obj,GetCurrentObjectType()); - - CMainFrame* mainfrm=(CMainFrame*) AfxGetMainWnd(); - mainfrm->OnObjectProperties(obj); - foundname=true; - } - } - -} - -void CUnitToolsDlgBar::OnButtonEdit() -{ - // get current selection, if any - CListCtrl* listctrl=(CListCtrl*) GetDlgItem(IDC_LIST_OBJECTBROWSER); - POSITION pos=listctrl->GetFirstSelectedItemPosition(); - if (!pos) { - // nothing selected, nothing to do - return; - } - - // get object at position - const std::vector& objects=g_ObjMan.m_ObjectTypes[GetCurrentObjectType()].m_Objects; - CObjectEntry* obj=objects[(int) pos-1]; - CMainFrame* mainfrm=(CMainFrame*) AfxGetMainWnd(); - mainfrm->OnObjectProperties(obj); -} - - -void CUnitToolsDlgBar::OnClickListObjectBrowser(NMHDR* pNMHDR, LRESULT* pResult) -{ - CListCtrl* listctrl=(CListCtrl*) GetDlgItem(IDC_LIST_OBJECTBROWSER); - - // deselect current selection in list ctrl, if any - POSITION pos=listctrl->GetFirstSelectedItemPosition(); - if (pos) { - g_ObjMan.SetSelectedObject(g_ObjMan.m_ObjectTypes[GetCurrentObjectType()].m_Objects[(int) pos-1]); - } - - // shift to add mode - SetAddUnitMode(); - - *pResult = 0; -} - -int CUnitToolsDlgBar::GetCurrentObjectType() -{ - CComboBox* objecttypes=(CComboBox*) GetDlgItem(IDC_COMBO_OBJECTTYPES); - return objecttypes->GetCurSel(); -} - -void CUnitToolsDlgBar::OnSelChangeObjectTypes() -{ - // clear out the listctrl - CListCtrl* listctrl=(CListCtrl*) GetDlgItem(IDC_LIST_OBJECTBROWSER); - listctrl->DeleteAllItems(); - - // add new items back to listbox - std::vector& objects=g_ObjMan.m_ObjectTypes[GetCurrentObjectType()].m_Objects; - for (uint i=0;iInsertItem(i,(const char*) objects[i]->m_Name,i); - } - - g_ObjMan.SetSelectedObject(0); -} - -void CUnitToolsDlgBar::OnButtonSelect() -{ - SetSelectMode(); -} - -void CUnitToolsDlgBar::SetSelectMode() -{ - ((CButton*) GetDlgItem(IDC_BUTTON_SELECT))->SetState(TRUE); - ((CButton*) GetDlgItem(IDC_BUTTON_ADDUNIT))->SetState(FALSE); - m_Mode=SELECT_MODE; - g_ToolMan.SetActiveTool(CSelectObjectTool::GetTool()); -} - -void CUnitToolsDlgBar::OnButtonAddUnit() -{ - SetAddUnitMode(); -} - -void CUnitToolsDlgBar::SetAddUnitMode() -{ - ((CButton*) GetDlgItem(IDC_BUTTON_SELECT))->SetState(FALSE); - ((CButton*) GetDlgItem(IDC_BUTTON_ADDUNIT))->SetState(TRUE); - m_Mode=ADDUNIT_MODE; - g_ToolMan.SetActiveTool(CPaintObjectTool::GetTool()); +#include "stdafx.h" +#include "MainFrm.h" +#include "SimpleEdit.h" +#include "ObjectManager.h" +#include "UnitToolsDlgBar.h" +#include "PaintObjectTool.h" +#include "SelectObjectTool.h" +#include "ToolManager.h" + +BEGIN_MESSAGE_MAP(CUnitToolsDlgBar, CDialogBar) + //{{AFX_MSG_MAP(CUnitToolsDlgBar) + // NOTE - the ClassWizard will add and remove mapping macros here. + //}}AFX_MSG_MAP + ON_BN_CLICKED(IDC_BUTTON_SELECT, OnButtonSelect) + ON_BN_CLICKED(IDC_BUTTON_ADDUNIT, OnButtonAddUnit) + ON_BN_CLICKED(IDC_BUTTON_ADD, OnButtonAdd) + ON_BN_CLICKED(IDC_BUTTON_EDIT, OnButtonEdit) + ON_NOTIFY(NM_CLICK, IDC_LIST_OBJECTBROWSER, OnClickListObjectBrowser) + ON_CBN_SELCHANGE(IDC_COMBO_OBJECTTYPES, OnSelChangeObjectTypes) +END_MESSAGE_MAP() + + +CUnitToolsDlgBar::CUnitToolsDlgBar() +{ +} + +CUnitToolsDlgBar::~CUnitToolsDlgBar() +{ +} + +BOOL CUnitToolsDlgBar::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 CUnitToolsDlgBar::Create(CWnd * pParentWnd, UINT nIDTemplate,UINT nStyle, UINT nID) +{ + if (!Create(pParentWnd, MAKEINTRESOURCE(nIDTemplate), nStyle, nID)) { + return FALSE; + } + + return TRUE; +} + + +BOOL CUnitToolsDlgBar::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); + + // setup the list ctrl + CListCtrl* listctrl=(CListCtrl*) GetDlgItem(IDC_LIST_OBJECTBROWSER); + listctrl->GetClientRect(&rect); + listctrl->InsertColumn(0,_T("Item Name"),LVCFMT_LEFT,rect.Width()); + + + // build combo box for object types + CComboBox* objecttypes=(CComboBox*) GetDlgItem(IDC_COMBO_OBJECTTYPES); + + const std::vector& types=g_ObjMan.m_ObjectTypes; + for (uint i=0;iAddString((const char*) types[i].m_Name); + } + if (types.size()>0) { + // select first type + objecttypes->SetCurSel(0); + + // set initial list contents + if (types.size()) { + const std::vector& objects=types[0].m_Objects; + for (uint i=0;iInsertItem(i,(const char*) objects[i]->m_Name,i); + } + } + } + + CButton* addunit=(CButton*) GetDlgItem(IDC_BUTTON_ADDUNIT); + addunit->SetBitmap(::LoadBitmap(::GetModuleHandle(0),MAKEINTRESOURCE(IDB_BITMAP_ADDUNIT))); + + CButton* selectunit=(CButton*) GetDlgItem(IDC_BUTTON_SELECT); + selectunit->SetBitmap(::LoadBitmap(::GetModuleHandle(0),MAKEINTRESOURCE(IDB_BITMAP_SELECTUNIT))); + + OnButtonSelect(); + + return TRUE; +} + +void CUnitToolsDlgBar::OnUpdateCmdUI(CFrameWnd* pTarget, BOOL bDisableIfNoHndler) +{ + bDisableIfNoHndler = FALSE; + CDialogBar::OnUpdateCmdUI(pTarget,bDisableIfNoHndler); +} + +void CUnitToolsDlgBar::OnButtonAdd() +{ + bool foundname=false; + CSimpleEdit dlg("Enter Object Name"); + while (!foundname && dlg.DoModal()==IDOK) { + // get object name + CString& name=dlg.m_Text; + if (name.GetLength()==0) { + MessageBox("Bad name","Error"); + } else if (g_ObjMan.FindObject(name)!=0) { + MessageBox("Object with that name already exists","Error"); + } else { + // add to list ctrl + CListCtrl* listctrl=(CListCtrl*) GetDlgItem(IDC_LIST_OBJECTBROWSER); + int index=listctrl->GetItemCount(); + listctrl->InsertItem(index,(const char*) name,index); + + // deselect current selection in list ctrl, if any + POSITION pos=listctrl->GetFirstSelectedItemPosition(); + if (pos) { + int oldindex=listctrl->GetNextSelectedItem(pos); + listctrl->SetItemState(oldindex, 0, LVIS_SELECTED); + } + + // select new entry + listctrl->SetItemState(index, LVIS_SELECTED, LVIS_SELECTED); + + // now enter edit mode + CObjectEntry* obj=new CObjectEntry(GetCurrentObjectType()); + obj->m_Name=name; + g_ObjMan.AddObject(obj,GetCurrentObjectType()); + + CMainFrame* mainfrm=(CMainFrame*) AfxGetMainWnd(); + mainfrm->OnObjectProperties(obj); + foundname=true; + } + } + +} + +void CUnitToolsDlgBar::OnButtonEdit() +{ + // get current selection, if any + CListCtrl* listctrl=(CListCtrl*) GetDlgItem(IDC_LIST_OBJECTBROWSER); + POSITION pos=listctrl->GetFirstSelectedItemPosition(); + if (!pos) { + // nothing selected, nothing to do + return; + } + + // get object at position + const std::vector& objects=g_ObjMan.m_ObjectTypes[GetCurrentObjectType()].m_Objects; + CObjectEntry* obj=objects[(int) pos-1]; + CMainFrame* mainfrm=(CMainFrame*) AfxGetMainWnd(); + mainfrm->OnObjectProperties(obj); +} + + +void CUnitToolsDlgBar::OnClickListObjectBrowser(NMHDR* pNMHDR, LRESULT* pResult) +{ + CListCtrl* listctrl=(CListCtrl*) GetDlgItem(IDC_LIST_OBJECTBROWSER); + + // deselect current selection in list ctrl, if any + POSITION pos=listctrl->GetFirstSelectedItemPosition(); + if (pos) { + g_ObjMan.SetSelectedObject(g_ObjMan.m_ObjectTypes[GetCurrentObjectType()].m_Objects[(int) pos-1]); + } + + // shift to add mode + SetAddUnitMode(); + + *pResult = 0; +} + +int CUnitToolsDlgBar::GetCurrentObjectType() +{ + CComboBox* objecttypes=(CComboBox*) GetDlgItem(IDC_COMBO_OBJECTTYPES); + return objecttypes->GetCurSel(); +} + +void CUnitToolsDlgBar::OnSelChangeObjectTypes() +{ + // clear out the listctrl + CListCtrl* listctrl=(CListCtrl*) GetDlgItem(IDC_LIST_OBJECTBROWSER); + listctrl->DeleteAllItems(); + + // add new items back to listbox + std::vector& objects=g_ObjMan.m_ObjectTypes[GetCurrentObjectType()].m_Objects; + for (uint i=0;iInsertItem(i,(const char*) objects[i]->m_Name,i); + } + + g_ObjMan.SetSelectedObject(0); +} + +void CUnitToolsDlgBar::OnButtonSelect() +{ + SetSelectMode(); +} + +void CUnitToolsDlgBar::SetSelectMode() +{ + ((CButton*) GetDlgItem(IDC_BUTTON_SELECT))->SetState(TRUE); + ((CButton*) GetDlgItem(IDC_BUTTON_ADDUNIT))->SetState(FALSE); + m_Mode=SELECT_MODE; + g_ToolMan.SetActiveTool(CSelectObjectTool::GetTool()); +} + +void CUnitToolsDlgBar::OnButtonAddUnit() +{ + SetAddUnitMode(); +} + +void CUnitToolsDlgBar::SetAddUnitMode() +{ + ((CButton*) GetDlgItem(IDC_BUTTON_SELECT))->SetState(FALSE); + ((CButton*) GetDlgItem(IDC_BUTTON_ADDUNIT))->SetState(TRUE); + m_Mode=ADDUNIT_MODE; + g_ToolMan.SetActiveTool(CPaintObjectTool::GetTool()); } \ No newline at end of file diff --git a/source/sced/UnitToolsDlgBar.h b/source/sced/UnitToolsDlgBar.h index 878893ee9d..5c2a9746f8 100755 --- a/source/sced/UnitToolsDlgBar.h +++ b/source/sced/UnitToolsDlgBar.h @@ -1,36 +1,36 @@ -#ifndef _UNITTOOLSDLGBAR_H -#define _UNITTOOLSDLGBAR_H - -class CUnitToolsDlgBar : public CDialogBar -{ -public: - CUnitToolsDlgBar(); - ~CUnitToolsDlgBar(); - - 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); - - enum { SELECT_MODE, ADDUNIT_MODE } m_Mode; - - void SetSelectMode(); - void SetAddUnitMode(); - -protected: - BOOL OnInitDialog(); - int GetCurrentObjectType(); - - // Generated message map functions - //{{AFX_MSG(CUnitToolsDlgBar) - afx_msg void OnButtonAdd(); - afx_msg void OnButtonEdit(); - afx_msg void OnButtonAddUnit(); - afx_msg void OnButtonSelect(); - afx_msg void OnClickListObjectBrowser(NMHDR* pNMHDR, LRESULT* pResult); - afx_msg void CUnitToolsDlgBar::OnSelChangeObjectTypes(); - //}}AFX_MSG - DECLARE_MESSAGE_MAP() -}; - - -#endif +#ifndef _UNITTOOLSDLGBAR_H +#define _UNITTOOLSDLGBAR_H + +class CUnitToolsDlgBar : public CDialogBar +{ +public: + CUnitToolsDlgBar(); + ~CUnitToolsDlgBar(); + + 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); + + enum { SELECT_MODE, ADDUNIT_MODE } m_Mode; + + void SetSelectMode(); + void SetAddUnitMode(); + +protected: + BOOL OnInitDialog(); + int GetCurrentObjectType(); + + // Generated message map functions + //{{AFX_MSG(CUnitToolsDlgBar) + afx_msg void OnButtonAdd(); + afx_msg void OnButtonEdit(); + afx_msg void OnButtonAddUnit(); + afx_msg void OnButtonSelect(); + afx_msg void OnClickListObjectBrowser(NMHDR* pNMHDR, LRESULT* pResult); + afx_msg void CUnitToolsDlgBar::OnSelChangeObjectTypes(); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + + +#endif diff --git a/source/sced/UserConfig.cpp b/source/sced/UserConfig.cpp index 8ea5b9f8bc..ad98fea4ec 100755 --- a/source/sced/UserConfig.cpp +++ b/source/sced/UserConfig.cpp @@ -1,126 +1,126 @@ -#include "UserConfig.h" -#include - -CUserConfig g_UserCfg; - -CUserConfig::CUserConfig() -{ - m_ScrollSpeed=5; - m_MapLoadDir="mods\\official\\maps\\scenarios"; - m_MapSaveDir="mods\\official\\maps\\scenarios"; - m_TerrainLoadDir="mods\\official\\art\\textures\\terrain"; - m_TerrainSaveDir="mods\\official\\art\\textures\\terrain"; - m_PMDSaveDir="."; - m_ModelLoadDir="mods\\official\\art\\meshes"; - m_ModelTexLoadDir="mods\\official\\art\\textures\\skins"; - m_ModelAnimationDir="mods\\official\\art\\animation"; - m_TextureExt="dds"; -} - -void CUserConfig::SetOptionString(ECfgOption opt,const char* str) -{ - switch (opt) { - case CFG_MAPLOADDIR: - m_MapLoadDir=str; - break; - - case CFG_MAPSAVEDIR: - m_MapSaveDir=str; - break; - - case CFG_TERRAINLOADDIR: - m_TerrainLoadDir=str; - break; - - case CFG_TERRAINSAVEDIR: - m_TerrainSaveDir=str; - break; - - case CFG_PMDSAVEDIR: - m_PMDSaveDir=str; - break; - - case CFG_MODELLOADDIR: - m_ModelLoadDir=str; - break; - - case CFG_MODELTEXLOADDIR: - m_ModelTexLoadDir=str; - break; - - case CFG_MODELANIMATIONDIR: - m_ModelAnimationDir=str; - break; - - case CFG_TEXTUREEXT: - m_TextureExt=str; - break; - - default: - assert(0 && "unhandled case statement"); - } -} - -const char* CUserConfig::GetOptionString(ECfgOption opt) -{ - switch (opt) { - case CFG_MAPLOADDIR: - return (const char*) m_MapLoadDir; - - case CFG_MAPSAVEDIR: - return (const char*) m_MapSaveDir; - - case CFG_TERRAINLOADDIR: - return (const char*) m_TerrainLoadDir; - - case CFG_TERRAINSAVEDIR: - return (const char*) m_TerrainSaveDir; - - case CFG_PMDSAVEDIR: - return (const char*) m_PMDSaveDir; - - case CFG_MODELLOADDIR: - return (const char*) m_ModelLoadDir; - - case CFG_MODELTEXLOADDIR: - return (const char*) m_ModelTexLoadDir; - - case CFG_MODELANIMATIONDIR: - return (const char*) m_ModelAnimationDir; - - case CFG_TEXTUREEXT: - return (const char*) m_TextureExt; - - default: - assert(0 && "unhandled case statement"); - } - - return 0; -} - - -void CUserConfig::SetOptionInt(ECfgOption opt,int value) -{ - switch (opt) { - case CFG_SCROLLSPEED: - m_ScrollSpeed=value; - break; - - default: - assert(0 && "unhandled case statement"); - } -} - -int CUserConfig::GetOptionInt(ECfgOption opt) -{ - switch (opt) { - case CFG_SCROLLSPEED: - return m_ScrollSpeed; - - default: - assert(0 && "unhandled case statement"); - } - - return 0; -} - +#include "UserConfig.h" +#include + +CUserConfig g_UserCfg; + +CUserConfig::CUserConfig() +{ + m_ScrollSpeed=5; + m_MapLoadDir="mods\\official\\maps\\scenarios"; + m_MapSaveDir="mods\\official\\maps\\scenarios"; + m_TerrainLoadDir="mods\\official\\art\\textures\\terrain"; + m_TerrainSaveDir="mods\\official\\art\\textures\\terrain"; + m_PMDSaveDir="."; + m_ModelLoadDir="mods\\official\\art\\meshes"; + m_ModelTexLoadDir="mods\\official\\art\\textures\\skins"; + m_ModelAnimationDir="mods\\official\\art\\animation"; + m_TextureExt="dds"; +} + +void CUserConfig::SetOptionString(ECfgOption opt,const char* str) +{ + switch (opt) { + case CFG_MAPLOADDIR: + m_MapLoadDir=str; + break; + + case CFG_MAPSAVEDIR: + m_MapSaveDir=str; + break; + + case CFG_TERRAINLOADDIR: + m_TerrainLoadDir=str; + break; + + case CFG_TERRAINSAVEDIR: + m_TerrainSaveDir=str; + break; + + case CFG_PMDSAVEDIR: + m_PMDSaveDir=str; + break; + + case CFG_MODELLOADDIR: + m_ModelLoadDir=str; + break; + + case CFG_MODELTEXLOADDIR: + m_ModelTexLoadDir=str; + break; + + case CFG_MODELANIMATIONDIR: + m_ModelAnimationDir=str; + break; + + case CFG_TEXTUREEXT: + m_TextureExt=str; + break; + + default: + assert(0 && "unhandled case statement"); + } +} + +const char* CUserConfig::GetOptionString(ECfgOption opt) +{ + switch (opt) { + case CFG_MAPLOADDIR: + return (const char*) m_MapLoadDir; + + case CFG_MAPSAVEDIR: + return (const char*) m_MapSaveDir; + + case CFG_TERRAINLOADDIR: + return (const char*) m_TerrainLoadDir; + + case CFG_TERRAINSAVEDIR: + return (const char*) m_TerrainSaveDir; + + case CFG_PMDSAVEDIR: + return (const char*) m_PMDSaveDir; + + case CFG_MODELLOADDIR: + return (const char*) m_ModelLoadDir; + + case CFG_MODELTEXLOADDIR: + return (const char*) m_ModelTexLoadDir; + + case CFG_MODELANIMATIONDIR: + return (const char*) m_ModelAnimationDir; + + case CFG_TEXTUREEXT: + return (const char*) m_TextureExt; + + default: + assert(0 && "unhandled case statement"); + } + + return 0; +} + + +void CUserConfig::SetOptionInt(ECfgOption opt,int value) +{ + switch (opt) { + case CFG_SCROLLSPEED: + m_ScrollSpeed=value; + break; + + default: + assert(0 && "unhandled case statement"); + } +} + +int CUserConfig::GetOptionInt(ECfgOption opt) +{ + switch (opt) { + case CFG_SCROLLSPEED: + return m_ScrollSpeed; + + default: + assert(0 && "unhandled case statement"); + } + + return 0; +} + diff --git a/source/sced/UserConfig.h b/source/sced/UserConfig.h index eba1920de4..3ea0f06b68 100755 --- a/source/sced/UserConfig.h +++ b/source/sced/UserConfig.h @@ -1,55 +1,55 @@ -#ifndef _USERCONFIG_H -#define _USERCONFIG_H - -#include "ps\CStr.h" - -enum ECfgOption { - CFG_MAPLOADDIR, - CFG_MAPSAVEDIR, - CFG_TERRAINLOADDIR, - CFG_TERRAINSAVEDIR, - CFG_PMDSAVEDIR, - CFG_MODELLOADDIR, - CFG_MODELTEXLOADDIR, - CFG_MODELANIMATIONDIR, - CFG_TEXTUREEXT, - CFG_SCROLLSPEED -}; - -class CUserConfig -{ -public: - CUserConfig(); - - void SetOptionString(ECfgOption opt,const char* str); - const char* GetOptionString(ECfgOption opt); - - void SetOptionInt(ECfgOption opt,int value); - int GetOptionInt(ECfgOption opt); - -private: - // map load directory - CStr m_MapLoadDir; - // map save directory - CStr m_MapSaveDir; - // terrain load directory - CStr m_TerrainLoadDir; - // terrain save directory - CStr m_TerrainSaveDir; - // PMD save directory - CStr m_PMDSaveDir; - // model load directory - CStr m_ModelLoadDir; - // model texture load directory - CStr m_ModelTexLoadDir; - // model animation load directory - CStr m_ModelAnimationDir; - // texture file extension - CStr m_TextureExt; - // map scroll speed - int m_ScrollSpeed; -}; - -extern CUserConfig g_UserCfg; - +#ifndef _USERCONFIG_H +#define _USERCONFIG_H + +#include "ps\CStr.h" + +enum ECfgOption { + CFG_MAPLOADDIR, + CFG_MAPSAVEDIR, + CFG_TERRAINLOADDIR, + CFG_TERRAINSAVEDIR, + CFG_PMDSAVEDIR, + CFG_MODELLOADDIR, + CFG_MODELTEXLOADDIR, + CFG_MODELANIMATIONDIR, + CFG_TEXTUREEXT, + CFG_SCROLLSPEED +}; + +class CUserConfig +{ +public: + CUserConfig(); + + void SetOptionString(ECfgOption opt,const char* str); + const char* GetOptionString(ECfgOption opt); + + void SetOptionInt(ECfgOption opt,int value); + int GetOptionInt(ECfgOption opt); + +private: + // map load directory + CStr m_MapLoadDir; + // map save directory + CStr m_MapSaveDir; + // terrain load directory + CStr m_TerrainLoadDir; + // terrain save directory + CStr m_TerrainSaveDir; + // PMD save directory + CStr m_PMDSaveDir; + // model load directory + CStr m_ModelLoadDir; + // model texture load directory + CStr m_ModelTexLoadDir; + // model animation load directory + CStr m_ModelAnimationDir; + // texture file extension + CStr m_TextureExt; + // map scroll speed + int m_ScrollSpeed; +}; + +extern CUserConfig g_UserCfg; + #endif \ No newline at end of file diff --git a/source/sced/WebLinkButton.cpp b/source/sced/WebLinkButton.cpp index 15d570d8ee..a286b57c08 100755 --- a/source/sced/WebLinkButton.cpp +++ b/source/sced/WebLinkButton.cpp @@ -1,78 +1,78 @@ -// WebLinkButton.cpp : implementation file -// - -#include "stdafx.h" -#include "ScEd.h" -#include "WebLinkButton.h" - -///////////////////////////////////////////////////////////////////////////// -// CWebLinkButton - -CWebLinkButton::CWebLinkButton() : m_Clicked(FALSE), m_HandCursor(0) -{ -} - -CWebLinkButton::~CWebLinkButton() -{ -} - - -BEGIN_MESSAGE_MAP(CWebLinkButton, CButton) - //{{AFX_MSG_MAP(CWebLinkButton) - ON_CONTROL_REFLECT(BN_CLICKED, OnClicked) - ON_WM_MOUSEMOVE() - //}}AFX_MSG_MAP -END_MESSAGE_MAP() - -///////////////////////////////////////////////////////////////////////////// -// CWebLinkButton message handlers - -void CWebLinkButton::OnClicked() -{ - m_Clicked=TRUE; - - CString url("http://"); - url+=m_Address; - ShellExecute(NULL,"open",(LPCTSTR) url,NULL,NULL,SW_SHOW); -} - -void CWebLinkButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) -{ - CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC); - CRect rect = lpDrawItemStruct->rcItem; - - if (m_Address.GetLength()>0) { - - // get a LOGFONT for current font, but underlined - CFont* font=GetFont(); - LOGFONT logFont; - font->GetLogFont(&logFont); - logFont.lfUnderline=TRUE; - - // build font from this, select into DC - CFont newfont; - newfont.CreateFontIndirect(&logFont); - CFont* oldfont=pDC->SelectObject(&newfont); - - // draw text - pDC->SetTextColor(m_Clicked ? RGB(0,0,128) : RGB(0,0,255)); - pDC->TextOut(rect.left,(rect.bottom+rect.top)/2,m_Address); - - // restore old font - pDC->SelectObject(&oldfont); - } -} - - -void CWebLinkButton::OnMouseMove(UINT nFlags, CPoint point) -{ - if (!m_HandCursor){//!m_MouseHovering) { - m_HandCursor=AfxGetApp()->LoadStandardCursor(MAKEINTRESOURCE(32649)); - if (!m_HandCursor) { - // ack - couldn't get the hand : must be running on Win95/Win98 (unsupported?) .. just - // use any difference cursor for the minute - m_HandCursor=AfxGetApp()->LoadStandardCursor(IDC_UPARROW); - } - } - ::SetCursor(m_HandCursor); -} +// WebLinkButton.cpp : implementation file +// + +#include "stdafx.h" +#include "ScEd.h" +#include "WebLinkButton.h" + +///////////////////////////////////////////////////////////////////////////// +// CWebLinkButton + +CWebLinkButton::CWebLinkButton() : m_Clicked(FALSE), m_HandCursor(0) +{ +} + +CWebLinkButton::~CWebLinkButton() +{ +} + + +BEGIN_MESSAGE_MAP(CWebLinkButton, CButton) + //{{AFX_MSG_MAP(CWebLinkButton) + ON_CONTROL_REFLECT(BN_CLICKED, OnClicked) + ON_WM_MOUSEMOVE() + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CWebLinkButton message handlers + +void CWebLinkButton::OnClicked() +{ + m_Clicked=TRUE; + + CString url("http://"); + url+=m_Address; + ShellExecute(NULL,"open",(LPCTSTR) url,NULL,NULL,SW_SHOW); +} + +void CWebLinkButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) +{ + CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC); + CRect rect = lpDrawItemStruct->rcItem; + + if (m_Address.GetLength()>0) { + + // get a LOGFONT for current font, but underlined + CFont* font=GetFont(); + LOGFONT logFont; + font->GetLogFont(&logFont); + logFont.lfUnderline=TRUE; + + // build font from this, select into DC + CFont newfont; + newfont.CreateFontIndirect(&logFont); + CFont* oldfont=pDC->SelectObject(&newfont); + + // draw text + pDC->SetTextColor(m_Clicked ? RGB(0,0,128) : RGB(0,0,255)); + pDC->TextOut(rect.left,(rect.bottom+rect.top)/2,m_Address); + + // restore old font + pDC->SelectObject(&oldfont); + } +} + + +void CWebLinkButton::OnMouseMove(UINT nFlags, CPoint point) +{ + if (!m_HandCursor){//!m_MouseHovering) { + m_HandCursor=AfxGetApp()->LoadStandardCursor(MAKEINTRESOURCE(32649)); + if (!m_HandCursor) { + // ack - couldn't get the hand : must be running on Win95/Win98 (unsupported?) .. just + // use any difference cursor for the minute + m_HandCursor=AfxGetApp()->LoadStandardCursor(IDC_UPARROW); + } + } + ::SetCursor(m_HandCursor); +} diff --git a/source/sced/WebLinkButton.h b/source/sced/WebLinkButton.h index 6c9b3f0bd5..f5b8401faf 100755 --- a/source/sced/WebLinkButton.h +++ b/source/sced/WebLinkButton.h @@ -1,54 +1,54 @@ -#if !defined(AFX_WEBLINKBUTTON_H__99561EFB_6294_4249_B339_8364DD26EDB5__INCLUDED_) -#define AFX_WEBLINKBUTTON_H__99561EFB_6294_4249_B339_8364DD26EDB5__INCLUDED_ - -#if _MSC_VER > 1000 -#pragma once -#endif // _MSC_VER > 1000 -// WebLinkButton.h : header file -// - -///////////////////////////////////////////////////////////////////////////// -// CWebLinkButton window - -class CWebLinkButton : public CButton -{ -// Construction -public: - CWebLinkButton(); - -// Attributes -public: - CString m_Address; - BOOL m_Clicked; - HCURSOR m_HandCursor; - -// Operations -public: - -// Overrides - // ClassWizard generated virtual function overrides - //{{AFX_VIRTUAL(CWebLinkButton) - public: - virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct); - //}}AFX_VIRTUAL - -// Implementation -public: - virtual ~CWebLinkButton(); - - // Generated message map functions -protected: - //{{AFX_MSG(CWebLinkButton) - afx_msg void OnClicked(); - afx_msg void OnMouseMove(UINT nFlags, CPoint point); - //}}AFX_MSG - - DECLARE_MESSAGE_MAP() -}; - -///////////////////////////////////////////////////////////////////////////// - -//{{AFX_INSERT_LOCATION}} -// Microsoft Visual C++ will insert additional declarations immediately before the previous line. - -#endif // !defined(AFX_WEBLINKBUTTON_H__99561EFB_6294_4249_B339_8364DD26EDB5__INCLUDED_) +#if !defined(AFX_WEBLINKBUTTON_H__99561EFB_6294_4249_B339_8364DD26EDB5__INCLUDED_) +#define AFX_WEBLINKBUTTON_H__99561EFB_6294_4249_B339_8364DD26EDB5__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 +// WebLinkButton.h : header file +// + +///////////////////////////////////////////////////////////////////////////// +// CWebLinkButton window + +class CWebLinkButton : public CButton +{ +// Construction +public: + CWebLinkButton(); + +// Attributes +public: + CString m_Address; + BOOL m_Clicked; + HCURSOR m_HandCursor; + +// Operations +public: + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CWebLinkButton) + public: + virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct); + //}}AFX_VIRTUAL + +// Implementation +public: + virtual ~CWebLinkButton(); + + // Generated message map functions +protected: + //{{AFX_MSG(CWebLinkButton) + afx_msg void OnClicked(); + afx_msg void OnMouseMove(UINT nFlags, CPoint point); + //}}AFX_MSG + + DECLARE_MESSAGE_MAP() +}; + +///////////////////////////////////////////////////////////////////////////// + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_WEBLINKBUTTON_H__99561EFB_6294_4249_B339_8364DD26EDB5__INCLUDED_) diff --git a/source/sced/resource.h b/source/sced/resource.h index 9cbb4b63bb..7a863f54ec 100755 --- a/source/sced/resource.h +++ b/source/sced/resource.h @@ -1,113 +1,113 @@ -//{{NO_DEPENDENCIES}} -// Microsoft Developer Studio generated include file. -// Used by ScEd.rc -// -#define IDD_ABOUTBOX 100 -#define IDD_PROPPAGE_NAVIGATION 102 -#define IDD_DIALOGBAR_TEXTURETOOLS 103 -#define IDR_MAINFRAME 128 -#define IDR_SCEDTYPE 129 -#define IDD_DIALOG_LIGHTSETTINGS 133 -#define IDD_DIALOGBAR_MODELTOOLS 134 -#define IDD_DIALOGBAR_UNITTOOLS 134 -#define IDB_LOGO 135 -#define IDD_DIALOG_OPTIONS 137 -#define IDD_DIALOGBAR_ELEVATIONTOOLS 138 -#define IDD_DIALOGBAR_UNITPROPERTIES 139 -#define IDD_DIALOG_SIMPLEEDIT 140 -#define IDI_ICON_UNITMODE 141 -#define IDI_ICON_NEWUNIT 142 -#define IDI_ICON_SELECT 143 -#define IDD_DIALOG_MAPSIZE 144 -#define IDB_BITMAP_SELECT 146 -#define IDB_BITMAP_TEXTURETOOLS 148 -#define IDB_BITMAP_ELEVATIONTOOLS 149 -#define IDB_BITMAP_MODELTOOLS 150 -#define IDD_DIALOGBAR_BRUSHSHAPEEDITOR 151 -#define IDD_PROPPAGE_SHADOWS 152 -#define IDB_BITMAP_SELECTUNIT 153 -#define IDD_UNITPROPERTIES_TEXTURES 153 -#define IDB_BITMAP_ADDUNIT 154 -#define IDD_UNITPROPERTIES_ANIMATIONS 154 -#define IDC_BUTTON_SUNCOLOR 1001 -#define IDC_EDIT_MODEL 1001 -#define IDC_BUTTON_TERRAINAMBIENTCOLOR 1002 -#define IDC_EDIT_TEXTURE 1002 -#define IDC_BUTTON_APPLY 1003 -#define IDC_BUTTON_MODELBROWSE 1004 -#define IDC_BUTTON_DIRECTION 1005 -#define IDC_BUTTON_TEXTUREBROWSE 1005 -#define IDC_BUTTON_ELEVATION 1006 -#define IDC_BUTTON_REFRESH 1006 -#define IDC_EDIT_DIRECTION 1007 -#define IDC_EDIT_NAME 1007 -#define IDC_BUTTON_UNITSAMBIENTCOLOR 1008 -#define IDC_BUTTON_BACK 1008 -#define IDC_EDIT_ELEVATION 1009 -#define IDC_SPIN_DIRECTION 1010 -#define IDC_SPIN_ELEVATION 1011 -#define IDC_STATIC_VERSION 1011 -#define IDC_EDIT_ANIMATION 1011 -#define IDC_BUTTON_LAUNCHWFG 1012 -#define IDC_BUTTON_ANIMATIONBROWSE 1012 -#define IDC_SLIDER_BRUSHSIZE 1013 -#define IDC_SLIDER_BRUSHEFFECT 1014 -#define IDC_LIST_TEXTUREBROWSER 1015 -#define IDC_BUTTON_ADD 1016 -#define IDC_BUTTON_EDIT 1017 -#define IDC_STATIC_CURRENTTEXTURE 1018 -#define IDC_STATIC_CURRENTMODEL 1020 -#define IDC_LIST_MODELBROWSER 1021 -#define IDC_LIST_OBJECTBROWSER 1021 -#define IDC_SLIDER_RTSSCROLLSPEED 1023 -#define IDC_RADIO_RAISE 1027 -#define IDC_RADIO_SMOOTH 1028 -#define IDC_EDIT1 1028 -#define IDC_COMBO_TERRAINTYPES 1030 -#define IDC_COMBO1 1030 -#define IDC_RADIO_SMALL 1031 -#define IDC_RADIO_MEDIUM 1032 -#define IDC_COMBO_OBJECTTYPES 1032 -#define IDC_RADIO_LARGE 1033 -#define IDC_BUTTON_SELECT 1033 -#define IDC_RADIO_HUGE 1034 -#define IDC_BUTTON_ELEVATIONTOOLS 1034 -#define IDC_BUTTON_TEXTURETOOLS 1035 -#define IDC_BUTTON_MODELTOOLS 1036 -#define IDC_BUTTON_ADDUNIT 1038 -#define IDC_CHECK_SHADOWS 1039 -#define IDC_BUTTON_SHADOWCOLOR 1040 -#define IDC_SLIDER_SHADOWQUALITY 1041 -#define ID_TERRAIN_LOAD 32772 -#define ID_TERRAIN_RANDOMMAP 32773 -#define ID_LIGHTING_SETTINGS 32774 -#define ID_VIEW_GRID 32778 -#define ID_VIEW_TERRAIN_GRID 32778 -#define ID_VIEW_SCREENSHOT 32779 -#define IDR_TEXTURE_TOOLS 32781 -#define ID_TOOLS_OPTIONS 32782 -#define IDR_ELEVATION_TOOLS 32783 -#define IDR_UNIT_TOOLS 32785 -#define IDR_RESIZE_MAP 32786 -#define ID_VIEW_TERRAIN_WIREFRAME 32787 -#define ID_VIEW_TERRAIN_SOLID 32788 -#define ID_FILE_LOADMAP 32789 -#define ID_FILE_SAVEMAP 32790 -#define ID_VIEW_MODEL_SOLID 32791 -#define ID_VIEW_MODEL_GRID 32792 -#define ID_VIEW_MODEL_WIREFRAME 32793 -#define ID_VIEW_RENDERSTATS 32794 -#define ID_TEST_STOP 32797 -#define ID_TEST_GO 32798 - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_3D_CONTROLS 1 -#define _APS_NEXT_RESOURCE_VALUE 156 -#define _APS_NEXT_COMMAND_VALUE 32799 -#define _APS_NEXT_CONTROL_VALUE 1044 -#define _APS_NEXT_SYMED_VALUE 101 -#endif -#endif +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// Used by ScEd.rc +// +#define IDD_ABOUTBOX 100 +#define IDD_PROPPAGE_NAVIGATION 102 +#define IDD_DIALOGBAR_TEXTURETOOLS 103 +#define IDR_MAINFRAME 128 +#define IDR_SCEDTYPE 129 +#define IDD_DIALOG_LIGHTSETTINGS 133 +#define IDD_DIALOGBAR_MODELTOOLS 134 +#define IDD_DIALOGBAR_UNITTOOLS 134 +#define IDB_LOGO 135 +#define IDD_DIALOG_OPTIONS 137 +#define IDD_DIALOGBAR_ELEVATIONTOOLS 138 +#define IDD_DIALOGBAR_UNITPROPERTIES 139 +#define IDD_DIALOG_SIMPLEEDIT 140 +#define IDI_ICON_UNITMODE 141 +#define IDI_ICON_NEWUNIT 142 +#define IDI_ICON_SELECT 143 +#define IDD_DIALOG_MAPSIZE 144 +#define IDB_BITMAP_SELECT 146 +#define IDB_BITMAP_TEXTURETOOLS 148 +#define IDB_BITMAP_ELEVATIONTOOLS 149 +#define IDB_BITMAP_MODELTOOLS 150 +#define IDD_DIALOGBAR_BRUSHSHAPEEDITOR 151 +#define IDD_PROPPAGE_SHADOWS 152 +#define IDB_BITMAP_SELECTUNIT 153 +#define IDD_UNITPROPERTIES_TEXTURES 153 +#define IDB_BITMAP_ADDUNIT 154 +#define IDD_UNITPROPERTIES_ANIMATIONS 154 +#define IDC_BUTTON_SUNCOLOR 1001 +#define IDC_EDIT_MODEL 1001 +#define IDC_BUTTON_TERRAINAMBIENTCOLOR 1002 +#define IDC_EDIT_TEXTURE 1002 +#define IDC_BUTTON_APPLY 1003 +#define IDC_BUTTON_MODELBROWSE 1004 +#define IDC_BUTTON_DIRECTION 1005 +#define IDC_BUTTON_TEXTUREBROWSE 1005 +#define IDC_BUTTON_ELEVATION 1006 +#define IDC_BUTTON_REFRESH 1006 +#define IDC_EDIT_DIRECTION 1007 +#define IDC_EDIT_NAME 1007 +#define IDC_BUTTON_UNITSAMBIENTCOLOR 1008 +#define IDC_BUTTON_BACK 1008 +#define IDC_EDIT_ELEVATION 1009 +#define IDC_SPIN_DIRECTION 1010 +#define IDC_SPIN_ELEVATION 1011 +#define IDC_STATIC_VERSION 1011 +#define IDC_EDIT_ANIMATION 1011 +#define IDC_BUTTON_LAUNCHWFG 1012 +#define IDC_BUTTON_ANIMATIONBROWSE 1012 +#define IDC_SLIDER_BRUSHSIZE 1013 +#define IDC_SLIDER_BRUSHEFFECT 1014 +#define IDC_LIST_TEXTUREBROWSER 1015 +#define IDC_BUTTON_ADD 1016 +#define IDC_BUTTON_EDIT 1017 +#define IDC_STATIC_CURRENTTEXTURE 1018 +#define IDC_STATIC_CURRENTMODEL 1020 +#define IDC_LIST_MODELBROWSER 1021 +#define IDC_LIST_OBJECTBROWSER 1021 +#define IDC_SLIDER_RTSSCROLLSPEED 1023 +#define IDC_RADIO_RAISE 1027 +#define IDC_RADIO_SMOOTH 1028 +#define IDC_EDIT1 1028 +#define IDC_COMBO_TERRAINTYPES 1030 +#define IDC_COMBO1 1030 +#define IDC_RADIO_SMALL 1031 +#define IDC_RADIO_MEDIUM 1032 +#define IDC_COMBO_OBJECTTYPES 1032 +#define IDC_RADIO_LARGE 1033 +#define IDC_BUTTON_SELECT 1033 +#define IDC_RADIO_HUGE 1034 +#define IDC_BUTTON_ELEVATIONTOOLS 1034 +#define IDC_BUTTON_TEXTURETOOLS 1035 +#define IDC_BUTTON_MODELTOOLS 1036 +#define IDC_BUTTON_ADDUNIT 1038 +#define IDC_CHECK_SHADOWS 1039 +#define IDC_BUTTON_SHADOWCOLOR 1040 +#define IDC_SLIDER_SHADOWQUALITY 1041 +#define ID_TERRAIN_LOAD 32772 +#define ID_TERRAIN_RANDOMMAP 32773 +#define ID_LIGHTING_SETTINGS 32774 +#define ID_VIEW_GRID 32778 +#define ID_VIEW_TERRAIN_GRID 32778 +#define ID_VIEW_SCREENSHOT 32779 +#define IDR_TEXTURE_TOOLS 32781 +#define ID_TOOLS_OPTIONS 32782 +#define IDR_ELEVATION_TOOLS 32783 +#define IDR_UNIT_TOOLS 32785 +#define IDR_RESIZE_MAP 32786 +#define ID_VIEW_TERRAIN_WIREFRAME 32787 +#define ID_VIEW_TERRAIN_SOLID 32788 +#define ID_FILE_LOADMAP 32789 +#define ID_FILE_SAVEMAP 32790 +#define ID_VIEW_MODEL_SOLID 32791 +#define ID_VIEW_MODEL_GRID 32792 +#define ID_VIEW_MODEL_WIREFRAME 32793 +#define ID_VIEW_RENDERSTATS 32794 +#define ID_TEST_STOP 32797 +#define ID_TEST_GO 32798 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_3D_CONTROLS 1 +#define _APS_NEXT_RESOURCE_VALUE 156 +#define _APS_NEXT_COMMAND_VALUE 32799 +#define _APS_NEXT_CONTROL_VALUE 1044 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/source/scripting/ScriptCustomTypes.cpp b/source/scripting/ScriptCustomTypes.cpp index 00e061d785..1543087fc4 100755 --- a/source/scripting/ScriptCustomTypes.cpp +++ b/source/scripting/ScriptCustomTypes.cpp @@ -1,38 +1,38 @@ - -#include "ScriptingHost.h" - -// POINT2D - -JSClass Point2dClass = -{ - "Point2d", 0, - JS_PropertyStub, JS_PropertyStub, - JS_PropertyStub, JS_PropertyStub, - JS_EnumerateStub, JS_ResolveStub, - JS_ConvertStub, JS_FinalizeStub -}; - -JSPropertySpec Point2dProperties[] = -{ - {"x", 0, JSPROP_ENUMERATE}, - {"y", 1, JSPROP_ENUMERATE}, - {0} -}; - -JSBool Point2d_Constructor(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) -{ - if (argc == 2) - { - g_ScriptingHost.SetObjectProperty(obj, "x", argv[0]); - g_ScriptingHost.SetObjectProperty(obj, "y", argv[1]); - } - else - { - jsval zero = INT_TO_JSVAL(0); - g_ScriptingHost.SetObjectProperty(obj, "x", zero); - g_ScriptingHost.SetObjectProperty(obj, "y", zero); - } - - return JS_TRUE; -} - + +#include "ScriptingHost.h" + +// POINT2D + +JSClass Point2dClass = +{ + "Point2d", 0, + JS_PropertyStub, JS_PropertyStub, + JS_PropertyStub, JS_PropertyStub, + JS_EnumerateStub, JS_ResolveStub, + JS_ConvertStub, JS_FinalizeStub +}; + +JSPropertySpec Point2dProperties[] = +{ + {"x", 0, JSPROP_ENUMERATE}, + {"y", 1, JSPROP_ENUMERATE}, + {0} +}; + +JSBool Point2d_Constructor(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + if (argc == 2) + { + g_ScriptingHost.SetObjectProperty(obj, "x", argv[0]); + g_ScriptingHost.SetObjectProperty(obj, "y", argv[1]); + } + else + { + jsval zero = INT_TO_JSVAL(0); + g_ScriptingHost.SetObjectProperty(obj, "x", zero); + g_ScriptingHost.SetObjectProperty(obj, "y", zero); + } + + return JS_TRUE; +} + diff --git a/source/scripting/ScriptCustomTypes.h b/source/scripting/ScriptCustomTypes.h index c3fa5dee3d..1b387f9c64 100755 --- a/source/scripting/ScriptCustomTypes.h +++ b/source/scripting/ScriptCustomTypes.h @@ -1,17 +1,17 @@ - -#ifndef _SCRIPTCUSTOMTYPES_H_ -#define _SCRIPTCUSTOMTYPES_H_ - -// Custom object types - -// Whilst Point2d is fully coded, it is never registered so is not available in script -// This is mostly as a demonstration of what you need to code to add a new type - -// VECTOR2D -extern JSClass Point2dClass; -extern JSPropertySpec Point2dProperties[]; -JSBool Point2d_Constructor(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval); - - - -#endif + +#ifndef _SCRIPTCUSTOMTYPES_H_ +#define _SCRIPTCUSTOMTYPES_H_ + +// Custom object types + +// Whilst Point2d is fully coded, it is never registered so is not available in script +// This is mostly as a demonstration of what you need to code to add a new type + +// VECTOR2D +extern JSClass Point2dClass; +extern JSPropertySpec Point2dProperties[]; +JSBool Point2d_Constructor(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval); + + + +#endif diff --git a/source/scripting/ScriptGlue.cpp b/source/scripting/ScriptGlue.cpp index 48dd669b7e..947788560c 100755 --- a/source/scripting/ScriptGlue.cpp +++ b/source/scripting/ScriptGlue.cpp @@ -1,48 +1,48 @@ - -#include "ScriptGlue.h" - -// Parameters for the table are: - -// 1: The name the function will be called as from script -// 2: The number of aguments this function expects -// 3: Depreciated, always zero -// 4: Reserved for future use, always zero - -JSFunctionSpec ScriptFunctionTable[] = -{ - {"WriteLog", WriteLog, 1, 0, 0}, - - {0, 0, 0, 0, 0}, -}; - -// Allow scripts to output to the global log file -JSBool WriteLog(JSContext * context, JSObject * globalObject, unsigned int argc, jsval * argv, jsval * rval) -{ - if (argc < 1) - return JS_FALSE; - - for (int i = 0; i < (int)argc; i++) - { - if (JSVAL_IS_INT(argv[i])) - { - printf("%d", JSVAL_TO_INT(argv[i])); - } - - if (JSVAL_IS_DOUBLE(argv[i])) - { - double d = g_ScriptingHost.ValueToDouble(argv[i]); - printf("%e", d); - } - - if (JSVAL_IS_STRING(argv[i])) - { - JSString * str = JS_ValueToString(context, argv[i]); - char * chars = JS_GetStringBytes(str); - printf(chars); - } - } - - printf("\n"); - - return JS_TRUE; -} + +#include "ScriptGlue.h" + +// Parameters for the table are: + +// 1: The name the function will be called as from script +// 2: The number of aguments this function expects +// 3: Depreciated, always zero +// 4: Reserved for future use, always zero + +JSFunctionSpec ScriptFunctionTable[] = +{ + {"WriteLog", WriteLog, 1, 0, 0}, + + {0, 0, 0, 0, 0}, +}; + +// Allow scripts to output to the global log file +JSBool WriteLog(JSContext * context, JSObject * globalObject, unsigned int argc, jsval * argv, jsval * rval) +{ + if (argc < 1) + return JS_FALSE; + + for (int i = 0; i < (int)argc; i++) + { + if (JSVAL_IS_INT(argv[i])) + { + printf("%d", JSVAL_TO_INT(argv[i])); + } + + if (JSVAL_IS_DOUBLE(argv[i])) + { + double d = g_ScriptingHost.ValueToDouble(argv[i]); + printf("%e", d); + } + + if (JSVAL_IS_STRING(argv[i])) + { + JSString * str = JS_ValueToString(context, argv[i]); + char * chars = JS_GetStringBytes(str); + printf(chars); + } + } + + printf("\n"); + + return JS_TRUE; +} diff --git a/source/scripting/ScriptGlue.h b/source/scripting/ScriptGlue.h index e4586e5de7..140ccbf584 100755 --- a/source/scripting/ScriptGlue.h +++ b/source/scripting/ScriptGlue.h @@ -1,11 +1,11 @@ - -#ifndef _SCRIPTGLUE_H_ -#define _SCRIPTGLUE_H_ - -#include "ScriptingHost.h" - -JSBool WriteLog(JSContext * context, JSObject * globalObject, unsigned int argc, jsval *argv, jsval *rval); - -JSFunctionSpec ScriptFunctionTable[]; - -#endif + +#ifndef _SCRIPTGLUE_H_ +#define _SCRIPTGLUE_H_ + +#include "ScriptingHost.h" + +JSBool WriteLog(JSContext * context, JSObject * globalObject, unsigned int argc, jsval *argv, jsval *rval); + +JSFunctionSpec ScriptFunctionTable[]; + +#endif diff --git a/source/scripting/ScriptingHost.cpp b/source/scripting/ScriptingHost.cpp index 6805af87e9..e7bef59300 100755 --- a/source/scripting/ScriptingHost.cpp +++ b/source/scripting/ScriptingHost.cpp @@ -1,319 +1,319 @@ - -#include "ScriptingHost.h" -#include "ScriptGlue.h" -#include -#include -#include - -#pragma comment (lib, "js32.lib") - -namespace -{ - const int RUNTIME_MEMORY_ALLOWANCE = 16 * 1024 * 1024; - const int STACK_CHUNK_SIZE = 16 * 1024; - - JSClass GlobalClass = - { - "global", 0, - JS_PropertyStub, JS_PropertyStub, - JS_PropertyStub, JS_PropertyStub, - JS_EnumerateStub, JS_ResolveStub, - JS_ConvertStub, JS_FinalizeStub - }; -} - -ScriptingHost::ScriptingHost() : m_RunTime(NULL), m_Context(NULL), m_GlobalObject(NULL) -{ - m_RunTime = JS_NewRuntime(RUNTIME_MEMORY_ALLOWANCE); - - if (m_RunTime == NULL) - { - throw (std::string("ScriptingHost: Failed to create JavaScript runtime")); - } - - m_Context = JS_NewContext(m_RunTime, STACK_CHUNK_SIZE); - - if (m_Context == NULL) - { - throw (std::string("ScriptingHost: Failed to create JavaScript context")); - } - - JS_SetErrorReporter(m_Context, ScriptingHost::ErrorReporter); - - m_GlobalObject = JS_NewObject(m_Context, &GlobalClass, NULL, NULL); - - if (m_GlobalObject == NULL) - { - throw (std::string("ScriptingHost: Failed to create global object")); - } - - if (JS_InitStandardClasses(m_Context, m_GlobalObject) == JSVAL_FALSE) - { - throw (std::string("ScriptingHost: Failed to init standard classes")); - } - - if (JS_DefineFunctions(m_Context, m_GlobalObject, ScriptFunctionTable) == JS_FALSE) - { - throw (std::string("ScriptingHost: Failed to setup native functions")); - } - - std::cout << "Scripting environment initialized" << std::endl; -} - -ScriptingHost::~ScriptingHost() -{ - if (m_Context != NULL) - { - JS_DestroyContext(m_Context); - m_Context = NULL; - } - - if (m_RunTime != NULL) - { - JS_DestroyRuntime(m_RunTime); - m_RunTime = NULL; - } -} - -void ScriptingHost::LoadScriptFromDisk(const std::string & fileName) -{ - std::string script; - std::string line; - - std::ifstream scriptFile(fileName.c_str()); - - if (scriptFile.is_open() == false) - { - throw (std::string("Could not open file: ") + fileName); - } - - while (scriptFile.eof() == false) - { - std::getline(scriptFile, line); - script += line; - script += '\n'; - } - - jsval rval; - JSBool ok = JS_EvaluateScript(m_Context, m_GlobalObject, script.c_str(), (unsigned int)script.length(), fileName.c_str(), 0, &rval); - - if (ok == JS_FALSE) - { - throw (std::string("Error loading script from disk: ") + fileName); - } -} - -jsval ScriptingHost::CallFunction(const std::string & functionName, jsval * params, int numParams) -{ - jsval result; - - JSBool ok = JS_CallFunctionName(m_Context, m_GlobalObject, functionName.c_str(), numParams, params, &result); - - if (ok == JS_FALSE) - { - throw (std::string("Failure whilst calling script funtion: ") + functionName); - } - - return result; -} - -jsval ScriptingHost::ExecuteScript(const std::string & script) -{ - jsval rval; - - JSBool ok = JS_EvaluateScript(m_Context, m_GlobalObject, script.c_str(), (int)script.length(), "Console", 0, &rval); - - return rval; -} - -void ScriptingHost::RegisterFunction(const std::string & functionName, JSNative function, int numArgs) -{ - JSFunction * func = JS_DefineFunction(m_Context, m_GlobalObject, functionName.c_str(), function, numArgs, 0); - - if (func == NULL) - { - throw (std::string("Could not register function ") + functionName); - } -} - -void ScriptingHost::DefineConstant(const std::string & name, int value) -{ - // First remove this constant if it already exists - JS_DeleteProperty(m_Context, m_GlobalObject, name.c_str()); - - JSBool ok = JS_DefineProperty( m_Context, m_GlobalObject, name.c_str(), INT_TO_JSVAL(value), - NULL, NULL, JSPROP_READONLY); - - if (ok == JS_FALSE) - { - throw (std::string("Could not create constant")); - } -} - -void ScriptingHost::DefineConstant(const std::string & name, double value) -{ - // First remove this constant if it already exists - JS_DeleteProperty(m_Context, m_GlobalObject, name.c_str()); - - struct JSConstDoubleSpec spec[2]; - - spec[0].name = name.c_str(); - spec[0].dval = value; - spec[0].flags = JSPROP_READONLY; - - spec[1].name = 0; - spec[1].dval = 0.0; - spec[1].flags = 0; - - JSBool ok = JS_DefineConstDoubles(m_Context, m_GlobalObject, spec); - - if (ok == JS_FALSE) - { - throw (std::string("Could not create constant")); - } -} - -void ScriptingHost::DefineCustomObjectType(JSClass *clasp, JSNative constructor, uintN minArgs, JSPropertySpec *ps, JSFunctionSpec *fs, JSPropertySpec *static_ps, JSFunctionSpec *static_fs) -{ - std::string typeName = clasp->name; - - if (m_CustomObjectTypes.find(typeName) != m_CustomObjectTypes.end()) - { - // This type already exists - throw std::string("Type already exists"); - } - - JSObject * obj = JS_InitClass( m_Context, m_GlobalObject, 0, - clasp, - constructor, minArgs, // Constructor, min args - ps, fs, // Properties, methods - static_ps, static_fs); // Constructor properties, methods - - if (obj != NULL) - { - CustomType type; - - type.m_Object = obj; - type.m_Class = clasp; - - m_CustomObjectTypes[typeName] = type; - } - else - { - throw std::string("Type creation failed"); - } -} - -JSObject * ScriptingHost::CreateCustomObject(const std::string & typeName) -{ - std::map < std::string, CustomType > ::iterator it = m_CustomObjectTypes.find(typeName); - - if (it == m_CustomObjectTypes.end()) - { - throw std::string("Tried to create a type that doesn't exist"); - } - - return JS_NewObject(m_Context, (*it).second.m_Class, (*it).second.m_Object, NULL); - -} - -void ScriptingHost::SetObjectProperty(JSObject * object, const std::string & propertyName, jsval value) -{ - JS_SetProperty(m_Context, object, propertyName.c_str(), &value); -} - -int ScriptingHost::ValueToInt(const jsval value) -{ - int i = 0; - - JSBool ok = JS_ValueToInt32(m_Context, value, (int32*)&i); - - if (ok == JS_FALSE) - { - throw (std::string("Convert to int failed")); - } - - return i; -} - -bool ScriptingHost::ValueToBool(const jsval value) -{ - JSBool b; - - JSBool ok = JS_ValueToBoolean(m_Context, value, &b); - - if (ok == JS_FALSE) - { - throw (std::string("Convert to bool failed")); - } - - return b == JS_TRUE; -} - -std::string ScriptingHost::ValueToString(const jsval value) -{ - JSString * string = JS_ValueToString(m_Context, value); - - return std::string(JS_GetStringBytes(string)); -} - -double ScriptingHost::ValueToDouble(const jsval value) -{ - jsdouble d; - - JSBool ok = JS_ValueToNumber(m_Context, value, &d); - - if (ok == JS_FALSE) - { - throw (std::string("Convert to double failed")); - } - - return d; -} - -void ScriptingHost::ErrorReporter(JSContext * context, const char * message, JSErrorReport * report) -{ - if (report->filename != NULL) - { - std::cout << report->filename << " (" << report->lineno << ") "; - } - - if (message != NULL) - { - std::cout << message << std::endl; - } - else - { - std::cout << "No error message available" << std::endl; - } -} - -void ScriptingHost::Tick(float timeElapsed) -{ - if (timeElapsed > 0.2f) timeElapsed = 0.2f; - - for (int i = 0; i < (int)m_DelayedScripts.size(); ) - { - m_DelayedScripts[i].m_SecondsToExecution -= timeElapsed; - - if (m_DelayedScripts[i].m_SecondsToExecution <= 0.0f) - { - this->ExecuteScript(m_DelayedScripts[i].m_FunctionName); - m_DelayedScripts.erase(m_DelayedScripts.begin() + i); - } - else - { - i++; - } - } -} - -void ScriptingHost::AddDelayedScript(const std::string & functionName, float delaySeconds) -{ - m_DelayedScripts.push_back(DelayedScriptExecutor(functionName, delaySeconds)); -} - -void ScriptingHost::_CollectGarbage() -{ - JS_GC(m_Context); -} + +#include "ScriptingHost.h" +#include "ScriptGlue.h" +#include +#include +#include + +#pragma comment (lib, "js32.lib") + +namespace +{ + const int RUNTIME_MEMORY_ALLOWANCE = 16 * 1024 * 1024; + const int STACK_CHUNK_SIZE = 16 * 1024; + + JSClass GlobalClass = + { + "global", 0, + JS_PropertyStub, JS_PropertyStub, + JS_PropertyStub, JS_PropertyStub, + JS_EnumerateStub, JS_ResolveStub, + JS_ConvertStub, JS_FinalizeStub + }; +} + +ScriptingHost::ScriptingHost() : m_RunTime(NULL), m_Context(NULL), m_GlobalObject(NULL) +{ + m_RunTime = JS_NewRuntime(RUNTIME_MEMORY_ALLOWANCE); + + if (m_RunTime == NULL) + { + throw (std::string("ScriptingHost: Failed to create JavaScript runtime")); + } + + m_Context = JS_NewContext(m_RunTime, STACK_CHUNK_SIZE); + + if (m_Context == NULL) + { + throw (std::string("ScriptingHost: Failed to create JavaScript context")); + } + + JS_SetErrorReporter(m_Context, ScriptingHost::ErrorReporter); + + m_GlobalObject = JS_NewObject(m_Context, &GlobalClass, NULL, NULL); + + if (m_GlobalObject == NULL) + { + throw (std::string("ScriptingHost: Failed to create global object")); + } + + if (JS_InitStandardClasses(m_Context, m_GlobalObject) == JSVAL_FALSE) + { + throw (std::string("ScriptingHost: Failed to init standard classes")); + } + + if (JS_DefineFunctions(m_Context, m_GlobalObject, ScriptFunctionTable) == JS_FALSE) + { + throw (std::string("ScriptingHost: Failed to setup native functions")); + } + + std::cout << "Scripting environment initialized" << std::endl; +} + +ScriptingHost::~ScriptingHost() +{ + if (m_Context != NULL) + { + JS_DestroyContext(m_Context); + m_Context = NULL; + } + + if (m_RunTime != NULL) + { + JS_DestroyRuntime(m_RunTime); + m_RunTime = NULL; + } +} + +void ScriptingHost::LoadScriptFromDisk(const std::string & fileName) +{ + std::string script; + std::string line; + + std::ifstream scriptFile(fileName.c_str()); + + if (scriptFile.is_open() == false) + { + throw (std::string("Could not open file: ") + fileName); + } + + while (scriptFile.eof() == false) + { + std::getline(scriptFile, line); + script += line; + script += '\n'; + } + + jsval rval; + JSBool ok = JS_EvaluateScript(m_Context, m_GlobalObject, script.c_str(), (unsigned int)script.length(), fileName.c_str(), 0, &rval); + + if (ok == JS_FALSE) + { + throw (std::string("Error loading script from disk: ") + fileName); + } +} + +jsval ScriptingHost::CallFunction(const std::string & functionName, jsval * params, int numParams) +{ + jsval result; + + JSBool ok = JS_CallFunctionName(m_Context, m_GlobalObject, functionName.c_str(), numParams, params, &result); + + if (ok == JS_FALSE) + { + throw (std::string("Failure whilst calling script funtion: ") + functionName); + } + + return result; +} + +jsval ScriptingHost::ExecuteScript(const std::string & script) +{ + jsval rval; + + JSBool ok = JS_EvaluateScript(m_Context, m_GlobalObject, script.c_str(), (int)script.length(), "Console", 0, &rval); + + return rval; +} + +void ScriptingHost::RegisterFunction(const std::string & functionName, JSNative function, int numArgs) +{ + JSFunction * func = JS_DefineFunction(m_Context, m_GlobalObject, functionName.c_str(), function, numArgs, 0); + + if (func == NULL) + { + throw (std::string("Could not register function ") + functionName); + } +} + +void ScriptingHost::DefineConstant(const std::string & name, int value) +{ + // First remove this constant if it already exists + JS_DeleteProperty(m_Context, m_GlobalObject, name.c_str()); + + JSBool ok = JS_DefineProperty( m_Context, m_GlobalObject, name.c_str(), INT_TO_JSVAL(value), + NULL, NULL, JSPROP_READONLY); + + if (ok == JS_FALSE) + { + throw (std::string("Could not create constant")); + } +} + +void ScriptingHost::DefineConstant(const std::string & name, double value) +{ + // First remove this constant if it already exists + JS_DeleteProperty(m_Context, m_GlobalObject, name.c_str()); + + struct JSConstDoubleSpec spec[2]; + + spec[0].name = name.c_str(); + spec[0].dval = value; + spec[0].flags = JSPROP_READONLY; + + spec[1].name = 0; + spec[1].dval = 0.0; + spec[1].flags = 0; + + JSBool ok = JS_DefineConstDoubles(m_Context, m_GlobalObject, spec); + + if (ok == JS_FALSE) + { + throw (std::string("Could not create constant")); + } +} + +void ScriptingHost::DefineCustomObjectType(JSClass *clasp, JSNative constructor, uintN minArgs, JSPropertySpec *ps, JSFunctionSpec *fs, JSPropertySpec *static_ps, JSFunctionSpec *static_fs) +{ + std::string typeName = clasp->name; + + if (m_CustomObjectTypes.find(typeName) != m_CustomObjectTypes.end()) + { + // This type already exists + throw std::string("Type already exists"); + } + + JSObject * obj = JS_InitClass( m_Context, m_GlobalObject, 0, + clasp, + constructor, minArgs, // Constructor, min args + ps, fs, // Properties, methods + static_ps, static_fs); // Constructor properties, methods + + if (obj != NULL) + { + CustomType type; + + type.m_Object = obj; + type.m_Class = clasp; + + m_CustomObjectTypes[typeName] = type; + } + else + { + throw std::string("Type creation failed"); + } +} + +JSObject * ScriptingHost::CreateCustomObject(const std::string & typeName) +{ + std::map < std::string, CustomType > ::iterator it = m_CustomObjectTypes.find(typeName); + + if (it == m_CustomObjectTypes.end()) + { + throw std::string("Tried to create a type that doesn't exist"); + } + + return JS_NewObject(m_Context, (*it).second.m_Class, (*it).second.m_Object, NULL); + +} + +void ScriptingHost::SetObjectProperty(JSObject * object, const std::string & propertyName, jsval value) +{ + JS_SetProperty(m_Context, object, propertyName.c_str(), &value); +} + +int ScriptingHost::ValueToInt(const jsval value) +{ + int i = 0; + + JSBool ok = JS_ValueToInt32(m_Context, value, (int32*)&i); + + if (ok == JS_FALSE) + { + throw (std::string("Convert to int failed")); + } + + return i; +} + +bool ScriptingHost::ValueToBool(const jsval value) +{ + JSBool b; + + JSBool ok = JS_ValueToBoolean(m_Context, value, &b); + + if (ok == JS_FALSE) + { + throw (std::string("Convert to bool failed")); + } + + return b == JS_TRUE; +} + +std::string ScriptingHost::ValueToString(const jsval value) +{ + JSString * string = JS_ValueToString(m_Context, value); + + return std::string(JS_GetStringBytes(string)); +} + +double ScriptingHost::ValueToDouble(const jsval value) +{ + jsdouble d; + + JSBool ok = JS_ValueToNumber(m_Context, value, &d); + + if (ok == JS_FALSE) + { + throw (std::string("Convert to double failed")); + } + + return d; +} + +void ScriptingHost::ErrorReporter(JSContext * context, const char * message, JSErrorReport * report) +{ + if (report->filename != NULL) + { + std::cout << report->filename << " (" << report->lineno << ") "; + } + + if (message != NULL) + { + std::cout << message << std::endl; + } + else + { + std::cout << "No error message available" << std::endl; + } +} + +void ScriptingHost::Tick(float timeElapsed) +{ + if (timeElapsed > 0.2f) timeElapsed = 0.2f; + + for (int i = 0; i < (int)m_DelayedScripts.size(); ) + { + m_DelayedScripts[i].m_SecondsToExecution -= timeElapsed; + + if (m_DelayedScripts[i].m_SecondsToExecution <= 0.0f) + { + this->ExecuteScript(m_DelayedScripts[i].m_FunctionName); + m_DelayedScripts.erase(m_DelayedScripts.begin() + i); + } + else + { + i++; + } + } +} + +void ScriptingHost::AddDelayedScript(const std::string & functionName, float delaySeconds) +{ + m_DelayedScripts.push_back(DelayedScriptExecutor(functionName, delaySeconds)); +} + +void ScriptingHost::_CollectGarbage() +{ + JS_GC(m_Context); +} diff --git a/source/scripting/ScriptingHost.h b/source/scripting/ScriptingHost.h index 4c82c8a995..d54b8a8bbe 100755 --- a/source/scripting/ScriptingHost.h +++ b/source/scripting/ScriptingHost.h @@ -1,83 +1,83 @@ - -#ifndef _SCRIPTINGHOST_H_ -#define _SCRIPTINGHOST_H_ - -#define XP_WIN -#include - -#include -#include -#include - -#include "Singleton.h" - -class DelayedScriptExecutor -{ -public: - DelayedScriptExecutor(const std::string & functionName, float delaySeconds) - : m_FunctionName(functionName), m_SecondsToExecution(delaySeconds) - { - } - - std::string m_FunctionName; - float m_SecondsToExecution; -}; - -class CustomType -{ -public: - JSObject * m_Object; - JSClass * m_Class; -}; - -class ScriptingHost : public Singleton < ScriptingHost > -{ -private: - JSRuntime * m_RunTime; - JSContext * m_Context; - JSObject * m_GlobalObject; - - JSErrorReport m_ErrorReport; - - std::vector < DelayedScriptExecutor > m_DelayedScripts; - std::map < std::string, CustomType > m_CustomObjectTypes; - - void _CollectGarbage(); - -public: - - ScriptingHost(); - ~ScriptingHost(); - - void LoadScriptFromDisk(const std::string & fileName); - - jsval CallFunction(const std::string & functionName, jsval * params, int numParams); - - jsval ExecuteScript(const std::string & script); - - void RegisterFunction(const std::string & functionName, JSNative function, int numArgs); - - void DefineConstant(const std::string & name, int value); - void DefineConstant(const std::string & name, double value); - - void DefineCustomObjectType(JSClass *clasp, JSNative constructor, uintN nargs, JSPropertySpec *ps, JSFunctionSpec *fs, JSPropertySpec *static_ps, JSFunctionSpec *static_fs); - - JSObject * CreateCustomObject(const std::string & typeName); - - void SetObjectProperty(JSObject * object, const std::string & propertyName, jsval value); - - int ValueToInt(const jsval value); - bool ValueToBool(const jsval value); - std::string ValueToString(const jsval value); - double ValueToDouble(const jsval value); - - void Tick(float timeElapsed); - - void AddDelayedScript(const std::string & functionName, float delaySeconds); - - static void ErrorReporter(JSContext * context, const char * message, JSErrorReport * report); -}; - -#define g_ScriptingHost ScriptingHost::GetSingleton() - -#endif + +#ifndef _SCRIPTINGHOST_H_ +#define _SCRIPTINGHOST_H_ + +#define XP_WIN +#include + +#include +#include +#include + +#include "Singleton.h" + +class DelayedScriptExecutor +{ +public: + DelayedScriptExecutor(const std::string & functionName, float delaySeconds) + : m_FunctionName(functionName), m_SecondsToExecution(delaySeconds) + { + } + + std::string m_FunctionName; + float m_SecondsToExecution; +}; + +class CustomType +{ +public: + JSObject * m_Object; + JSClass * m_Class; +}; + +class ScriptingHost : public Singleton < ScriptingHost > +{ +private: + JSRuntime * m_RunTime; + JSContext * m_Context; + JSObject * m_GlobalObject; + + JSErrorReport m_ErrorReport; + + std::vector < DelayedScriptExecutor > m_DelayedScripts; + std::map < std::string, CustomType > m_CustomObjectTypes; + + void _CollectGarbage(); + +public: + + ScriptingHost(); + ~ScriptingHost(); + + void LoadScriptFromDisk(const std::string & fileName); + + jsval CallFunction(const std::string & functionName, jsval * params, int numParams); + + jsval ExecuteScript(const std::string & script); + + void RegisterFunction(const std::string & functionName, JSNative function, int numArgs); + + void DefineConstant(const std::string & name, int value); + void DefineConstant(const std::string & name, double value); + + void DefineCustomObjectType(JSClass *clasp, JSNative constructor, uintN nargs, JSPropertySpec *ps, JSFunctionSpec *fs, JSPropertySpec *static_ps, JSFunctionSpec *static_fs); + + JSObject * CreateCustomObject(const std::string & typeName); + + void SetObjectProperty(JSObject * object, const std::string & propertyName, jsval value); + + int ValueToInt(const jsval value); + bool ValueToBool(const jsval value); + std::string ValueToString(const jsval value); + double ValueToDouble(const jsval value); + + void Tick(float timeElapsed); + + void AddDelayedScript(const std::string & functionName, float delaySeconds); + + static void ErrorReporter(JSContext * context, const char * message, JSErrorReport * report); +}; + +#define g_ScriptingHost ScriptingHost::GetSingleton() + +#endif diff --git a/source/tools/pmdexp/DllEntry.cpp b/source/tools/pmdexp/DllEntry.cpp index 6ac07785bc..9ad7e08bcd 100755 --- a/source/tools/pmdexp/DllEntry.cpp +++ b/source/tools/pmdexp/DllEntry.cpp @@ -1,125 +1,125 @@ -/********************************************************************** - *< - FILE: DllEntry.cpp - - DESCRIPTION: Contains the Dll Entry stuff - - CREATED BY: - - HISTORY: - - *> Copyright (c) 2000, All Rights Reserved. - **********************************************************************/ -#include "PMDExp.h" -#include "PSAExp.h" -#include "PSProp.h" -#include "MaxInc.h" - - -#define PMDEXP_CLASS_ID Class_ID(0x71d92656, 0x136330c5) -#define PSAEXP_CLASS_ID Class_ID(0x6cf86c73, 0x54e0844) - -HINSTANCE hInstance; -static int controlsInit = FALSE; - -TCHAR* GetString(int id) -{ - static TCHAR buf[256]; - - if (hInstance) { - if (!LoadString(hInstance, id, buf, sizeof(buf))) { - return NULL; - } - return buf; - } - return NULL; -} - -////////////////////////////////////////////////////////////////////////////////////// -// PMDExpClassDesc: required class to expose PMDExp to MAX -class PMDExpClassDesc : public ClassDesc2 -{ -public: - int IsPublic() { return TRUE; } - void * Create(BOOL loading = FALSE) { return new PMDExp(); } - const TCHAR * ClassName() { return GetString(IDS_PSA_CLASS_NAME); } - SClass_ID SuperClassID() { return SCENE_EXPORT_CLASS_ID; } - Class_ID ClassID() { return PMDEXP_CLASS_ID; } - const TCHAR* Category() { return GetString(IDS_CATEGORY); } - - const TCHAR* InternalName() { return _T("PMDExp"); } - HINSTANCE HInstance() { return hInstance; } - -}; - -static PMDExpClassDesc PMDExpDesc; -ClassDesc2* GetPMDExpDesc() { return &PMDExpDesc; } - -////////////////////////////////////////////////////////////////////////////////////// -// PSAExpClassDesc: required class to expose PSAExp to MAX -class PSAExpClassDesc : public ClassDesc2 -{ -public: - int IsPublic() { return TRUE; } - void * Create(BOOL loading = FALSE) { return new PSAExp(); } - const TCHAR * ClassName() { return GetString(IDS_PSA_CLASS_NAME); } - SClass_ID SuperClassID() { return SCENE_EXPORT_CLASS_ID; } - Class_ID ClassID() { return PSAEXP_CLASS_ID; } - const TCHAR* Category() { return GetString(IDS_CATEGORY); } - - const TCHAR* InternalName() { return _T("PSAExp"); } - HINSTANCE HInstance() { return hInstance; } - -}; - -static PSAExpClassDesc PSAExpDesc; -ClassDesc2* GetPSAExpDesc() { return &PSAExpDesc; } - - - - -BOOL WINAPI DllMain(HINSTANCE hinstDLL,ULONG fdwReason,LPVOID lpvReserved) -{ - hInstance = hinstDLL; // Hang on to this DLL's instance handle. - - if (!controlsInit) { - controlsInit = TRUE; - InitCustomControls(hInstance); // Initialize MAX's custom controls - InitCommonControls(); // Initialize Win95 controls - } - - return (TRUE); -} - - -__declspec(dllexport) const TCHAR* LibDescription() -{ - return GetString(IDS_LIBDESCRIPTION); -} - -__declspec(dllexport) int LibNumberClasses() -{ - return 3; -} - -__declspec(dllexport) ClassDesc* LibClassDesc(int i) -{ - switch(i) { - case 0: return GetPMDExpDesc(); - case 1: return GetPSAExpDesc(); - case 2: return GetPSPropDesc(); - default: return 0; - } -} - -__declspec(dllexport) ULONG LibVersion() -{ - return VERSION_3DSMAX; -} - -__declspec( dllexport ) ULONG CanAutoDefer() -{ - return 1; -} - - +/********************************************************************** + *< + FILE: DllEntry.cpp + + DESCRIPTION: Contains the Dll Entry stuff + + CREATED BY: + + HISTORY: + + *> Copyright (c) 2000, All Rights Reserved. + **********************************************************************/ +#include "PMDExp.h" +#include "PSAExp.h" +#include "PSProp.h" +#include "MaxInc.h" + + +#define PMDEXP_CLASS_ID Class_ID(0x71d92656, 0x136330c5) +#define PSAEXP_CLASS_ID Class_ID(0x6cf86c73, 0x54e0844) + +HINSTANCE hInstance; +static int controlsInit = FALSE; + +TCHAR* GetString(int id) +{ + static TCHAR buf[256]; + + if (hInstance) { + if (!LoadString(hInstance, id, buf, sizeof(buf))) { + return NULL; + } + return buf; + } + return NULL; +} + +////////////////////////////////////////////////////////////////////////////////////// +// PMDExpClassDesc: required class to expose PMDExp to MAX +class PMDExpClassDesc : public ClassDesc2 +{ +public: + int IsPublic() { return TRUE; } + void * Create(BOOL loading = FALSE) { return new PMDExp(); } + const TCHAR * ClassName() { return GetString(IDS_PSA_CLASS_NAME); } + SClass_ID SuperClassID() { return SCENE_EXPORT_CLASS_ID; } + Class_ID ClassID() { return PMDEXP_CLASS_ID; } + const TCHAR* Category() { return GetString(IDS_CATEGORY); } + + const TCHAR* InternalName() { return _T("PMDExp"); } + HINSTANCE HInstance() { return hInstance; } + +}; + +static PMDExpClassDesc PMDExpDesc; +ClassDesc2* GetPMDExpDesc() { return &PMDExpDesc; } + +////////////////////////////////////////////////////////////////////////////////////// +// PSAExpClassDesc: required class to expose PSAExp to MAX +class PSAExpClassDesc : public ClassDesc2 +{ +public: + int IsPublic() { return TRUE; } + void * Create(BOOL loading = FALSE) { return new PSAExp(); } + const TCHAR * ClassName() { return GetString(IDS_PSA_CLASS_NAME); } + SClass_ID SuperClassID() { return SCENE_EXPORT_CLASS_ID; } + Class_ID ClassID() { return PSAEXP_CLASS_ID; } + const TCHAR* Category() { return GetString(IDS_CATEGORY); } + + const TCHAR* InternalName() { return _T("PSAExp"); } + HINSTANCE HInstance() { return hInstance; } + +}; + +static PSAExpClassDesc PSAExpDesc; +ClassDesc2* GetPSAExpDesc() { return &PSAExpDesc; } + + + + +BOOL WINAPI DllMain(HINSTANCE hinstDLL,ULONG fdwReason,LPVOID lpvReserved) +{ + hInstance = hinstDLL; // Hang on to this DLL's instance handle. + + if (!controlsInit) { + controlsInit = TRUE; + InitCustomControls(hInstance); // Initialize MAX's custom controls + InitCommonControls(); // Initialize Win95 controls + } + + return (TRUE); +} + + +__declspec(dllexport) const TCHAR* LibDescription() +{ + return GetString(IDS_LIBDESCRIPTION); +} + +__declspec(dllexport) int LibNumberClasses() +{ + return 3; +} + +__declspec(dllexport) ClassDesc* LibClassDesc(int i) +{ + switch(i) { + case 0: return GetPMDExpDesc(); + case 1: return GetPSAExpDesc(); + case 2: return GetPSPropDesc(); + default: return 0; + } +} + +__declspec(dllexport) ULONG LibVersion() +{ + return VERSION_3DSMAX; +} + +__declspec( dllexport ) ULONG CanAutoDefer() +{ + return 1; +} + + diff --git a/source/tools/pmdexp/ExpMesh.cpp b/source/tools/pmdexp/ExpMesh.cpp index 27414465b6..42c4d54cab 100755 --- a/source/tools/pmdexp/ExpMesh.cpp +++ b/source/tools/pmdexp/ExpMesh.cpp @@ -1,463 +1,463 @@ -#include "ExpMesh.h" -#include "ExpUtil.h" -#include "ExpSkeleton.h" -#include "VertexTree.h" -#include "VNormal.h" - -#include "phyexp.h" - - -//////////////////////////////////////////////////////////////////////////////// -// TMNegParity: return whether the given matrix has a negative scale or not -inline bool TMNegParity(Matrix3 &Mat) -{ - return (DotProd(CrossProd(Mat.GetRow(0),Mat.GetRow(1)),Mat.GetRow(2)) < 0.0) ? 1 : 0; -} - - -//////////////////////////////////////////////////////////////////////////////// -// GetTriObjectFromNode: return a pointer to a TriObject -// given an INode or return NULL if the node cannot be converted -// to a TriObject -static TriObject* GetTriObjectFromNode(INode* node,bool& deleteIt) -{ - deleteIt = false; - Object* obj=node->EvalWorldState(0).obj; - if (obj) { - if (obj->CanConvertToType(Class_ID(TRIOBJ_CLASS_ID, 0))) { - TriObject *tri=(TriObject*) obj->ConvertToType(0,Class_ID(TRIOBJ_CLASS_ID,0)); - - // note that the TriObject should only be deleted if the pointer to it is - // not equal to the object pointer that called ConvertToType() - if (obj != tri) { - deleteIt = true; - } - return tri; - } - } - - return 0; -} - -//////////////////////////////////////////////////////////////////////////////// -// GetPhysiqueFromNode: return a pointer to a Physique modifier found -// in the modifier stack of the given INode, or return NULL is no Physique -// modifier can be found -static Modifier* GetPhysiqueFromNode(INode* node) -{ - // Get object from node. Abort if no object. - Object* object=node->GetObjectRef(); - if (!object) return 0; - - // ss derived object? - if (object->SuperClassID()==GEN_DERIVOB_CLASS_ID) { - // yes -> cast - IDerivedObject* derivedObj=static_cast(object); - - // iterate over all entries of the modifier stack - int modStackIndex=0; - while (modStackIndexNumModifiers()) { - - // get current modifier - Modifier* modifier=derivedObj->GetModifier(modStackIndex); - Class_ID clsid=modifier->ClassID(); - - // check if it's a Physique - if (modifier->ClassID()==Class_ID(PHYSIQUE_CLASS_ID_A, PHYSIQUE_CLASS_ID_B)) { - // yes -> return it - return modifier; - } - - // advance to next modifier stack entry - modStackIndex++; - } - } - - // not found .. - return 0; -} - - - -PMDExpMesh::PMDExpMesh(INode* node,const ExpSkeleton* skeleton) - : m_Node(node), m_Skeleton(skeleton) -{ -} - -bool PMDExpMesh::IsMesh(Object* obj) -{ - assert(obj); - if (obj->CanConvertToType(Class_ID(TRIOBJ_CLASS_ID, 0))) { - return true; - } else { - return false; - } -} - -//////////////////////////////////////////////////////////////////////////////// -// InsertBlend: insert the given bone/weight blend into the given blend set -void PMDExpMesh::InsertBlend(unsigned char bone,float weight,SVertexBlend& blend) -{ - // get position where this blend should be inserted - int i=0; - while (weight=SVertexBlend::SIZE) { - // all other blends carry greater weight; reject this blend - return; - } - - for (int j=SVertexBlend::SIZE-2;j>=i;j--) { - blend.m_Bone[j+1]=blend.m_Bone[j]; - blend.m_Weight[j+1]=blend.m_Weight[j]; - } - - blend.m_Bone[i]=bone; - blend.m_Weight[i]=weight; -} - -void PMDExpMesh::BuildVertexBlends(Mesh& mesh,VBlendList& blends) -{ - // allocate blends - int numVerts=mesh.getNumVerts(); - blends.resize(mesh.getNumVerts()); - - // set all blends to null - for (int i=0;iGetInterface(I_PHYINTERFACE); - if(phyExport) { - // get ModContext interface from export interface for this INode - IPhyContextExport *contextExport=(IPhyContextExport*) phyExport->GetContextInterface(m_Node); - if(contextExport) { - // export all the vertices as if they are rigid .. - contextExport->ConvertToRigid(TRUE); - // .. and disable blending - contextExport->AllowBlending(FALSE); - - // check number of vertices assigned to physique matches mesh total - if (contextExport->GetNumberVertices()!=mesh.getNumVerts()) { -// LogError("vtx mismatch!\n"); - return; - } - - for (int i=0;iGetVertexInterface(i); - if (vertexexport) { - - // get type of vertex - int type=vertexexport->GetVertexType(); - - if (type==RIGID_TYPE) { - IPhyRigidVertex* rigidVertex=(IPhyRigidVertex*) vertexexport; - - // get attached bone - INode* boneNode=rigidVertex->GetNode(); - if (boneNode) { - // store blend - blend.m_Bone[0]=m_Skeleton->FindBoneByNode(boneNode); - - if (blend.m_Bone[0]==0xff) { -// LogError("Failed to find bonenode %s (0x%p)\n",boneNode->GetName(),boneNode); - } - blend.m_Weight[0]=1.0f; - } - } else { - // must be RIGID_BLENDED_TYPE vertex - IPhyBlendedRigidVertex* blendedVertex=(IPhyBlendedRigidVertex*) vertexexport; - - // get number of nodes affecting vertex; clamp to SVertexBlend::SIZE - int numBones=blendedVertex->GetNumberNodes(); - - for (int boneindex=0;boneindexGetWeight(boneindex); - if (boneWeight>0.001f) { - // get boneindex'th bone - INode* boneNode=blendedVertex->GetNode(boneindex); - // store blend - (need to check for prior bones using same bone?) - unsigned char bone=m_Skeleton->FindBoneByNode(boneNode); - if (bone==0xff) { - //LogError("Failed to find bonenode %s (0x%p)\n",boneNode->GetName(),boneNode); - } else { - InsertBlend(bone,boneWeight,blend); - } - } - } - -#if 0 - if (blend.m_Bone[0]==0xff) { - // ugh - all bones must have zero weight .. use the root bone with a weight of 1? - blend.m_Bone[0]=0; - blend.m_Weight[0]=1; - } -#else - if (blend.m_Bone[0]==0xff) { - // ugh - all bones must have zero weight .. try again and assign all bones equal weight - // TODO, RC 13/03/04 - log warning for this; most likely user error in enveloping/bone assignment - for (boneindex=0;boneindexGetNode(boneindex); - // store blend - (need to check for prior bones using same bone?) - unsigned char bone=m_Skeleton->FindBoneByNode(boneNode); - if (bone==0xff) { - //LogError("Failed to find bonenode %s (0x%p)\n",boneNode->GetName(),boneNode); - } else { - InsertBlend(bone,boneWeight,blend); - } - } - } -#endif - - // normalise bone weights of this blend such that they sum to 1 - int j; - float totalweight=0; - for (j=0;jReleaseVertexInterface(vertexexport); - } else { - //LogError("No vertexexport interface!\n"); - } - } - } else { - //LogError("No contextexport interface!\n"); - } - } -} - - - -static CVector3D SkinVertex(const ExpSkeleton* skeleton,const CVector3D& pos,const SVertexBlend& blend) -{ - CVector3D result(0,0,0); - for (int i=0;im_Bones[blend.m_Bone[i]]->m_Transform; - CVector3D tmp=m.Transform(pos); - result+=tmp*blend.m_Weight[i]; - } - - return result; -} - -static CVector3D SkinNormal(const ExpSkeleton* skeleton,const CVector3D& pos,const SVertexBlend& blend) -{ - CMatrix3D minv,minvtrans; - CVector3D result(0,0,0); - for (int i=0;im_Bones[blend.m_Bone[i]]->m_Transform; - m.GetInverse(minv); - minv.GetTranspose(minvtrans); - CVector3D tmp=minvtrans.Transform(pos); - result+=tmp*blend.m_Weight[i]; - } - - return result; -} - -static CVector3D UnskinPoint(const ExpSkeleton* skeleton,const CVector3D& pos,const SVertexBlend& blend) -{ - CMatrix3D m,minv; - m.SetZero(); - for (int i=0;im_Bones[blend.m_Bone[i]]->m_Transform; - m+=m2*blend.m_Weight[i]; - } - m.GetInverse(minv); - - return minv.Transform(pos); -} - -static CVector3D UnskinNormal(const ExpSkeleton* skeleton,const CVector3D& nrm,const SVertexBlend& blend) -{ - CMatrix3D m,minv,minvtrans; - m.SetZero(); - for (int i=0;im_Bones[blend.m_Bone[i]]->m_Transform; - m+=m2*blend.m_Weight[i]; - } - m.GetInverse(minv); - minv.GetTranspose(minvtrans); - minvtrans.GetInverse(m); - - return m.Rotate(nrm); -} - -CVector3D* PMDExpMesh::BuildVertexPoints(Mesh& mesh,VBlendList& vblends) -{ - // get transform to world space - Matrix3 tm=m_Node->GetObjectTM(0); - bool negScale=TMNegParity(tm); - - int numverts=mesh.getNumVerts(); - CVector3D* transPts=new CVector3D[numverts]; - - // transform each vertex and store in output array - for (int i=0;iGetObjectTM(0); - bool negScale=TMNegParity(tm); - - // allocate basis vectors for dot product lighting - VNormal* vnormals=new VNormal[mesh.getNumVerts()]; - - for (u32 i=0;inormalize(); - while (vnorm) { - vnorm->_normal=UnskinNormal(m_Skeleton,vnorm->_normal,vblends[i]); - vnorm=vnorm->next; - } - } - vnormals[i].normalize(); - } - - // .. and return them - return vnormals; -} - -void PMDExpMesh::BuildVerticesAndFaces(Mesh& mesh,VertexList& vertices,CVector3D* vpoints,VBlendList& vblends,VNormal* vnormals,FaceList& faces) -{ - // assume worst case and reserve enough space up front .. - u32 numFaces=mesh.getNumFaces(); - vertices.reserve(numFaces*3); - - // initialise outgoing face array - faces.resize(numFaces); - - // create a vertex tree setup to fill unique vertices into outgoing array - VertexTree vtxtree(vertices); - - // get transform to world space - Matrix3 tm=m_Node->GetObjectTM(0); - bool negScale=TMNegParity(tm); - - // iterate through faces - for (u32 i=0;i_normal : CVector3D(0,0,0); - faces[i].m_V[k]=vtxtree.insert(vtx); - } - - if (negScale) { - int t=faces[i].m_V[1]; - faces[i].m_V[1]=faces[i].m_V[2]; - faces[i].m_V[2]=t; - } - - faces[i].m_MAXindex=i; - faces[i].m_Smooth=mesh.faces[i].smGroup; - } -} - -ExpMesh* PMDExpMesh::Build() -{ - // get mesh from node - bool delTriObj; - TriObject* triObj=GetTriObjectFromNode(m_Node,delTriObj); - Mesh& mesh=triObj->mesh; - - ExpMesh* expmesh=new ExpMesh; - - // build vertex positions/blends from given mesh data - CVector3D* vpoints=BuildVertexPoints(mesh,expmesh->m_Blends); - - // build vertex normals from mesh data and vertex positions - VNormal* vnormals=BuildVertexNormals(mesh,expmesh->m_Blends); - - // build face and vertex lists - BuildVerticesAndFaces(mesh,expmesh->m_Vertices,vpoints,expmesh->m_Blends,vnormals,expmesh->m_Faces); - - // clean up .. - delete[] vnormals; - delete[] vpoints; - if (delTriObj) { - triObj->DeleteThis(); - } - - return expmesh; -} - - +#include "ExpMesh.h" +#include "ExpUtil.h" +#include "ExpSkeleton.h" +#include "VertexTree.h" +#include "VNormal.h" + +#include "phyexp.h" + + +//////////////////////////////////////////////////////////////////////////////// +// TMNegParity: return whether the given matrix has a negative scale or not +inline bool TMNegParity(Matrix3 &Mat) +{ + return (DotProd(CrossProd(Mat.GetRow(0),Mat.GetRow(1)),Mat.GetRow(2)) < 0.0) ? 1 : 0; +} + + +//////////////////////////////////////////////////////////////////////////////// +// GetTriObjectFromNode: return a pointer to a TriObject +// given an INode or return NULL if the node cannot be converted +// to a TriObject +static TriObject* GetTriObjectFromNode(INode* node,bool& deleteIt) +{ + deleteIt = false; + Object* obj=node->EvalWorldState(0).obj; + if (obj) { + if (obj->CanConvertToType(Class_ID(TRIOBJ_CLASS_ID, 0))) { + TriObject *tri=(TriObject*) obj->ConvertToType(0,Class_ID(TRIOBJ_CLASS_ID,0)); + + // note that the TriObject should only be deleted if the pointer to it is + // not equal to the object pointer that called ConvertToType() + if (obj != tri) { + deleteIt = true; + } + return tri; + } + } + + return 0; +} + +//////////////////////////////////////////////////////////////////////////////// +// GetPhysiqueFromNode: return a pointer to a Physique modifier found +// in the modifier stack of the given INode, or return NULL is no Physique +// modifier can be found +static Modifier* GetPhysiqueFromNode(INode* node) +{ + // Get object from node. Abort if no object. + Object* object=node->GetObjectRef(); + if (!object) return 0; + + // ss derived object? + if (object->SuperClassID()==GEN_DERIVOB_CLASS_ID) { + // yes -> cast + IDerivedObject* derivedObj=static_cast(object); + + // iterate over all entries of the modifier stack + int modStackIndex=0; + while (modStackIndexNumModifiers()) { + + // get current modifier + Modifier* modifier=derivedObj->GetModifier(modStackIndex); + Class_ID clsid=modifier->ClassID(); + + // check if it's a Physique + if (modifier->ClassID()==Class_ID(PHYSIQUE_CLASS_ID_A, PHYSIQUE_CLASS_ID_B)) { + // yes -> return it + return modifier; + } + + // advance to next modifier stack entry + modStackIndex++; + } + } + + // not found .. + return 0; +} + + + +PMDExpMesh::PMDExpMesh(INode* node,const ExpSkeleton* skeleton) + : m_Node(node), m_Skeleton(skeleton) +{ +} + +bool PMDExpMesh::IsMesh(Object* obj) +{ + assert(obj); + if (obj->CanConvertToType(Class_ID(TRIOBJ_CLASS_ID, 0))) { + return true; + } else { + return false; + } +} + +//////////////////////////////////////////////////////////////////////////////// +// InsertBlend: insert the given bone/weight blend into the given blend set +void PMDExpMesh::InsertBlend(unsigned char bone,float weight,SVertexBlend& blend) +{ + // get position where this blend should be inserted + int i=0; + while (weight=SVertexBlend::SIZE) { + // all other blends carry greater weight; reject this blend + return; + } + + for (int j=SVertexBlend::SIZE-2;j>=i;j--) { + blend.m_Bone[j+1]=blend.m_Bone[j]; + blend.m_Weight[j+1]=blend.m_Weight[j]; + } + + blend.m_Bone[i]=bone; + blend.m_Weight[i]=weight; +} + +void PMDExpMesh::BuildVertexBlends(Mesh& mesh,VBlendList& blends) +{ + // allocate blends + int numVerts=mesh.getNumVerts(); + blends.resize(mesh.getNumVerts()); + + // set all blends to null + for (int i=0;iGetInterface(I_PHYINTERFACE); + if(phyExport) { + // get ModContext interface from export interface for this INode + IPhyContextExport *contextExport=(IPhyContextExport*) phyExport->GetContextInterface(m_Node); + if(contextExport) { + // export all the vertices as if they are rigid .. + contextExport->ConvertToRigid(TRUE); + // .. and disable blending + contextExport->AllowBlending(FALSE); + + // check number of vertices assigned to physique matches mesh total + if (contextExport->GetNumberVertices()!=mesh.getNumVerts()) { +// LogError("vtx mismatch!\n"); + return; + } + + for (int i=0;iGetVertexInterface(i); + if (vertexexport) { + + // get type of vertex + int type=vertexexport->GetVertexType(); + + if (type==RIGID_TYPE) { + IPhyRigidVertex* rigidVertex=(IPhyRigidVertex*) vertexexport; + + // get attached bone + INode* boneNode=rigidVertex->GetNode(); + if (boneNode) { + // store blend + blend.m_Bone[0]=m_Skeleton->FindBoneByNode(boneNode); + + if (blend.m_Bone[0]==0xff) { +// LogError("Failed to find bonenode %s (0x%p)\n",boneNode->GetName(),boneNode); + } + blend.m_Weight[0]=1.0f; + } + } else { + // must be RIGID_BLENDED_TYPE vertex + IPhyBlendedRigidVertex* blendedVertex=(IPhyBlendedRigidVertex*) vertexexport; + + // get number of nodes affecting vertex; clamp to SVertexBlend::SIZE + int numBones=blendedVertex->GetNumberNodes(); + + for (int boneindex=0;boneindexGetWeight(boneindex); + if (boneWeight>0.001f) { + // get boneindex'th bone + INode* boneNode=blendedVertex->GetNode(boneindex); + // store blend - (need to check for prior bones using same bone?) + unsigned char bone=m_Skeleton->FindBoneByNode(boneNode); + if (bone==0xff) { + //LogError("Failed to find bonenode %s (0x%p)\n",boneNode->GetName(),boneNode); + } else { + InsertBlend(bone,boneWeight,blend); + } + } + } + +#if 0 + if (blend.m_Bone[0]==0xff) { + // ugh - all bones must have zero weight .. use the root bone with a weight of 1? + blend.m_Bone[0]=0; + blend.m_Weight[0]=1; + } +#else + if (blend.m_Bone[0]==0xff) { + // ugh - all bones must have zero weight .. try again and assign all bones equal weight + // TODO, RC 13/03/04 - log warning for this; most likely user error in enveloping/bone assignment + for (boneindex=0;boneindexGetNode(boneindex); + // store blend - (need to check for prior bones using same bone?) + unsigned char bone=m_Skeleton->FindBoneByNode(boneNode); + if (bone==0xff) { + //LogError("Failed to find bonenode %s (0x%p)\n",boneNode->GetName(),boneNode); + } else { + InsertBlend(bone,boneWeight,blend); + } + } + } +#endif + + // normalise bone weights of this blend such that they sum to 1 + int j; + float totalweight=0; + for (j=0;jReleaseVertexInterface(vertexexport); + } else { + //LogError("No vertexexport interface!\n"); + } + } + } else { + //LogError("No contextexport interface!\n"); + } + } +} + + + +static CVector3D SkinVertex(const ExpSkeleton* skeleton,const CVector3D& pos,const SVertexBlend& blend) +{ + CVector3D result(0,0,0); + for (int i=0;im_Bones[blend.m_Bone[i]]->m_Transform; + CVector3D tmp=m.Transform(pos); + result+=tmp*blend.m_Weight[i]; + } + + return result; +} + +static CVector3D SkinNormal(const ExpSkeleton* skeleton,const CVector3D& pos,const SVertexBlend& blend) +{ + CMatrix3D minv,minvtrans; + CVector3D result(0,0,0); + for (int i=0;im_Bones[blend.m_Bone[i]]->m_Transform; + m.GetInverse(minv); + minv.GetTranspose(minvtrans); + CVector3D tmp=minvtrans.Transform(pos); + result+=tmp*blend.m_Weight[i]; + } + + return result; +} + +static CVector3D UnskinPoint(const ExpSkeleton* skeleton,const CVector3D& pos,const SVertexBlend& blend) +{ + CMatrix3D m,minv; + m.SetZero(); + for (int i=0;im_Bones[blend.m_Bone[i]]->m_Transform; + m+=m2*blend.m_Weight[i]; + } + m.GetInverse(minv); + + return minv.Transform(pos); +} + +static CVector3D UnskinNormal(const ExpSkeleton* skeleton,const CVector3D& nrm,const SVertexBlend& blend) +{ + CMatrix3D m,minv,minvtrans; + m.SetZero(); + for (int i=0;im_Bones[blend.m_Bone[i]]->m_Transform; + m+=m2*blend.m_Weight[i]; + } + m.GetInverse(minv); + minv.GetTranspose(minvtrans); + minvtrans.GetInverse(m); + + return m.Rotate(nrm); +} + +CVector3D* PMDExpMesh::BuildVertexPoints(Mesh& mesh,VBlendList& vblends) +{ + // get transform to world space + Matrix3 tm=m_Node->GetObjectTM(0); + bool negScale=TMNegParity(tm); + + int numverts=mesh.getNumVerts(); + CVector3D* transPts=new CVector3D[numverts]; + + // transform each vertex and store in output array + for (int i=0;iGetObjectTM(0); + bool negScale=TMNegParity(tm); + + // allocate basis vectors for dot product lighting + VNormal* vnormals=new VNormal[mesh.getNumVerts()]; + + for (u32 i=0;inormalize(); + while (vnorm) { + vnorm->_normal=UnskinNormal(m_Skeleton,vnorm->_normal,vblends[i]); + vnorm=vnorm->next; + } + } + vnormals[i].normalize(); + } + + // .. and return them + return vnormals; +} + +void PMDExpMesh::BuildVerticesAndFaces(Mesh& mesh,VertexList& vertices,CVector3D* vpoints,VBlendList& vblends,VNormal* vnormals,FaceList& faces) +{ + // assume worst case and reserve enough space up front .. + u32 numFaces=mesh.getNumFaces(); + vertices.reserve(numFaces*3); + + // initialise outgoing face array + faces.resize(numFaces); + + // create a vertex tree setup to fill unique vertices into outgoing array + VertexTree vtxtree(vertices); + + // get transform to world space + Matrix3 tm=m_Node->GetObjectTM(0); + bool negScale=TMNegParity(tm); + + // iterate through faces + for (u32 i=0;i_normal : CVector3D(0,0,0); + faces[i].m_V[k]=vtxtree.insert(vtx); + } + + if (negScale) { + int t=faces[i].m_V[1]; + faces[i].m_V[1]=faces[i].m_V[2]; + faces[i].m_V[2]=t; + } + + faces[i].m_MAXindex=i; + faces[i].m_Smooth=mesh.faces[i].smGroup; + } +} + +ExpMesh* PMDExpMesh::Build() +{ + // get mesh from node + bool delTriObj; + TriObject* triObj=GetTriObjectFromNode(m_Node,delTriObj); + Mesh& mesh=triObj->mesh; + + ExpMesh* expmesh=new ExpMesh; + + // build vertex positions/blends from given mesh data + CVector3D* vpoints=BuildVertexPoints(mesh,expmesh->m_Blends); + + // build vertex normals from mesh data and vertex positions + VNormal* vnormals=BuildVertexNormals(mesh,expmesh->m_Blends); + + // build face and vertex lists + BuildVerticesAndFaces(mesh,expmesh->m_Vertices,vpoints,expmesh->m_Blends,vnormals,expmesh->m_Faces); + + // clean up .. + delete[] vnormals; + delete[] vpoints; + if (delTriObj) { + triObj->DeleteThis(); + } + + return expmesh; +} + + diff --git a/source/tools/pmdexp/ExpMesh.h b/source/tools/pmdexp/ExpMesh.h index 13bbf09e54..e978b97bf6 100755 --- a/source/tools/pmdexp/ExpMesh.h +++ b/source/tools/pmdexp/ExpMesh.h @@ -1,81 +1,81 @@ -#ifndef __EXPMESH_H -#define __EXPMESH_H - -#include -#include "MaxInc.h" -#include "lib\types.h" -#include "Vector3D.h" - -#include "ExpVertex.h" - -class VNormal; -class ExpSkeleton; - -//////////////////////////////////////////////////////////////////////// -// ExpFace: face declaration used in building mesh geometry -struct ExpFace { - // vertex indices - u32 m_V[3]; - // index of this face in max's face list (necessary, since extra - // faces may be created in fixing t-junctions, but it's still - // necessary to map back to MAX for eg. getting material on face) - u32 m_MAXindex; - // smoothing group - u32 m_Smooth; - // face normal - CVector3D m_Normal; - // face area - float m_Area; -}; - -// handy typedefs -typedef std::vector IndexList; -typedef std::vector PointList; -typedef std::vector FaceList; -typedef std::vector VertexList; -typedef std::vector VBlendList; - -//////////////////////////////////////////////////////////////////////// -// ExpMesh: mesh type used in building mesh geometry -class ExpMesh -{ -public: - // list of faces in mesh - FaceList m_Faces; - // list of vertices used by mesh - VertexList m_Vertices; - // list of vertex blends used by mesh - VBlendList m_Blends; -}; - -//////////////////////////////////////////////////////////////////////// -// PMDExpMesh: class used for building output meshes -class PMDExpMesh -{ -public: - PMDExpMesh(INode* node,const ExpSkeleton* skeleton); - - static bool IsMesh(Object* obj); - ExpMesh* Build(); - - -private: - // the node we're constructing the mesh from - INode* m_Node; - // the skeleton attached to the mesh, if any - const ExpSkeleton* m_Skeleton; - - // construct list of vertices and faces used by mesh - void BuildVerticesAndFaces(Mesh& mesh,VertexList& vertices,CVector3D* vpoints,VBlendList& vblends,VNormal* vnormals,FaceList& faces); - // build and return vertex normals, accounting for smoothing groups - VNormal* BuildVertexNormals(Mesh& mesh,VBlendList& vblends); - // build and return vertex blends (determined by Physique), if any - void BuildVertexBlends(Mesh& mesh,VBlendList& blends); - // insert the given bone/weight blend into the given blend set - void InsertBlend(unsigned char bone,float weight,SVertexBlend& blend); - - CVector3D* BuildVertexPoints(Mesh& mesh,VBlendList& vblends); - -}; - +#ifndef __EXPMESH_H +#define __EXPMESH_H + +#include +#include "MaxInc.h" +#include "lib\types.h" +#include "Vector3D.h" + +#include "ExpVertex.h" + +class VNormal; +class ExpSkeleton; + +//////////////////////////////////////////////////////////////////////// +// ExpFace: face declaration used in building mesh geometry +struct ExpFace { + // vertex indices + u32 m_V[3]; + // index of this face in max's face list (necessary, since extra + // faces may be created in fixing t-junctions, but it's still + // necessary to map back to MAX for eg. getting material on face) + u32 m_MAXindex; + // smoothing group + u32 m_Smooth; + // face normal + CVector3D m_Normal; + // face area + float m_Area; +}; + +// handy typedefs +typedef std::vector IndexList; +typedef std::vector PointList; +typedef std::vector FaceList; +typedef std::vector VertexList; +typedef std::vector VBlendList; + +//////////////////////////////////////////////////////////////////////// +// ExpMesh: mesh type used in building mesh geometry +class ExpMesh +{ +public: + // list of faces in mesh + FaceList m_Faces; + // list of vertices used by mesh + VertexList m_Vertices; + // list of vertex blends used by mesh + VBlendList m_Blends; +}; + +//////////////////////////////////////////////////////////////////////// +// PMDExpMesh: class used for building output meshes +class PMDExpMesh +{ +public: + PMDExpMesh(INode* node,const ExpSkeleton* skeleton); + + static bool IsMesh(Object* obj); + ExpMesh* Build(); + + +private: + // the node we're constructing the mesh from + INode* m_Node; + // the skeleton attached to the mesh, if any + const ExpSkeleton* m_Skeleton; + + // construct list of vertices and faces used by mesh + void BuildVerticesAndFaces(Mesh& mesh,VertexList& vertices,CVector3D* vpoints,VBlendList& vblends,VNormal* vnormals,FaceList& faces); + // build and return vertex normals, accounting for smoothing groups + VNormal* BuildVertexNormals(Mesh& mesh,VBlendList& vblends); + // build and return vertex blends (determined by Physique), if any + void BuildVertexBlends(Mesh& mesh,VBlendList& blends); + // insert the given bone/weight blend into the given blend set + void InsertBlend(unsigned char bone,float weight,SVertexBlend& blend); + + CVector3D* BuildVertexPoints(Mesh& mesh,VBlendList& vblends); + +}; + #endif \ No newline at end of file diff --git a/source/tools/pmdexp/ExpProp.cpp b/source/tools/pmdexp/ExpProp.cpp index 151f1435ce..deace640e1 100755 --- a/source/tools/pmdexp/ExpProp.cpp +++ b/source/tools/pmdexp/ExpProp.cpp @@ -1,44 +1,44 @@ -#include "PSProp.h" -#include "ExpProp.h" -#include "ExpUtil.h" -#include "decomp.h" - -PMDExpProp::PMDExpProp(INode* node) : m_Node(node) -{ -} - -bool PMDExpProp::IsProp(Object* obj) -{ - return obj->ClassID()==PSPROP_CLASS_ID ? true : false; -} - -ExpProp* PMDExpProp::Build() -{ - ExpProp* prop=new ExpProp; - prop->m_Name=m_Node->GetName(); - prop->m_Parent=m_Node->GetParentNode(); - - // build local transformation matrix - INode *parent; - Matrix3 parentTM, nodeTM, localTM; - nodeTM = m_Node->GetNodeTM(0); - parent = m_Node->GetParentNode(); - parentTM = parent->GetNodeTM(0); - localTM = nodeTM*Inverse(parentTM); - - // decompose it to get translation and rotation - AffineParts parts; - decomp_affine(localTM,&parts); - - // get translation from affine parts - MAXtoGL(parts.t); - prop->m_Position=CVector3D(parts.t.x,parts.t.y,parts.t.z); - - // get rotation from affine parts - prop->m_Rotation.m_V.X=parts.q.x; - prop->m_Rotation.m_V.Y=parts.q.z; - prop->m_Rotation.m_V.Z=parts.q.y; - prop->m_Rotation.m_W=parts.q.w; - - return prop; +#include "PSProp.h" +#include "ExpProp.h" +#include "ExpUtil.h" +#include "decomp.h" + +PMDExpProp::PMDExpProp(INode* node) : m_Node(node) +{ +} + +bool PMDExpProp::IsProp(Object* obj) +{ + return obj->ClassID()==PSPROP_CLASS_ID ? true : false; +} + +ExpProp* PMDExpProp::Build() +{ + ExpProp* prop=new ExpProp; + prop->m_Name=m_Node->GetName(); + prop->m_Parent=m_Node->GetParentNode(); + + // build local transformation matrix + INode *parent; + Matrix3 parentTM, nodeTM, localTM; + nodeTM = m_Node->GetNodeTM(0); + parent = m_Node->GetParentNode(); + parentTM = parent->GetNodeTM(0); + localTM = nodeTM*Inverse(parentTM); + + // decompose it to get translation and rotation + AffineParts parts; + decomp_affine(localTM,&parts); + + // get translation from affine parts + MAXtoGL(parts.t); + prop->m_Position=CVector3D(parts.t.x,parts.t.y,parts.t.z); + + // get rotation from affine parts + prop->m_Rotation.m_V.X=parts.q.x; + prop->m_Rotation.m_V.Y=parts.q.z; + prop->m_Rotation.m_V.Z=parts.q.y; + prop->m_Rotation.m_W=parts.q.w; + + return prop; } \ No newline at end of file diff --git a/source/tools/pmdexp/ExpProp.h b/source/tools/pmdexp/ExpProp.h index 6721225c13..6dddaf674b 100755 --- a/source/tools/pmdexp/ExpProp.h +++ b/source/tools/pmdexp/ExpProp.h @@ -1,38 +1,38 @@ -#ifndef _EXPPROP_H -#define _EXPPROP_H - -#include "CStr.h" -#include "Vector3D.h" -#include "Quaternion.h" - -//////////////////////////////////////////////////////////////////////// -// ExpProp: prop object used on export -class ExpProp -{ -public: - // name of prop - CStr m_Name; - // position relative to parent - CVector3D m_Position; - // rotation relative to parent - CQuaternion m_Rotation; - // parent node - INode* m_Parent; -}; - -//////////////////////////////////////////////////////////////////////// -// PMDExpProp: class used for building output props -class PMDExpProp -{ -public: - PMDExpProp(INode* node); - - static bool IsProp(Object* obj); - ExpProp* Build(); - -private: - // the node we're constructing the prop from - INode* m_Node; -}; - +#ifndef _EXPPROP_H +#define _EXPPROP_H + +#include "CStr.h" +#include "Vector3D.h" +#include "Quaternion.h" + +//////////////////////////////////////////////////////////////////////// +// ExpProp: prop object used on export +class ExpProp +{ +public: + // name of prop + CStr m_Name; + // position relative to parent + CVector3D m_Position; + // rotation relative to parent + CQuaternion m_Rotation; + // parent node + INode* m_Parent; +}; + +//////////////////////////////////////////////////////////////////////// +// PMDExpProp: class used for building output props +class PMDExpProp +{ +public: + PMDExpProp(INode* node); + + static bool IsProp(Object* obj); + ExpProp* Build(); + +private: + // the node we're constructing the prop from + INode* m_Node; +}; + #endif \ No newline at end of file diff --git a/source/tools/pmdexp/ExpSkeleton.cpp b/source/tools/pmdexp/ExpSkeleton.cpp index 9a3ac80d4a..26e78945e0 100755 --- a/source/tools/pmdexp/ExpSkeleton.cpp +++ b/source/tools/pmdexp/ExpSkeleton.cpp @@ -1,173 +1,173 @@ -#include "ExpSkeleton.h" -#include "ExpUtil.h" -#include "bipexp.h" -#include "decomp.h" -#include "ModelDef.h" -#include "SkeletonAnimDef.h" - -///////////////////////////////////////////////////////////////////////////////// -// ExpSkeleton constructor -ExpSkeleton::ExpSkeleton() -{ -} - -///////////////////////////////////////////////////////////////////////////////// -// ExpSkeleton destructor -ExpSkeleton::~ExpSkeleton() -{ - for (int i=0;iGetTMController(); - - // check classID for footprints - return (c && (c->ClassID()==FOOTPRINT_CLASS_ID)) ? true : false; -} - -///////////////////////////////////////////////////////////////////////////////// -// IsBone: return true if given node is a skeletal biped bone, else false -bool ExpSkeleton::IsBone(INode* node) -{ - // get nodes transform control - Control* c=node->GetTMController(); - - // check classID for either a root or a child bone - return (c && (c->ClassID()==BIPSLAVE_CONTROL_CLASS_ID || c->ClassID()==BIPBODY_CONTROL_CLASS_ID)) ? true : false; -} - -///////////////////////////////////////////////////////////////////////////////// -// IsSkeleton: return true if given node is the root of a skeleton, else false -bool ExpSkeleton::IsSkeletonRoot(INode* node) -{ - // get nodes transform control - Control* c=node->GetTMController(); - - // check for biped root - return (c && c->ClassID()==BIPBODY_CONTROL_CLASS_ID) ? true : false; -} - -///////////////////////////////////////////////////////////////////////////////// -// BuildSkeletons: build all skeletons from given root node -void ExpSkeleton::BuildSkeletons(INode* node,std::vector& skeletons) -{ - if (IsSkeletonRoot(node)) { - // build skeleton from this node - Build traverses all children - // of given node - ExpSkeleton* skeleton=new ExpSkeleton; - skeleton->Build(node,0); - skeletons.push_back(skeleton); - } else { - // traverse into children as this object wasn't a skeleton root - for (int i=0;iNumberOfChildren();i++) { - BuildSkeletons(node->GetChildNode(i),skeletons); - } - } -} - -//////////////////////////////////////////////////////////////////////////////// -// FindBoneByNode: search skeleton looking for matching bone using given node; -// return index of given node in the skeleton, 0xff if not found -u8 ExpSkeleton::FindBoneByNode(INode* boneNode) const -{ - if (!boneNode) return 0xff; - - for (int j=0;jm_Node==boneNode) return j; - } - - return 0xff; -} - - -///////////////////////////////////////////////////////////////////////////////// -// Build: traverse node heirachy adding bones to skeleton -void ExpSkeleton::Build(INode* node,ExpBone* parent) -{ - if (IsBone(node)) { - - // build bone - ExpBone* bone=new ExpBone; - bone->m_Node=node; - bone->m_Parent=parent; - - // get bone's translation and rotation relative to root at time 0 - GetBoneTransformComponents(node,0,bone->m_Translation,bone->m_Rotation); - - // build transform from bone to object space - CMatrix3D m; - bone->m_Transform.SetIdentity(); - bone->m_Transform.Rotate(bone->m_Rotation); - bone->m_Transform.Translate(bone->m_Translation); - - // add bone to parent's list of children and complete bone list - if (parent) parent->m_Children.push_back(bone); - m_Bones.push_back(bone); - - char buf[256]; - sprintf(buf,"bonenode 0x%p (%s) added\n",node,node->GetName()); - OutputDebugString(buf); - - for (int i=0;iNumberOfChildren();i++) { - Build(node->GetChildNode(i),bone); - } - } -} - -///////////////////////////////////////////////////////////////////////////////// -// BuildAnimation: build and return a complete animation for this skeleton over -// given time range -CSkeletonAnimDef* ExpSkeleton::BuildAnimation(TimeValue start,TimeValue end,float rate) -{ - CSkeletonAnimDef* anim=new CSkeletonAnimDef; - anim->m_Name="God Knows"; - anim->m_NumFrames=1+(end-start)/rate; - anim->m_NumKeys=m_Bones.size(); - anim->m_FrameTime=rate; - anim->m_Keys=new CSkeletonAnimDef::Key[anim->m_NumFrames*anim->m_NumKeys]; - - u32 counter=0; - TimeValue t=start; - while (tm_Keys[counter++]; - GetBoneTransformComponents(m_Bones[i]->m_Node,t,key.m_Translation,key.m_Rotation); - } - t+=rate; - } - - return anim; -} - -/////////////////////////////////////////////////////////////////////////////////////// -// GetBoneTransformComponents: calculate the translation and rotation -// values of the given bone, relative to the root bone, at the given time -void ExpSkeleton::GetBoneTransformComponents(INode* node,TimeValue t, - CVector3D& trans,CQuaternion& rot) -{ - Matrix3 nodeTM=node->GetNodeTM(t); - nodeTM.NoScale(); - - // decompose it to get translation and rotation - AffineParts parts; - decomp_affine(nodeTM,&parts); - - // get translation from affine parts - MAXtoGL(parts.t); - trans=CVector3D(parts.t.x,parts.t.y,parts.t.z); - - // get rotation from affine parts - rot.m_V.X=parts.q.x; - rot.m_V.Y=parts.q.z; - rot.m_V.Z=parts.q.y; - rot.m_W=parts.q.w; +#include "ExpSkeleton.h" +#include "ExpUtil.h" +#include "bipexp.h" +#include "decomp.h" +#include "ModelDef.h" +#include "SkeletonAnimDef.h" + +///////////////////////////////////////////////////////////////////////////////// +// ExpSkeleton constructor +ExpSkeleton::ExpSkeleton() +{ +} + +///////////////////////////////////////////////////////////////////////////////// +// ExpSkeleton destructor +ExpSkeleton::~ExpSkeleton() +{ + for (int i=0;iGetTMController(); + + // check classID for footprints + return (c && (c->ClassID()==FOOTPRINT_CLASS_ID)) ? true : false; +} + +///////////////////////////////////////////////////////////////////////////////// +// IsBone: return true if given node is a skeletal biped bone, else false +bool ExpSkeleton::IsBone(INode* node) +{ + // get nodes transform control + Control* c=node->GetTMController(); + + // check classID for either a root or a child bone + return (c && (c->ClassID()==BIPSLAVE_CONTROL_CLASS_ID || c->ClassID()==BIPBODY_CONTROL_CLASS_ID)) ? true : false; +} + +///////////////////////////////////////////////////////////////////////////////// +// IsSkeleton: return true if given node is the root of a skeleton, else false +bool ExpSkeleton::IsSkeletonRoot(INode* node) +{ + // get nodes transform control + Control* c=node->GetTMController(); + + // check for biped root + return (c && c->ClassID()==BIPBODY_CONTROL_CLASS_ID) ? true : false; +} + +///////////////////////////////////////////////////////////////////////////////// +// BuildSkeletons: build all skeletons from given root node +void ExpSkeleton::BuildSkeletons(INode* node,std::vector& skeletons) +{ + if (IsSkeletonRoot(node)) { + // build skeleton from this node - Build traverses all children + // of given node + ExpSkeleton* skeleton=new ExpSkeleton; + skeleton->Build(node,0); + skeletons.push_back(skeleton); + } else { + // traverse into children as this object wasn't a skeleton root + for (int i=0;iNumberOfChildren();i++) { + BuildSkeletons(node->GetChildNode(i),skeletons); + } + } +} + +//////////////////////////////////////////////////////////////////////////////// +// FindBoneByNode: search skeleton looking for matching bone using given node; +// return index of given node in the skeleton, 0xff if not found +u8 ExpSkeleton::FindBoneByNode(INode* boneNode) const +{ + if (!boneNode) return 0xff; + + for (int j=0;jm_Node==boneNode) return j; + } + + return 0xff; +} + + +///////////////////////////////////////////////////////////////////////////////// +// Build: traverse node heirachy adding bones to skeleton +void ExpSkeleton::Build(INode* node,ExpBone* parent) +{ + if (IsBone(node)) { + + // build bone + ExpBone* bone=new ExpBone; + bone->m_Node=node; + bone->m_Parent=parent; + + // get bone's translation and rotation relative to root at time 0 + GetBoneTransformComponents(node,0,bone->m_Translation,bone->m_Rotation); + + // build transform from bone to object space + CMatrix3D m; + bone->m_Transform.SetIdentity(); + bone->m_Transform.Rotate(bone->m_Rotation); + bone->m_Transform.Translate(bone->m_Translation); + + // add bone to parent's list of children and complete bone list + if (parent) parent->m_Children.push_back(bone); + m_Bones.push_back(bone); + + char buf[256]; + sprintf(buf,"bonenode 0x%p (%s) added\n",node,node->GetName()); + OutputDebugString(buf); + + for (int i=0;iNumberOfChildren();i++) { + Build(node->GetChildNode(i),bone); + } + } +} + +///////////////////////////////////////////////////////////////////////////////// +// BuildAnimation: build and return a complete animation for this skeleton over +// given time range +CSkeletonAnimDef* ExpSkeleton::BuildAnimation(TimeValue start,TimeValue end,float rate) +{ + CSkeletonAnimDef* anim=new CSkeletonAnimDef; + anim->m_Name="God Knows"; + anim->m_NumFrames=1+(end-start)/rate; + anim->m_NumKeys=m_Bones.size(); + anim->m_FrameTime=rate; + anim->m_Keys=new CSkeletonAnimDef::Key[anim->m_NumFrames*anim->m_NumKeys]; + + u32 counter=0; + TimeValue t=start; + while (tm_Keys[counter++]; + GetBoneTransformComponents(m_Bones[i]->m_Node,t,key.m_Translation,key.m_Rotation); + } + t+=rate; + } + + return anim; +} + +/////////////////////////////////////////////////////////////////////////////////////// +// GetBoneTransformComponents: calculate the translation and rotation +// values of the given bone, relative to the root bone, at the given time +void ExpSkeleton::GetBoneTransformComponents(INode* node,TimeValue t, + CVector3D& trans,CQuaternion& rot) +{ + Matrix3 nodeTM=node->GetNodeTM(t); + nodeTM.NoScale(); + + // decompose it to get translation and rotation + AffineParts parts; + decomp_affine(nodeTM,&parts); + + // get translation from affine parts + MAXtoGL(parts.t); + trans=CVector3D(parts.t.x,parts.t.y,parts.t.z); + + // get rotation from affine parts + rot.m_V.X=parts.q.x; + rot.m_V.Y=parts.q.z; + rot.m_V.Z=parts.q.y; + rot.m_W=parts.q.w; } \ No newline at end of file diff --git a/source/tools/pmdexp/ExpSkeleton.h b/source/tools/pmdexp/ExpSkeleton.h index 2dad02ffa8..615ebccfc1 100755 --- a/source/tools/pmdexp/ExpSkeleton.h +++ b/source/tools/pmdexp/ExpSkeleton.h @@ -1,74 +1,74 @@ -#ifndef __EXPSKELETON_H -#define __EXPSKELETON_H - -#include -#include "MaxInc.h" -#include "res/res.h" -#include "Matrix3D.h" -#include "Vector3D.h" -#include "Quaternion.h" - -class CSkeleton; -class CSkeletonAnimDef; - -//////////////////////////////////////////////////////////////////////// -// ExpBone: bone type used during export -class ExpBone -{ -public: - // MAX bone node - INode* m_Node; - // transform from object to this bones space at time 0 - CMatrix3D m_Transform; - // translation relative to root bone at time 0 - CVector3D m_Translation; - // rotation relative to root bone at time 0 - CQuaternion m_Rotation; - // parent of this bone; 0 for root bone - ExpBone* m_Parent; - // children of this bone - std::vector m_Children; -}; - -//////////////////////////////////////////////////////////////////////// -// ExpSkeleton: -class ExpSkeleton -{ -public: - //////////////////////////////////////////////////////////////////////// - // static methods for skeleton creation, destruction and type queries: - - // build all skeletons from given root node - static void BuildSkeletons(INode* node,std::vector& skeletons); - // return true if given node is a skeletal biped bone, else false - static bool IsBone(INode* node); - // return true if given node is biped footprints, else false - static bool IsFootprints(INode* node); - // return true if given node is the root of a skeleton, else false - static bool IsSkeletonRoot(INode* node); - -public: - // constructor, destructor - ExpSkeleton(); - ~ExpSkeleton(); - - // search skeleton looking for matching bone using given node; - // return index of given node in the skeleton, 0xff if not found - u8 FindBoneByNode(INode* boneNode) const; - - // build and return a complete animation for this skeleton over given time range - CSkeletonAnimDef* BuildAnimation(TimeValue start,TimeValue end,float rate); - -private: - // traverse node heirachy adding bones to skeleton - void Build(INode* node,ExpBone* parent=0); - // calculate the translation and rotation values of the given bone, - // relative to the root bone, at the given time - void GetBoneTransformComponents(INode* node,TimeValue t,CVector3D& trans,CQuaternion& rot); - -public: - // list of bones in skeleton; root bone is m_Bones[0] - std::vector m_Bones; -}; - +#ifndef __EXPSKELETON_H +#define __EXPSKELETON_H + +#include +#include "MaxInc.h" +#include "res/res.h" +#include "Matrix3D.h" +#include "Vector3D.h" +#include "Quaternion.h" + +class CSkeleton; +class CSkeletonAnimDef; + +//////////////////////////////////////////////////////////////////////// +// ExpBone: bone type used during export +class ExpBone +{ +public: + // MAX bone node + INode* m_Node; + // transform from object to this bones space at time 0 + CMatrix3D m_Transform; + // translation relative to root bone at time 0 + CVector3D m_Translation; + // rotation relative to root bone at time 0 + CQuaternion m_Rotation; + // parent of this bone; 0 for root bone + ExpBone* m_Parent; + // children of this bone + std::vector m_Children; +}; + +//////////////////////////////////////////////////////////////////////// +// ExpSkeleton: +class ExpSkeleton +{ +public: + //////////////////////////////////////////////////////////////////////// + // static methods for skeleton creation, destruction and type queries: + + // build all skeletons from given root node + static void BuildSkeletons(INode* node,std::vector& skeletons); + // return true if given node is a skeletal biped bone, else false + static bool IsBone(INode* node); + // return true if given node is biped footprints, else false + static bool IsFootprints(INode* node); + // return true if given node is the root of a skeleton, else false + static bool IsSkeletonRoot(INode* node); + +public: + // constructor, destructor + ExpSkeleton(); + ~ExpSkeleton(); + + // search skeleton looking for matching bone using given node; + // return index of given node in the skeleton, 0xff if not found + u8 FindBoneByNode(INode* boneNode) const; + + // build and return a complete animation for this skeleton over given time range + CSkeletonAnimDef* BuildAnimation(TimeValue start,TimeValue end,float rate); + +private: + // traverse node heirachy adding bones to skeleton + void Build(INode* node,ExpBone* parent=0); + // calculate the translation and rotation values of the given bone, + // relative to the root bone, at the given time + void GetBoneTransformComponents(INode* node,TimeValue t,CVector3D& trans,CQuaternion& rot); + +public: + // list of bones in skeleton; root bone is m_Bones[0] + std::vector m_Bones; +}; + #endif \ No newline at end of file diff --git a/source/tools/pmdexp/ExpUtil.cpp b/source/tools/pmdexp/ExpUtil.cpp index d59e2e1b8a..59fe43c0e2 100755 --- a/source/tools/pmdexp/ExpUtil.cpp +++ b/source/tools/pmdexp/ExpUtil.cpp @@ -1,12 +1,12 @@ -#include "MaxInc.h" -#include "ExpUtil.h" - -////////////////////////////////////////////////////////////////////// -// MAXtoGL: convert point from MAX's coordinate system to that used -// within the engine -void MAXtoGL(Point3 &pnt) -{ - float tmp = pnt.y; - pnt.y = pnt.z; - pnt.z = tmp; -} +#include "MaxInc.h" +#include "ExpUtil.h" + +////////////////////////////////////////////////////////////////////// +// MAXtoGL: convert point from MAX's coordinate system to that used +// within the engine +void MAXtoGL(Point3 &pnt) +{ + float tmp = pnt.y; + pnt.y = pnt.z; + pnt.z = tmp; +} diff --git a/source/tools/pmdexp/ExpUtil.h b/source/tools/pmdexp/ExpUtil.h index ebccf5ef28..4768aa0ebf 100755 --- a/source/tools/pmdexp/ExpUtil.h +++ b/source/tools/pmdexp/ExpUtil.h @@ -1,9 +1,9 @@ -#ifndef _EXPUTIL_H -#define _EXPUTIL_H - -class Point3; - -extern void MAXtoGL(Point3 &pnt); - - +#ifndef _EXPUTIL_H +#define _EXPUTIL_H + +class Point3; + +extern void MAXtoGL(Point3 &pnt); + + #endif \ No newline at end of file diff --git a/source/tools/pmdexp/ExpVertex.h b/source/tools/pmdexp/ExpVertex.h index 688ce2086b..81cb7be863 100755 --- a/source/tools/pmdexp/ExpVertex.h +++ b/source/tools/pmdexp/ExpVertex.h @@ -1,22 +1,22 @@ -#ifndef __EXPVERTEX_H -#define __EXPVERTEX_H - -#include "lib\types.h" -#include "Vector3D.h" -#include "ModelDef.h" - -//////////////////////////////////////////////////////////////////////// -// ExpVertex: vertex type used in building mesh geometry -struct ExpVertex { - // index into original meshes point list - unsigned int m_Index; - // object space position - CVector3D m_Pos; - // object space normal - CVector3D m_Normal; - // uv coordinates - float m_UVs[2]; -}; - -#endif - +#ifndef __EXPVERTEX_H +#define __EXPVERTEX_H + +#include "lib\types.h" +#include "Vector3D.h" +#include "ModelDef.h" + +//////////////////////////////////////////////////////////////////////// +// ExpVertex: vertex type used in building mesh geometry +struct ExpVertex { + // index into original meshes point list + unsigned int m_Index; + // object space position + CVector3D m_Pos; + // object space normal + CVector3D m_Normal; + // uv coordinates + float m_UVs[2]; +}; + +#endif + diff --git a/source/tools/pmdexp/MaxInc.h b/source/tools/pmdexp/MaxInc.h index 436a5fd871..fcff91f04b 100755 --- a/source/tools/pmdexp/MaxInc.h +++ b/source/tools/pmdexp/MaxInc.h @@ -1,15 +1,15 @@ -#ifndef _MAXINC_H -#define _MAXINC_H - -#define timeval MAX_timeval -//#define ERROR MAX_ERROR - -#include "Max.h" -#include "iparamb2.h" -#include "iparamm2.h" -#include "istdplug.h" -#include "resource.h" - -#undef timeval - -#endif +#ifndef _MAXINC_H +#define _MAXINC_H + +#define timeval MAX_timeval +//#define ERROR MAX_ERROR + +#include "Max.h" +#include "iparamb2.h" +#include "iparamm2.h" +#include "istdplug.h" +#include "resource.h" + +#undef timeval + +#endif diff --git a/source/tools/pmdexp/PMDExp.cpp b/source/tools/pmdexp/PMDExp.cpp index caa08e2543..8fcc2ea9c6 100755 --- a/source/tools/pmdexp/PMDExp.cpp +++ b/source/tools/pmdexp/PMDExp.cpp @@ -1,276 +1,276 @@ -#include "PMDExp.h" -#include "ExpMesh.h" -#include "ExpProp.h" -#include "ExpSkeleton.h" - -#undef PI -#include "ModelDef.h" - - -////////////////////////////////////////////////////////////////////// -// PMDExp constructor -PMDExp::PMDExp() -{ -} - -////////////////////////////////////////////////////////////////////// -// PMDExp destructor -PMDExp::~PMDExp() -{ -} - -////////////////////////////////////////////////////////////////////// -// ExtCount: return the number of file name extensions supported -// by the plug-in. -int PMDExp::ExtCount() -{ - return 1; -} - -////////////////////////////////////////////////////////////////////// -// Ext: return the ith file name extension -const TCHAR* PMDExp::Ext(int n) -{ - return _T("pmd"); -} - -////////////////////////////////////////////////////////////////////// -// LongDesc: return long ASCII description -const TCHAR* PMDExp::LongDesc() -{ - return _T("Prometheus Model Data"); -} - -////////////////////////////////////////////////////////////////////// -// ShortDesc: return short ASCII description -const TCHAR* PMDExp::ShortDesc() -{ - return _T("Prometheus Model"); -} - -////////////////////////////////////////////////////////////////////// -// AuthorName: return author name -const TCHAR* PMDExp::AuthorName() -{ - return _T("Rich Cross"); -} - -////////////////////////////////////////////////////////////////////// -// CopyrightMessage: return copyright message -const TCHAR* PMDExp::CopyrightMessage() -{ - return _T("(c) Wildfire Games 2004"); -} - -////////////////////////////////////////////////////////////////////// -// OtherMessage1: return some other message (or don't, in this case) -const TCHAR* PMDExp::OtherMessage1() -{ - return _T(""); -} - -////////////////////////////////////////////////////////////////////// -// OtherMessage2: return some other message (or don't, in this case) -const TCHAR* PMDExp::OtherMessage2() -{ - return _T(""); -} - -////////////////////////////////////////////////////////////////////// -// Version: return version number * 100 (i.e. v3.01 = 301) -unsigned int PMDExp::Version() -{ - return 1; -} - -////////////////////////////////////////////////////////////////////// -// ShowAbout: show an about box (or don't, in this case) -void PMDExp::ShowAbout(HWND hWnd) -{ -} - -////////////////////////////////////////////////////////////////////// -// SupportsOptions: return true for each option supported by each -// extension the exporter supports -BOOL PMDExp::SupportsOptions(int ext, DWORD options) -{ - // return TRUE to indicate export selected supported - return TRUE; -} - -////////////////////////////////////////////////////////////////////// -// DoExport: actually perform the export to the given filename -int PMDExp::DoExport(const TCHAR *name,ExpInterface *ei,Interface *ip, BOOL suppressPrompts, DWORD options) -{ - // result of the export: assume we'll fail somewhere along the way - BOOL res=FALSE; - - // save off the interface ptr - m_IP=ip; - - // save off the options - m_Options=options; - - // build any skeletons in MAXs heirarchy before going any further - std::vector skeletons; - ExpSkeleton::BuildSkeletons(m_IP->GetRootNode(),skeletons); - if (skeletons.size()>1) { - MessageBox(GetActiveWindow(),"Found more than one skeleton in scene","Error",MB_OK); - } else { - // build list of meshes and props from nodes in MAXs heirarchy - std::vector meshes; - std::vector props; - ExpSkeleton* skeleton=skeletons.size()>0 ? skeletons[0] : 0; - BuildOutputList(m_IP->GetRootNode(),skeleton,meshes,props); - if (meshes.size()==0) { - // hmm .. nothing there? - MessageBox(GetActiveWindow(),"Failed to find any meshes to export","Error",MB_OK); - } else { - // build a model from the node tree and any skeleton in scene - CModelDef* model=BuildModel(meshes,props,skeleton); - if (!model) { - MessageBox(GetActiveWindow(),"Failed to create model","Error",MB_OK); - } else { - try { - CModelDef::Save(name,model); - res=TRUE; - } catch (...) { - res=FALSE; - } - - MessageBox(GetActiveWindow(),res ? "Export Complete" : "Error saving model",res ? "Info" : "Error",MB_OK); - } - - for (int i=0;i& meshes,std::vector& props) -{ - // get object attached to node - ObjectState os=node->EvalWorldState(0); - if (os.obj) { - // handle export selected - if ((m_Options & SCENE_EXPORT_SELECTED) && !node->Selected()) { - // ignore .. - } else { - // mesh? - bool isMesh=true; // assume so - if (isMesh && !PMDExpMesh::IsMesh(os.obj)) isMesh=false; - if (isMesh && ExpSkeleton::IsBone(node)) isMesh=false; - if (isMesh && ExpSkeleton::IsFootprints(node)) isMesh=false; - - if (isMesh) { - PMDExpMesh meshbuilder(node,skeleton); - ExpMesh* mesh=meshbuilder.Build(); - meshes.push_back(mesh); - } else { - // not a mesh - a prop? - if (PMDExpProp::IsProp(os.obj)) { - PMDExpProp propbuilder(node); - ExpProp* prop=propbuilder.Build(); - props.push_back(prop); - } - } - } - } - - // traverse into children - for (int i=0;iNumberOfChildren();i++) { - BuildOutputList(node->GetChildNode(i),skeleton,meshes,props); - } -} - - -///////////////////////////////////////////////////////////////////////////////// -// BuildModel: weld together given list of meshes, and attach props; return -// result as a CModelDef -CModelDef* PMDExp::BuildModel(std::vector& meshes,std::vector& props, - ExpSkeleton* skeleton) -{ - SVertexBlend nullBlend; - memset(nullBlend.m_Bone,0xff,sizeof(nullBlend.m_Bone)); - memset(nullBlend.m_Weight,0,sizeof(nullBlend.m_Weight)); - - // sum up total number of vertices and faces - u32 totalVerts=0,totalFaces=0; - for (int i=0;im_Vertices.size(); - totalFaces+=meshes[i]->m_Faces.size(); - } - - CModelDef* mdl=new CModelDef; - - mdl->m_NumVertices=totalVerts; - mdl->m_pVertices=new SModelVertex[totalVerts]; - - mdl->m_NumFaces=totalFaces; - mdl->m_pFaces=new SModelFace[totalFaces]; - - mdl->m_NumBones=skeleton ? skeleton->m_Bones.size() : 0; - mdl->m_Bones=new CBoneState[mdl->m_NumBones]; - - // build vertices - int vcount=0; - for (i=0;im_Vertices; - const VBlendList& blends=meshes[i]->m_Blends; - for (int j=0;jm_pVertices[vcount].m_Coords=verts[j].m_Pos; - mdl->m_pVertices[vcount].m_Norm=verts[j].m_Normal; - mdl->m_pVertices[vcount].m_U=verts[j].m_UVs[0]; - mdl->m_pVertices[vcount].m_V=verts[j].m_UVs[1]; - mdl->m_pVertices[vcount].m_Blend=blends.size()>0 ? blends[verts[j].m_Index] : nullBlend; - vcount++; - } - } - - // build faces - int fcount=0; - int offset=0; - for (i=0;im_Faces; - for (int j=0;jm_pFaces[fcount].m_Verts[0]=faces[j].m_V[0]+offset; - mdl->m_pFaces[fcount].m_Verts[1]=faces[j].m_V[1]+offset; - mdl->m_pFaces[fcount].m_Verts[2]=faces[j].m_V[2]+offset; - fcount++; - } - offset+=meshes[i]->m_Vertices.size(); - } - - // build bones - for (i=0;im_NumBones;i++) { - mdl->m_Bones[i].m_Translation=skeleton->m_Bones[i]->m_Translation; - mdl->m_Bones[i].m_Rotation=skeleton->m_Bones[i]->m_Rotation; - } - - // attach props - mdl->m_NumPropPoints=props.size(); - mdl->m_PropPoints=new SPropPoint[mdl->m_NumPropPoints]; - for (i=0;im_NumPropPoints;i++) { - mdl->m_PropPoints[i].m_Name=props[i]->m_Name; - mdl->m_PropPoints[i].m_Position=props[i]->m_Position; - mdl->m_PropPoints[i].m_Rotation=props[i]->m_Rotation; - mdl->m_PropPoints[i].m_BoneIndex=skeleton ? skeleton->FindBoneByNode(props[i]->m_Parent) : 0xff; - } - - // all done - return mdl; -} - - +#include "PMDExp.h" +#include "ExpMesh.h" +#include "ExpProp.h" +#include "ExpSkeleton.h" + +#undef PI +#include "ModelDef.h" + + +////////////////////////////////////////////////////////////////////// +// PMDExp constructor +PMDExp::PMDExp() +{ +} + +////////////////////////////////////////////////////////////////////// +// PMDExp destructor +PMDExp::~PMDExp() +{ +} + +////////////////////////////////////////////////////////////////////// +// ExtCount: return the number of file name extensions supported +// by the plug-in. +int PMDExp::ExtCount() +{ + return 1; +} + +////////////////////////////////////////////////////////////////////// +// Ext: return the ith file name extension +const TCHAR* PMDExp::Ext(int n) +{ + return _T("pmd"); +} + +////////////////////////////////////////////////////////////////////// +// LongDesc: return long ASCII description +const TCHAR* PMDExp::LongDesc() +{ + return _T("Prometheus Model Data"); +} + +////////////////////////////////////////////////////////////////////// +// ShortDesc: return short ASCII description +const TCHAR* PMDExp::ShortDesc() +{ + return _T("Prometheus Model"); +} + +////////////////////////////////////////////////////////////////////// +// AuthorName: return author name +const TCHAR* PMDExp::AuthorName() +{ + return _T("Rich Cross"); +} + +////////////////////////////////////////////////////////////////////// +// CopyrightMessage: return copyright message +const TCHAR* PMDExp::CopyrightMessage() +{ + return _T("(c) Wildfire Games 2004"); +} + +////////////////////////////////////////////////////////////////////// +// OtherMessage1: return some other message (or don't, in this case) +const TCHAR* PMDExp::OtherMessage1() +{ + return _T(""); +} + +////////////////////////////////////////////////////////////////////// +// OtherMessage2: return some other message (or don't, in this case) +const TCHAR* PMDExp::OtherMessage2() +{ + return _T(""); +} + +////////////////////////////////////////////////////////////////////// +// Version: return version number * 100 (i.e. v3.01 = 301) +unsigned int PMDExp::Version() +{ + return 1; +} + +////////////////////////////////////////////////////////////////////// +// ShowAbout: show an about box (or don't, in this case) +void PMDExp::ShowAbout(HWND hWnd) +{ +} + +////////////////////////////////////////////////////////////////////// +// SupportsOptions: return true for each option supported by each +// extension the exporter supports +BOOL PMDExp::SupportsOptions(int ext, DWORD options) +{ + // return TRUE to indicate export selected supported + return TRUE; +} + +////////////////////////////////////////////////////////////////////// +// DoExport: actually perform the export to the given filename +int PMDExp::DoExport(const TCHAR *name,ExpInterface *ei,Interface *ip, BOOL suppressPrompts, DWORD options) +{ + // result of the export: assume we'll fail somewhere along the way + BOOL res=FALSE; + + // save off the interface ptr + m_IP=ip; + + // save off the options + m_Options=options; + + // build any skeletons in MAXs heirarchy before going any further + std::vector skeletons; + ExpSkeleton::BuildSkeletons(m_IP->GetRootNode(),skeletons); + if (skeletons.size()>1) { + MessageBox(GetActiveWindow(),"Found more than one skeleton in scene","Error",MB_OK); + } else { + // build list of meshes and props from nodes in MAXs heirarchy + std::vector meshes; + std::vector props; + ExpSkeleton* skeleton=skeletons.size()>0 ? skeletons[0] : 0; + BuildOutputList(m_IP->GetRootNode(),skeleton,meshes,props); + if (meshes.size()==0) { + // hmm .. nothing there? + MessageBox(GetActiveWindow(),"Failed to find any meshes to export","Error",MB_OK); + } else { + // build a model from the node tree and any skeleton in scene + CModelDef* model=BuildModel(meshes,props,skeleton); + if (!model) { + MessageBox(GetActiveWindow(),"Failed to create model","Error",MB_OK); + } else { + try { + CModelDef::Save(name,model); + res=TRUE; + } catch (...) { + res=FALSE; + } + + MessageBox(GetActiveWindow(),res ? "Export Complete" : "Error saving model",res ? "Info" : "Error",MB_OK); + } + + for (int i=0;i& meshes,std::vector& props) +{ + // get object attached to node + ObjectState os=node->EvalWorldState(0); + if (os.obj) { + // handle export selected + if ((m_Options & SCENE_EXPORT_SELECTED) && !node->Selected()) { + // ignore .. + } else { + // mesh? + bool isMesh=true; // assume so + if (isMesh && !PMDExpMesh::IsMesh(os.obj)) isMesh=false; + if (isMesh && ExpSkeleton::IsBone(node)) isMesh=false; + if (isMesh && ExpSkeleton::IsFootprints(node)) isMesh=false; + + if (isMesh) { + PMDExpMesh meshbuilder(node,skeleton); + ExpMesh* mesh=meshbuilder.Build(); + meshes.push_back(mesh); + } else { + // not a mesh - a prop? + if (PMDExpProp::IsProp(os.obj)) { + PMDExpProp propbuilder(node); + ExpProp* prop=propbuilder.Build(); + props.push_back(prop); + } + } + } + } + + // traverse into children + for (int i=0;iNumberOfChildren();i++) { + BuildOutputList(node->GetChildNode(i),skeleton,meshes,props); + } +} + + +///////////////////////////////////////////////////////////////////////////////// +// BuildModel: weld together given list of meshes, and attach props; return +// result as a CModelDef +CModelDef* PMDExp::BuildModel(std::vector& meshes,std::vector& props, + ExpSkeleton* skeleton) +{ + SVertexBlend nullBlend; + memset(nullBlend.m_Bone,0xff,sizeof(nullBlend.m_Bone)); + memset(nullBlend.m_Weight,0,sizeof(nullBlend.m_Weight)); + + // sum up total number of vertices and faces + u32 totalVerts=0,totalFaces=0; + for (int i=0;im_Vertices.size(); + totalFaces+=meshes[i]->m_Faces.size(); + } + + CModelDef* mdl=new CModelDef; + + mdl->m_NumVertices=totalVerts; + mdl->m_pVertices=new SModelVertex[totalVerts]; + + mdl->m_NumFaces=totalFaces; + mdl->m_pFaces=new SModelFace[totalFaces]; + + mdl->m_NumBones=skeleton ? skeleton->m_Bones.size() : 0; + mdl->m_Bones=new CBoneState[mdl->m_NumBones]; + + // build vertices + int vcount=0; + for (i=0;im_Vertices; + const VBlendList& blends=meshes[i]->m_Blends; + for (int j=0;jm_pVertices[vcount].m_Coords=verts[j].m_Pos; + mdl->m_pVertices[vcount].m_Norm=verts[j].m_Normal; + mdl->m_pVertices[vcount].m_U=verts[j].m_UVs[0]; + mdl->m_pVertices[vcount].m_V=verts[j].m_UVs[1]; + mdl->m_pVertices[vcount].m_Blend=blends.size()>0 ? blends[verts[j].m_Index] : nullBlend; + vcount++; + } + } + + // build faces + int fcount=0; + int offset=0; + for (i=0;im_Faces; + for (int j=0;jm_pFaces[fcount].m_Verts[0]=faces[j].m_V[0]+offset; + mdl->m_pFaces[fcount].m_Verts[1]=faces[j].m_V[1]+offset; + mdl->m_pFaces[fcount].m_Verts[2]=faces[j].m_V[2]+offset; + fcount++; + } + offset+=meshes[i]->m_Vertices.size(); + } + + // build bones + for (i=0;im_NumBones;i++) { + mdl->m_Bones[i].m_Translation=skeleton->m_Bones[i]->m_Translation; + mdl->m_Bones[i].m_Rotation=skeleton->m_Bones[i]->m_Rotation; + } + + // attach props + mdl->m_NumPropPoints=props.size(); + mdl->m_PropPoints=new SPropPoint[mdl->m_NumPropPoints]; + for (i=0;im_NumPropPoints;i++) { + mdl->m_PropPoints[i].m_Name=props[i]->m_Name; + mdl->m_PropPoints[i].m_Position=props[i]->m_Position; + mdl->m_PropPoints[i].m_Rotation=props[i]->m_Rotation; + mdl->m_PropPoints[i].m_BoneIndex=skeleton ? skeleton->FindBoneByNode(props[i]->m_Parent) : 0xff; + } + + // all done + return mdl; +} + + diff --git a/source/tools/pmdexp/PMDExp.h b/source/tools/pmdexp/PMDExp.h index 5ef73b5ab7..3f631322e2 100755 --- a/source/tools/pmdexp/PMDExp.h +++ b/source/tools/pmdexp/PMDExp.h @@ -1,53 +1,53 @@ -#ifndef __PMDEXP_H -#define __PMDEXP_H - -// necessary includes -#include "MaxInc.h" -#include - -// necessary declarations -class ExpMesh; -class ExpProp; -class ExpSkeleton; -class CModelDef; - -///////////////////////////////////////////////////////////////// -// PMDExp: -class PMDExp : public SceneExport -{ -public: - PMDExp(); - ~PMDExp(); - - // standard stuff that Max requires - int ExtCount(); // Number of extensions supported - const TCHAR* Ext(int n); // Extension #n (i.e. "3DS") - const TCHAR* LongDesc(); // Long ASCII description (i.e. "Autodesk 3D Studio File") - const TCHAR* ShortDesc(); // Short ASCII description (i.e. "3D Studio") - const TCHAR* AuthorName(); // ASCII Author name - const TCHAR* CopyrightMessage(); // ASCII Copyright message - const TCHAR* OtherMessage1(); // Other message #1 - const TCHAR* OtherMessage2(); // Other message #2 - unsigned int Version(); // Version number * 100 (i.e. v3.01 = 301) - void ShowAbout(HWND hWnd); // Show DLL's "About..." box - - BOOL SupportsOptions(int ext, DWORD options); - int DoExport(const TCHAR *name,ExpInterface *ei,Interface *i, BOOL suppressPrompts=FALSE, DWORD options=0); - -private: - // BuildOutputList: traverse heirarchy collecting meshes/props - void BuildOutputList(INode* node,ExpSkeleton* skeleton, - std::vector& meshes,std::vector& props); - // WeldMeshes: weld together given list of meshes; return result as a CModelDef - CModelDef* BuildModel(std::vector& meshes,std::vector& props,ExpSkeleton* skeleton); - - // pointer to MAXs Interface object - Interface* m_IP; - // handle to the export parameters window - HWND m_Params; - // export options - DWORD m_Options; -}; - - -#endif +#ifndef __PMDEXP_H +#define __PMDEXP_H + +// necessary includes +#include "MaxInc.h" +#include + +// necessary declarations +class ExpMesh; +class ExpProp; +class ExpSkeleton; +class CModelDef; + +///////////////////////////////////////////////////////////////// +// PMDExp: +class PMDExp : public SceneExport +{ +public: + PMDExp(); + ~PMDExp(); + + // standard stuff that Max requires + int ExtCount(); // Number of extensions supported + const TCHAR* Ext(int n); // Extension #n (i.e. "3DS") + const TCHAR* LongDesc(); // Long ASCII description (i.e. "Autodesk 3D Studio File") + const TCHAR* ShortDesc(); // Short ASCII description (i.e. "3D Studio") + const TCHAR* AuthorName(); // ASCII Author name + const TCHAR* CopyrightMessage(); // ASCII Copyright message + const TCHAR* OtherMessage1(); // Other message #1 + const TCHAR* OtherMessage2(); // Other message #2 + unsigned int Version(); // Version number * 100 (i.e. v3.01 = 301) + void ShowAbout(HWND hWnd); // Show DLL's "About..." box + + BOOL SupportsOptions(int ext, DWORD options); + int DoExport(const TCHAR *name,ExpInterface *ei,Interface *i, BOOL suppressPrompts=FALSE, DWORD options=0); + +private: + // BuildOutputList: traverse heirarchy collecting meshes/props + void BuildOutputList(INode* node,ExpSkeleton* skeleton, + std::vector& meshes,std::vector& props); + // WeldMeshes: weld together given list of meshes; return result as a CModelDef + CModelDef* BuildModel(std::vector& meshes,std::vector& props,ExpSkeleton* skeleton); + + // pointer to MAXs Interface object + Interface* m_IP; + // handle to the export parameters window + HWND m_Params; + // export options + DWORD m_Options; +}; + + +#endif diff --git a/source/tools/pmdexp/PSAExp.cpp b/source/tools/pmdexp/PSAExp.cpp index 09b410e0c8..fcdb5b1035 100755 --- a/source/tools/pmdexp/PSAExp.cpp +++ b/source/tools/pmdexp/PSAExp.cpp @@ -1,143 +1,143 @@ -#include "PSAExp.h" -#include "ExpMesh.h" -#include "ExpSkeleton.h" - -#undef PI -#include "ModelDef.h" -#include "SkeletonAnim.h" - -////////////////////////////////////////////////////////////////////// -// PSAExp constructor -PSAExp::PSAExp() -{ -} - -////////////////////////////////////////////////////////////////////// -// PSAExp destructor -PSAExp::~PSAExp() -{ -} - -////////////////////////////////////////////////////////////////////// -// ExtCount: return the number of file name extensions supported -// by the plug-in. -int PSAExp::ExtCount() -{ - return 1; -} - -////////////////////////////////////////////////////////////////////// -// Ext: return the ith file name extension -const TCHAR* PSAExp::Ext(int n) -{ - return _T("psa"); -} - -////////////////////////////////////////////////////////////////////// -// LongDesc: return long ASCII description -const TCHAR* PSAExp::LongDesc() -{ - return _T("Prometheus Skeleton Anim"); -} - -////////////////////////////////////////////////////////////////////// -// ShortDesc: return short ASCII description -const TCHAR* PSAExp::ShortDesc() -{ - return _T("Prometheus Anim"); -} - -////////////////////////////////////////////////////////////////////// -// AuthorName: return author name -const TCHAR* PSAExp::AuthorName() -{ - return _T("Rich Cross"); -} - -////////////////////////////////////////////////////////////////////// -// CopyrightMessage: return copyright message -const TCHAR* PSAExp::CopyrightMessage() -{ - return _T("(c) Wildfire Games 2004"); -} - -////////////////////////////////////////////////////////////////////// -// OtherMessage1: return some other message (or don't, in this case) -const TCHAR* PSAExp::OtherMessage1() -{ - return _T(""); -} - -////////////////////////////////////////////////////////////////////// -// OtherMessage2: return some other message (or don't, in this case) -const TCHAR* PSAExp::OtherMessage2() -{ - return _T(""); -} - -////////////////////////////////////////////////////////////////////// -// Version: return version number * 100 (i.e. v3.01 = 301) -unsigned int PSAExp::Version() -{ - return 1; -} - -////////////////////////////////////////////////////////////////////// -// ShowAbout: show an about box (or don't, in this case) -void PSAExp::ShowAbout(HWND hWnd) -{ -} - -////////////////////////////////////////////////////////////////////// -// SupportsOptions: return true for each option supported by each -// extension the exporter supports -BOOL PSAExp::SupportsOptions(int ext, DWORD options) -{ - // return TRUE to indicate export selected supported - return TRUE; -} - -////////////////////////////////////////////////////////////////////// -// DoExport: actually perform the export to the given filename -int PSAExp::DoExport(const TCHAR *name,ExpInterface *ei,Interface *ip, BOOL suppressPrompts, DWORD options) -{ - // result of the export: assume we'll fail somewhere along the way - BOOL res=FALSE; - - // save off the interface ptr - m_IP=ip; - - // save off the options - m_Options=options; - - // build any skeletons in MAXs heirarchy before going any further - std::vector skeletons; - ExpSkeleton::BuildSkeletons(m_IP->GetRootNode(),skeletons); - if (skeletons.size()>1) { - MessageBox(GetActiveWindow(),"Found more than one skeleton in scene","Error",MB_OK); - } else if (skeletons.size()==0) { - MessageBox(GetActiveWindow(),"No skeletons found in scene","Error",MB_OK); - } else { - // build an animation from first skeleton - ExpSkeleton* skeleton=skeletons[0]; - Interval interval=m_IP->GetAnimRange(); - CSkeletonAnimDef* anim=skeleton->BuildAnimation(interval.Start(),interval.End(),1000/30); - try { - CSkeletonAnimDef::Save(name,anim); - res=TRUE; - } catch (...) { - res=FALSE; - } - - MessageBox(GetActiveWindow(),res ? "Export Complete" : "Error saving model",res ? "Info" : "Error",MB_OK); - } - - // clean up - for (int i=0;i skeletons; + ExpSkeleton::BuildSkeletons(m_IP->GetRootNode(),skeletons); + if (skeletons.size()>1) { + MessageBox(GetActiveWindow(),"Found more than one skeleton in scene","Error",MB_OK); + } else if (skeletons.size()==0) { + MessageBox(GetActiveWindow(),"No skeletons found in scene","Error",MB_OK); + } else { + // build an animation from first skeleton + ExpSkeleton* skeleton=skeletons[0]; + Interval interval=m_IP->GetAnimRange(); + CSkeletonAnimDef* anim=skeleton->BuildAnimation(interval.Start(),interval.End(),1000/30); + try { + CSkeletonAnimDef::Save(name,anim); + res=TRUE; + } catch (...) { + res=FALSE; + } + + MessageBox(GetActiveWindow(),res ? "Export Complete" : "Error saving model",res ? "Info" : "Error",MB_OK); + } + + // clean up + for (int i=0;i - -// necessary declarations -class ExpMesh; -class ExpSkeleton; -class CModelDef; -class CSkeleton; - -///////////////////////////////////////////////////////////////// -// PSAExp: -class PSAExp : public SceneExport -{ -public: - PSAExp(); - ~PSAExp(); - - // standard stuff that Max requires - int ExtCount(); // Number of extensions supported - const TCHAR* Ext(int n); // Extension #n (i.e. "3DS") - const TCHAR* LongDesc(); // Long ASCII description (i.e. "Autodesk 3D Studio File") - const TCHAR* ShortDesc(); // Short ASCII description (i.e. "3D Studio") - const TCHAR* AuthorName(); // ASCII Author name - const TCHAR* CopyrightMessage(); // ASCII Copyright message - const TCHAR* OtherMessage1(); // Other message #1 - const TCHAR* OtherMessage2(); // Other message #2 - unsigned int Version(); // Version number * 100 (i.e. v3.01 = 301) - void ShowAbout(HWND hWnd); // Show DLL's "About..." box - - BOOL SupportsOptions(int ext, DWORD options); - int DoExport(const TCHAR *name,ExpInterface *ei,Interface *i, BOOL suppressPrompts=FALSE, DWORD options=0); - -private: - // pointer to MAXs Interface object - Interface* m_IP; - // handle to the export parameters window - HWND m_Params; - // export options - DWORD m_Options; - // list of all skeletons found in scene - std::vector m_Skeletons; -}; - - -#endif +#ifndef __PSAEXP_H +#define __PSAEXP_H + +// necessary includes +#include "MaxInc.h" +#include + +// necessary declarations +class ExpMesh; +class ExpSkeleton; +class CModelDef; +class CSkeleton; + +///////////////////////////////////////////////////////////////// +// PSAExp: +class PSAExp : public SceneExport +{ +public: + PSAExp(); + ~PSAExp(); + + // standard stuff that Max requires + int ExtCount(); // Number of extensions supported + const TCHAR* Ext(int n); // Extension #n (i.e. "3DS") + const TCHAR* LongDesc(); // Long ASCII description (i.e. "Autodesk 3D Studio File") + const TCHAR* ShortDesc(); // Short ASCII description (i.e. "3D Studio") + const TCHAR* AuthorName(); // ASCII Author name + const TCHAR* CopyrightMessage(); // ASCII Copyright message + const TCHAR* OtherMessage1(); // Other message #1 + const TCHAR* OtherMessage2(); // Other message #2 + unsigned int Version(); // Version number * 100 (i.e. v3.01 = 301) + void ShowAbout(HWND hWnd); // Show DLL's "About..." box + + BOOL SupportsOptions(int ext, DWORD options); + int DoExport(const TCHAR *name,ExpInterface *ei,Interface *i, BOOL suppressPrompts=FALSE, DWORD options=0); + +private: + // pointer to MAXs Interface object + Interface* m_IP; + // handle to the export parameters window + HWND m_Params; + // export options + DWORD m_Options; + // list of all skeletons found in scene + std::vector m_Skeletons; +}; + + +#endif diff --git a/source/tools/pmdexp/PSProp.cpp b/source/tools/pmdexp/PSProp.cpp index f4509b6229..d0c5841320 100755 --- a/source/tools/pmdexp/PSProp.cpp +++ b/source/tools/pmdexp/PSProp.cpp @@ -1,924 +1,924 @@ -/********************************************************************** - *< - FILE: pthelp.cpp - - DESCRIPTION: A point helper implementation - - CREATED BY: - - HISTORY: created 14 July 1995 - - *> Copyright (c) 1995, All Rights Reserved. - **********************************************************************/ - -#include "PSProp.h" - - -//------------------------------------------------------ - -// in prim.cpp - The dll instance handle -extern HINSTANCE hInstance; - -#define AXIS_LENGTH 20.0f -#define ZFACT (float).005; - -void AxisViewportRect(ViewExp *vpt, const Matrix3 &tm, float length, Rect *rect); -void DrawAxis(ViewExp *vpt, const Matrix3 &tm, float length, BOOL screenSize); -Box3 GetAxisBox(ViewExp *vpt, const Matrix3 &tm,float length,int resetTM); - - -////////////////////////////////////////////////////////////////////////////////////// -// PSPropClassDesc : required class to expose PSProp to MAX -class PSPropClassDesc : public ClassDesc2 -{ -public: - int IsPublic() { return 1; } - void * Create(BOOL loading = FALSE) { return new PSPropObject; } - const TCHAR * ClassName() { return GetString(IDS_DB_POINT_CLASS); } - SClass_ID SuperClassID() { return HELPER_CLASS_ID; } - Class_ID ClassID() { return PSPROP_CLASS_ID; } - const TCHAR* Category() { return _T("PS Helpers"); } - - const TCHAR* InternalName() {return _T("PSProp");} - HINSTANCE HInstance() {return hInstance;} -}; - -PSPropClassDesc pointHelpObjDesc; -ClassDesc* GetPSPropDesc() { return &pointHelpObjDesc; } - - -// class variable for point class. -IObjParam *PSPropObject::ip = NULL; -PSPropObject *PSPropObject::editOb = NULL; - - -//HWND PSPropObject::hParams = NULL; -//IObjParam *PSPropObject::iObjParams; - -//int PSPropObject::dlgShowAxis = TRUE; -//float PSPropObject::dlgAxisLength = AXIS_LENGTH; - -void resetPointParams() -{ - //PSPropObject::dlgShowAxis = TRUE; - //PSPropObject::dlgAxisLength = AXIS_LENGTH; -} - - - - - -#define PBLOCK_REF_NO 0 - -// The following two enums are transfered to the istdplug.h by AG: 01/20/2002 -// in order to access the parameters for use in Spline IK Control modifier -// and the Spline IK Solver - -// block IDs -//enum { pointobj_params, }; - -// pointobj_params IDs - -// enum { -// pointobj_size, pointobj_centermarker, pointobj_axistripod, -// pointobj_cross, pointobj_box, pointobj_screensize, pointobj_drawontop }; - -// per instance block -static ParamBlockDesc2 pointobj_param_blk( - - pointobj_params, _T("PointObjectParameters"), 0, &pointHelpObjDesc, P_AUTO_CONSTRUCT+P_AUTO_UI, PBLOCK_REF_NO, - - //rollout - IDD_NEW_POINTPARAM, IDS_POINT_PARAMS, 0, 0, NULL, - - // params - pointobj_size, _T("size"), TYPE_FLOAT, P_ANIMATABLE, IDS_POINT_SIZE, - p_default, 20.0, - p_ms_default, 20.0, - p_range, 0.0f, float(1.0E30), - p_ui, TYPE_SPINNER, EDITTYPE_UNIVERSE, IDC_POINT_SIZE, IDC_POINT_SIZESPIN, SPIN_AUTOSCALE, - end, - - - pointobj_centermarker, _T("centermarker"), TYPE_BOOL, P_ANIMATABLE, IDS_POINT_CENTERMARKER, - p_default, FALSE, - p_ui, TYPE_SINGLECHEKBOX, IDC_POINT_MARKER, - end, - - pointobj_axistripod, _T("axistripod"), TYPE_BOOL, P_ANIMATABLE, IDS_POINT_AXISTRIPOD, - p_default, FALSE, - p_ui, TYPE_SINGLECHEKBOX, IDC_POINT_AXIS, - end, - - pointobj_cross, _T("cross"), TYPE_BOOL, P_ANIMATABLE, IDS_POINT_CROSS, - p_default, TRUE, - p_ui, TYPE_SINGLECHEKBOX, IDC_POINT_CROSS, - end, - - pointobj_box, _T("box"), TYPE_BOOL, P_ANIMATABLE, IDS_POINT_BOX, - p_default, FALSE, - p_ui, TYPE_SINGLECHEKBOX, IDC_POINT_BOX, - end, - - pointobj_screensize, _T("constantscreensize"), TYPE_BOOL, P_ANIMATABLE, IDS_POINT_SCREENSIZE, - p_default, FALSE, - p_ui, TYPE_SINGLECHEKBOX, IDC_POINT_SCREENSIZE, - end, - - pointobj_drawontop, _T("drawontop"), TYPE_BOOL, P_ANIMATABLE, IDS_POINT_DRAWONTOP, - p_default, FALSE, - p_ui, TYPE_SINGLECHEKBOX, IDC_POINT_DRAWONTOP, - end, - - end - ); - - - - - -/* -INT_PTR CALLBACK PointParamProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam) - { - PSPropObject *po = (PSPropObject*)GetWindowLongPtr(hWnd,GWLP_USERDATA); - if (!po && msg!=WM_INITDIALOG) return FALSE; - - switch (msg) { - case WM_INITDIALOG: { - po = (PSPropObject*)lParam; - SetWindowLongPtr(hWnd,GWLP_USERDATA,lParam); - CheckDlgButton(hWnd,IDC_SHOWAXIS,po->showAxis); - - ISpinnerControl *spin = - GetISpinner(GetDlgItem(hWnd,IDC_AXISLENGHSPIN)); - spin->SetLimits(10,1000,FALSE); - spin->SetScale(0.1f); - spin->SetValue(po->axisLength,FALSE); - spin->LinkToEdit(GetDlgItem(hWnd,IDC_AXISLENGTH),EDITTYPE_FLOAT); - ReleaseISpinner(spin); - return FALSE; - } - - case CC_SPINNER_CHANGE: { - ISpinnerControl *spin = (ISpinnerControl*)lParam; - po->axisLength = spin->GetFVal(); - po->NotifyDependents(FOREVER,PART_OBJ,REFMSG_CHANGE); - po->iObjParams->RedrawViews(po->iObjParams->GetTime()); - break; - } - - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDC_SHOWAXIS: - po->showAxis = IsDlgButtonChecked(hWnd,IDC_SHOWAXIS); - po->NotifyDependents(FOREVER,PART_OBJ,REFMSG_CHANGE); - po->iObjParams->RedrawViews(po->iObjParams->GetTime()); - break; - } - break; - - default: - return FALSE; - } - - return TRUE; - } -*/ - -void PSPropObject::BeginEditParams( - IObjParam *ip, ULONG flags,Animatable *prev) - { - this->ip = ip; - editOb = this; - pointHelpObjDesc.BeginEditParams(ip, this, flags, prev); - - /* - iObjParams = ip; - if (!hParams) { - hParams = ip->AddRollupPage( - hInstance, - MAKEINTRESOURCE(IDD_POINTPARAM), - PointParamProc, - GetString(IDS_DB_PARAMETERS), - (LPARAM)this ); - ip->RegisterDlgWnd(hParams); - } else { - SetWindowLongPtr(hParams,GWLP_USERDATA,(LONG_PTR)this); - CheckDlgButton(hParams,IDC_SHOWAXIS,showAxis); - ISpinnerControl *spin = - GetISpinner(GetDlgItem(hParams,IDC_AXISLENGHSPIN)); - spin->SetValue(axisLength,FALSE); - ReleaseISpinner(spin); - } - */ - } - -void PSPropObject::EndEditParams( - IObjParam *ip, ULONG flags,Animatable *next) - { - editOb = NULL; - this->ip = NULL; - pointHelpObjDesc.EndEditParams(ip, this, flags, next); - ClearAFlag(A_OBJ_CREATING); - - /* - dlgShowAxis = IsDlgButtonChecked(hParams, IDC_SHOWAXIS ); - ISpinnerControl *spin = GetISpinner(GetDlgItem(hParams,IDC_AXISLENGHSPIN)); - dlgAxisLength = spin->GetFVal(); - ReleaseISpinner(spin); - if (flags&END_EDIT_REMOVEUI) { - ip->UnRegisterDlgWnd(hParams); - ip->DeleteRollupPage(hParams); - hParams = NULL; - } else { - SetWindowLongPtr(hParams,GWLP_USERDATA,0); - } - iObjParams = NULL; - */ - } - - -PSPropObject::PSPropObject() - { - pointHelpObjDesc.MakeAutoParamBlocks(this); - showAxis = TRUE; //dlgShowAxis; - axisLength = 10.0f; //dlgAxisLength; - suspendSnap = FALSE; - SetAFlag(A_OBJ_CREATING); - } - -PSPropObject::~PSPropObject() - { - DeleteAllRefsFromMe(); - } - -IParamArray *PSPropObject::GetParamBlock() - { - return (IParamArray*)pblock2; - } - -int PSPropObject::GetParamBlockIndex(int id) - { - if (pblock2 && id>=0 && idNumParams()) return id; - else return -1; - } - - -class PointHelpObjCreateCallBack: public CreateMouseCallBack { - PSPropObject *ob; - public: - int proc( ViewExp *vpt,int msg, int point, int flags, IPoint2 m, Matrix3& mat ); - void SetObj(PSPropObject *obj) { ob = obj; } - }; - -int PointHelpObjCreateCallBack::proc(ViewExp *vpt,int msg, int point, int flags, IPoint2 m, Matrix3& mat ) { - - #ifdef _OSNAP - if (msg == MOUSE_FREEMOVE) - { - #ifdef _3D_CREATE - vpt->SnapPreview(m,m,NULL, SNAP_IN_3D); - #else - vpt->SnapPreview(m,m,NULL, SNAP_IN_PLANE); - #endif - } - #endif - - if (msg==MOUSE_POINT||msg==MOUSE_MOVE) { - switch(point) { - case 0: { - - // Find the node and plug in the wire color - ULONG handle; - ob->NotifyDependents(FOREVER, (PartID)&handle, REFMSG_GET_NODE_HANDLE); - INode *node; - node = GetCOREInterface()->GetINodeByHandle(handle); - if (node) { - Point3 color(0,0,1);// = GetUIColor(COLOR_POINT_OBJ); - node->SetWireColor(RGB(color.x*255.0f, color.y*255.0f, color.z*255.0f)); - } - - ob->suspendSnap = TRUE; - #ifdef _3D_CREATE - mat.SetTrans(vpt->SnapPoint(m,m,NULL,SNAP_IN_3D)); - #else - mat.SetTrans(vpt->SnapPoint(m,m,NULL,SNAP_IN_PLANE)); - #endif - break; - } - - case 1: - #ifdef _3D_CREATE - mat.SetTrans(vpt->SnapPoint(m,m,NULL,SNAP_IN_3D)); - #else - mat.SetTrans(vpt->SnapPoint(m,m,NULL,SNAP_IN_PLANE)); - #endif - if (msg==MOUSE_POINT) { - ob->suspendSnap = FALSE; - return 0; - } - break; - } - } else - if (msg == MOUSE_ABORT) { - return CREATE_ABORT; - } - return 1; - } - -static PointHelpObjCreateCallBack pointHelpCreateCB; - -CreateMouseCallBack* PSPropObject::GetCreateMouseCallBack() { - pointHelpCreateCB.SetObj(this); - return(&pointHelpCreateCB); - } - -void PSPropObject::SetExtendedDisplay(int flags) - { - extDispFlags = flags; - } - - -void PSPropObject::GetLocalBoundBox( - TimeValue t, INode* inode, ViewExp* vpt, Box3& box ) - { - Matrix3 tm = inode->GetObjectTM(t); - - float size; - int screenSize; - pblock2->GetValue(pointobj_size, t, size, FOREVER); - pblock2->GetValue(pointobj_screensize, t, screenSize, FOREVER); - - float zoom = 1.0f; - if (screenSize) { - zoom = vpt->GetScreenScaleFactor(tm.GetTrans())*ZFACT; - } - if (zoom==0.0f) zoom = 1.0f; - - size *= zoom; - box = Box3(Point3(0,0,0), Point3(0,0,0)); - box += Point3(size*0.5f, 0.0f, 0.0f); - box += Point3( 0.0f, size*0.5f, 0.0f); - box += Point3( 0.0f, 0.0f, size*0.5f); - box += Point3(-size*0.5f, 0.0f, 0.0f); - box += Point3( 0.0f, -size*0.5f, 0.0f); - box += Point3( 0.0f, 0.0f, -size*0.5f); - - box.EnlargeBy(10.0f/zoom); - - /* - if (showAxis) - box = GetAxisBox(vpt,tm,showAxis?axisLength:0.0f, TRUE); - else - box = Box3(Point3(0,0,0), Point3(0,0,0)); - */ - } - -void PSPropObject::GetWorldBoundBox( - TimeValue t, INode* inode, ViewExp* vpt, Box3& box ) - { - Matrix3 tm; - tm = inode->GetObjectTM(t); - Box3 lbox; - - GetLocalBoundBox(t, inode, vpt, lbox); - box = Box3(tm.GetTrans(), tm.GetTrans()); - for (int i=0; i<8; i++) { - box += lbox * tm; - } - /* - if(!(extDispFlags & EXT_DISP_ZOOM_EXT) && showAxis) - box = GetAxisBox(vpt,tm,showAxis?axisLength:0.0f, FALSE); - else - box = Box3(tm.GetTrans(), tm.GetTrans()); - */ - } - - -void PSPropObject::Snap(TimeValue t, INode* inode, SnapInfo *snap, IPoint2 *p, ViewExp *vpt) - { - if(suspendSnap) - return; - - Matrix3 tm = inode->GetObjectTM(t); - GraphicsWindow *gw = vpt->getGW(); - gw->setTransform(tm); - - Matrix3 invPlane = Inverse(snap->plane); - - // Make sure the vertex priority is active and at least as important as the best snap so far - if(snap->vertPriority > 0 && snap->vertPriority <= snap->priority) { - Point2 fp = Point2((float)p->x, (float)p->y); - Point2 screen2; - IPoint3 pt3; - - Point3 thePoint(0,0,0); - // If constrained to the plane, make sure this point is in it! - if(snap->snapType == SNAP_2D || snap->flags & SNAP_IN_PLANE) { - Point3 test = thePoint * tm * invPlane; - if(fabs(test.z) > 0.0001) // Is it in the plane (within reason)? - return; - } - gw->wTransPoint(&thePoint,&pt3); - screen2.x = (float)pt3.x; - screen2.y = (float)pt3.y; - - // Are we within the snap radius? - int len = (int)Length(screen2 - fp); - if(len <= snap->strength) { - // Is this priority better than the best so far? - if(snap->vertPriority < snap->priority) { - snap->priority = snap->vertPriority; - snap->bestWorld = thePoint * tm; - snap->bestScreen = screen2; - snap->bestDist = len; - } - else - if(len < snap->bestDist) { - snap->priority = snap->vertPriority; - snap->bestWorld = thePoint * tm; - snap->bestScreen = screen2; - snap->bestDist = len; - } - } - } - } - - - - -int PSPropObject::DrawAndHit(TimeValue t, INode *inode, ViewExp *vpt) - { - float size; - int centerMarker, axisTripod, cross, box, screenSize, drawOnTop; - -// Color color = inode->GetWireColor(); - - Interval ivalid = FOREVER; - pblock2->GetValue(pointobj_size, t, size, ivalid); - pblock2->GetValue(pointobj_centermarker, t, centerMarker, ivalid); - pblock2->GetValue(pointobj_axistripod, t, axisTripod, ivalid); - pblock2->GetValue(pointobj_cross, t, cross, ivalid); - pblock2->GetValue(pointobj_box, t, box, ivalid); - pblock2->GetValue(pointobj_screensize, t, screenSize, ivalid); - pblock2->GetValue(pointobj_drawontop, t, drawOnTop, ivalid); - - Matrix3 tm(1); - Point3 pt(0,0,0); - Point3 pts[5]; - - vpt->getGW()->setTransform(tm); - tm = inode->GetObjectTM(t); - - int limits = vpt->getGW()->getRndLimits(); - if (drawOnTop) vpt->getGW()->setRndLimits(limits & ~GW_Z_BUFFER); - - if (inode->Selected()) { - vpt->getGW()->setColor( TEXT_COLOR, GetUIColor(COLOR_SELECTION) ); - vpt->getGW()->setColor( LINE_COLOR, GetUIColor(COLOR_SELECTION) ); - } else if (!inode->IsFrozen() && !inode->Dependent()) { - //vpt->getGW()->setColor( TEXT_COLOR, GetUIColor(COLOR_POINT_AXES) ); - //vpt->getGW()->setColor( LINE_COLOR, GetUIColor(COLOR_POINT_AXES) ); - vpt->getGW()->setColor( TEXT_COLOR, Color(0,0,1)); - vpt->getGW()->setColor( LINE_COLOR, Color(0,0,1)); - } - - if (axisTripod) { - DrawAxis(vpt, tm, size, screenSize); - } - - size *= 0.5f; - - float zoom = vpt->GetScreenScaleFactor(tm.GetTrans())*ZFACT; - if (screenSize) { - tm.Scale(Point3(zoom,zoom,zoom)); - } - - vpt->getGW()->setTransform(tm); - - if (!inode->IsFrozen() && !inode->Dependent() && !inode->Selected()) { - //vpt->getGW()->setColor(LINE_COLOR, GetUIColor(COLOR_POINT_OBJ)); - vpt->getGW()->setColor( LINE_COLOR, Color(0,0,1)); - } - - if (centerMarker) { - vpt->getGW()->marker(&pt,X_MRKR); - } - - if (cross) { - // X - pts[0] = Point3(-size, 0.0f, 0.0f); pts[1] = Point3(size, 0.0f, 0.0f); - vpt->getGW()->polyline(2, pts, NULL, NULL, FALSE, NULL); - - // Y - pts[0] = Point3(0.0f, -size, 0.0f); pts[1] = Point3(0.0f, size, 0.0f); - vpt->getGW()->polyline(2, pts, NULL, NULL, FALSE, NULL); - - // Z - pts[0] = Point3(0.0f, 0.0f, -size); pts[1] = Point3(0.0f, 0.0f, size); - vpt->getGW()->polyline(2, pts, NULL, NULL, FALSE, NULL); - } - - if (box) { - - // Make the box half the size - size = size * 0.5f; - - // Bottom - pts[0] = Point3(-size, -size, -size); - pts[1] = Point3(-size, size, -size); - pts[2] = Point3( size, size, -size); - pts[3] = Point3( size, -size, -size); - vpt->getGW()->polyline(4, pts, NULL, NULL, TRUE, NULL); - - // Top - pts[0] = Point3(-size, -size, size); - pts[1] = Point3(-size, size, size); - pts[2] = Point3( size, size, size); - pts[3] = Point3( size, -size, size); - vpt->getGW()->polyline(4, pts, NULL, NULL, TRUE, NULL); - - // Sides - pts[0] = Point3(-size, -size, -size); - pts[1] = Point3(-size, -size, size); - vpt->getGW()->polyline(2, pts, NULL, NULL, FALSE, NULL); - - pts[0] = Point3(-size, size, -size); - pts[1] = Point3(-size, size, size); - vpt->getGW()->polyline(2, pts, NULL, NULL, FALSE, NULL); - - pts[0] = Point3( size, size, -size); - pts[1] = Point3( size, size, size); - vpt->getGW()->polyline(2, pts, NULL, NULL, FALSE, NULL); - - pts[0] = Point3( size, -size, -size); - pts[1] = Point3( size, -size, size); - vpt->getGW()->polyline(2, pts, NULL, NULL, FALSE, NULL); - } - - vpt->getGW()->setRndLimits(limits); - - return 1; - } - -int PSPropObject::HitTest( - TimeValue t, INode *inode, int type, int crossing, int flags, IPoint2 *p, ViewExp *vpt) - { - Matrix3 tm(1); - HitRegion hitRegion; - DWORD savedLimits; - Point3 pt(0,0,0); - - vpt->getGW()->setTransform(tm); - GraphicsWindow *gw = vpt->getGW(); - Material *mtl = gw->getMaterial(); - - tm = inode->GetObjectTM(t); - MakeHitRegion(hitRegion, type, crossing, 4, p); - - gw->setRndLimits(((savedLimits = gw->getRndLimits())|GW_PICK)&~GW_ILLUM); - gw->setHitRegion(&hitRegion); - gw->clearHitCode(); - - DrawAndHit(t, inode, vpt); - -/* - if (showAxis) { - DrawAxis(vpt,tm,axisLength,screenSize); - } - vpt->getGW()->setTransform(tm); - vpt->getGW()->marker(&pt,X_MRKR); -*/ - - gw->setRndLimits(savedLimits); - - if((hitRegion.type != POINT_RGN) && !hitRegion.crossing) - return TRUE; - return gw->checkHitCode(); - } - - - -int PSPropObject::Display( - TimeValue t, INode* inode, ViewExp *vpt, int flags) - { - DrawAndHit(t, inode, vpt); - /* - Matrix3 tm(1); - Point3 pt(0,0,0); - - vpt->getGW()->setTransform(tm); - tm = inode->GetObjectTM(t); - - if (showAxis) { - DrawAxis(vpt,tm,axisLength,inode->Selected(),inode->IsFrozen()); - } - - - vpt->getGW()->setTransform(tm); - if(!inode->IsFrozen()) - vpt->getGW()->setColor(LINE_COLOR,GetUIColor(COLOR_POINT_OBJ)); - vpt->getGW()->marker(&pt,X_MRKR); - */ - - return(0); - } - - - -// -// Reference Managment: -// - -// This is only called if the object MAKES references to other things. -RefResult PSPropObject::NotifyRefChanged( - Interval changeInt, RefTargetHandle hTarget, - PartID& partID, RefMessage message ) - { - switch (message) { - case REFMSG_CHANGE: - if (editOb==this) InvalidateUI(); - break; - } - return(REF_SUCCEED); - } - -void PSPropObject::InvalidateUI() - { - pointobj_param_blk.InvalidateUI(pblock2->LastNotifyParamID()); - } - -Interval PSPropObject::ObjectValidity(TimeValue t) - { - float size; - int centerMarker, axisTripod, cross, box, screenSize, drawOnTop; - - Interval ivalid = FOREVER; - pblock2->GetValue(pointobj_size, t, size, ivalid); - pblock2->GetValue(pointobj_centermarker, t, centerMarker, ivalid); - pblock2->GetValue(pointobj_axistripod, t, axisTripod, ivalid); - pblock2->GetValue(pointobj_cross, t, cross, ivalid); - pblock2->GetValue(pointobj_box, t, box, ivalid); - pblock2->GetValue(pointobj_screensize, t, screenSize, ivalid); - pblock2->GetValue(pointobj_drawontop, t, drawOnTop, ivalid); - - return ivalid; - } - -ObjectState PSPropObject::Eval(TimeValue t) - { - return ObjectState(this); - } - -RefTargetHandle PSPropObject::Clone(RemapDir& remap) - { - PSPropObject* newob = new PSPropObject(); - newob->showAxis = showAxis; - newob->axisLength = axisLength; - newob->ReplaceReference(0, pblock2->Clone(remap)); - BaseClone(this, newob, remap); - return(newob); - } - - -void PSPropObject::UpdateParamblockFromVars() - { - SuspendAnimate(); - AnimateOff(); - - pblock2->SetValue(pointobj_size, TimeValue(0), axisLength); - pblock2->SetValue(pointobj_centermarker, TimeValue(0), TRUE); - pblock2->SetValue(pointobj_axistripod, TimeValue(0), showAxis); - pblock2->SetValue(pointobj_cross, TimeValue(0), FALSE); - pblock2->SetValue(pointobj_box, TimeValue(0), FALSE); - pblock2->SetValue(pointobj_screensize, TimeValue(0), TRUE); - - ResumeAnimate(); - } - - -class PointHelperPostLoadCallback : public PostLoadCallback { - public: - PSPropObject *pobj; - - PointHelperPostLoadCallback(PSPropObject *p) {pobj=p;} - void proc(ILoad *iload) { - pobj->UpdateParamblockFromVars(); - } - }; - -#define SHOW_AXIS_CHUNK 0x0100 -#define AXIS_LENGTH_CHUNK 0x0110 -#define POINT_HELPER_R4_CHUNKID 0x0120 // new version of point helper for R4 (updated to use PB2) - -IOResult PSPropObject::Load(ILoad *iload) - { - ULONG nb; - IOResult res = IO_OK; - BOOL oldVersion = TRUE; - - while (IO_OK==(res=iload->OpenChunk())) { - switch (iload->CurChunkID()) { - - case SHOW_AXIS_CHUNK: - res = iload->Read(&showAxis,sizeof(showAxis),&nb); - break; - - case AXIS_LENGTH_CHUNK: - res = iload->Read(&axisLength,sizeof(axisLength),&nb); - break; - - case POINT_HELPER_R4_CHUNKID: - oldVersion = FALSE; - break; - } - - res = iload->CloseChunk(); - if (res!=IO_OK) return res; - } - - if (oldVersion) { - iload->RegisterPostLoadCallback(new PointHelperPostLoadCallback(this)); - } - - return IO_OK; - } - -IOResult PSPropObject::Save(ISave *isave) - { - /* - isave->BeginChunk(SHOW_AXIS_CHUNK); - isave->Write(&showAxis,sizeof(showAxis),&nb); - isave->EndChunk(); - - isave->BeginChunk(AXIS_LENGTH_CHUNK); - isave->Write(&axisLength,sizeof(axisLength),&nb); - isave->EndChunk(); - */ - - isave->BeginChunk(POINT_HELPER_R4_CHUNKID); - isave->EndChunk(); - - return IO_OK; - } - - -/*--------------------------------------------------------------------*/ -// -// Stole this from scene.cpp -// Probably couldn't hurt to make an API... -// -// - - -void Text( ViewExp *vpt, TCHAR *str, Point3 &pt ) - { - vpt->getGW()->text( &pt, str ); - } - -static void DrawAnAxis( ViewExp *vpt, Point3 axis ) - { - Point3 v1, v2, v[3]; - v1 = axis * (float)0.9; - if ( axis.x != 0.0 || axis.y != 0.0 ) { - v2 = Point3( axis.y, -axis.x, axis.z ) * (float)0.1; - } else { - v2 = Point3( axis.x, axis.z, -axis.y ) * (float)0.1; - } - - v[0] = Point3(0.0,0.0,0.0); - v[1] = axis; - vpt->getGW()->polyline( 2, v, NULL, NULL, FALSE, NULL ); - v[0] = axis; - v[1] = v1+v2; - vpt->getGW()->polyline( 2, v, NULL, NULL, FALSE, NULL ); - v[0] = axis; - v[1] = v1-v2; - vpt->getGW()->polyline( 2, v, NULL, NULL, FALSE, NULL ); - } - - -void DrawAxis(ViewExp *vpt, const Matrix3 &tm, float length, BOOL screenSize) - { - Matrix3 tmn = tm; - float zoom; - - // Get width of viewport in world units: --DS - zoom = vpt->GetScreenScaleFactor(tmn.GetTrans())*ZFACT; - - if (screenSize) { - tmn.Scale( Point3(zoom,zoom,zoom) ); - } - vpt->getGW()->setTransform( tmn ); - - Text( vpt, _T("x"), Point3(length,0.0f,0.0f) ); - DrawAnAxis( vpt, Point3(length,0.0f,0.0f) ); - - Text( vpt, _T("y"), Point3(0.0f,length,0.0f) ); - DrawAnAxis( vpt, Point3(0.0f,length,0.0f) ); - - Text( vpt, _T("z"), Point3(0.0f,0.0f,length) ); - DrawAnAxis( vpt, Point3(0.0f,0.0f,length) ); - } - - - -//--- RB 7/17/2000: the code below seems to be unused --------------------------------------------------- - - -Box3 GetAxisBox(ViewExp *vpt, const Matrix3 &tm,float length,int resetTM) - { - Matrix3 tmn = tm; - Box3 box; - float zoom; - - // Get width of viewport in world units: --DS - zoom = vpt->GetScreenScaleFactor(tmn.GetTrans())*ZFACT; - if (zoom==0.0f) zoom = 1.0f; -// tmn.Scale(Point3(zoom,zoom,zoom)); - length *= zoom; - if(resetTM) - tmn.IdentityMatrix(); - - box += Point3(0.0f,0.0f,0.0f) * tmn; - box += Point3(length,0.0f,0.0f) * tmn; - box += Point3(0.0f,length,0.0f) * tmn; - box += Point3(0.0f,0.0f,length) * tmn; - box += Point3(-length/5.f,0.0f,0.0f) * tmn; - box += Point3(0.0f,-length/5.f,0.0f) * tmn; - box += Point3(0.0f,0.0f,-length/5.0f) * tmn; - box.EnlargeBy(10.0f/zoom); - return box; - } - - -inline void EnlargeRectIPoint3( RECT *rect, IPoint3& pt ) - { - if ( pt.x < rect->left ) rect->left = pt.x; - if ( pt.x > rect->right ) rect->right = pt.x; - if ( pt.y < rect->top ) rect->top = pt.y; - if ( pt.y > rect->bottom ) rect->bottom = pt.y; - } - -// This is a guess - need to find real w/h. -#define FONT_HEIGHT 11 -#define FONT_WIDTH 9 - - -static void AxisRect( GraphicsWindow *gw, Point3 axis, Rect *rect ) - { - Point3 v1, v2, v; - IPoint3 iv; - v1 = axis * (float)0.9; - if ( axis.x != 0.0 || axis.y != 0.0 ) { - v2 = Point3( axis.y, -axis.x, axis.z ) * (float)0.1; - } else { - v2 = Point3( axis.x, axis.z, -axis.y ) * (float)0.1; - } - v = axis; - gw->wTransPoint( &v, &iv ); - EnlargeRectIPoint3( rect, iv); - - iv.x += FONT_WIDTH; - iv.y -= FONT_HEIGHT; - EnlargeRectIPoint3( rect, iv); - - v = v1+v2; - gw->wTransPoint( &v, &iv ); - EnlargeRectIPoint3( rect, iv); - v = v1-v2; - gw->wTransPoint( &v, &iv ); - EnlargeRectIPoint3( rect, iv); - } - - -void AxisViewportRect(ViewExp *vpt, const Matrix3 &tm, float length, Rect *rect) - { - Matrix3 tmn = tm; - float zoom; - IPoint3 wpt; - Point3 pt; - GraphicsWindow *gw = vpt->getGW(); - - // Get width of viewport in world units: --DS - zoom = vpt->GetScreenScaleFactor(tmn.GetTrans())*ZFACT; - - tmn.Scale( Point3(zoom,zoom,zoom) ); - gw->setTransform( tmn ); - pt = Point3(0.0f, 0.0f, 0.0f); - gw->wTransPoint( &pt, &wpt ); - rect->left = rect->right = wpt.x; - rect->top = rect->bottom = wpt.y; - - AxisRect( gw, Point3(length,0.0f,0.0f),rect ); - AxisRect( gw, Point3(0.0f,length,0.0f),rect ); - AxisRect( gw, Point3(0.0f,0.0f,length),rect ); - - rect->right += 2; - rect->bottom += 2; - rect->left -= 2; - rect->top -= 2; - } - - - +/********************************************************************** + *< + FILE: pthelp.cpp + + DESCRIPTION: A point helper implementation + + CREATED BY: + + HISTORY: created 14 July 1995 + + *> Copyright (c) 1995, All Rights Reserved. + **********************************************************************/ + +#include "PSProp.h" + + +//------------------------------------------------------ + +// in prim.cpp - The dll instance handle +extern HINSTANCE hInstance; + +#define AXIS_LENGTH 20.0f +#define ZFACT (float).005; + +void AxisViewportRect(ViewExp *vpt, const Matrix3 &tm, float length, Rect *rect); +void DrawAxis(ViewExp *vpt, const Matrix3 &tm, float length, BOOL screenSize); +Box3 GetAxisBox(ViewExp *vpt, const Matrix3 &tm,float length,int resetTM); + + +////////////////////////////////////////////////////////////////////////////////////// +// PSPropClassDesc : required class to expose PSProp to MAX +class PSPropClassDesc : public ClassDesc2 +{ +public: + int IsPublic() { return 1; } + void * Create(BOOL loading = FALSE) { return new PSPropObject; } + const TCHAR * ClassName() { return GetString(IDS_DB_POINT_CLASS); } + SClass_ID SuperClassID() { return HELPER_CLASS_ID; } + Class_ID ClassID() { return PSPROP_CLASS_ID; } + const TCHAR* Category() { return _T("PS Helpers"); } + + const TCHAR* InternalName() {return _T("PSProp");} + HINSTANCE HInstance() {return hInstance;} +}; + +PSPropClassDesc pointHelpObjDesc; +ClassDesc* GetPSPropDesc() { return &pointHelpObjDesc; } + + +// class variable for point class. +IObjParam *PSPropObject::ip = NULL; +PSPropObject *PSPropObject::editOb = NULL; + + +//HWND PSPropObject::hParams = NULL; +//IObjParam *PSPropObject::iObjParams; + +//int PSPropObject::dlgShowAxis = TRUE; +//float PSPropObject::dlgAxisLength = AXIS_LENGTH; + +void resetPointParams() +{ + //PSPropObject::dlgShowAxis = TRUE; + //PSPropObject::dlgAxisLength = AXIS_LENGTH; +} + + + + + +#define PBLOCK_REF_NO 0 + +// The following two enums are transfered to the istdplug.h by AG: 01/20/2002 +// in order to access the parameters for use in Spline IK Control modifier +// and the Spline IK Solver + +// block IDs +//enum { pointobj_params, }; + +// pointobj_params IDs + +// enum { +// pointobj_size, pointobj_centermarker, pointobj_axistripod, +// pointobj_cross, pointobj_box, pointobj_screensize, pointobj_drawontop }; + +// per instance block +static ParamBlockDesc2 pointobj_param_blk( + + pointobj_params, _T("PointObjectParameters"), 0, &pointHelpObjDesc, P_AUTO_CONSTRUCT+P_AUTO_UI, PBLOCK_REF_NO, + + //rollout + IDD_NEW_POINTPARAM, IDS_POINT_PARAMS, 0, 0, NULL, + + // params + pointobj_size, _T("size"), TYPE_FLOAT, P_ANIMATABLE, IDS_POINT_SIZE, + p_default, 20.0, + p_ms_default, 20.0, + p_range, 0.0f, float(1.0E30), + p_ui, TYPE_SPINNER, EDITTYPE_UNIVERSE, IDC_POINT_SIZE, IDC_POINT_SIZESPIN, SPIN_AUTOSCALE, + end, + + + pointobj_centermarker, _T("centermarker"), TYPE_BOOL, P_ANIMATABLE, IDS_POINT_CENTERMARKER, + p_default, FALSE, + p_ui, TYPE_SINGLECHEKBOX, IDC_POINT_MARKER, + end, + + pointobj_axistripod, _T("axistripod"), TYPE_BOOL, P_ANIMATABLE, IDS_POINT_AXISTRIPOD, + p_default, FALSE, + p_ui, TYPE_SINGLECHEKBOX, IDC_POINT_AXIS, + end, + + pointobj_cross, _T("cross"), TYPE_BOOL, P_ANIMATABLE, IDS_POINT_CROSS, + p_default, TRUE, + p_ui, TYPE_SINGLECHEKBOX, IDC_POINT_CROSS, + end, + + pointobj_box, _T("box"), TYPE_BOOL, P_ANIMATABLE, IDS_POINT_BOX, + p_default, FALSE, + p_ui, TYPE_SINGLECHEKBOX, IDC_POINT_BOX, + end, + + pointobj_screensize, _T("constantscreensize"), TYPE_BOOL, P_ANIMATABLE, IDS_POINT_SCREENSIZE, + p_default, FALSE, + p_ui, TYPE_SINGLECHEKBOX, IDC_POINT_SCREENSIZE, + end, + + pointobj_drawontop, _T("drawontop"), TYPE_BOOL, P_ANIMATABLE, IDS_POINT_DRAWONTOP, + p_default, FALSE, + p_ui, TYPE_SINGLECHEKBOX, IDC_POINT_DRAWONTOP, + end, + + end + ); + + + + + +/* +INT_PTR CALLBACK PointParamProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam) + { + PSPropObject *po = (PSPropObject*)GetWindowLongPtr(hWnd,GWLP_USERDATA); + if (!po && msg!=WM_INITDIALOG) return FALSE; + + switch (msg) { + case WM_INITDIALOG: { + po = (PSPropObject*)lParam; + SetWindowLongPtr(hWnd,GWLP_USERDATA,lParam); + CheckDlgButton(hWnd,IDC_SHOWAXIS,po->showAxis); + + ISpinnerControl *spin = + GetISpinner(GetDlgItem(hWnd,IDC_AXISLENGHSPIN)); + spin->SetLimits(10,1000,FALSE); + spin->SetScale(0.1f); + spin->SetValue(po->axisLength,FALSE); + spin->LinkToEdit(GetDlgItem(hWnd,IDC_AXISLENGTH),EDITTYPE_FLOAT); + ReleaseISpinner(spin); + return FALSE; + } + + case CC_SPINNER_CHANGE: { + ISpinnerControl *spin = (ISpinnerControl*)lParam; + po->axisLength = spin->GetFVal(); + po->NotifyDependents(FOREVER,PART_OBJ,REFMSG_CHANGE); + po->iObjParams->RedrawViews(po->iObjParams->GetTime()); + break; + } + + case WM_COMMAND: + switch (LOWORD(wParam)) { + case IDC_SHOWAXIS: + po->showAxis = IsDlgButtonChecked(hWnd,IDC_SHOWAXIS); + po->NotifyDependents(FOREVER,PART_OBJ,REFMSG_CHANGE); + po->iObjParams->RedrawViews(po->iObjParams->GetTime()); + break; + } + break; + + default: + return FALSE; + } + + return TRUE; + } +*/ + +void PSPropObject::BeginEditParams( + IObjParam *ip, ULONG flags,Animatable *prev) + { + this->ip = ip; + editOb = this; + pointHelpObjDesc.BeginEditParams(ip, this, flags, prev); + + /* + iObjParams = ip; + if (!hParams) { + hParams = ip->AddRollupPage( + hInstance, + MAKEINTRESOURCE(IDD_POINTPARAM), + PointParamProc, + GetString(IDS_DB_PARAMETERS), + (LPARAM)this ); + ip->RegisterDlgWnd(hParams); + } else { + SetWindowLongPtr(hParams,GWLP_USERDATA,(LONG_PTR)this); + CheckDlgButton(hParams,IDC_SHOWAXIS,showAxis); + ISpinnerControl *spin = + GetISpinner(GetDlgItem(hParams,IDC_AXISLENGHSPIN)); + spin->SetValue(axisLength,FALSE); + ReleaseISpinner(spin); + } + */ + } + +void PSPropObject::EndEditParams( + IObjParam *ip, ULONG flags,Animatable *next) + { + editOb = NULL; + this->ip = NULL; + pointHelpObjDesc.EndEditParams(ip, this, flags, next); + ClearAFlag(A_OBJ_CREATING); + + /* + dlgShowAxis = IsDlgButtonChecked(hParams, IDC_SHOWAXIS ); + ISpinnerControl *spin = GetISpinner(GetDlgItem(hParams,IDC_AXISLENGHSPIN)); + dlgAxisLength = spin->GetFVal(); + ReleaseISpinner(spin); + if (flags&END_EDIT_REMOVEUI) { + ip->UnRegisterDlgWnd(hParams); + ip->DeleteRollupPage(hParams); + hParams = NULL; + } else { + SetWindowLongPtr(hParams,GWLP_USERDATA,0); + } + iObjParams = NULL; + */ + } + + +PSPropObject::PSPropObject() + { + pointHelpObjDesc.MakeAutoParamBlocks(this); + showAxis = TRUE; //dlgShowAxis; + axisLength = 10.0f; //dlgAxisLength; + suspendSnap = FALSE; + SetAFlag(A_OBJ_CREATING); + } + +PSPropObject::~PSPropObject() + { + DeleteAllRefsFromMe(); + } + +IParamArray *PSPropObject::GetParamBlock() + { + return (IParamArray*)pblock2; + } + +int PSPropObject::GetParamBlockIndex(int id) + { + if (pblock2 && id>=0 && idNumParams()) return id; + else return -1; + } + + +class PointHelpObjCreateCallBack: public CreateMouseCallBack { + PSPropObject *ob; + public: + int proc( ViewExp *vpt,int msg, int point, int flags, IPoint2 m, Matrix3& mat ); + void SetObj(PSPropObject *obj) { ob = obj; } + }; + +int PointHelpObjCreateCallBack::proc(ViewExp *vpt,int msg, int point, int flags, IPoint2 m, Matrix3& mat ) { + + #ifdef _OSNAP + if (msg == MOUSE_FREEMOVE) + { + #ifdef _3D_CREATE + vpt->SnapPreview(m,m,NULL, SNAP_IN_3D); + #else + vpt->SnapPreview(m,m,NULL, SNAP_IN_PLANE); + #endif + } + #endif + + if (msg==MOUSE_POINT||msg==MOUSE_MOVE) { + switch(point) { + case 0: { + + // Find the node and plug in the wire color + ULONG handle; + ob->NotifyDependents(FOREVER, (PartID)&handle, REFMSG_GET_NODE_HANDLE); + INode *node; + node = GetCOREInterface()->GetINodeByHandle(handle); + if (node) { + Point3 color(0,0,1);// = GetUIColor(COLOR_POINT_OBJ); + node->SetWireColor(RGB(color.x*255.0f, color.y*255.0f, color.z*255.0f)); + } + + ob->suspendSnap = TRUE; + #ifdef _3D_CREATE + mat.SetTrans(vpt->SnapPoint(m,m,NULL,SNAP_IN_3D)); + #else + mat.SetTrans(vpt->SnapPoint(m,m,NULL,SNAP_IN_PLANE)); + #endif + break; + } + + case 1: + #ifdef _3D_CREATE + mat.SetTrans(vpt->SnapPoint(m,m,NULL,SNAP_IN_3D)); + #else + mat.SetTrans(vpt->SnapPoint(m,m,NULL,SNAP_IN_PLANE)); + #endif + if (msg==MOUSE_POINT) { + ob->suspendSnap = FALSE; + return 0; + } + break; + } + } else + if (msg == MOUSE_ABORT) { + return CREATE_ABORT; + } + return 1; + } + +static PointHelpObjCreateCallBack pointHelpCreateCB; + +CreateMouseCallBack* PSPropObject::GetCreateMouseCallBack() { + pointHelpCreateCB.SetObj(this); + return(&pointHelpCreateCB); + } + +void PSPropObject::SetExtendedDisplay(int flags) + { + extDispFlags = flags; + } + + +void PSPropObject::GetLocalBoundBox( + TimeValue t, INode* inode, ViewExp* vpt, Box3& box ) + { + Matrix3 tm = inode->GetObjectTM(t); + + float size; + int screenSize; + pblock2->GetValue(pointobj_size, t, size, FOREVER); + pblock2->GetValue(pointobj_screensize, t, screenSize, FOREVER); + + float zoom = 1.0f; + if (screenSize) { + zoom = vpt->GetScreenScaleFactor(tm.GetTrans())*ZFACT; + } + if (zoom==0.0f) zoom = 1.0f; + + size *= zoom; + box = Box3(Point3(0,0,0), Point3(0,0,0)); + box += Point3(size*0.5f, 0.0f, 0.0f); + box += Point3( 0.0f, size*0.5f, 0.0f); + box += Point3( 0.0f, 0.0f, size*0.5f); + box += Point3(-size*0.5f, 0.0f, 0.0f); + box += Point3( 0.0f, -size*0.5f, 0.0f); + box += Point3( 0.0f, 0.0f, -size*0.5f); + + box.EnlargeBy(10.0f/zoom); + + /* + if (showAxis) + box = GetAxisBox(vpt,tm,showAxis?axisLength:0.0f, TRUE); + else + box = Box3(Point3(0,0,0), Point3(0,0,0)); + */ + } + +void PSPropObject::GetWorldBoundBox( + TimeValue t, INode* inode, ViewExp* vpt, Box3& box ) + { + Matrix3 tm; + tm = inode->GetObjectTM(t); + Box3 lbox; + + GetLocalBoundBox(t, inode, vpt, lbox); + box = Box3(tm.GetTrans(), tm.GetTrans()); + for (int i=0; i<8; i++) { + box += lbox * tm; + } + /* + if(!(extDispFlags & EXT_DISP_ZOOM_EXT) && showAxis) + box = GetAxisBox(vpt,tm,showAxis?axisLength:0.0f, FALSE); + else + box = Box3(tm.GetTrans(), tm.GetTrans()); + */ + } + + +void PSPropObject::Snap(TimeValue t, INode* inode, SnapInfo *snap, IPoint2 *p, ViewExp *vpt) + { + if(suspendSnap) + return; + + Matrix3 tm = inode->GetObjectTM(t); + GraphicsWindow *gw = vpt->getGW(); + gw->setTransform(tm); + + Matrix3 invPlane = Inverse(snap->plane); + + // Make sure the vertex priority is active and at least as important as the best snap so far + if(snap->vertPriority > 0 && snap->vertPriority <= snap->priority) { + Point2 fp = Point2((float)p->x, (float)p->y); + Point2 screen2; + IPoint3 pt3; + + Point3 thePoint(0,0,0); + // If constrained to the plane, make sure this point is in it! + if(snap->snapType == SNAP_2D || snap->flags & SNAP_IN_PLANE) { + Point3 test = thePoint * tm * invPlane; + if(fabs(test.z) > 0.0001) // Is it in the plane (within reason)? + return; + } + gw->wTransPoint(&thePoint,&pt3); + screen2.x = (float)pt3.x; + screen2.y = (float)pt3.y; + + // Are we within the snap radius? + int len = (int)Length(screen2 - fp); + if(len <= snap->strength) { + // Is this priority better than the best so far? + if(snap->vertPriority < snap->priority) { + snap->priority = snap->vertPriority; + snap->bestWorld = thePoint * tm; + snap->bestScreen = screen2; + snap->bestDist = len; + } + else + if(len < snap->bestDist) { + snap->priority = snap->vertPriority; + snap->bestWorld = thePoint * tm; + snap->bestScreen = screen2; + snap->bestDist = len; + } + } + } + } + + + + +int PSPropObject::DrawAndHit(TimeValue t, INode *inode, ViewExp *vpt) + { + float size; + int centerMarker, axisTripod, cross, box, screenSize, drawOnTop; + +// Color color = inode->GetWireColor(); + + Interval ivalid = FOREVER; + pblock2->GetValue(pointobj_size, t, size, ivalid); + pblock2->GetValue(pointobj_centermarker, t, centerMarker, ivalid); + pblock2->GetValue(pointobj_axistripod, t, axisTripod, ivalid); + pblock2->GetValue(pointobj_cross, t, cross, ivalid); + pblock2->GetValue(pointobj_box, t, box, ivalid); + pblock2->GetValue(pointobj_screensize, t, screenSize, ivalid); + pblock2->GetValue(pointobj_drawontop, t, drawOnTop, ivalid); + + Matrix3 tm(1); + Point3 pt(0,0,0); + Point3 pts[5]; + + vpt->getGW()->setTransform(tm); + tm = inode->GetObjectTM(t); + + int limits = vpt->getGW()->getRndLimits(); + if (drawOnTop) vpt->getGW()->setRndLimits(limits & ~GW_Z_BUFFER); + + if (inode->Selected()) { + vpt->getGW()->setColor( TEXT_COLOR, GetUIColor(COLOR_SELECTION) ); + vpt->getGW()->setColor( LINE_COLOR, GetUIColor(COLOR_SELECTION) ); + } else if (!inode->IsFrozen() && !inode->Dependent()) { + //vpt->getGW()->setColor( TEXT_COLOR, GetUIColor(COLOR_POINT_AXES) ); + //vpt->getGW()->setColor( LINE_COLOR, GetUIColor(COLOR_POINT_AXES) ); + vpt->getGW()->setColor( TEXT_COLOR, Color(0,0,1)); + vpt->getGW()->setColor( LINE_COLOR, Color(0,0,1)); + } + + if (axisTripod) { + DrawAxis(vpt, tm, size, screenSize); + } + + size *= 0.5f; + + float zoom = vpt->GetScreenScaleFactor(tm.GetTrans())*ZFACT; + if (screenSize) { + tm.Scale(Point3(zoom,zoom,zoom)); + } + + vpt->getGW()->setTransform(tm); + + if (!inode->IsFrozen() && !inode->Dependent() && !inode->Selected()) { + //vpt->getGW()->setColor(LINE_COLOR, GetUIColor(COLOR_POINT_OBJ)); + vpt->getGW()->setColor( LINE_COLOR, Color(0,0,1)); + } + + if (centerMarker) { + vpt->getGW()->marker(&pt,X_MRKR); + } + + if (cross) { + // X + pts[0] = Point3(-size, 0.0f, 0.0f); pts[1] = Point3(size, 0.0f, 0.0f); + vpt->getGW()->polyline(2, pts, NULL, NULL, FALSE, NULL); + + // Y + pts[0] = Point3(0.0f, -size, 0.0f); pts[1] = Point3(0.0f, size, 0.0f); + vpt->getGW()->polyline(2, pts, NULL, NULL, FALSE, NULL); + + // Z + pts[0] = Point3(0.0f, 0.0f, -size); pts[1] = Point3(0.0f, 0.0f, size); + vpt->getGW()->polyline(2, pts, NULL, NULL, FALSE, NULL); + } + + if (box) { + + // Make the box half the size + size = size * 0.5f; + + // Bottom + pts[0] = Point3(-size, -size, -size); + pts[1] = Point3(-size, size, -size); + pts[2] = Point3( size, size, -size); + pts[3] = Point3( size, -size, -size); + vpt->getGW()->polyline(4, pts, NULL, NULL, TRUE, NULL); + + // Top + pts[0] = Point3(-size, -size, size); + pts[1] = Point3(-size, size, size); + pts[2] = Point3( size, size, size); + pts[3] = Point3( size, -size, size); + vpt->getGW()->polyline(4, pts, NULL, NULL, TRUE, NULL); + + // Sides + pts[0] = Point3(-size, -size, -size); + pts[1] = Point3(-size, -size, size); + vpt->getGW()->polyline(2, pts, NULL, NULL, FALSE, NULL); + + pts[0] = Point3(-size, size, -size); + pts[1] = Point3(-size, size, size); + vpt->getGW()->polyline(2, pts, NULL, NULL, FALSE, NULL); + + pts[0] = Point3( size, size, -size); + pts[1] = Point3( size, size, size); + vpt->getGW()->polyline(2, pts, NULL, NULL, FALSE, NULL); + + pts[0] = Point3( size, -size, -size); + pts[1] = Point3( size, -size, size); + vpt->getGW()->polyline(2, pts, NULL, NULL, FALSE, NULL); + } + + vpt->getGW()->setRndLimits(limits); + + return 1; + } + +int PSPropObject::HitTest( + TimeValue t, INode *inode, int type, int crossing, int flags, IPoint2 *p, ViewExp *vpt) + { + Matrix3 tm(1); + HitRegion hitRegion; + DWORD savedLimits; + Point3 pt(0,0,0); + + vpt->getGW()->setTransform(tm); + GraphicsWindow *gw = vpt->getGW(); + Material *mtl = gw->getMaterial(); + + tm = inode->GetObjectTM(t); + MakeHitRegion(hitRegion, type, crossing, 4, p); + + gw->setRndLimits(((savedLimits = gw->getRndLimits())|GW_PICK)&~GW_ILLUM); + gw->setHitRegion(&hitRegion); + gw->clearHitCode(); + + DrawAndHit(t, inode, vpt); + +/* + if (showAxis) { + DrawAxis(vpt,tm,axisLength,screenSize); + } + vpt->getGW()->setTransform(tm); + vpt->getGW()->marker(&pt,X_MRKR); +*/ + + gw->setRndLimits(savedLimits); + + if((hitRegion.type != POINT_RGN) && !hitRegion.crossing) + return TRUE; + return gw->checkHitCode(); + } + + + +int PSPropObject::Display( + TimeValue t, INode* inode, ViewExp *vpt, int flags) + { + DrawAndHit(t, inode, vpt); + /* + Matrix3 tm(1); + Point3 pt(0,0,0); + + vpt->getGW()->setTransform(tm); + tm = inode->GetObjectTM(t); + + if (showAxis) { + DrawAxis(vpt,tm,axisLength,inode->Selected(),inode->IsFrozen()); + } + + + vpt->getGW()->setTransform(tm); + if(!inode->IsFrozen()) + vpt->getGW()->setColor(LINE_COLOR,GetUIColor(COLOR_POINT_OBJ)); + vpt->getGW()->marker(&pt,X_MRKR); + */ + + return(0); + } + + + +// +// Reference Managment: +// + +// This is only called if the object MAKES references to other things. +RefResult PSPropObject::NotifyRefChanged( + Interval changeInt, RefTargetHandle hTarget, + PartID& partID, RefMessage message ) + { + switch (message) { + case REFMSG_CHANGE: + if (editOb==this) InvalidateUI(); + break; + } + return(REF_SUCCEED); + } + +void PSPropObject::InvalidateUI() + { + pointobj_param_blk.InvalidateUI(pblock2->LastNotifyParamID()); + } + +Interval PSPropObject::ObjectValidity(TimeValue t) + { + float size; + int centerMarker, axisTripod, cross, box, screenSize, drawOnTop; + + Interval ivalid = FOREVER; + pblock2->GetValue(pointobj_size, t, size, ivalid); + pblock2->GetValue(pointobj_centermarker, t, centerMarker, ivalid); + pblock2->GetValue(pointobj_axistripod, t, axisTripod, ivalid); + pblock2->GetValue(pointobj_cross, t, cross, ivalid); + pblock2->GetValue(pointobj_box, t, box, ivalid); + pblock2->GetValue(pointobj_screensize, t, screenSize, ivalid); + pblock2->GetValue(pointobj_drawontop, t, drawOnTop, ivalid); + + return ivalid; + } + +ObjectState PSPropObject::Eval(TimeValue t) + { + return ObjectState(this); + } + +RefTargetHandle PSPropObject::Clone(RemapDir& remap) + { + PSPropObject* newob = new PSPropObject(); + newob->showAxis = showAxis; + newob->axisLength = axisLength; + newob->ReplaceReference(0, pblock2->Clone(remap)); + BaseClone(this, newob, remap); + return(newob); + } + + +void PSPropObject::UpdateParamblockFromVars() + { + SuspendAnimate(); + AnimateOff(); + + pblock2->SetValue(pointobj_size, TimeValue(0), axisLength); + pblock2->SetValue(pointobj_centermarker, TimeValue(0), TRUE); + pblock2->SetValue(pointobj_axistripod, TimeValue(0), showAxis); + pblock2->SetValue(pointobj_cross, TimeValue(0), FALSE); + pblock2->SetValue(pointobj_box, TimeValue(0), FALSE); + pblock2->SetValue(pointobj_screensize, TimeValue(0), TRUE); + + ResumeAnimate(); + } + + +class PointHelperPostLoadCallback : public PostLoadCallback { + public: + PSPropObject *pobj; + + PointHelperPostLoadCallback(PSPropObject *p) {pobj=p;} + void proc(ILoad *iload) { + pobj->UpdateParamblockFromVars(); + } + }; + +#define SHOW_AXIS_CHUNK 0x0100 +#define AXIS_LENGTH_CHUNK 0x0110 +#define POINT_HELPER_R4_CHUNKID 0x0120 // new version of point helper for R4 (updated to use PB2) + +IOResult PSPropObject::Load(ILoad *iload) + { + ULONG nb; + IOResult res = IO_OK; + BOOL oldVersion = TRUE; + + while (IO_OK==(res=iload->OpenChunk())) { + switch (iload->CurChunkID()) { + + case SHOW_AXIS_CHUNK: + res = iload->Read(&showAxis,sizeof(showAxis),&nb); + break; + + case AXIS_LENGTH_CHUNK: + res = iload->Read(&axisLength,sizeof(axisLength),&nb); + break; + + case POINT_HELPER_R4_CHUNKID: + oldVersion = FALSE; + break; + } + + res = iload->CloseChunk(); + if (res!=IO_OK) return res; + } + + if (oldVersion) { + iload->RegisterPostLoadCallback(new PointHelperPostLoadCallback(this)); + } + + return IO_OK; + } + +IOResult PSPropObject::Save(ISave *isave) + { + /* + isave->BeginChunk(SHOW_AXIS_CHUNK); + isave->Write(&showAxis,sizeof(showAxis),&nb); + isave->EndChunk(); + + isave->BeginChunk(AXIS_LENGTH_CHUNK); + isave->Write(&axisLength,sizeof(axisLength),&nb); + isave->EndChunk(); + */ + + isave->BeginChunk(POINT_HELPER_R4_CHUNKID); + isave->EndChunk(); + + return IO_OK; + } + + +/*--------------------------------------------------------------------*/ +// +// Stole this from scene.cpp +// Probably couldn't hurt to make an API... +// +// + + +void Text( ViewExp *vpt, TCHAR *str, Point3 &pt ) + { + vpt->getGW()->text( &pt, str ); + } + +static void DrawAnAxis( ViewExp *vpt, Point3 axis ) + { + Point3 v1, v2, v[3]; + v1 = axis * (float)0.9; + if ( axis.x != 0.0 || axis.y != 0.0 ) { + v2 = Point3( axis.y, -axis.x, axis.z ) * (float)0.1; + } else { + v2 = Point3( axis.x, axis.z, -axis.y ) * (float)0.1; + } + + v[0] = Point3(0.0,0.0,0.0); + v[1] = axis; + vpt->getGW()->polyline( 2, v, NULL, NULL, FALSE, NULL ); + v[0] = axis; + v[1] = v1+v2; + vpt->getGW()->polyline( 2, v, NULL, NULL, FALSE, NULL ); + v[0] = axis; + v[1] = v1-v2; + vpt->getGW()->polyline( 2, v, NULL, NULL, FALSE, NULL ); + } + + +void DrawAxis(ViewExp *vpt, const Matrix3 &tm, float length, BOOL screenSize) + { + Matrix3 tmn = tm; + float zoom; + + // Get width of viewport in world units: --DS + zoom = vpt->GetScreenScaleFactor(tmn.GetTrans())*ZFACT; + + if (screenSize) { + tmn.Scale( Point3(zoom,zoom,zoom) ); + } + vpt->getGW()->setTransform( tmn ); + + Text( vpt, _T("x"), Point3(length,0.0f,0.0f) ); + DrawAnAxis( vpt, Point3(length,0.0f,0.0f) ); + + Text( vpt, _T("y"), Point3(0.0f,length,0.0f) ); + DrawAnAxis( vpt, Point3(0.0f,length,0.0f) ); + + Text( vpt, _T("z"), Point3(0.0f,0.0f,length) ); + DrawAnAxis( vpt, Point3(0.0f,0.0f,length) ); + } + + + +//--- RB 7/17/2000: the code below seems to be unused --------------------------------------------------- + + +Box3 GetAxisBox(ViewExp *vpt, const Matrix3 &tm,float length,int resetTM) + { + Matrix3 tmn = tm; + Box3 box; + float zoom; + + // Get width of viewport in world units: --DS + zoom = vpt->GetScreenScaleFactor(tmn.GetTrans())*ZFACT; + if (zoom==0.0f) zoom = 1.0f; +// tmn.Scale(Point3(zoom,zoom,zoom)); + length *= zoom; + if(resetTM) + tmn.IdentityMatrix(); + + box += Point3(0.0f,0.0f,0.0f) * tmn; + box += Point3(length,0.0f,0.0f) * tmn; + box += Point3(0.0f,length,0.0f) * tmn; + box += Point3(0.0f,0.0f,length) * tmn; + box += Point3(-length/5.f,0.0f,0.0f) * tmn; + box += Point3(0.0f,-length/5.f,0.0f) * tmn; + box += Point3(0.0f,0.0f,-length/5.0f) * tmn; + box.EnlargeBy(10.0f/zoom); + return box; + } + + +inline void EnlargeRectIPoint3( RECT *rect, IPoint3& pt ) + { + if ( pt.x < rect->left ) rect->left = pt.x; + if ( pt.x > rect->right ) rect->right = pt.x; + if ( pt.y < rect->top ) rect->top = pt.y; + if ( pt.y > rect->bottom ) rect->bottom = pt.y; + } + +// This is a guess - need to find real w/h. +#define FONT_HEIGHT 11 +#define FONT_WIDTH 9 + + +static void AxisRect( GraphicsWindow *gw, Point3 axis, Rect *rect ) + { + Point3 v1, v2, v; + IPoint3 iv; + v1 = axis * (float)0.9; + if ( axis.x != 0.0 || axis.y != 0.0 ) { + v2 = Point3( axis.y, -axis.x, axis.z ) * (float)0.1; + } else { + v2 = Point3( axis.x, axis.z, -axis.y ) * (float)0.1; + } + v = axis; + gw->wTransPoint( &v, &iv ); + EnlargeRectIPoint3( rect, iv); + + iv.x += FONT_WIDTH; + iv.y -= FONT_HEIGHT; + EnlargeRectIPoint3( rect, iv); + + v = v1+v2; + gw->wTransPoint( &v, &iv ); + EnlargeRectIPoint3( rect, iv); + v = v1-v2; + gw->wTransPoint( &v, &iv ); + EnlargeRectIPoint3( rect, iv); + } + + +void AxisViewportRect(ViewExp *vpt, const Matrix3 &tm, float length, Rect *rect) + { + Matrix3 tmn = tm; + float zoom; + IPoint3 wpt; + Point3 pt; + GraphicsWindow *gw = vpt->getGW(); + + // Get width of viewport in world units: --DS + zoom = vpt->GetScreenScaleFactor(tmn.GetTrans())*ZFACT; + + tmn.Scale( Point3(zoom,zoom,zoom) ); + gw->setTransform( tmn ); + pt = Point3(0.0f, 0.0f, 0.0f); + gw->wTransPoint( &pt, &wpt ); + rect->left = rect->right = wpt.x; + rect->top = rect->bottom = wpt.y; + + AxisRect( gw, Point3(length,0.0f,0.0f),rect ); + AxisRect( gw, Point3(0.0f,length,0.0f),rect ); + AxisRect( gw, Point3(0.0f,0.0f,length),rect ); + + rect->right += 2; + rect->bottom += 2; + rect->left -= 2; + rect->top -= 2; + } + + + diff --git a/source/tools/pmdexp/PSProp.h b/source/tools/pmdexp/PSProp.h index fd9efb59b5..ca610db660 100755 --- a/source/tools/pmdexp/PSProp.h +++ b/source/tools/pmdexp/PSProp.h @@ -1,95 +1,95 @@ -#ifndef _PSPROP_H -#define _PSPROP_H - -#include "MaxInc.h" - -TCHAR *GetString(int id); - -#define PSPROP_CLASS_ID Class_ID(0x353f201d, 0x3d01408d) - -extern ClassDesc* GetPSPropDesc(); - -class PSPropObject : public HelperObject -{ -public: - static IObjParam *ip; - static PSPropObject *editOb; - IParamBlock2 *pblock2; - - // Class vars - /* - static HWND hParams; - static IObjParam *iObjParams; - static int dlgShowAxis; - static float dlgAxisLength; - */ - - // Snap suspension flag (TRUE during creation only) - BOOL suspendSnap; - - // Old params... these are for loading old files only. Params are now stored in pb2. - BOOL showAxis; - float axisLength; - - // For use by display system - int extDispFlags; - - // inherited virtual methods for Reference-management - RefResult NotifyRefChanged( Interval changeInt, RefTargetHandle hTarget, - PartID& partID, RefMessage message ); - - PSPropObject(); - ~PSPropObject(); - - // From BaseObject - int HitTest(TimeValue t, INode* inode, int type, int crossing, int flags, IPoint2 *p, ViewExp *vpt); - void Snap(TimeValue t, INode* inode, SnapInfo *snap, IPoint2 *p, ViewExp *vpt); - void SetExtendedDisplay(int flags); - int Display(TimeValue t, INode* inode, ViewExp *vpt, int flags); - CreateMouseCallBack* GetCreateMouseCallBack(); - void BeginEditParams( IObjParam *ip, ULONG flags,Animatable *prev); - void EndEditParams( IObjParam *ip, ULONG flags,Animatable *next); - TCHAR *GetObjectName() {return GetString(IDS_POINT_HELPER_NAME);} - - // From Object - ObjectState Eval(TimeValue time); - void InitNodeName(TSTR& s) { s = GetString(IDS_DB_POINT); } - ObjectHandle ApplyTransform(Matrix3& matrix) {return this;} - int CanConvertToType(Class_ID obtype) {return FALSE;} - Object* ConvertToType(TimeValue t, Class_ID obtype) {assert(0);return NULL;} - void GetWorldBoundBox(TimeValue t, INode *mat, ViewExp *vpt, Box3& box ); - void GetLocalBoundBox(TimeValue t, INode *mat, ViewExp *vpt, Box3& box ); - int DoOwnSelectHilite() { return 1; } - Interval ObjectValidity(TimeValue t); - int UsesWireColor() {return TRUE;} - - // Animatable methods - void DeleteThis() { delete this; } - Class_ID ClassID() { return PSPROP_CLASS_ID; } - void GetClassName(TSTR& s) { s = TSTR(GetString(IDS_DB_POINTHELPER_CLASS)); } - int IsKeyable(){ return 0;} - int NumSubs() { return 1; } - Animatable* SubAnim(int i) { return pblock2; } - TSTR SubAnimName(int i) { return TSTR(_T("Parameters"));} - IParamArray *GetParamBlock(); - int GetParamBlockIndex(int id); - int NumParamBlocks() { return 1; } - IParamBlock2* GetParamBlock(int i) { return pblock2; } - IParamBlock2* GetParamBlockByID(short id) { return pblock2; } - - // From ref - RefTargetHandle Clone(RemapDir& remap = NoRemap()); - IOResult Load(ILoad *iload); - IOResult Save(ISave *isave); - int NumRefs() {return 1;} - RefTargetHandle GetReference(int i) {return pblock2;} - void SetReference(int i, RefTargetHandle rtarg) {pblock2=(IParamBlock2*)rtarg;} - - // Local methods - void InvalidateUI(); - void UpdateParamblockFromVars(); - int DrawAndHit(TimeValue t, INode *inode, ViewExp *vpt); -}; - - -#endif +#ifndef _PSPROP_H +#define _PSPROP_H + +#include "MaxInc.h" + +TCHAR *GetString(int id); + +#define PSPROP_CLASS_ID Class_ID(0x353f201d, 0x3d01408d) + +extern ClassDesc* GetPSPropDesc(); + +class PSPropObject : public HelperObject +{ +public: + static IObjParam *ip; + static PSPropObject *editOb; + IParamBlock2 *pblock2; + + // Class vars + /* + static HWND hParams; + static IObjParam *iObjParams; + static int dlgShowAxis; + static float dlgAxisLength; + */ + + // Snap suspension flag (TRUE during creation only) + BOOL suspendSnap; + + // Old params... these are for loading old files only. Params are now stored in pb2. + BOOL showAxis; + float axisLength; + + // For use by display system + int extDispFlags; + + // inherited virtual methods for Reference-management + RefResult NotifyRefChanged( Interval changeInt, RefTargetHandle hTarget, + PartID& partID, RefMessage message ); + + PSPropObject(); + ~PSPropObject(); + + // From BaseObject + int HitTest(TimeValue t, INode* inode, int type, int crossing, int flags, IPoint2 *p, ViewExp *vpt); + void Snap(TimeValue t, INode* inode, SnapInfo *snap, IPoint2 *p, ViewExp *vpt); + void SetExtendedDisplay(int flags); + int Display(TimeValue t, INode* inode, ViewExp *vpt, int flags); + CreateMouseCallBack* GetCreateMouseCallBack(); + void BeginEditParams( IObjParam *ip, ULONG flags,Animatable *prev); + void EndEditParams( IObjParam *ip, ULONG flags,Animatable *next); + TCHAR *GetObjectName() {return GetString(IDS_POINT_HELPER_NAME);} + + // From Object + ObjectState Eval(TimeValue time); + void InitNodeName(TSTR& s) { s = GetString(IDS_DB_POINT); } + ObjectHandle ApplyTransform(Matrix3& matrix) {return this;} + int CanConvertToType(Class_ID obtype) {return FALSE;} + Object* ConvertToType(TimeValue t, Class_ID obtype) {assert(0);return NULL;} + void GetWorldBoundBox(TimeValue t, INode *mat, ViewExp *vpt, Box3& box ); + void GetLocalBoundBox(TimeValue t, INode *mat, ViewExp *vpt, Box3& box ); + int DoOwnSelectHilite() { return 1; } + Interval ObjectValidity(TimeValue t); + int UsesWireColor() {return TRUE;} + + // Animatable methods + void DeleteThis() { delete this; } + Class_ID ClassID() { return PSPROP_CLASS_ID; } + void GetClassName(TSTR& s) { s = TSTR(GetString(IDS_DB_POINTHELPER_CLASS)); } + int IsKeyable(){ return 0;} + int NumSubs() { return 1; } + Animatable* SubAnim(int i) { return pblock2; } + TSTR SubAnimName(int i) { return TSTR(_T("Parameters"));} + IParamArray *GetParamBlock(); + int GetParamBlockIndex(int id); + int NumParamBlocks() { return 1; } + IParamBlock2* GetParamBlock(int i) { return pblock2; } + IParamBlock2* GetParamBlockByID(short id) { return pblock2; } + + // From ref + RefTargetHandle Clone(RemapDir& remap = NoRemap()); + IOResult Load(ILoad *iload); + IOResult Save(ISave *isave); + int NumRefs() {return 1;} + RefTargetHandle GetReference(int i) {return pblock2;} + void SetReference(int i, RefTargetHandle rtarg) {pblock2=(IParamBlock2*)rtarg;} + + // Local methods + void InvalidateUI(); + void UpdateParamblockFromVars(); + int DrawAndHit(TimeValue t, INode *inode, ViewExp *vpt); +}; + + +#endif diff --git a/source/tools/pmdexp/Tree.h b/source/tools/pmdexp/Tree.h index 2db160e136..d098d1d3a0 100755 --- a/source/tools/pmdexp/Tree.h +++ b/source/tools/pmdexp/Tree.h @@ -1,212 +1,212 @@ -#ifndef __TREE_H -#define __TREE_H - -////////////////////////////////////////////////////////////////////////////// -// Tree: template class to build a binary tree of elements of class T -template -class Tree -{ -public: - template - class Node { - public: - Node* _Next; - - public: - Node() : _Left(0), _Right(0) {} - - int _Index; - T _Element; - Node* _Left; - Node* _Right; - }; - - -public: - Tree(); - ~Tree(); - - void Clear(); - - int Find(T& element); - int Find(Node* _node,T& _vtx); - - int Add(T& element); - int Add(Node* _node,T& _vtx,int _index); - - // total nodes currently in tree - int Entries() { return _Size; } - - void Reserve(int count) { _AllocatedNodes.reserve(count); } - - T& operator[](int index) { return _AllocatedNodes[index]->_Element; } - -private: - // the root node of the tree - Node* _Root; - // all allocated nodes in tree - std::vector*> _AllocatedNodes; - // size of tree - int _Size; - // the comparison function used to compare two elements in the tree - Cmp _Cmp; -}; - -//*************************************************************************** -// Default Tree constructor - create tree with no allocated nodes -//*************************************************************************** -template -Tree::Tree() -{ - _Root=0; - _Size=0; -} - - -//*************************************************************************** -// Tree destructor -//*************************************************************************** -template -Tree::~Tree() -{ - Clear(); -} - - -template -void Tree::Clear() -{ - for (int i=0;i<_AllocatedNodes.Entries();i++) { - _NodePile.Release(_AllocatedNodes[i]); - } - _AllocatedNodes.SetSize(0); - _Root=0; - _Size=0; -} - -//*************************************************************************** -// Add : insert an element into the tree; return the index of the treenode -// at which the element was added, or, if an identical element was already -// in the tree, return it's index -//*************************************************************************** -template -int Tree::Add(T& element) -{ - if (_Root) { - int index=Add(_Root,element,_Size); - if (index==_Size) { - // element added to tree - _Size++; - } else { - // element not added - } - return index; - } else { - _Root=_NodePile.Allocate(); - _AllocatedNodes.Add(_Root); - _Root->_Element=element; - _Root->_Index=0; - _Root->_Left=0; - _Root->_Right=0; - _Size++; - return 0; - } -} - - -//*************************************************************************** -// Add : insert an element into the given node; return the index of the -// treenode at which the element was added, or, if an identical element was -// already in the tree, return it's index -//*************************************************************************** -template -int Tree::Add(Node* _node,T& element,int _index) -{ - // compare given element with element at given node - int cmp=_Cmp.compare(_node->_Element,element); - if (cmp==0) { - // identical - return index of this node - return _node->_Index; - } else { - if (cmp==-1) { - // this node less than new node - if (_node->_Left) { - // send down left tree - return Add(_node->_Left,element,_index); - } else { - // no left node - create one - _node->_Left=_NodePile.Allocate(); - _AllocatedNodes.Add(_node->_Left); - _node->_Left->_Element=element; - _node->_Left->_Index=_index; - _node->_Left->_Left=0; - _node->_Left->_Right=0; - return _index; - } - } else { - // this node greater than new node - if (_node->_Right) { - // send down right tree - return Add(_node->_Right,element,_index); - } else { - // no right node - create one - _node->_Right=_NodePile.Allocate(); - _AllocatedNodes.Add(_node->_Right); - _node->_Right->_Element=element; - _node->_Right->_Index=_index; - _node->_Right->_Left=0; - _node->_Right->_Right=0; - return _index; - } - } - } -} - -//*************************************************************************** -// Find: try and find a matching element in the tree; return the index of the -// treenode at which a match was found, or -1 if no match found -//*************************************************************************** -template -int Tree::Find(T& element) -{ - return _Root ? Find(_Root,element) : -1; -} - - -//*************************************************************************** -// Find: try and find a matching element in the given node; return the index -// of the treenode at which a match was found, or -1 if no match found -//*************************************************************************** -template -int Tree::Find(Node* _node,T& element) -{ - // compare given element with element at given node - int cmp=_Cmp.compare(_node->_Element,element); - if (cmp==0) { - // identical - return index of this node - return _node->_Index; - } else { - if (cmp==-1) { - // this node less than new node - if (_node->_Left) { - // send down left tree - return Find(_node->_Left,element); - } else { - // no left node - no match on this subtree - return -1; - } - } else { - // this node greater than new node - if (_node->_Right) { - // send down right tree - return Find(_node->_Right,element); - } else { - // no left node - no match on this subtree - return -1; - } - } - } -} - - +#ifndef __TREE_H +#define __TREE_H + +////////////////////////////////////////////////////////////////////////////// +// Tree: template class to build a binary tree of elements of class T +template +class Tree +{ +public: + template + class Node { + public: + Node* _Next; + + public: + Node() : _Left(0), _Right(0) {} + + int _Index; + T _Element; + Node* _Left; + Node* _Right; + }; + + +public: + Tree(); + ~Tree(); + + void Clear(); + + int Find(T& element); + int Find(Node* _node,T& _vtx); + + int Add(T& element); + int Add(Node* _node,T& _vtx,int _index); + + // total nodes currently in tree + int Entries() { return _Size; } + + void Reserve(int count) { _AllocatedNodes.reserve(count); } + + T& operator[](int index) { return _AllocatedNodes[index]->_Element; } + +private: + // the root node of the tree + Node* _Root; + // all allocated nodes in tree + std::vector*> _AllocatedNodes; + // size of tree + int _Size; + // the comparison function used to compare two elements in the tree + Cmp _Cmp; +}; + +//*************************************************************************** +// Default Tree constructor - create tree with no allocated nodes +//*************************************************************************** +template +Tree::Tree() +{ + _Root=0; + _Size=0; +} + + +//*************************************************************************** +// Tree destructor +//*************************************************************************** +template +Tree::~Tree() +{ + Clear(); +} + + +template +void Tree::Clear() +{ + for (int i=0;i<_AllocatedNodes.Entries();i++) { + _NodePile.Release(_AllocatedNodes[i]); + } + _AllocatedNodes.SetSize(0); + _Root=0; + _Size=0; +} + +//*************************************************************************** +// Add : insert an element into the tree; return the index of the treenode +// at which the element was added, or, if an identical element was already +// in the tree, return it's index +//*************************************************************************** +template +int Tree::Add(T& element) +{ + if (_Root) { + int index=Add(_Root,element,_Size); + if (index==_Size) { + // element added to tree + _Size++; + } else { + // element not added + } + return index; + } else { + _Root=_NodePile.Allocate(); + _AllocatedNodes.Add(_Root); + _Root->_Element=element; + _Root->_Index=0; + _Root->_Left=0; + _Root->_Right=0; + _Size++; + return 0; + } +} + + +//*************************************************************************** +// Add : insert an element into the given node; return the index of the +// treenode at which the element was added, or, if an identical element was +// already in the tree, return it's index +//*************************************************************************** +template +int Tree::Add(Node* _node,T& element,int _index) +{ + // compare given element with element at given node + int cmp=_Cmp.compare(_node->_Element,element); + if (cmp==0) { + // identical - return index of this node + return _node->_Index; + } else { + if (cmp==-1) { + // this node less than new node + if (_node->_Left) { + // send down left tree + return Add(_node->_Left,element,_index); + } else { + // no left node - create one + _node->_Left=_NodePile.Allocate(); + _AllocatedNodes.Add(_node->_Left); + _node->_Left->_Element=element; + _node->_Left->_Index=_index; + _node->_Left->_Left=0; + _node->_Left->_Right=0; + return _index; + } + } else { + // this node greater than new node + if (_node->_Right) { + // send down right tree + return Add(_node->_Right,element,_index); + } else { + // no right node - create one + _node->_Right=_NodePile.Allocate(); + _AllocatedNodes.Add(_node->_Right); + _node->_Right->_Element=element; + _node->_Right->_Index=_index; + _node->_Right->_Left=0; + _node->_Right->_Right=0; + return _index; + } + } + } +} + +//*************************************************************************** +// Find: try and find a matching element in the tree; return the index of the +// treenode at which a match was found, or -1 if no match found +//*************************************************************************** +template +int Tree::Find(T& element) +{ + return _Root ? Find(_Root,element) : -1; +} + + +//*************************************************************************** +// Find: try and find a matching element in the given node; return the index +// of the treenode at which a match was found, or -1 if no match found +//*************************************************************************** +template +int Tree::Find(Node* _node,T& element) +{ + // compare given element with element at given node + int cmp=_Cmp.compare(_node->_Element,element); + if (cmp==0) { + // identical - return index of this node + return _node->_Index; + } else { + if (cmp==-1) { + // this node less than new node + if (_node->_Left) { + // send down left tree + return Find(_node->_Left,element); + } else { + // no left node - no match on this subtree + return -1; + } + } else { + // this node greater than new node + if (_node->_Right) { + // send down right tree + return Find(_node->_Right,element); + } else { + // no left node - no match on this subtree + return -1; + } + } + } +} + + #endif \ No newline at end of file diff --git a/source/tools/pmdexp/VNormal.cpp b/source/tools/pmdexp/VNormal.cpp index b662bbb24d..8be27ae540 100755 --- a/source/tools/pmdexp/VNormal.cpp +++ b/source/tools/pmdexp/VNormal.cpp @@ -1,56 +1,56 @@ -#include "MaxInc.h" -#include "VNormal.h" - - - -void VNormal::add(CVector3D& n,unsigned int s) -{ - if (!(s&smooth) && init) { - if (next) { - next->add(n,s); - } else { - next=new VNormal(n,s); - } - } else { - _normal+=n; - smooth|=s; - init=true; - } -} - -VNormal* VNormal::get(unsigned int s) -{ - if (smooth&s || !next) { - return this; - } else { - return next->get(s); - } -} - -void VNormal::get(unsigned int s,CVector3D& normal) -{ - if (smooth&s || !next) { - normal=_normal; - } else { - next->get(s,normal); - } -} - -void VNormal::normalize() -{ - VNormal *ptr = next, *prev = this; - while (ptr) { - if (ptr->smooth&smooth) { - _normal += ptr->_normal; - prev->next = ptr->next; - delete ptr; - ptr = prev->next; - } else { - prev = ptr; - ptr = ptr->next; - } - } - - _normal.Normalize(); - if (next) next->normalize(); -} +#include "MaxInc.h" +#include "VNormal.h" + + + +void VNormal::add(CVector3D& n,unsigned int s) +{ + if (!(s&smooth) && init) { + if (next) { + next->add(n,s); + } else { + next=new VNormal(n,s); + } + } else { + _normal+=n; + smooth|=s; + init=true; + } +} + +VNormal* VNormal::get(unsigned int s) +{ + if (smooth&s || !next) { + return this; + } else { + return next->get(s); + } +} + +void VNormal::get(unsigned int s,CVector3D& normal) +{ + if (smooth&s || !next) { + normal=_normal; + } else { + next->get(s,normal); + } +} + +void VNormal::normalize() +{ + VNormal *ptr = next, *prev = this; + while (ptr) { + if (ptr->smooth&smooth) { + _normal += ptr->_normal; + prev->next = ptr->next; + delete ptr; + ptr = prev->next; + } else { + prev = ptr; + ptr = ptr->next; + } + } + + _normal.Normalize(); + if (next) next->normalize(); +} diff --git a/source/tools/pmdexp/VNormal.h b/source/tools/pmdexp/VNormal.h index 9c47ca4fbf..24a13489ea 100755 --- a/source/tools/pmdexp/VNormal.h +++ b/source/tools/pmdexp/VNormal.h @@ -1,36 +1,36 @@ -#ifndef __VNORMAL_H -#define __VNORMAL_H - -#include "Vector3D.h" - -class VNormal -{ -public: - CVector3D _normal; - unsigned int smooth; - VNormal *next; - bool init; - - VNormal() { - smooth=0; - next=0; - init=false; - _normal=CVector3D(0,0,0); - } - - VNormal(CVector3D& n,unsigned int s) { - next=0; - init=true; - _normal=n; - smooth=s; - } - - ~VNormal() {delete next;} - void add(CVector3D &n,unsigned int s); - VNormal* get(unsigned int s); - void get(unsigned int s,CVector3D& normal); - void normalize(); -}; - - +#ifndef __VNORMAL_H +#define __VNORMAL_H + +#include "Vector3D.h" + +class VNormal +{ +public: + CVector3D _normal; + unsigned int smooth; + VNormal *next; + bool init; + + VNormal() { + smooth=0; + next=0; + init=false; + _normal=CVector3D(0,0,0); + } + + VNormal(CVector3D& n,unsigned int s) { + next=0; + init=true; + _normal=n; + smooth=s; + } + + ~VNormal() {delete next;} + void add(CVector3D &n,unsigned int s); + VNormal* get(unsigned int s); + void get(unsigned int s,CVector3D& normal); + void normalize(); +}; + + #endif \ No newline at end of file diff --git a/source/tools/pmdexp/VertexTree.h b/source/tools/pmdexp/VertexTree.h index 2dd7be81ca..7265b3692d 100755 --- a/source/tools/pmdexp/VertexTree.h +++ b/source/tools/pmdexp/VertexTree.h @@ -1,158 +1,158 @@ -#ifndef __VERTEXTREE_H -#define __VERTEXTREE_H - -// necessary includes -#include "ExpVertex.h" - -//////////////////////////////////////////////////////////////////////////////////////////// -// VertexTree: template tree class for building unique vertices in varying fashions; the -// template parameter Cmp specifies a function which compares (and possibly modifies) -// two vertices -// FIXME: ugh .. modifying a vertex already in the tree may cause it to be in the -// wrong position in the tree -template -class VertexTree -{ -private: - struct Node { - Node(int index,ExpVertex& vtx) : _index(index), _vertex(vtx), _left(0), _right(0) {} - - // index into the output _vertices array - int _index; - // reference to actual vertex on the node (vertex itself in _vertices array) - ExpVertex& _vertex; - // children - Node* _left; - Node* _right; - }; - -public: - VertexTree(VertexList& vertices) : _vertices(vertices), _treeroot(0) {} - - int insert(const ExpVertex& vtx) { - // copy incoming vertex in case the comparison function wants to modify - // it before storing it .. - ExpVertex copy=vtx; - if (_treeroot) { - return insert(_treeroot,copy); - } else { - _vertices.push_back(copy); - _treeroot=new Node(0,_vertices.back()); - return 0; - } - } - - int insert(Node* node,ExpVertex& vtx) { - // compare given element with element at given node - Cmp compareFn; - int cmp=compareFn(node->_vertex,vtx); - if (cmp==0) { - // matching vertex found - return node->_index; - } else { - if (cmp==-1) { - // this node less than new node - if (node->_left) { - // send down left tree - return insert(node->_left,vtx); - } else { - // no left node - create one - _vertices.push_back(vtx); - node->_left=new Node(_vertices.size()-1,_vertices.back()); - return _vertices.size()-1; - } - } else { - // this node greater than new node - if (node->_right) { - // send down right tree - return insert(node->_right,vtx); - } else { - // no right node - create one - _vertices.push_back(vtx); - node->_right=new Node(_vertices.size()-1,_vertices.back()); - return _vertices.size()-1; - } - } - } - } - -private: - Node* _treeroot; - VertexList& _vertices; -}; - - -class UniqueVertexCmp { -public: - int operator()(ExpVertex& left,ExpVertex& right) { - // check distance between two vertices .. - CVector3D vec3=left.m_Pos-right.m_Pos; - if (vec3.GetLength()>0.0001f) { - // vertices too far apart to weld .. sort on x,y,z - if (left.m_Pos[0]right.m_Pos[0]) { - return 1; - } else { - if (left.m_Pos[1]right.m_Pos[1]) { - return 1; - } else { - if (left.m_Pos[2]0.0001f) { - // uvs too far apart to weld .. sort on u,v - if (left.m_UVs[0]right.m_UVs[0]) { - return 1; - } else { - if (left.m_UVs[1]right.m_Normal[0]) { - return 1; - } else { - if (left.m_Normal[1]right.m_Normal[1]) { - return 1; - } else { - if (left.m_Normal[2]right.m_Normal[2]) { - return 1; - } else { - return 0; - } - } - } - } - } - } -}; - +#ifndef __VERTEXTREE_H +#define __VERTEXTREE_H + +// necessary includes +#include "ExpVertex.h" + +//////////////////////////////////////////////////////////////////////////////////////////// +// VertexTree: template tree class for building unique vertices in varying fashions; the +// template parameter Cmp specifies a function which compares (and possibly modifies) +// two vertices +// FIXME: ugh .. modifying a vertex already in the tree may cause it to be in the +// wrong position in the tree +template +class VertexTree +{ +private: + struct Node { + Node(int index,ExpVertex& vtx) : _index(index), _vertex(vtx), _left(0), _right(0) {} + + // index into the output _vertices array + int _index; + // reference to actual vertex on the node (vertex itself in _vertices array) + ExpVertex& _vertex; + // children + Node* _left; + Node* _right; + }; + +public: + VertexTree(VertexList& vertices) : _vertices(vertices), _treeroot(0) {} + + int insert(const ExpVertex& vtx) { + // copy incoming vertex in case the comparison function wants to modify + // it before storing it .. + ExpVertex copy=vtx; + if (_treeroot) { + return insert(_treeroot,copy); + } else { + _vertices.push_back(copy); + _treeroot=new Node(0,_vertices.back()); + return 0; + } + } + + int insert(Node* node,ExpVertex& vtx) { + // compare given element with element at given node + Cmp compareFn; + int cmp=compareFn(node->_vertex,vtx); + if (cmp==0) { + // matching vertex found + return node->_index; + } else { + if (cmp==-1) { + // this node less than new node + if (node->_left) { + // send down left tree + return insert(node->_left,vtx); + } else { + // no left node - create one + _vertices.push_back(vtx); + node->_left=new Node(_vertices.size()-1,_vertices.back()); + return _vertices.size()-1; + } + } else { + // this node greater than new node + if (node->_right) { + // send down right tree + return insert(node->_right,vtx); + } else { + // no right node - create one + _vertices.push_back(vtx); + node->_right=new Node(_vertices.size()-1,_vertices.back()); + return _vertices.size()-1; + } + } + } + } + +private: + Node* _treeroot; + VertexList& _vertices; +}; + + +class UniqueVertexCmp { +public: + int operator()(ExpVertex& left,ExpVertex& right) { + // check distance between two vertices .. + CVector3D vec3=left.m_Pos-right.m_Pos; + if (vec3.GetLength()>0.0001f) { + // vertices too far apart to weld .. sort on x,y,z + if (left.m_Pos[0]right.m_Pos[0]) { + return 1; + } else { + if (left.m_Pos[1]right.m_Pos[1]) { + return 1; + } else { + if (left.m_Pos[2]0.0001f) { + // uvs too far apart to weld .. sort on u,v + if (left.m_UVs[0]right.m_UVs[0]) { + return 1; + } else { + if (left.m_UVs[1]right.m_Normal[0]) { + return 1; + } else { + if (left.m_Normal[1]right.m_Normal[1]) { + return 1; + } else { + if (left.m_Normal[2]right.m_Normal[2]) { + return 1; + } else { + return 0; + } + } + } + } + } + } +}; + #endif \ No newline at end of file diff --git a/source/tools/pmdexp/resource.h b/source/tools/pmdexp/resource.h index 3511883303..7d18ec9c19 100755 --- a/source/tools/pmdexp/resource.h +++ b/source/tools/pmdexp/resource.h @@ -1,54 +1,54 @@ -//{{NO_DEPENDENCIES}} -// Microsoft Developer Studio generated include file. -// Used by PMDExp.rc -// -#define IDS_LIBDESCRIPTION 1 -#define IDS_CATEGORY 2 -#define IDS_CLASS_NAME 3 -#define IDS_PMD_CLASS_NAME 3 -#define IDS_PARAMS 4 -#define IDS_SPIN 5 -#define IDS_PSA_CLASS_NAME 6 -#define IDD_PANEL 101 -#define IDC_CLOSEBUTTON 1000 -#define IDC_DOSTUFF 1000 -#define IDC_COLOR 1456 -#define IDC_EDIT 1490 -#define IDC_SPIN 1496 - -#define IDD_NEW_POINTPARAM 118 - -#define IDC_POINT_SIZE 1059 -#define IDC_POINT_SIZESPIN 1060 -#define IDC_POINT_AXIS 1061 -#define IDC_POINT_MARKER 1062 -#define IDC_POINT_CROSS 1063 -#define IDC_POINT_BOX 1064 -#define IDC_POINT_SCREENSIZE 1065 -#define IDC_POINT_DRAWONTOP 1066 - -#define IDS_DB_POINT 8 -#define IDS_DB_POINTHELPER 9 -#define IDS_DB_POINTHELPER_CLASS 10 -#define IDS_DB_POINT_CLASS 11 - -#define IDS_POINT_PARAMS 18 -#define IDS_POINT_SIZE 19 -#define IDS_POINT_CENTERMARKER 20 -#define IDS_POINT_AXISTRIPOD 21 -#define IDS_POINT_CROSS 22 -#define IDS_POINT_BOX 23 -#define IDS_POINT_SCREENSIZE 24 -#define IDS_POINT_HELPER_NAME 25 -#define IDS_POINT_DRAWONTOP 26 - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 101 -#define _APS_NEXT_COMMAND_VALUE 40001 -#define _APS_NEXT_CONTROL_VALUE 1001 -#define _APS_NEXT_SYMED_VALUE 101 -#endif -#endif +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// Used by PMDExp.rc +// +#define IDS_LIBDESCRIPTION 1 +#define IDS_CATEGORY 2 +#define IDS_CLASS_NAME 3 +#define IDS_PMD_CLASS_NAME 3 +#define IDS_PARAMS 4 +#define IDS_SPIN 5 +#define IDS_PSA_CLASS_NAME 6 +#define IDD_PANEL 101 +#define IDC_CLOSEBUTTON 1000 +#define IDC_DOSTUFF 1000 +#define IDC_COLOR 1456 +#define IDC_EDIT 1490 +#define IDC_SPIN 1496 + +#define IDD_NEW_POINTPARAM 118 + +#define IDC_POINT_SIZE 1059 +#define IDC_POINT_SIZESPIN 1060 +#define IDC_POINT_AXIS 1061 +#define IDC_POINT_MARKER 1062 +#define IDC_POINT_CROSS 1063 +#define IDC_POINT_BOX 1064 +#define IDC_POINT_SCREENSIZE 1065 +#define IDC_POINT_DRAWONTOP 1066 + +#define IDS_DB_POINT 8 +#define IDS_DB_POINTHELPER 9 +#define IDS_DB_POINTHELPER_CLASS 10 +#define IDS_DB_POINT_CLASS 11 + +#define IDS_POINT_PARAMS 18 +#define IDS_POINT_SIZE 19 +#define IDS_POINT_CENTERMARKER 20 +#define IDS_POINT_AXISTRIPOD 21 +#define IDS_POINT_CROSS 22 +#define IDS_POINT_BOX 23 +#define IDS_POINT_SCREENSIZE 24 +#define IDS_POINT_HELPER_NAME 25 +#define IDS_POINT_DRAWONTOP 26 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 101 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1001 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif