Files
Client/GameTools/Zallad3D SceneClass/WBLightMap.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

510 lines
12 KiB
C++

// WBLightMap.cpp: implementation of the WBLightMap class.
//
//////////////////////////////////////////////////////////////////////
#include "WBLightMap.h"
#include "WBLightMapGenerator.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
float WBLightMapFace::area()
{
if(m_bSetArea == true)
return m_fArea;
int i;
D3DXVECTOR3 vec1,vec2,vec3;
float fArea = 0.0f;
// if(m_iVertsNum < 2)
// return -1.0f;
for( i = 2; i < m_iVerts; i++ )
{
float fLength = 0.0f;
vec1 = m_pVerts[i].m_vecPos - m_pVerts[0].m_vecPos;
vec2 = m_pVerts[i - 1].m_vecPos - m_pVerts[0].m_vecPos;
D3DXVec3Cross(&vec3,&vec1,&vec2);
fLength = (D3DXVec3Length(&vec3) * 0.5f);
fArea += fLength;
}
return fArea;
}
void WBLightMapFace::CalcNormal()
{
if(m_iVerts >= 3) {
D3DXVECTOR3 vec1,vec2,vec3;
vec1 = m_pVerts[1].m_vecPos - m_pVerts[0].m_vecPos;
vec2 = m_pVerts[2].m_vecPos - m_pVerts[0].m_vecPos;
D3DXVec3Cross(&vec3,&vec1,&vec2);
D3DXVec3Normalize(&vec3,&vec3);
m_vecNormal = vec3;
}
}
int WBLightMapFace::InsidePolygon(D3DXVECTOR3 vecPoint)
{
if((vecPoint.x >= m_vecMin.x) && (vecPoint.y >= m_vecMin.y )&& (vecPoint.z >= m_vecMin.z))
{
if((vecPoint.x <= m_vecMax.x) && (vecPoint.y <= m_vecMax.y )&& (vecPoint.z <= m_vecMax.z))
return 1;
}
return 0;
}
// Ãæµ¹½Ã 1 return
int WBLightMapFace::RayCollision(D3DXVECTOR3 vecStart,D3DXVECTOR3 vecDir,float fLength)
{
/*
static D3DXVECTOR3 v[3],n;
v[0].x = m_pVerts[0].m_vecPos.x + m_vecNormal.x * fLength;
v[0].y = m_pVerts[0].m_vecPos.y + m_vecNormal.y * fLength;
v[0].z = m_pVerts[0].m_vecPos.z + m_vecNormal.z * fLength;
v[1].x = m_pVerts[1].m_vecPos.x + m_vecNormal.x * fLength;
v[1].y = m_pVerts[1].m_vecPos.y + m_vecNormal.y * fLength;
v[1].z = m_pVerts[1].m_vecPos.z + m_vecNormal.z * fLength;
v[2].x = m_pVerts[2].m_vecPos.x + m_vecNormal.x * fLength;
v[2].y = m_pVerts[2].m_vecPos.y + m_vecNormal.y * fLength;
v[2].z = m_pVerts[2].m_vecPos.z + m_vecNormal.z * fLength;
D3DXVec3Cross(&n,&(v[1] - v[0]),&(v[2] - v[0]));
D3DXVec3Normalize(&n,&n);
float x = D3DXVec3Dot(&n,&vecDir);
if(x > -WBSMALL)
return 0;
float fDist = (D3DXVec3Dot(&n,&(v[0])) - D3DXVec3Dot(&n,&vecStart)) / x;
if(fDist < 0)
return 0;
D3DXVECTOR3 vec3Vec;
vec3Vec.x = vecStart.x + vecDir.x * fDist;
vec3Vec.y = vecStart.y + vecDir.y * fDist;
vec3Vec.z = vecStart.z + vecDir.z * fDist;
int i,j,crossings=0,u0,u1;
n.x=(float)fabs(n.x);
n.y=(float)fabs(n.y);
n.z=(float)fabs(n.z);
if (n.x>n.y && n.x>n.z)
{ u0=1; u1=2; }
else
if (n.y>n.x && n.y>n.z)
{ u0=0; u1=2; }
else
{ u0=0; u1=1; }
v[0][u0]-=vec3Vec[u0];
v[1][u0]-=vec3Vec[u0];
v[2][u0]-=vec3Vec[u0];
v[0][u1]-=vec3Vec[u1];
v[1][u1]-=vec3Vec[u1];
v[2][u1]-=vec3Vec[u1];
for( i=0; i<3; i++ )
{
j=(i+1) % 3;
if(((v[i][u1]<-WBSMALL) && (v[j][u1]>=0)) || ((v[j][u1]<-WBSMALL) && (v[i][u1]>=0.0)))
if((v[i][u0]>=0.0) && (v[j][u0]>=0.0))
++crossings;
else
if((v[i][u0]>=0.0) || (v[j][u0]>=0.0))
if((v[i][u0]-v[i][u1]*(v[j][u0]-v[i][u0])/(v[j][u1]-v[i][u1]))>WBSMALL)
++crossings;
}
if((crossings%2)==0)
return 0;
else
return 1;
*/
/////////////////////////
/*
float fDot = D3DXVec3Dot(&m_vecNormal,&vecDir);
if(fDot > -WBSMALL)
return 0;
float fDist = (D3DXVec3Dot(&m_vecNormal,&m_pVerts[0].m_vecPos) - D3DXVec3Dot(&m_vecNormal,&vecStart)) / fDot;
if(fDist <0)
return 0;
D3DXVECTOR3 vec3Vec;
vec3Vec.x = vecStart.x + vecDir.x * fDist;
vec3Vec.y = vecStart.y + vecDir.y * fDist;
vec3Vec.z = vecStart.z + vecDir.z * fDist;
for( int i=0;i<m_iVerts;i++ )
{
if (((vec3Vec.x-m_pVerts[i].m_vecPos.x)*(m_pEdge[i].x)+
(vec3Vec.y-m_pVerts[i].m_vecPos.y)*(m_pEdge[i].y)+
(vec3Vec.z-m_pVerts[i].m_vecPos.z)*(m_pEdge[i].z))>0)
return 0;
}
return 1;
*/
/*
float fDot = D3DXVec3Dot(&m_vecNormal,&vecDir);
if(WB_FPSIGNBIT(fDot) == 0)
return 0;
float fDist = (d0 - D3DXVec3Dot(&m_vecNormal,&vecStart)) / fDot;
if(WB_FPSIGNBIT(fDist) || fDist >= fLength)
return 0;
D3DXVECTOR3 vec3Vec = vecStart + vecDir * fDist;
for( int i=0;i<m_iVerts;i++ )
{
if (((vec3Vec.x-m_pVerts[i].m_vecPos.x)*(m_pEdge[i].x)+
(vec3Vec.y-m_pVerts[i].m_vecPos.y)*(m_pEdge[i].y)+
(vec3Vec.z-m_pVerts[i].m_vecPos.z)*(m_pEdge[i].z))>0)
return 0;
}
return 1;
*/
// °¡Àå ÃÖ½Å
D3DXVECTOR3 v;
float d,x;
int i=0,j=0;
for( i = 0; i < m_iVerts; i+=3,j+=4 )
{
x=D3DXVec3Dot(&(m_pEdge[j]),&vecDir);
if (WB_FPSIGNBIT(x)==0)
continue;
d=(m_pEdgeValue[j] - D3DXVec3Dot(&(m_pEdge[j]),&vecStart))/x;
if (WB_FPSIGNBIT(d) || d>= fLength)
continue;
v= vecStart + vecDir * d;
if ((v.x-m_pVerts[i].m_vecPos.x)*(m_pEdge[j+1].x)+
(v.y-m_pVerts[i].m_vecPos.y)*(m_pEdge[j+1].y)+
(v.z-m_pVerts[i].m_vecPos.z)*(m_pEdge[j+1].z)>0)
continue;
if ((v.x-m_pVerts[i+1].m_vecPos.x)*(m_pEdge[j+2].x)+
(v.y-m_pVerts[i+1].m_vecPos.y)*(m_pEdge[j+2].y)+
(v.z-m_pVerts[i+1].m_vecPos.z)*(m_pEdge[j+2].z)>0)
continue;
if ((v.x-m_pVerts[i+2].m_vecPos.x)*(m_pEdge[j+3].x)+
(v.y-m_pVerts[i+2].m_vecPos.y)*(m_pEdge[j+3].y)+
(v.z-m_pVerts[i+2].m_vecPos.z)*(m_pEdge[j+3].z)>0)
continue;
return 1;
}
return 0;
/* D3DXVECTOR3 v;
float d,x;
int i=0,j=0;
for( i = 0; i < m_iPlaneVertex; i+=3,j+=4 )
{
x=D3DXVec3Dot(&(m_pEdge[j]),&vecDir);
if (WB_FPSIGNBIT(x)==0)
continue;
d=(m_pEdgeValue[j] - D3DXVec3Dot(&(m_pEdge[j]),&vecStart))/x;
if (WB_FPSIGNBIT(d) || d>= fLength)
continue;
v= vecStart + vecDir * d;
if ((v.x-m_pPlaneVertex[i].x)*(m_pEdge[j+1].x)+
(v.y-m_pPlaneVertex[i].y)*(m_pEdge[j+1].y)+
(v.z-m_pPlaneVertex[i].z)*(m_pEdge[j+1].z)>0)
continue;
if ((v.x-m_pPlaneVertex[i+1].x)*(m_pEdge[j+2].x)+
(v.y-m_pPlaneVertex[i+1].y)*(m_pEdge[j+2].y)+
(v.z-m_pPlaneVertex[i+1].z)*(m_pEdge[j+2].z)>0)
continue;
if ((v.x-m_pPlaneVertex[i+2].x)*(m_pEdge[j+3].x)+
(v.y-m_pPlaneVertex[i+2].y)*(m_pEdge[j+3].y)+
(v.z-m_pPlaneVertex[i+2].z)*(m_pEdge[j+3].z)>0)
continue;
return 1;
}
return 0;
*/
/////////////////////////
}
int WBLightMapFace::RayCollision(D3DXVECTOR3 vecStart,D3DXVECTOR3 vecEnd)
{
//float fDist = -D3DXVec3Dot(&m_vecNormal,&(m_pVerts[0].m_vecPos));
float fValue1 = D3DXVec3Dot(&m_vecNormal,&vecStart) + m_fDist;
float fValue2 = D3DXVec3Dot(&m_vecNormal,&vecEnd) + m_fDist;
if((fValue1 * fValue2) <0.0f)
{
/// Ãæµ¹ point Get
/* D3DXVECTOR3 vecLine = vecEnd - vecStart;
D3DXVECTOR3 vecPoint;
D3DXVec3Normalize(&vecLine, &vecLine);
float Numbers = -(D3DXVec3Dot(&m_vecNormal,&vecStart) + fDist);
float Denum = D3DXVec3Dot(&m_vecNormal,&vecLine);
if(Denum == 0.0f)
vecPoint = vecStart;
else
{
float fDist2 = Numbers / Denum;
vecPoint.x = vecStart.x + vecLine.x * fDist2;
vecPoint.y = vecStart.y + vecLine.y * fDist2;
vecPoint.z = vecStart.z + vecLine.z * fDist2;
}
// Ãæµ¹ Æ÷ÀÎÆ®°¡ polygon ¾ÈÀÎÁö Å×½ºÆ®
if(InsidePolygon(vecPoint))*/
return 1;
}
return 0;
}
void WBLightMapFace::GetMinMax()
{
int i,j;
if(m_iVerts <= 0)
return;
else
{
// Get Min
D3DXVECTOR3 vecMin = m_pVerts[0].m_vecPos;
for( i = 1; i < m_iVerts; i++ )
{
if(vecMin.x > m_pVerts[i].m_vecPos.x)
vecMin.x = m_pVerts[i].m_vecPos.x;
if(vecMin.y > m_pVerts[i].m_vecPos.y)
vecMin.y = m_pVerts[i].m_vecPos.y;
if(vecMin.z > m_pVerts[i].m_vecPos.z)
vecMin.z = m_pVerts[i].m_vecPos.z;
}
m_vecMin = vecMin;
// Get Max
D3DXVECTOR3 vecMax = m_pVerts[0].m_vecPos;
for( i = 1; i < m_iVerts; i++ )
{
if(vecMax.x < m_pVerts[i].m_vecPos.x)
vecMax.x = m_pVerts[i].m_vecPos.x;
if(vecMax.y < m_pVerts[i].m_vecPos.y)
vecMax.y = m_pVerts[i].m_vecPos.y;
if(vecMax.z < m_pVerts[i].m_vecPos.z)
vecMax.z = m_pVerts[i].m_vecPos.z;
}
m_vecMax = vecMax;
m_fDist = -(D3DXVec3Dot(&(m_vecNormal),&(m_pVerts[0].m_vecPos)));
d0 = -(D3DXVec3Dot(&(m_vecNormal),&(m_pVerts[0].m_vecPos)));
// Edge °è»ê
m_pEdge = new D3DXVECTOR3[m_iVerts * 4];
m_pEdgeValue = new float[m_iVerts * 4];
for( i = 0, j = 0; i < m_iVerts; i+=3,j+=4 )
{
D3DXVECTOR3 vec1 = m_pVerts[i + 1].m_vecPos - m_pVerts[i].m_vecPos;
D3DXVECTOR3 vec2 = m_pVerts[i + 2].m_vecPos - m_pVerts[i].m_vecPos;
D3DXVec3Cross(&(m_pEdge[j]),&vec1,&vec2);
D3DXVec3Normalize(&(m_pEdge[j]),&(m_pEdge[j]));
m_pEdgeValue[j] = D3DXVec3Dot(&(m_pEdge[j]),&(m_pVerts[i].m_vecPos));
D3DXVec3Cross(&(m_pEdge[j + 1]),&(m_pVerts[i + 1].m_vecPos - m_pVerts[i].m_vecPos),&(m_pEdge[j]));
D3DXVec3Normalize(&(m_pEdge[j + 1]),&(m_pEdge[j + 1]));
D3DXVec3Cross(&(m_pEdge[j + 2]),&(m_pVerts[i + 2].m_vecPos - m_pVerts[i + 1].m_vecPos),&(m_pEdge[j]));
D3DXVec3Normalize(&(m_pEdge[j + 2]),&(m_pEdge[j + 2]));
D3DXVec3Cross(&(m_pEdge[j + 3]),&(m_pVerts[i].m_vecPos - m_pVerts[i + 2].m_vecPos),&(m_pEdge[j]));
D3DXVec3Normalize(&(m_pEdge[j + 3]),&(m_pEdge[j + 3]));
}
}
/* m_pEdge = new D3DXVECTOR3[m_iVerts];
m_pEdgeValue = new float[m_iVerts];
for( i = 0; i < m_iVerts; i++ )
{
D3DXVECTOR3 vec1 = m_pVerts[(i + 1) % m_iVerts].m_vecPos - m_pVerts[i].m_vecPos;
D3DXVec3Cross(&m_pEdge[i],&vec1,&m_vecNormal);
D3DXVec3Normalize(&m_pEdge[i],&m_pEdge[i]);
}
}
*/
}
WBLightMap::WBLightMap(int f,int p,int x,int y,int sx,int sy,int bp)
{
m_iFaceId = f;
pic=p;
offsetx=x;
offsety=y;
sizex=sx;
sizey=sy;
bytespixel=bp;
bytesx=sx*bp;
bytesxy=bytesx*sy;
bmp=new unsigned char[bytesxy];
}
WBLightMap::~WBLightMap()
{
delete[] bmp;
}
void WBLightMap::set_base(WBLightMapFace *f,WBLightMapTex *lmp,D3DXVECTOR3& pos)
{
v0 = f->m_pVerts[0].m_vecPos + pos;
v1 = f->m_pVerts[1].m_vecPos - f->m_pVerts[0].m_vecPos;
v2 = f->m_pVerts[2].m_vecPos - f->m_pVerts[0].m_vecPos;
uv[0][0]=(f->m_pVerts[0].m_vecTexcoord.x);
uv[0][1]=(f->m_pVerts[0].m_vecTexcoord.y);
uv[1][0]=(f->m_pVerts[1].m_vecTexcoord.x)-(f->m_pVerts[0].m_vecTexcoord.x);
uv[1][1]=(f->m_pVerts[1].m_vecTexcoord.y)-(f->m_pVerts[0].m_vecTexcoord.y);
uv[2][0]=(f->m_pVerts[2].m_vecTexcoord.x)-(f->m_pVerts[0].m_vecTexcoord.x);
uv[2][1]=(f->m_pVerts[2].m_vecTexcoord.y)-(f->m_pVerts[0].m_vecTexcoord.y);
det=(uv[1][0]*uv[2][1])-(uv[2][0]*uv[1][1]);
normal=f->m_vecNormal;
D3DXVECTOR3 p1,p2;
map_point((float)(offsetx)/lmp->sizex,(float)(offsety)/lmp->sizey,d0);
map_point((float)(offsetx+sizex)/lmp->sizex,(float)(offsety)/lmp->sizey,p1);
map_point((float)(offsetx)/lmp->sizex,(float)(offsety+sizey)/lmp->sizey,p2);
d1=p1-d0;
d2=p2-d0;
}
void WBLightMap::map_point(float u, float v, D3DXVECTOR3 &point)
{
u-=uv[0][0];
v-=uv[0][1];
if(fabs(det) <= 0.00001)
{
point = v0;
}
else {
point=
v0+
v1*((u*uv[2][1]-uv[2][0]*v)/det)+
v2*((uv[1][0]*v-u*uv[1][1])/det);
}
}
void WBLightMap::map_point_local(float u, float v, D3DXVECTOR3 &p,D3DXVECTOR3 &n)
{
static D3DXVECTOR3 pn[2];
if(m_iFaceId != -1)
{
p=d0+d1*u+d2*v;
n=normal;
}
}
void WBLightMap::illum(D3DXVECTOR3& pos,D3DXVECTOR3& color,float radius,int shadows)
{
int i,j,k;
unsigned char *uc;
float fi=1.0f/sizex,fj=1.0f/sizey,fu,fv;
float dist,dot,r=radius*radius;
D3DXVECTOR3 p,n,dir;
fv=fj*0.5f;
for( j=0;j<sizey;j++,fv+=fj )
{
fu=fi*0.5f;
uc=&bmp[j*bytesx];
for( i=0;i<sizex;i++,fu+=fi )
{
map_point_local(fu,fv,p,n);
dir=p-pos;
dist=(dir.x * dir.x) + (dir.y * dir.y) + (dir.z * dir.z);
if (dist>r)
uc+=3;
else
{
dist=(float)sqrt(dist);
dir*=1.0f/dist;
dot=D3DXVec3Dot(&dir,&normal);
if ((shadows&1) && dot>0)
{
uc+=3;
continue;
}
if (shadows&8 &&
WBLightMapGenerator::collision_test(pos,p-dir))
{
uc+=3;
continue;
}
dist=(1.0f-dist/radius);
if (shadows&2)
dist*=dist;
if (shadows&4)
dist*=-dot;
dist*=255.0;
k=(int)(color.x*dist)+(int)(*uc);
*(uc++)=k>255?255:k;
k=(int)(color.y*dist)+(int)(*uc);
*(uc++)=k>255?255:k;
k=(int)(color.z*dist)+(int)(*uc);
*(uc++)=k>255?255:k;
}
}
}
}
void WBLightMap::load(WBLightMapTex *lmp)
{
int i,j=sizex*bytespixel;
for( i=0;i<sizey;i++ )
memcpy(
&bmp[i*bytesx],
&lmp->bmp[(i+offsety)*lmp->bytesx+offsetx*lmp->bytespixel],
j);
}
void WBLightMap::save(WBLightMapTex *lmp)
{
int i,j=sizex*bytespixel;
for( i=0;i<sizey;i++ )
memcpy(
&lmp->bmp[(i+offsety)*lmp->bytesx+offsetx*lmp->bytespixel],
&bmp[i*bytesx],
j);
}