Move git root from Client/ to src/ to track all source code: - Client: Game client source (moved to Client/Client/) - Server: Game server source - GameTools: Development tools - CryptoSource: Encryption utilities - database: Database scripts - Script: Game scripts - rylCoder_16.02.2008_src: Legacy coder tools - GMFont, Game: Additional resources 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
405 lines
10 KiB
C++
405 lines
10 KiB
C++
#include "ROcclusion.h"
|
||
|
||
/*
|
||
void ROcclusion::CheckCulling(LPDIRECT3DDEVICE8 ,ROcclusionUnit *list,int num,float camera_x,float camera_y,float camera_z);
|
||
void ROcclusion::SortList(ROcclusionUnit *,int num,float camerax,float cameray,float cameraz,LPDIRECT3DDEVICE8 );
|
||
|
||
void ROcclusion::HorizonCull(LPDIRECT3DDEVICE8 ,ROcclusionUnit *,int listnum);
|
||
void ROcclusion::Hculling(ROcclusionUnit *list,int listnum,int start_index,float ,float ,float );
|
||
void ROcclusion::InitVolume();
|
||
*/
|
||
ROcclusionVolume *ROcclusion::m_Volume;
|
||
unsigned long ROcclusion::m_VWidth;
|
||
unsigned long ROcclusion::m_VHeight;
|
||
int ROcclusion::m_ViewObject;
|
||
int ROcclusion::m_HidenObject;
|
||
|
||
|
||
/////////////////////////////// ROcclusionUnit ////////////////////////////////////
|
||
void ROcclusionUnit::FindPoint(D3DXVECTOR3 *point)
|
||
{
|
||
int i;
|
||
|
||
D3DXVECTOR3 tmp_sum = D3DXVECTOR3(0.0f,0.0f,0.0f);
|
||
D3DXVECTOR3 tmp_cube[8];
|
||
|
||
int min_index = 0;
|
||
int max_index = 0;
|
||
|
||
int zover_count = 0;
|
||
int zover_count2 = 0;
|
||
|
||
unsigned long Screen_width = 0;
|
||
unsigned long Screen_height = 0;
|
||
D3DXMATRIX t_project;
|
||
D3DXMATRIX t_view;
|
||
D3DXMATRIX t_world;
|
||
|
||
D3DXVECTOR3 view_vec[3];
|
||
D3DXVECTOR4 view_vec2[3];
|
||
|
||
D3DVIEWPORT8 t_viewport;
|
||
D3DXVECTOR3 min_value,max_value,target_value;
|
||
|
||
m_Device->GetTransform(D3DTS_VIEW,&t_view);
|
||
|
||
m_Device->GetViewport(&t_viewport);
|
||
m_Device->GetTransform(D3DTS_WORLD,&t_world);
|
||
m_Device->GetTransform(D3DTS_PROJECTION,&t_project);
|
||
Screen_width = t_viewport.Width;
|
||
Screen_height = t_viewport.Height;
|
||
|
||
for( i=0; i < 8; i++ )
|
||
{
|
||
|
||
tmp_cube[i] = D3DXVECTOR3(m_Cube.m_vecVertex[i].x,m_Cube.m_vecVertex[i].y,m_Cube.m_vecVertex[i].z);
|
||
|
||
tmp_sum += tmp_cube[i];
|
||
|
||
|
||
D3DXVec3Project(&(view_vec[0]),
|
||
&(tmp_cube[min_index]),
|
||
&t_viewport,
|
||
&t_project,
|
||
&t_view,
|
||
&t_world);
|
||
|
||
D3DXVec3Project(&(view_vec[1]),
|
||
&(tmp_cube[i]),
|
||
&t_viewport,
|
||
&t_project,
|
||
&t_view,
|
||
&t_world);
|
||
|
||
D3DXVec3Project(&(view_vec[2]),
|
||
&(tmp_cube[max_index]),
|
||
&t_viewport,
|
||
&t_project,
|
||
&t_view,
|
||
&t_world);
|
||
|
||
max_value = view_vec[2];
|
||
min_value = view_vec[0];
|
||
target_value = view_vec[1];
|
||
|
||
|
||
|
||
//z value<75><65> 0 ~ 1<><31> <20>Ѿ<D1BE><EEB0A1> ȭ<><C8AD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̴<EFBFBD>
|
||
if( target_value.z > 1.0f || target_value.z < 0.0f )
|
||
{
|
||
zover_count++;
|
||
zover_count2++;
|
||
continue;
|
||
}
|
||
if( min_value.z > 1.0f || min_value.z <0.0f )
|
||
{
|
||
min_index = i;
|
||
zover_count++;
|
||
|
||
}
|
||
if( max_value.z > 1.0f || max_value.z <0.0f )
|
||
{
|
||
max_index = i;
|
||
zover_count2++;
|
||
}
|
||
|
||
if( min_value.x > target_value.x ) { //min value
|
||
min_index = i;
|
||
}
|
||
else if( min_value.x == target_value.x )
|
||
{
|
||
if( min_value.y > target_value.y )
|
||
min_index = i;
|
||
}
|
||
|
||
if( max_value.x == target_value.x ) //max value
|
||
{
|
||
if( max_value.y > target_value.y )
|
||
max_index = i;
|
||
}
|
||
else if( max_value.x < target_value.x )
|
||
{
|
||
max_index = i;
|
||
}
|
||
|
||
}//for
|
||
tmp_sum /=8;
|
||
|
||
point[2] = tmp_sum;
|
||
|
||
if(zover_count >= 8) // min value overflow
|
||
point[0] = D3DXVECTOR3(FAIL,FAIL,FAIL);
|
||
else
|
||
point[0] = tmp_cube[min_index];
|
||
|
||
if(zover_count2 >= 8) // max value overflow
|
||
point[1] = D3DXVECTOR3(FAIL,FAIL,FAIL);
|
||
else
|
||
point[1] = tmp_cube[max_index];
|
||
|
||
}
|
||
void ROcclusionUnit::Create(LPDIRECT3DDEVICE8 device)
|
||
{
|
||
|
||
m_Device = device;
|
||
|
||
D3DXVECTOR3 Point[3];
|
||
|
||
D3DXVECTOR3 min;
|
||
D3DXVECTOR3 max;
|
||
D3DXVECTOR3 center;
|
||
|
||
FindPoint(Point);
|
||
|
||
min = Point[0];
|
||
max = Point[1];
|
||
center = Point[2];
|
||
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> ȭ<><C8AD> <20>ٱ<EFBFBD><D9B1><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
if( min.x == FAIL && min.y == FAIL && min.z == FAIL )
|
||
(*m_bVis) = false;
|
||
if( max.x == FAIL && max.y == FAIL && max.z == FAIL )
|
||
(*m_bVis) = false;
|
||
//
|
||
|
||
CreateOccBox(min,max,center,false);
|
||
|
||
|
||
}
|
||
|
||
//int projected arg == min,max <20><><EFBFBD><EFBFBD> <20>̹<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>Ǿ<EFBFBD><C7BE>ִ<EFBFBD><D6B4><EFBFBD>..
|
||
void ROcclusionUnit::CreateOccBox(D3DXVECTOR3 min,D3DXVECTOR3 max,D3DXVECTOR3 center,bool projected)
|
||
{
|
||
m_OccBox.m_vecCenter = center;
|
||
if(!projected) //world axis min max point input
|
||
{
|
||
// min point,max point setting
|
||
D3DXVECTOR3 projectedpoint[2];
|
||
|
||
D3DXMATRIX t_project;
|
||
D3DXMATRIX t_view;
|
||
D3DXMATRIX t_world;
|
||
|
||
|
||
D3DVIEWPORT8 t_viewport;
|
||
|
||
m_Device->GetViewport(&t_viewport);
|
||
m_Device->GetTransform(D3DTS_WORLD,&t_world);
|
||
m_Device->GetTransform(D3DTS_VIEW,&t_view);
|
||
m_Device->GetTransform(D3DTS_PROJECTION,&t_project);
|
||
//projected 2d space
|
||
D3DXVec3Project(&(projectedpoint[0]),
|
||
&(min),
|
||
&t_viewport,
|
||
&t_project,
|
||
&t_view,
|
||
&t_world);
|
||
|
||
D3DXVec3Project(&(projectedpoint[1]),
|
||
&(max),
|
||
&t_viewport,
|
||
&t_project,
|
||
&t_view,
|
||
&t_world);
|
||
|
||
|
||
m_OccBox.m_vecMin.x = projectedpoint[0].x;
|
||
m_OccBox.m_vecMin.y = projectedpoint[0].y;
|
||
|
||
m_OccBox.m_vecMax.x = projectedpoint[1].x;
|
||
m_OccBox.m_vecMax.y = projectedpoint[1].y;
|
||
}
|
||
else //<2F>̹<EFBFBD> projection <20><> <20><><EFBFBD>·<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
{
|
||
m_OccBox.m_vecMin.x = min.x;
|
||
m_OccBox.m_vecMin.y = min.y;
|
||
|
||
m_OccBox.m_vecMax.x = max.x;
|
||
m_OccBox.m_vecMax.y = max.y;
|
||
}
|
||
}
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
|
||
int OcclusionHCompare(const void *arg1,const void *arg2)
|
||
{
|
||
|
||
if(((ROcclusionUnit *)arg1)->m_OccBox.m_fZValue > ((ROcclusionUnit *)arg2)->m_OccBox.m_fZValue)
|
||
return 1;
|
||
else if(((ROcclusionUnit *)arg1)->m_OccBox.m_fZValue < ((ROcclusionUnit *)arg2)->m_OccBox.m_fZValue)
|
||
return -1;
|
||
return 0;
|
||
|
||
}
|
||
|
||
//camera <20><>ġ<EFBFBD><C4A1> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> list sort
|
||
void ROcclusion::SortList(ROcclusionUnit *list,int num,float camerax,float cameray,float cameraz,LPDIRECT3DDEVICE8 device)
|
||
{
|
||
int i;
|
||
|
||
D3DXMATRIX cameratm;
|
||
D3DXMATRIX invcamera;
|
||
|
||
device->GetTransform(D3DTS_VIEW,&cameratm);
|
||
D3DXMatrixInverse(&invcamera,NULL,&cameratm);
|
||
|
||
D3DXVECTOR4 src,dst;
|
||
|
||
for( i=0; i < num; i++ )
|
||
{
|
||
D3DXVec3Transform(&src,&list[i].m_OccBox.m_vecCenter,&cameratm);
|
||
list[i].m_OccBox.m_fZValue = src.z;
|
||
}
|
||
|
||
qsort((void *)list,(size_t)num, sizeof(ROcclusionUnit),OcclusionHCompare);
|
||
|
||
}
|
||
|
||
void ROcclusion::CheckCulling(LPDIRECT3DDEVICE8 device,ROcclusionUnit *list,int num,float camera_x,float camera_y,float camera_z) {
|
||
int i;
|
||
|
||
for( i = 0; i < num ; i++)
|
||
list[i].Create(device); // 2D Box Create
|
||
|
||
SortList(list,num,camera_x,camera_y,camera_z,device);
|
||
HorizonCull(device,list,num);
|
||
|
||
m_ViewObject = m_HidenObject = 0;
|
||
|
||
//culling info set
|
||
for( i = 0; i < num; i++ )
|
||
{
|
||
if( (*list[i].m_bVis) )
|
||
m_ViewObject++;
|
||
else
|
||
m_HidenObject++;
|
||
}
|
||
|
||
}
|
||
void ROcclusion::InitVolume() // Screen Volume Init
|
||
{
|
||
for(int k=0;k<(int)m_VWidth;k++)
|
||
m_Volume[k].m_Height = (float)m_VHeight;
|
||
}
|
||
//<2F><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ͽ<EFBFBD> culling <20><><EFBFBD><EFBFBD>
|
||
void ROcclusion::Hculling(ROcclusionUnit *list,int listnum,int start_index,float camerax,float cameray,float cameraz)
|
||
{
|
||
|
||
for( int i = start_index; i < listnum; i++ )
|
||
{
|
||
if( (*list[i].m_bVis) ) // <20>˻<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>̴<EFBFBD> <20><>ü<EFBFBD><C3BC><EFBFBD><EFBFBD> <20>˻<EFBFBD>
|
||
{
|
||
int count = 0;
|
||
|
||
if( list[i].m_OccBox.m_vecMin.x > list[i].m_OccBox.m_vecMax.x )
|
||
{
|
||
float tmp_index = list[i].m_OccBox.m_vecMin.x;
|
||
list[i].m_OccBox.m_vecMin.x = list[i].m_OccBox.m_vecMax.x;
|
||
list[i].m_OccBox.m_vecMax.x = tmp_index;
|
||
}
|
||
|
||
|
||
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||
list[i].m_OccBox.m_vecMin.y = ( list[i].m_OccBox.m_vecMin.y > list[i].m_OccBox.m_vecMax.y ) ? list[i].m_OccBox.m_vecMin.y : list[i].m_OccBox.m_vecMax.y;
|
||
list[i].m_OccBox.m_vecMax.y = list[i].m_OccBox.m_vecMin.y;
|
||
|
||
list[i].m_OccBox.m_vecMin.y = list[i].m_OccBox.m_vecMax.y = ( list[i].m_OccBox.m_vecMin.y > m_VHeight ) ? m_VHeight :
|
||
( (list[i].m_OccBox.m_vecMin.y < 0) ? 0 : list[i].m_OccBox.m_vecMin.y);
|
||
|
||
list[i].m_OccBox.m_vecMin.x = (list[i].m_OccBox.m_vecMin.x < 0 ) ? 0 : ((list[i].m_OccBox.m_vecMin.x > m_VWidth) ? (float)m_VWidth : list[i].m_OccBox.m_vecMin.x);
|
||
list[i].m_OccBox.m_vecMax.x = (list[i].m_OccBox.m_vecMax.x < 0 ) ? 0 : ((list[i].m_OccBox.m_vecMax.x > m_VWidth) ? (float)m_VWidth : list[i].m_OccBox.m_vecMax.x);
|
||
|
||
int min_index = (int)list[i].m_OccBox.m_vecMin.x;
|
||
int max_index = (int)list[i].m_OccBox.m_vecMax.x;
|
||
|
||
|
||
int width = max_index - min_index;
|
||
|
||
for(int k=min_index;k<max_index;k++)
|
||
{
|
||
if(m_Volume[k].m_Height < list[i].m_OccBox.m_vecMin.y) // not visible
|
||
count++;
|
||
}
|
||
|
||
if(count >= width) // 2d box <20><><EFBFBD>ΰ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ٸ<EFBFBD>
|
||
(*list[i].m_bVis) = false;
|
||
else
|
||
(*list[i].m_bVis) = true;
|
||
}
|
||
}
|
||
}
|
||
// <20>̹<EFBFBD> ī<><EFBFBD><DEB6><EFBFBD> <20>Ÿ<EFBFBD><C5B8><EFBFBD> <20><><EFBFBD><EFBFBD> sort <20><> <20>ڹǷ<DAB9> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ȴ<EFBFBD>
|
||
void ROcclusion::HorizonCull(LPDIRECT3DDEVICE8 device,ROcclusionUnit *list,int listnum)
|
||
{
|
||
|
||
|
||
if( m_Volume == NULL ) // <20><><EFBFBD><EFBFBD>ó<EFBFBD><C3B3> Volume<6D><65> Create <20>Ҷ<EFBFBD>.
|
||
{
|
||
D3DVIEWPORT8 t_viewport;
|
||
device->GetViewport(&t_viewport);
|
||
|
||
m_VWidth = t_viewport.Width; // Screen <20><> <20><>ǥ<EFBFBD><C7A5> <20><><EFBFBD><EFBFBD><EFBFBD>´<EFBFBD>
|
||
m_VHeight = t_viewport.Height;
|
||
|
||
m_Volume = new ROcclusionVolume[m_VWidth];
|
||
}
|
||
else
|
||
{
|
||
InitVolume(); // Volume <20>ʱ<EFBFBD>ȭ
|
||
}
|
||
|
||
for(int i=0;i<listnum;i++)
|
||
{
|
||
// min, max <20><> <20>߿<EFBFBD> ȭ<><C8AD><EFBFBD><EFBFBD> <20>Ѿ <20><><EFBFBD><EFBFBD> <20>ִ<EFBFBD><D6B4><EFBFBD> set
|
||
if(list[i].m_OccBox.m_fZValue < 0) {
|
||
(*(list[i].m_bVis)) = false;
|
||
continue;
|
||
}
|
||
if( (*list[i].m_bVis) )
|
||
{
|
||
|
||
if( list[i].m_OccBox.m_vecMin.x > list[i].m_OccBox.m_vecMax.x )
|
||
{
|
||
float tmp_index = list[i].m_OccBox.m_vecMin.x;
|
||
list[i].m_OccBox.m_vecMin.x = list[i].m_OccBox.m_vecMax.x;
|
||
list[i].m_OccBox.m_vecMax.x = tmp_index;
|
||
}
|
||
|
||
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||
|
||
list[i].m_OccBox.m_vecMin.y = ( list[i].m_OccBox.m_vecMin.y > list[i].m_OccBox.m_vecMax.y ) ? list[i].m_OccBox.m_vecMin.y : list[i].m_OccBox.m_vecMax.y;
|
||
list[i].m_OccBox.m_vecMax.y = list[i].m_OccBox.m_vecMin.y;
|
||
|
||
|
||
if(list[i].m_OccBox.m_vecMin.y == 0 && list[i].m_OccBox.m_vecMax.y == 0)
|
||
continue;
|
||
|
||
list[i].m_OccBox.m_vecMin.y = list[i].m_OccBox.m_vecMax.y = ( list[i].m_OccBox.m_vecMin.y > m_VHeight ) ? m_VHeight : ( (list[i].m_OccBox.m_vecMin.y < 0) ? 0 : list[i].m_OccBox.m_vecMin.y );
|
||
list[i].m_OccBox.m_vecMin.x = (list[i].m_OccBox.m_vecMin.x < 0 ) ? 0 : ((list[i].m_OccBox.m_vecMin.x > m_VWidth) ? (float)m_VWidth : list[i].m_OccBox.m_vecMin.x);
|
||
list[i].m_OccBox.m_vecMax.x = (list[i].m_OccBox.m_vecMax.x < 0 ) ? 0 : ((list[i].m_OccBox.m_vecMax.x > m_VWidth) ? (float)m_VWidth : list[i].m_OccBox.m_vecMax.x);
|
||
|
||
|
||
int min_index = (int)list[i].m_OccBox.m_vecMin.x;
|
||
int max_index = (int)list[i].m_OccBox.m_vecMax.x + 1;
|
||
|
||
//////
|
||
int width = max_index - min_index;
|
||
|
||
for(int j=min_index;j<=max_index;j++)
|
||
{
|
||
if(m_Volume[j].m_Height >= list[i].m_OccBox.m_vecMin.y)
|
||
m_Volume[j].m_Height = list[i].m_OccBox.m_vecMin.y;
|
||
}
|
||
// culling <20><><EFBFBD><EFBFBD>
|
||
D3DXMATRIX view;
|
||
D3DXMATRIX inv;
|
||
|
||
device->GetTransform(D3DTS_VIEW,&view);
|
||
D3DXMatrixInverse(&inv,NULL,&view);
|
||
|
||
Hculling(list,listnum,i+1,inv._41,inv._42,inv._43);
|
||
|
||
}
|
||
}
|
||
|
||
}
|