📄 gm_world.cpp
字号:
// GM_World.cpp: implementation of the GM_World class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "GM_World.h"
//typedef std::multimap<INDEX, GM_Object*> t_object_map;
typedef std::map<INDEX, std::vector<GM_Object*> > t_object_map;
typedef std::vector<GM_Object*> t_object_array;
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
GM_World::GM_World(CGsEngine* pEngine)
:m_background(pEngine)
{
m_pEngine = pEngine;
m_cell_width = 16;
m_cell_height = 16;
m_cell_rate = 1.5f;
m_num_grid_width = 0;
m_num_grid_height = 0;
m_fXOriginalPix = 0.0f;
m_fYOriginalPix = 0.0f;
m_rcOriginalPix = GRECT(0,0,0,0);
m_rcOriginalCell = GRECT(0,0,0,0);
m_dwSceneTime = 0;
m_dwSceneBaseTime = m_pEngine->m_dwEngineTime;
m_dwSceneStopTime = 0;
m_flag_grid_drawing = DRAW_GRID_NONE;
m_idObjFocus = 0;
// m_pRain = NULL;
// m_pSnow = NULL;
// m_pThunder = NULL;
//
// m_thunder_alpha = 0.0f;
// m_thunder_rate = 0.5f;
// m_thunder_time = 0.0f;
m_quake_grade = 0.0f;
m_quake_time = 0.0f;
m_simsky_height = 1000.0f;
m_ptr_ui_minimap = NULL;
m_active_range = 600;
m_mouse_grid = GPOINT(0,0);
}
GM_World::~GM_World()
{
Cleanup();
}
VOID GM_World::Cleanup()
{
m_scene_width = 0;
m_scene_height = 0;
m_num_grid_width = 0;
m_num_grid_height = 0;
m_fXOriginalPix = 0.0f;
m_fYOriginalPix = 0.0f;
m_rcOriginalPix = GRECT(0,0,0,0);
m_rcOriginalCell = GRECT(0,0,0,0);
m_dwSceneTime = 0;
m_dwSceneBaseTime = m_pEngine->m_dwEngineTime;
m_dwSceneStopTime = 0;
m_aNode.clear();
std::map<ID, GM_Object*>::iterator it = m_apObject.begin();
int a = m_apObject.size();
while(it!=m_apObject.end())
{
if(it->second)
delete(it->second);
it = m_apObject.erase(it);
}
// m_apObject.clear();
m_mapObject.clear();
// SAFE_DELETE(m_pRain);
// SAFE_DELETE(m_pSnow);
// SAFE_DELETE(m_pThunder);
}
BOOL GM_World::InitScene(int width, int height)
{
assert(m_cell_width!=0 && m_cell_height!=0);
Cleanup();
m_scene_width = width;
m_scene_height = height;
LONG a = m_scene_width;
LONG b = m_scene_height;
PickFlatGrid(a, b);
m_num_grid_width = a+1;
m_num_grid_height = b+1;
m_fXOriginalPix = 0.0f;
m_fYOriginalPix = 0.0f;
m_rcOriginalPix = GRECT(0,0,0,0);
m_rcOriginalCell = GRECT(0,0,0,0);
m_dwSceneTime = 0;
m_dwSceneBaseTime = m_pEngine->m_dwEngineTime;
m_dwSceneStopTime = 0;
int i,j;
_MESH_NODE node;
node.height = 0;
node.light = 1.0;
for(i=0; i<(m_num_grid_height+1)/2+1; i++)
{
for(j=0; j<m_num_grid_width+1; j++)
{
node.xFlat = (float)m_cell_width*j;
node.xRough = node.xFlat;
node.yFlat = -(float)m_cell_height/2.0*((j+1)%2) + (float)m_cell_height*i;
node.yRough = node.yFlat;
m_aNode.push_back(node);
}
}
for(i=0; i<m_num_grid_width*m_num_grid_height; i++)
{
m_aTerrain.push_back(0);
}
// m_pRain = new GS_Weather_Rain(this);
// m_pSnow = new GS_Weather_Snow(this);
// m_pThunder = new GS_Weather_Thunder(this);
return TRUE;
}
VOID GM_World::GridCenter(LONG& nX, LONG& nY)
{
nX = nX*m_cell_width + m_cell_width/2;
nY = nY*m_cell_height/2;
}
int GM_World::GridNodeIndexU(int nX, int nY)
{
return nY/2*(m_num_grid_width+1) + nX + (nX+nY)%2 ;
}
int GM_World::GridNodeIndexC(int nX, int nY)
{
return (nY/2+nY%2)*(m_num_grid_width+1) + nX + (nX+nY+1)%2 ;
}
int GM_World::GridNodeIndexD(int nX, int nY)
{
return (nY/2+1)*(m_num_grid_width+1) + nX + (nX+nY)%2 ;
}
INDEX GM_World::GridToIndex(LONG nX, LONG nY)
{
return nX + nY*m_num_grid_width;
}
VOID GM_World::IndexToGrid(INDEX index, LONG &nX, LONG &nY)
{
nX = index%m_num_grid_width;
nY = index/m_num_grid_width;
}
VOID GM_World::PickFlatGrid(LONG& nX, LONG& nY)
{
LONG a,b;
a = nX + nY * 2;
b = nX - nY * 2;
a = (a + sign(a) * m_cell_height) / m_cell_width /2;
b = (b + sign(b) * m_cell_height) / m_cell_width /2;
nX = nX / m_cell_width;//(a + b) / 2;
nY = (a - b);
}
VOID GM_World::PickRoughGrid(LONG& nX, LONG& nY)
{
PickFlatGrid(nX,nY);
}
VOID GM_World::GetOriginal(LONG& nX, LONG& nY)
{
nX = m_rcOriginalPix.left;
nY = m_rcOriginalPix.top;
}
VOID GM_World::PickFlatToRough(LONG& nX, LONG& nY)
{
}
VOID GM_World::PickRoughToFlat(LONG& nX, LONG& nY)
{
}
int GM_World::select_obj(std::vector<GM_Object*>&obj_array, LONG x, LONG y)
{
PickFlatGrid(x, y);
int ret = 0;
t_object_map::iterator it = m_mapObject.find(GridToIndex(x,y));
if(it!=m_mapObject.end())
{
obj_array = it->second;
ret = obj_array.size();
}
return ret;
}
VOID GM_World::PickSimSkyToScene(float &fX, float &fY, float &fZ, float* pfS)
{
float w_rate = 2.0f;
float h_rate = 2.0f;
//fY = fY*m_pEngine->GetRenderHeight()/m_simsky_height;
float z = fZ - m_rcOriginalPix.top;//((long)fZ)/m_pEngine->GetRenderHeight()*m_pEngine->GetRenderHeight();
float h = (m_pEngine->GetRenderHeight()-z)*h_rate+z;
//float a2 = (w_rate-1.0f)/h;
float x = m_pEngine->GetRenderHeight()/(w_rate-1.0f);
//fY = (sqrt(1.0f + a2*fY*(w_rate+1.0f)*m_pEngine->GetRenderHeight()/h) - 1.0f)/a2;
//fY = (fY*fY*a2/2.0f + fY)*2.0f*h/(w_rate+1.0f)/m_pEngine->GetRenderHeight();
//fY = exp(fY*fY/x/2.0f + fY)*2.0f/(w_rate+1.0f)*h/m_pEngine->GetRenderHeight();
float a = log(1+m_pEngine->GetRenderHeight()/x)/m_simsky_height;
fY = x*exp(a*fY)-x;
fX = (fX-m_pEngine->GetRenderWidth()/2.0f)*(x+fY)/x+m_pEngine->GetRenderWidth()/2.0f;
if(pfS)
*pfS = (x+fY)/x;
fY = z - fY;
fZ = 1.0 - fZ/m_scene_height;
}
VOID GM_World::FocusTo(LONG nX, LONG nY)
{
m_fXOriginalPix = nX - (LONG)m_pEngine->GetRenderWidth()/2;
m_fYOriginalPix = nY - (LONG)m_pEngine->GetRenderHeight()/2;
_CalcOriginal();
}
VOID GM_World::SetFocusObject(GM_Object *pObject)
{
if(pObject)
m_idObjFocus = pObject->GetID();
else
m_idObjFocus = 0;
}
VOID GM_World::SetOriginal(LONG nX, LONG nY)
{
m_fXOriginalPix = nX;
m_fYOriginalPix = nY;
_CalcOriginal();
}
VOID GM_World::_CalcOriginal()
{
m_rcOriginalPix.left = m_fXOriginalPix;
m_rcOriginalPix.top = m_fYOriginalPix;
if(m_rcOriginalPix.left>m_scene_width - (LONG)m_pEngine->GetRenderWidth())
{
m_rcOriginalPix.left=m_scene_width - m_pEngine->GetRenderWidth();
m_fXOriginalPix = m_rcOriginalPix.left;
}
if(m_rcOriginalPix.left<0)
{
m_rcOriginalPix.left=0;
m_fXOriginalPix = m_rcOriginalPix.left;
}
m_rcOriginalPix.right = m_rcOriginalPix.left + m_pEngine->GetRenderWidth();
if(m_rcOriginalPix.top>m_scene_height - (LONG)m_pEngine->GetRenderHeight())
{
m_rcOriginalPix.top=m_scene_height - m_pEngine->GetRenderHeight();
m_fYOriginalPix = m_rcOriginalPix.top;
}
if(m_rcOriginalPix.top<0)
{
m_rcOriginalPix.top=0;
m_fYOriginalPix = m_rcOriginalPix.top;
}
m_rcOriginalPix.bottom = m_rcOriginalPix.top + m_pEngine->GetRenderHeight();
m_rcOriginalCell = m_rcOriginalPix;
PickRoughGrid(m_rcOriginalCell.left, m_rcOriginalCell.top);
PickRoughGrid(m_rcOriginalCell.right, m_rcOriginalCell.bottom);
// m_rcOriginalCell.left -= 3;
if(m_rcOriginalCell.left<0)
m_rcOriginalCell.left = 0;
// m_rcOriginalCell.top -= 3;
if(m_rcOriginalCell.top<0)
m_rcOriginalCell.top = 0;
// m_rcOriginalCell.right += 5;
if(m_rcOriginalCell.right>m_num_grid_width)
m_rcOriginalCell.right = m_num_grid_width;
// m_rcOriginalCell.bottom += 5;
if(m_rcOriginalCell.bottom>m_num_grid_height)
m_rcOriginalCell.bottom = m_num_grid_height;
CalcMinimap();
}
VOID GM_World::MoveView(LONG nXspeed, LONG nYspeed)
{
float ft = m_pEngine->m_dwPassTime/10000.0f;
m_fXOriginalPix += nXspeed*ft;
m_fYOriginalPix += nYspeed*ft;
_CalcOriginal();
}
BOOL GM_World::OnUpdateViewport()
{
return false;
}
BOOL GM_World::Update()
{
m_background.Update();
// update object
m_mapObject.clear();
std::map<ID, GM_Object*>::iterator it = m_apObject.begin();
while(it!=m_apObject.end() )
{
GM_Object* pObj = it->second;
if(pObj->IsDismiss() || pObj->Update()<0)
{
SAFE_DELETE(pObj);
it = m_apObject.erase(it);
continue;
}
it++;
}
it = m_apObject.begin();
while(it!=m_apObject.end() )
{
it->second->RunAI();
it++;
}
if(!OnUpdateViewport())
{
GM_Object* pObj = GetObject(m_idObjFocus);
if(pObj)
{
m_fXOriginalPix = pObj->m_fPosX - (LONG)m_pEngine->GetRenderWidth()/2;
m_fYOriginalPix = pObj->m_fPosY - (LONG)m_pEngine->GetRenderHeight()/2;
}
_CalcOriginal();
}
//
//地震效果
if(m_quake_grade>0.0f)
{
LONG ox = m_quake_grade*2.0f*rnd() + m_rcOriginalPix.left - m_quake_grade;
LONG oy = m_quake_grade*2.0f*rnd() + m_rcOriginalPix.top - m_quake_grade;
SetOriginal(ox,oy);
if(m_quake_time>0)
{
m_quake_time -= m_pEngine->m_dwPassTime/10000.0f;
if(m_quake_time<=0)
{
m_quake_grade = 0.0f;
m_quake_time = 0.0f;
}
}
}
m_mouse_grid = m_pEngine->m_Pos+m_rcOriginalPix.top_left();
PickFlatGrid(m_mouse_grid.x, m_mouse_grid.y);
// yodate weather
// if(m_pRain)
// m_pRain->Update();
// if(m_pSnow)
// m_pSnow->Update();
// if(m_pThunder)
// m_pThunder->Update();
return TRUE;
}
HRESULT GM_World::Render()
{
HRESULT hr;
// m_background.Draw(-m_rcOriginalPix.left, -m_rcOriginalPix.top, 1.0f);
if(m_flag_grid_drawing!=DRAW_GRID_NONE)
DrawGrid();
m_pEngine->PreparePaint();
//draw object
std::multimap<float, GM_Object*> map_object;
// std::map<float, t_object_array> map_object;
std::map<ID, GM_Object*>::iterator it_id_obj = m_apObject.begin();
while(it_id_obj!=m_apObject.end())
{
if(it_id_obj->second && it_id_obj->second->m_bRender)
{
// map_object[-it_id_obj->second->m_fZbuf].push_back(it_id_obj->second);
map_object.insert(std::multimap<float, GM_Object*>::value_type(-it_id_obj->second->m_fZbuf,it_id_obj->second));
}
it_id_obj++;
}
std::multimap<float, GM_Object*>::iterator it = map_object.begin();
// std::map<float, t_object_array>::iterator it = map_object.begin();
while(it!=map_object.end() )
{
// for(int i=0; i<it->second.size(); i++)
// {
// hr = it->second[i]->Render();
// if(FAILED(hr))
// {
// map_object.clear();
// return hr;
// }
// }
hr = it->second->Render();
if(FAILED(hr))
{
map_object.clear();
return hr;
}
it++;
}
it = map_object.begin();
// std::map<float, t_object_array>::iterator it = map_object.begin();
while(it!=map_object.end() )
{
hr = it->second->Render2();
it++;
}
// it = map_object.begin();
// while(it!=map_object.end() )
// {
// it->second->GetAnimation()->GetTextureGroup()->ClearCache();
// it++;
// }
// map_object.clear();
/*
//DarkenScene(0.5f);
PreparePaint();
// render weather
if(m_pRain)
hr = m_pRain->Render();
if(m_pSnow)
hr = m_pSnow->Render();
if(m_pThunder)
hr = m_pThunder->Render();
//PreparePaint(D3DBLEND_SRCALPHA, D3DBLEND_INVSRCALPHA, D3DTOP_SELECTARG1, D3DTOP_SELECTARG1);
//Paint(0,0,FindParticle(GS_PARTICLE_LIGHT),0.0f,5.0f,20.0f,1.0F,0,0xffffffff);
//闪雷效果
if(m_thunder_alpha>0.0f)
{
pD3dDevice->SetRenderState(D3DRENDERSTATE_ZENABLE, false);
PreparePaint(D3DBLEND_SRCALPHA, D3DBLEND_INVSRCALPHA, D3DTOP_ADD, D3DTOP_SELECTARG2);
Render_PaintFast(0,0,NULL,0.0f,1.0f,1.0f,m_thunder_alpha,0xffffffff);
m_thunder_time += m_pEngine->m_dwPassTime/10000.0f;
m_thunder_alpha -= 0.5f*m_thunder_rate*m_thunder_time*m_thunder_time;
OnThunder();
pD3dDevice->SetRenderState(D3DRENDERSTATE_ZENABLE, true);
}
*/
return hr;
}
VOID GM_World::SetDrawGridFlag(DWORD flag)
{
m_flag_grid_drawing = flag;
}
HRESULT GM_World::DrawGrid()
{
HRESULT hr;
//maybe create in vertexbuff will fast
// D3DTLVERTEX* pVertex = new D3DTLVERTEX[(m_rcOriginalCell.width()+1)*(m_rcOriginalCell.height()+1)*3];
D3DTLVERTEX pVertex[3];
LPDIRECT3DDEVICE7 pD3dDevice = m_pEngine->GetD3dDevice();
pD3dDevice->SetTexture(0, NULL);
t_object_map::iterator it;
// PreparePaint(D3DBLEND_ZERO, D3DBLEND_SRCALPHA, D3DTOP_SELECTARG2, D3DTOP_SELECTARG2);
for(int y=m_rcOriginalCell.top; y<m_rcOriginalCell.bottom+1; y++)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -