2004-12-28 00:27:26 +01:00
|
|
|
#include "precompiled.h"
|
|
|
|
|
2005-11-19 23:27:53 +01:00
|
|
|
#include "MathUtil.h"
|
2004-06-11 00:24:03 +02:00
|
|
|
#include "EditorData.h"
|
2004-12-28 00:27:26 +01:00
|
|
|
#include "ui/UIGlobals.h"
|
2004-06-11 00:24:03 +02:00
|
|
|
#include "ToolManager.h"
|
|
|
|
#include "ObjectManager.h"
|
|
|
|
#include "UnitManager.h"
|
|
|
|
#include "TextureManager.h"
|
2005-06-20 19:34:17 +02:00
|
|
|
#include "TextureEntry.h"
|
2004-06-11 00:24:03 +02:00
|
|
|
#include "Model.h"
|
|
|
|
#include "SkeletonAnimManager.h"
|
2004-12-28 00:27:26 +01:00
|
|
|
#include "Unit.h"
|
2004-06-11 00:24:03 +02:00
|
|
|
|
|
|
|
#include "ogl.h"
|
2005-08-13 19:14:57 +02:00
|
|
|
#include "lib/res/graphics/tex.h"
|
2004-06-11 00:24:03 +02:00
|
|
|
#include "time.h"
|
|
|
|
|
|
|
|
#include "BaseEntityCollection.h"
|
|
|
|
#include "Entity.h"
|
|
|
|
#include "EntityHandles.h"
|
|
|
|
#include "EntityManager.h"
|
2004-12-28 00:27:26 +01:00
|
|
|
#include "ConfigDB.h"
|
|
|
|
#include "Scheduler.h"
|
2005-03-23 00:31:30 +01:00
|
|
|
#include "Loader.h"
|
2004-06-11 00:24:03 +02:00
|
|
|
|
2005-08-15 01:50:37 +02:00
|
|
|
#include "XML/XML.h"
|
2004-06-11 00:24:03 +02:00
|
|
|
|
2005-02-05 00:16:42 +01:00
|
|
|
#include "Game.h"
|
2005-08-08 05:59:50 +02:00
|
|
|
#include "GameAttributes.h"
|
2005-02-05 00:16:42 +01:00
|
|
|
|
2004-06-11 00:24:03 +02:00
|
|
|
const int NUM_ALPHA_MAPS = 14;
|
|
|
|
Handle AlphaMaps[NUM_ALPHA_MAPS];
|
|
|
|
|
2004-12-28 00:27:26 +01:00
|
|
|
extern CLightEnv g_LightEnv;
|
2004-06-11 00:24:03 +02:00
|
|
|
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
|
2004-12-28 00:27:26 +01:00
|
|
|
if (!LoadTerrain("temp/terrain.png")) return false;
|
2004-06-11 00:24:03 +02:00
|
|
|
|
|
|
|
// get default texture to apply to terrain
|
2005-06-20 19:34:17 +02:00
|
|
|
CTextureEntry* texture=g_TexMan.FindTexture("aaa.dds");
|
2004-06-11 00:24:03 +02:00
|
|
|
|
2005-02-05 00:16:42 +01:00
|
|
|
CTerrain* terrain = g_Game->GetWorld()->GetTerrain();
|
|
|
|
|
2004-06-11 00:24:03 +02:00
|
|
|
// cover entire terrain with default texture
|
2005-02-05 00:16:42 +01:00
|
|
|
u32 patchesPerSide=terrain->GetPatchesPerSide();
|
2004-06-11 00:24:03 +02:00
|
|
|
for (uint pj=0; pj<patchesPerSide; pj++) {
|
|
|
|
for (uint pi=0; pi<patchesPerSide; pi++) {
|
|
|
|
|
2005-02-05 00:16:42 +01:00
|
|
|
CPatch* patch=terrain->GetPatch(pi,pj);
|
2004-06-11 00:24:03 +02:00
|
|
|
|
|
|
|
for (int j=0;j<PATCH_SIZE;j++) {
|
|
|
|
for (int i=0;i<PATCH_SIZE;i++) {
|
|
|
|
patch->m_MiniPatches[j][i].Tex1=texture ? texture->GetHandle() : 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// setup camera
|
|
|
|
InitCamera();
|
|
|
|
|
|
|
|
// build the terrain plane
|
|
|
|
float h=128*HEIGHT_SCALE;
|
2005-02-05 00:16:42 +01:00
|
|
|
u32 mapSize=terrain->GetVerticesPerSide();
|
2004-06-11 00:24:03 +02:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Init: perform one time initialisation of the editor
|
|
|
|
bool CEditorData::Init()
|
|
|
|
{
|
2005-02-11 13:57:19 +01:00
|
|
|
// Set attributes for the game
|
|
|
|
g_GameAttributes.m_MapFile = L""; // start without a map
|
|
|
|
|
2005-04-03 07:02:00 +02:00
|
|
|
for (int i=1; i<8; ++i)
|
|
|
|
g_GameAttributes.GetSlot(i)->AssignLocal();
|
|
|
|
|
2005-02-05 00:16:42 +01:00
|
|
|
// Set up the actual game
|
|
|
|
g_Game = new CGame();
|
|
|
|
PSRETURN ret = g_Game->StartGame(&g_GameAttributes);
|
|
|
|
if (ret != PSRETURN_OK)
|
|
|
|
{
|
|
|
|
// Failed to start the game
|
|
|
|
delete g_Game;
|
|
|
|
g_Game = NULL;
|
|
|
|
return false;
|
|
|
|
}
|
2004-06-11 00:24:03 +02:00
|
|
|
|
2005-03-29 22:50:04 +02:00
|
|
|
LDR_NonprogressiveLoad();
|
2005-03-23 00:31:30 +01:00
|
|
|
|
2004-06-11 00:24:03 +02:00
|
|
|
// 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()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
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];
|
2005-06-20 19:34:17 +02:00
|
|
|
for (int i=0;i<4;i++) {
|
2004-06-11 00:24:03 +02:00
|
|
|
CVector3D rayDir=wPts[i]-rayOrigin;
|
|
|
|
rayDir.Normalize();
|
|
|
|
|
|
|
|
// get intersection point
|
|
|
|
m_TerrainPlane.FindRayIntersection(rayOrigin,rayDir,&hitPt[i]);
|
|
|
|
}
|
|
|
|
|
2005-02-05 00:16:42 +01:00
|
|
|
CTerrain* terrain = g_Game->GetWorld()->GetTerrain();
|
|
|
|
|
2005-06-20 19:34:17 +02:00
|
|
|
for (int i=0;i<4;i++) {
|
2004-06-11 00:24:03 +02:00
|
|
|
// convert to minimap space
|
|
|
|
float px=hitPt[i].X;
|
|
|
|
float pz=hitPt[i].Z;
|
2005-02-05 00:16:42 +01:00
|
|
|
g_MiniMap.m_ViewRect[i][0]=(197*px/float(CELL_SIZE*terrain->GetVerticesPerSide()));
|
|
|
|
g_MiniMap.m_ViewRect[i][1]=197*pz/float(CELL_SIZE*terrain->GetVerticesPerSide());
|
2004-06-11 00:24:03 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void CEditorData::RenderTerrain()
|
|
|
|
{
|
2005-02-05 00:16:42 +01:00
|
|
|
CTerrain* terrain = g_Game->GetWorld()->GetTerrain();
|
|
|
|
|
2004-12-28 00:27:26 +01:00
|
|
|
CFrustum frustum=g_NaviCam.GetCamera().GetFrustum();
|
2005-02-05 00:16:42 +01:00
|
|
|
u32 patchesPerSide= g_Game->GetWorld()->GetTerrain()->GetPatchesPerSide();
|
2004-06-11 00:24:03 +02:00
|
|
|
for (uint j=0; j<patchesPerSide; j++) {
|
|
|
|
for (uint i=0; i<patchesPerSide; i++) {
|
2005-02-05 00:16:42 +01:00
|
|
|
CPatch* patch=terrain->GetPatch(i,j);
|
2004-06-11 00:24:03 +02:00
|
|
|
if (frustum.IsBoxVisible (CVector3D(0,0,0),patch->GetBounds())) {
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////
|
2005-01-17 00:09:41 +01:00
|
|
|
// SubmitModelRecursive: recurse down given model, submitting it and all its descendants to the
|
2004-06-11 00:24:03 +02:00
|
|
|
// renderer
|
|
|
|
void SubmitModelRecursive(CModel* model)
|
|
|
|
{
|
|
|
|
g_Renderer.Submit(model);
|
|
|
|
|
|
|
|
const std::vector<CModel::Prop>& props=model->GetProps();
|
|
|
|
for (uint i=0;i<props.size();i++) {
|
|
|
|
SubmitModelRecursive(props[i].m_Model);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// RenderNoCull: render absolutely everything to a blank frame to force renderer
|
|
|
|
// to load required assets
|
|
|
|
void CEditorData::RenderNoCull()
|
|
|
|
{
|
|
|
|
g_Renderer.BeginFrame();
|
|
|
|
g_Renderer.SetCamera(g_NaviCam.GetCamera());
|
|
|
|
|
|
|
|
uint i,j;
|
|
|
|
const std::vector<CUnit*>& units=g_UnitMan.GetUnits();
|
|
|
|
for (i=0;i<units.size();++i) {
|
|
|
|
SubmitModelRecursive(units[i]->GetModel());
|
|
|
|
}
|
|
|
|
|
2005-02-05 00:16:42 +01:00
|
|
|
CTerrain* terrain = g_Game->GetWorld()->GetTerrain();
|
|
|
|
|
|
|
|
u32 patchesPerSide=terrain->GetPatchesPerSide();
|
2004-06-11 00:24:03 +02:00
|
|
|
for (j=0; j<patchesPerSide; j++) {
|
|
|
|
for (i=0; i<patchesPerSide; i++) {
|
2005-02-05 00:16:42 +01:00
|
|
|
CPatch* patch=terrain->GetPatch(i,j);
|
2004-06-11 00:24:03 +02:00
|
|
|
g_Renderer.Submit(patch);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
g_Renderer.FlushFrame();
|
|
|
|
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
|
|
|
|
g_Renderer.EndFrame();
|
|
|
|
}
|
|
|
|
|
|
|
|
void CEditorData::RenderModels()
|
|
|
|
{
|
2004-12-28 00:27:26 +01:00
|
|
|
CFrustum frustum=g_NaviCam.GetCamera().GetFrustum();
|
2004-06-11 00:24:03 +02:00
|
|
|
|
|
|
|
const std::vector<CUnit*>& units=g_UnitMan.GetUnits();
|
|
|
|
uint i;
|
|
|
|
for (i=0;i<units.size();++i) {
|
|
|
|
if (frustum.IsBoxVisible (CVector3D(0,0,0),units[i]->GetModel()->GetBounds())) {
|
|
|
|
SubmitModelRecursive(units[i]->GetModel());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void CEditorData::RenderWorld()
|
|
|
|
{
|
|
|
|
// render terrain
|
|
|
|
RenderTerrain();
|
|
|
|
|
|
|
|
// render all the units
|
|
|
|
RenderModels();
|
|
|
|
|
2005-01-17 00:09:41 +01:00
|
|
|
// flush prior to rendering overlays etc
|
2004-06-11 00:24:03 +02:00
|
|
|
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) {
|
2004-12-28 00:27:26 +01:00
|
|
|
g_Renderer.SetClearColor(0x00000000);
|
2004-06-11 00:24:03 +02:00
|
|
|
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();
|
2005-01-17 00:09:41 +01:00
|
|
|
|
|
|
|
const std::vector<CUnit*>& units=g_UnitMan.GetUnits();
|
|
|
|
for (size_t i=0;i<units.size();++i)
|
|
|
|
if (units[i]->GetEntity())
|
|
|
|
units[i]->GetEntity()->renderSelectionOutline();
|
|
|
|
|
2004-06-11 00:24:03 +02:00
|
|
|
} else {
|
|
|
|
g_Renderer.SetClearColor(0x00453015);
|
|
|
|
g_Renderer.BeginFrame();
|
|
|
|
|
2005-03-23 00:31:30 +01:00
|
|
|
// 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);
|
|
|
|
// }
|
2004-06-11 00:24:03 +02:00
|
|
|
|
|
|
|
// 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)
|
2005-11-20 15:35:52 +01:00
|
|
|
{
|
|
|
|
Tex t;
|
|
|
|
if(tex_load(filename, &t) < 0)
|
|
|
|
{
|
2004-06-11 00:24:03 +02:00
|
|
|
char buf[1024];
|
|
|
|
sprintf(buf,"Failed to load \"%s\"",filename);
|
|
|
|
ErrorBox(buf);
|
|
|
|
return false;
|
2005-11-20 15:35:52 +01:00
|
|
|
}
|
2004-06-11 00:24:03 +02:00
|
|
|
|
2005-11-20 15:35:52 +01:00
|
|
|
uint width=t.w, height=t.h, bpp=t.bpp;
|
|
|
|
void *ptr=tex_get_data(&t);
|
2004-06-11 00:24:03 +02:00
|
|
|
|
2005-11-20 15:35:52 +01:00
|
|
|
// rescale the texture to fit to the nearest of the 4 possible map sizes
|
|
|
|
u32 mapsize=9; // assume smallest map
|
|
|
|
if (width>11*PATCH_SIZE+1) mapsize=11;
|
|
|
|
if (width>13*PATCH_SIZE+1) mapsize=13;
|
|
|
|
if (width>17*PATCH_SIZE+1) mapsize=17;
|
|
|
|
|
|
|
|
u32 targetsize=mapsize*PATCH_SIZE+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);
|
2004-06-11 00:24:03 +02:00
|
|
|
|
2005-11-20 15:35:52 +01:00
|
|
|
// build 16 bit heightmap from red channel of texture
|
|
|
|
u16* heightmap=new u16[targetsize*targetsize];
|
|
|
|
int stride=bpp/8;
|
|
|
|
u16* hmptr=heightmap;
|
2004-06-11 00:24:03 +02:00
|
|
|
|
2005-11-20 15:35:52 +01:00
|
|
|
// get src of copy
|
|
|
|
const u8* dataptr = (bpp==8) ? data : ((bpp==24) ? data+2 : data+3);
|
|
|
|
|
|
|
|
// build heightmap
|
|
|
|
for (uint j=0;j<targetsize;++j) {
|
|
|
|
for (uint i=0;i<targetsize;++i) {
|
|
|
|
*hmptr=(*dataptr) << 8;
|
|
|
|
hmptr++;
|
|
|
|
dataptr+=stride;
|
|
|
|
}
|
2004-06-11 00:24:03 +02:00
|
|
|
}
|
2005-11-20 15:35:52 +01:00
|
|
|
|
|
|
|
// rebuild terrain
|
|
|
|
g_Game->GetWorld()->GetTerrain()->Resize(mapsize);
|
|
|
|
g_Game->GetWorld()->GetTerrain()->SetHeightMap(heightmap);
|
|
|
|
|
|
|
|
// clean up
|
|
|
|
delete[] data;
|
|
|
|
delete[] heightmap;
|
|
|
|
(void)tex_free(&t);
|
|
|
|
|
|
|
|
// re-initialise minimap - terrain size may have changed
|
|
|
|
g_MiniMap.Initialise();
|
|
|
|
|
|
|
|
return true;
|
2004-06-11 00:24:03 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// UpdateWorld: update time dependent data in the world to account for changes over
|
|
|
|
// the given time (in s)
|
|
|
|
void CEditorData::UpdateWorld(float time)
|
|
|
|
{
|
|
|
|
if (m_Mode==SCENARIO_EDIT || m_Mode==TEST_MODE) {
|
2005-01-12 15:31:47 +01:00
|
|
|
g_EntityManager.interpolateAll(0.f);
|
2004-06-11 00:24:03 +02:00
|
|
|
const std::vector<CUnit*>& units=g_UnitMan.GetUnits();
|
|
|
|
for (uint i=0;i<units.size();++i) {
|
|
|
|
units[i]->GetModel()->Update(time);
|
|
|
|
}
|
2005-04-03 07:02:00 +02:00
|
|
|
// if (m_Mode==TEST_MODE) {
|
|
|
|
// g_EntityManager.updateAll( time );
|
|
|
|
// }
|
2004-06-11 00:24:03 +02:00
|
|
|
} else {
|
2005-03-23 00:31:30 +01:00
|
|
|
// CObjectEntry* selobject=g_ObjMan.GetSelectedObject();
|
|
|
|
// if (selobject && selobject->m_Model) {
|
|
|
|
// selobject->m_Model->Update(time);
|
|
|
|
// }
|
2004-06-11 00:24:03 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void CEditorData::StartTestMode()
|
|
|
|
{
|
|
|
|
// initialise entities
|
2004-12-28 00:27:26 +01:00
|
|
|
g_EntityManager.InitializeAll();
|
2004-06-11 00:24:03 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void CEditorData::StopTestMode()
|
|
|
|
{
|
|
|
|
// make all units idle again
|
|
|
|
const std::vector<CUnit*>& units=g_UnitMan.GetUnits();
|
|
|
|
for (uint i=0;i<units.size();++i) {
|
2005-05-23 03:55:30 +02:00
|
|
|
units[i]->SetRandomAnimation("idle");
|
2004-06-11 00:24:03 +02:00
|
|
|
}
|
2004-05-29 23:45:04 +02:00
|
|
|
}
|