Files
Client/GameTools/Zallad3D SceneClass/ROcclusion.cpp
LGram16 dd97ddec92 Restructure repository to include all source folders
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>
2025-11-29 20:17:20 +09:00

405 lines
10 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#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);
}
}
}