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

995 lines
24 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.
// WBLightMapGenerator.cpp: implementation of the WBLightMapGenerator class.
//
//////////////////////////////////////////////////////////////////////
#include "WBLightMapGenerator.h"
#include "WBLightMapBuild.h"
int WBLightMapGenerator::m_iFaces;
vector<WBLightMapFace *> WBLightMapGenerator::m_lstFaces;
int WBLightMapGenerator::m_iLightMapPixel = 32;
int WBLightMapGenerator::m_iLightMapSize = 256;
//int WBLightMapGenerator::m_iLightMapAmb = 16;
int WBLightMapGenerator::m_iLightMapAmb = 14;
int WBLightMapGenerator::m_iLightSamples = 10;
//int WBLightMapGenerator::m_iLightJigg = 60;
int WBLightMapGenerator::m_iLightJigg = 60;
//float WBLightMapGenerator::m_fExposure = 0.09f;
float WBLightMapGenerator::m_fExposure = 5.5f;
int WBLightMapGenerator::m_iShadowSamples = 10;
int WBLightMapGenerator::m_iShadowFull = 0;
float WBLightMapGenerator::m_fShadowDist = 1000.0f;
//float WBLightMapGenerator::m_fShadowFactor = 0.95f;
float WBLightMapGenerator::m_fShadowFactor = 0.85f;
float *WBLightMapGenerator::emm = NULL;
float *WBLightMapGenerator::rad = NULL;
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
int ordenar_por_area_desc(const void *elem1, const void *elem2)
{
struct reta *r1, *r2;
r1=*(struct reta **)elem1;
r2=*(struct reta **)elem2;
return r2->sizex*r2->sizey-r1->sizex*r1->sizey;
}
retb::retb()
{
nl=0;
l=(struct reta **)malloc(0);
}
retb::~retb()
{
free(l);
}
void retb::add(struct reta *r)
{
l=(struct reta **)realloc(l, (++nl)*sizeof(struct reta *));
l[nl-1]=r;
}
int retb::calc(int max_sx, int max_sy)
{
struct reta r;
r.sizex=max_sx;
r.sizey=max_sy;
r.offsetx=0;
r.offsety=0;
r.offsetz=0;
for(int i=0; i<nl; i++) l[i]->offsetz=-1;
qsort((void *)l, (size_t)nl, sizeof(struct reta *), ordenar_por_area_desc);
while(arrumar(&r)) r.offsetz++;
return r.offsetz;
}
bool retb::arrumar(struct reta *rp)
{
int i, dsx, dsy;
struct reta r[2];
if((i=procura(rp->sizex, rp->sizey))==nl) return false;
l[i]->offsetx=rp->offsetx;
l[i]->offsety=rp->offsety;
l[i]->offsetz=rp->offsetz;
dsx=rp->sizex-l[i]->sizex;
dsy=rp->sizey-l[i]->sizey;
if(dsx*rp->sizey>dsy*rp->sizex)
{
r[0].sizex=dsx;
r[0].sizey=rp->sizey;
r[0].offsetx=rp->offsetx+l[i]->sizex;
r[0].offsety=rp->offsety;
r[0].offsetz=rp->offsetz;
r[1].sizex=l[i]->sizex;
r[1].sizey=dsy;
r[1].offsetx=rp->offsetx;
r[1].offsety=rp->offsety+l[i]->sizey;
r[1].offsetz=rp->offsetz;
}
else
{
r[0].sizex=rp->sizex;
r[0].sizey=dsy;
r[0].offsetx=rp->offsetx;
r[0].offsety=rp->offsety+l[i]->sizey;
r[0].offsetz=rp->offsetz;
r[1].sizex=dsx;
r[1].sizey=l[i]->sizey;
r[1].offsetx=rp->offsetx+l[i]->sizex;
r[1].offsety=rp->offsety;
r[1].offsetz=rp->offsetz;
}
for(i=0; i<2; i++) arrumar(&r[i]);
return true;
}
int retb::procura(int sx, int sy)
{
int i;
for(i=0;i<nl;i++)
if(l[i]->offsetz==-1 &&
l[i]->sizex<=sx && l[i]->sizey<=sy)
break;
return i;
}
WBLightMapGenerator::WBLightMapGenerator()
{
CleanStatic();
m_iFaces = 0;
m_lstFaces.clear();
m_iLightMaps = 0;
m_lstLightMaps.clear();
m_iLightMapTexs = 0;
m_lstLightMapTexs.clear();
m_iLights = 0;
m_lstLights.clear();
m_iLightMapPixel = 32;
m_iLightMapSize = 256;
}
WBLightMapGenerator::~WBLightMapGenerator()
{
int i;
if(m_iFaces != 0)
{
for( i = m_lstFaces.size() - 1; i >= 0; i-- )
{
delete m_lstFaces[i];
m_lstFaces[i] = NULL;
m_lstFaces.erase(&(m_lstFaces[i]));
}
m_lstFaces.clear();
}
if(m_iLightMaps != 0)
{
for( i = m_lstLightMaps.size() - 1; i >= 0; i-- )
{
delete m_lstLightMaps[i];
m_lstLightMaps[i] = NULL;
m_lstLightMaps.erase(&(m_lstLightMaps[i]));
}
m_lstLightMaps.clear();
}
if(m_iLightMapTexs != 0)
{
for( i = m_lstLightMapTexs.size() - 1; i >= 0; i-- )
{
delete m_lstLightMapTexs[i];
m_lstLightMapTexs[i] = NULL;
m_lstLightMapTexs.erase(&(m_lstLightMapTexs[i]));
}
m_lstLightMapTexs.clear();
}
for( i = 0; i < m_iLights; i++ )
{
m_lstLights[i] = NULL;
}
m_iLights = 0;
m_lstLights.clear();
}
void WBLightMapGenerator::InputLight(WBLight *pLight)
{
m_lstLights.push_back(pLight);
m_iLights++;
}
void WBLightMapGenerator::InputFace(WBLightMapFace *pFace)
{
// pFace->CalcNormal();
m_lstFaces.push_back(pFace);
m_iFaces++;
}
bool WBLightMapGenerator::LightMapGenerate(int iValue)
{
int i,j,l,k;
vector<int> *lstFaces;
vector<WBLightMapPlane> lstPlanes;
vector<int> lstPlaneFaces;
float fComp = 3.0f;
if( iValue == 1)
fComp = 4.71f;
for( i = 0; i < m_iFaces; i++ )
{
bool bNew = true;
for(int j = 0; j < lstPlanes.size(); j++ )
{
if(fabs(lstPlanes[j].m_vecNormal.x - m_lstFaces[i]->m_vecNormal.x) < 0.04f)
{
if(fabs(lstPlanes[j].m_vecNormal.y - m_lstFaces[i]->m_vecNormal.y) < 0.04f)
{
if(fabs(lstPlanes[j].m_vecNormal.z - m_lstFaces[i]->m_vecNormal.z) < 0.04f)
{
float fDistance[3];
fDistance[0]= D3DXVec3Dot(&lstPlanes[j].m_vecNormal, &( (m_lstFaces[i]->m_pVerts[0].m_vecPos)-(lstPlanes[j].m_vecVertex)));
fDistance[1]= D3DXVec3Dot(&lstPlanes[j].m_vecNormal, &( (m_lstFaces[i]->m_pVerts[1].m_vecPos)-(lstPlanes[j].m_vecVertex)));
fDistance[2]= D3DXVec3Dot(&lstPlanes[j].m_vecNormal, &( (m_lstFaces[i]->m_pVerts[2].m_vecPos)-(lstPlanes[j].m_vecVertex)));
if( fDistance[0] >= -fComp && fDistance[0] <= fComp &&
fDistance[1] >= -fComp && fDistance[1] <= fComp &&
fDistance[2] >= -fComp && fDistance[2] <= fComp)
{
bNew = false;
break;
}
}
}
}
/* if((fabs(lstPlanes[j].m_fDist - m_lstFaces[i]->m_fDist) < 7.0) &&
(fabs(lstPlanes[j].m_vecNormal.x - m_lstFaces[i]->m_vecNormal.x +
lstPlanes[j].m_vecNormal.y - m_lstFaces[i]->m_vecNormal.y +
lstPlanes[j].m_vecNormal.z - m_lstFaces[i]->m_vecNormal.z) < 0.01))
{
// if(m_lstFaces[lstPlaneFaces[j]]->m_iObject == m_lstFaces[i]->m_iObject)
// {
/* for(l = 0; l < 3; l++)
{
int iIndex = m_lstFaces[i]->m_iIndex[l];
for( k = 0; k < 3; k++)
{
int iTargetIndex = m_lstFaces[lstPlaneFaces[j]]->m_iIndex[k];
if(iTargetIndex == iIndex)
{
bNew = false;
break;
/* }
}
}
}
/*
for(l = 0; l < 3; l++)
{
int iIndex = m_lstFaces[i]->m_iIndex[l];
for( k = 0; k < 3; k++)
{
int iTargetIndex = m_lstFaces[lstPlaneFaces[j]]->m_iIndex[k];
if(iTargetIndex == iIndex)
{
bNew = false;
break;
}
}
}
}*/
}
if(bNew == true)
{
WBLightMapPlane NewPlane;
NewPlane.m_fDist = m_lstFaces[i]->m_fDist;
NewPlane.m_vecNormal = m_lstFaces[i]->m_vecNormal;
NewPlane.m_vecVertex = m_lstFaces[i]->m_pVerts[0].m_vecPos;
lstPlanes.push_back(NewPlane);
lstPlaneFaces.push_back(i);
}
}
lstFaces = new vector<int>[lstPlanes.size()];
for( i = 0; i < lstPlanes.size(); i++ )
{
lstFaces[i].clear();
}
for( i = 0; i < m_iFaces; i++ )
{
for( j = 0; j < lstPlanes.size(); j++ )
{
if(fabs(lstPlanes[j].m_vecNormal.x - m_lstFaces[i]->m_vecNormal.x) < 0.04f)
{
if(fabs(lstPlanes[j].m_vecNormal.y - m_lstFaces[i]->m_vecNormal.y) < 0.04f)
{
if(fabs(lstPlanes[j].m_vecNormal.z - m_lstFaces[i]->m_vecNormal.z) < 0.04f)
{
float fDistance[3];
fDistance[0]= D3DXVec3Dot(&lstPlanes[j].m_vecNormal, &( (m_lstFaces[i]->m_pVerts[0].m_vecPos)-(lstPlanes[j].m_vecVertex)));
fDistance[1]= D3DXVec3Dot(&lstPlanes[j].m_vecNormal, &( (m_lstFaces[i]->m_pVerts[1].m_vecPos)-(lstPlanes[j].m_vecVertex)));
fDistance[2]= D3DXVec3Dot(&lstPlanes[j].m_vecNormal, &( (m_lstFaces[i]->m_pVerts[2].m_vecPos)-(lstPlanes[j].m_vecVertex)));
if( fDistance[0] >= -fComp && fDistance[0] <= fComp &&
fDistance[1] >= -fComp && fDistance[1] <= fComp &&
fDistance[2] >= -fComp && fDistance[2] <= fComp)
{
lstFaces[j].push_back(i);
break;
}
}
}
}
/* if((fabs(lstPlanes[j].m_fDist - m_lstFaces[i]->m_fDist) < 7.0) &&
(fabs(lstPlanes[j].m_vecNormal.x - m_lstFaces[i]->m_vecNormal.x +
lstPlanes[j].m_vecNormal.y - m_lstFaces[i]->m_vecNormal.y +
lstPlanes[j].m_vecNormal.z - m_lstFaces[i]->m_vecNormal.z) < 0.01))
{
if(m_lstFaces[lstPlaneFaces[j]]->m_iObject == m_lstFaces[i]->m_iObject)
{
/* for(l = 0; l < 3; l++)
{
int iIndex = m_lstFaces[i]->m_iIndex[l];
for( k = 0; k < 3; k++)
{
int iTargetIndex = m_lstFaces[lstPlaneFaces[j]]->m_iIndex[k];
if(iTargetIndex == iIndex)
{
lstFaces[j].push_back(i);
break;
/* }
}
}*/
// lstFaces[j].push_back(i);
// break;
/* }
}*/
}
}
// Calc Plane Min Max Point,Area Value
for( i = 0; i < lstPlanes.size(); i++ )
{
WBLightVertex **pPos;
pPos = new WBLightVertex*[lstFaces[i].size() * 3];
int iCount = 0;
for(j = 0; j < lstFaces[i].size(); j++ )
{
pPos[iCount++] = &(m_lstFaces[lstFaces[i][j]]->m_pVerts[0]);
pPos[iCount++] = &(m_lstFaces[lstFaces[i][j]]->m_pVerts[1]);
pPos[iCount++] = &(m_lstFaces[lstFaces[i][j]]->m_pVerts[2]);
}
// Get Min Max Point
D3DXVECTOR3 vecMin = pPos[0]->m_vecPos;
D3DXVECTOR3 vecMax = pPos[0]->m_vecPos;
for( j = 1; j < iCount; j++ )
{
if(vecMin.x > pPos[j]->m_vecPos.x)
vecMin.x = pPos[j]->m_vecPos.x;
if(vecMin.y > pPos[j]->m_vecPos.y)
vecMin.y = pPos[j]->m_vecPos.y;
if(vecMin.z > pPos[j]->m_vecPos.z)
vecMin.z = pPos[j]->m_vecPos.z;
}
for( j = 1; j < iCount; j++ )
{
if(vecMax.x < pPos[j]->m_vecPos.x)
vecMax.x = pPos[j]->m_vecPos.x;
if(vecMax.y < pPos[j]->m_vecPos.y)
vecMax.y = pPos[j]->m_vecPos.y;
if(vecMax.z < pPos[j]->m_vecPos.z)
vecMax.z = pPos[j]->m_vecPos.z;
}
// Area
D3DXVECTOR3 vec1,vec2,vec3;
float fArea = 0.0f;
for( j = 0; j < iCount; j+=3 )
{
vec1 = pPos[j+1]->m_vecPos - pPos[j]->m_vecPos;
vec2 = pPos[j+2]->m_vecPos - pPos[j]->m_vecPos;
D3DXVec3Cross(&vec3,&vec1,&vec2);
fArea += (D3DXVec3Length(&vec3) * 0.5f);
}
/*
for( j = 2; j < iCount; j+=3 )
{
float fLength = 0.0f;
vec1 = pPos[j]->m_vecPos - pPos[j-2]->m_vecPos;
vec2 = pPos[j - 1]->m_vecPos - pPos[j-2]->m_vecPos;
D3DXVec3Cross(&vec3,&vec1,&vec2);
fLength = (D3DXVec3Length(&vec3) * 0.5f);
fArea += fLength;
}
*/
//Edge
/* D3DXVECTOR3 *PlaneEdge = new D3DXVECTOR3[ iCount* 4];
float *PlaneEdgeValue = new float[ iCount * 4];
for( j = 0, k = 0; j < iCount; j+=3,k+=4 )
{
D3DXVECTOR3 vec1 = pPos[j + 1]->m_vecPos - pPos[j]->m_vecPos;
D3DXVECTOR3 vec2 = pPos[j + 2]->m_vecPos - pPos[j]->m_vecPos;
D3DXVec3Cross(&(PlaneEdge[k]),&vec1,&vec2);
D3DXVec3Normalize(&(PlaneEdge[k]),&(PlaneEdge[k]));
PlaneEdgeValue[k] = D3DXVec3Dot(&(PlaneEdge[k]),&(pPos[j]->m_vecPos));
D3DXVec3Cross(&(PlaneEdge[k + 1]),&(pPos[j + 1]->m_vecPos - pPos[j]->m_vecPos),&(PlaneEdge[k]));
D3DXVec3Normalize(&(PlaneEdge[k + 1]),&(PlaneEdge[k + 1]));
D3DXVec3Cross(&(PlaneEdge[k + 2]),&(pPos[j + 2]->m_vecPos - pPos[j + 1]->m_vecPos),&(PlaneEdge[k]));
D3DXVec3Normalize(&(PlaneEdge[k + 2]),&(PlaneEdge[k + 2]));
D3DXVec3Cross(&(PlaneEdge[k + 3]),&(pPos[j]->m_vecPos - pPos[j + 2]->m_vecPos),&(PlaneEdge[k]));
D3DXVec3Normalize(&(PlaneEdge[k + 3]),&(PlaneEdge[k + 3]));
}
*/
for(j = 0; j < lstFaces[i].size(); j++ )
{
m_lstFaces[lstFaces[i][j]]->m_vecMin = vecMin;
m_lstFaces[lstFaces[i][j]]->m_vecMax = vecMax;
m_lstFaces[lstFaces[i][j]]->m_bSetArea = true;
m_lstFaces[lstFaces[i][j]]->m_fArea = fArea;
m_lstFaces[lstFaces[i][j]]->m_iLightMapId = m_iLightMaps;
m_lstFaces[lstFaces[i][j]]->m_iPlaneVertex = iCount;
/* m_lstFaces[lstFaces[i][j]]->m_pEdge = new D3DXVECTOR3[ iCount * 4];
memcpy(m_lstFaces[lstFaces[i][j]]->m_pEdge,PlaneEdge,sizeof(D3DXVECTOR3) * iCount * 4);
m_lstFaces[lstFaces[i][j]]->m_pEdgeValue = new float[iCount * 4];
memcpy(m_lstFaces[lstFaces[i][j]]->m_pEdgeValue,PlaneEdgeValue,sizeof(float) * iCount * 4);
m_lstFaces[lstFaces[i][j]]->m_pPlaneVertex = new D3DXVECTOR3[iCount];
for(k = 0; k < iCount; k++ )
{
m_lstFaces[lstFaces[i][j]]->m_pPlaneVertex[k] = pPos[k]->m_vecPos;
}
*/
}
/* delete[] PlaneEdge;
delete[] PlaneEdgeValue;
*/
WBLightMap *pLightMap = BuildLightMap(m_lstFaces[lstFaces[i][0]],pPos,(lstFaces[i].size() * 3));
pLightMap->m_iFaceId = lstFaces[i][0];
m_lstLightMaps.push_back(pLightMap);
m_iLightMaps++;
delete[] pPos;
}
for(i = 0; i < lstPlanes.size(); i++ )
lstFaces[i].clear();
delete[] lstFaces;
lstPlaneFaces.clear();
/*
for( i = 0; i < m_iFaces; i++ ) {
m_lstFaces[i]->m_iLightMapId = m_iLightMaps;
WBLightMap *pLightMap = BuildLightMap(m_lstFaces[i]);
pLightMap->m_iFaceId = i;
m_lstLightMaps.push_back(pLightMap);
m_iLightMaps++;
}
*/
retb r;
struct reta *rl=new struct reta[m_iLightMaps];
for( i=0;i<m_iLightMaps;i++ )
{
rl[i].sizex= m_lstLightMaps[i]->sizex;
rl[i].sizey= m_lstLightMaps[i]->sizey;
r.add(&rl[i]);
}
m_iLightMapTexs = r.calc(m_iLightMapSize, m_iLightMapSize);
for( i=0;i<m_iLightMaps;i++ )
{
m_lstLightMaps[i]->offsetx=rl[i].offsetx;
m_lstLightMaps[i]->offsety=rl[i].offsety;
m_lstLightMaps[i]->pic=rl[i].offsetz;
}
delete[] rl;
for( i=0;i<m_iLightMapTexs;i++ )
{
WBLightMapTex *pTex = new WBLightMapTex(m_iLightMapSize,m_iLightMapSize);
m_lstLightMapTexs.push_back(pTex);
}
for( i=0;i<m_iFaces;i++ )
{
if ((m_lstFaces[i]->m_iLightMapId) !=-1)
{
l=m_lstFaces[i]->m_iLightMapId;
for( j=0;j<m_lstFaces[i]->m_iVerts;j++ )
{
m_lstFaces[i]->m_pVerts[j].m_vecTexcoord.x =
(m_lstFaces[i]->m_pVerts[j].m_vecTexcoord.x * m_lstLightMaps[l]->sizex+
m_lstLightMaps[l]->offsetx) / m_iLightMapSize;
m_lstFaces[i]->m_pVerts[j].m_vecTexcoord.y =
(m_lstFaces[i]->m_pVerts[j].m_vecTexcoord.y * m_lstLightMaps[l]->sizey+
m_lstLightMaps[l]->offsety) / m_iLightMapSize;
}
}
}
for( i=0;i<m_iLightMapTexs;i++ )
memset(m_lstLightMapTexs[i]->bmp,0,m_lstLightMapTexs[i]->bytesxy);
j=0;
for( i=0;i<m_iLightMaps;i++ )
{
m_lstLightMaps[i]->set_base(m_lstFaces[m_lstLightMaps[i]->m_iFaceId],m_lstLightMapTexs[m_lstLightMaps[i]->pic]);
memset(m_lstLightMaps[i]->bmp,m_iLightMapAmb,m_lstLightMaps[i]->bytesxy);
m_lstLightMaps[i]->save(m_lstLightMapTexs[m_lstLightMaps[i]->pic]);
j+=(m_lstLightMaps[i]->sizex)*(m_lstLightMaps[i]->sizey);
}
HANDLE hStdOut=GetStdHandle(STD_OUTPUT_HANDLE);
COORD cd;
DWORD dwWordLens;
char strObjectInfo[256];
sprintf(strObjectInfo,"Calc Lighting");
cd.X=0;
cd.Y=3;
WriteConsoleOutputCharacter(hStdOut,strObjectInfo,strlen(strObjectInfo),cd,&dwWordLens);
ComputeLighting();
return true;
}
int WBLightMapGenerator::collision_test(D3DXVECTOR3 Pos1,D3DXVECTOR3 Pos2,int iFaceIndex,int k)
{
int i;
D3DXVECTOR3 vecLine = Pos2 - Pos1;
float fLength = D3DXVec3Length(&vecLine);
if(fLength < 0.1f)
return 0;
D3DXVec3Normalize(&vecLine,&vecLine);
for( i = 0; i < m_iFaces; i++ )
{
/* if(i == iFaceIndex)
continue;
*/
if(k == 0) {
if(m_lstFaces[i]->RayCollision(Pos1,Pos2))
return 1;
}
else {
if(m_lstFaces[i]->RayCollision(Pos1,vecLine,fLength))
return 1;
}
}
return 0;
}
void WBLightMapGenerator::ComputeLighting() {
HANDLE hStdOut=GetStdHandle(STD_OUTPUT_HANDLE);
COORD cd;
DWORD dwWordLens;
char strObjectInfo[256];
int i,j,k;
/* unsigned char *uc;
// face Color <20><><EFBFBD><EFBFBD> <20><>Ʈ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> setting
for( i=0;i<m_iFaces;i++ ) {
for( j=0;j < m_lstFaces[i]->m_iVerts;j++ )
{
uc=(unsigned char *)&m_lstFaces[i]->m_ucColor;
uc[0]= (unsigned char)WBLightMapGenerator::m_iLightMapAmb;
uc[1]= (unsigned char)WBLightMapGenerator::m_iLightMapAmb;
uc[2]= (unsigned char)WBLightMapGenerator::m_iLightMapAmb;
}
}*/
for( i=0;i<m_iLightMaps;i++ )
{
((WBLightMapBuild *)m_lstLightMaps[i])->set_base(0);
}
for( i=0;i<m_iLights;i++ )
{
if (WBLightMapGenerator::m_iLightSamples)
{
m_lstLights[i]->m_vecColor *= (1.0f/ WBLightMapGenerator::m_iLightSamples);
for( j = 0; j < WBLightMapGenerator::m_iLightSamples; j++)
{
sprintf(strObjectInfo,"Calc %d / %d Light, Sample : %d / %d",i + 1, m_iLights,j+1,WBLightMapGenerator::m_iLightSamples);
cd.X=0;
cd.Y=4;
WriteConsoleOutputCharacter(hStdOut,strObjectInfo,strlen(strObjectInfo),cd,&dwWordLens);
D3DXVECTOR3 vecRand;
vecRand = D3DXVECTOR3((WBLightMapGenerator::m_iLightJigg) * RLIGHT_FRAND,(WBLightMapGenerator::m_iLightJigg) * RLIGHT_FRAND,(WBLightMapGenerator::m_iLightJigg) * RLIGHT_FRAND);
// <20><> <20><><EFBFBD><EFBFBD>Ʈ<EFBFBD><C6AE> <20><><EFBFBD><EFBFBD> <20>޴<EFBFBD> leaf node face<63><65><EFBFBD><EFBFBD> <20><><EFBFBD>Ѵ<EFBFBD><D1B4><EFBFBD>
// illum <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>·<EFBFBD> Lightmap <20><> <20><><EFBFBD><EFBFBD> <20>Ѵ<EFBFBD>.
for( k = 0; k < m_iFaces; k++)
{
int iLightId = m_lstFaces[k]->m_iLightMapId;
m_lstLightMaps[iLightId]->illum(m_lstLights[i]->m_vecPos + vecRand,m_lstLights[i]->m_vecColor,m_lstLights[i]->m_fRange,4);
}
}
}
else
{
for( k = 0; k < m_iFaces; k++ )
{
int iLightId = m_lstFaces[k]->m_iLightMapId;
m_lstLightMaps[iLightId]->illum(m_lstLights[i]->m_vecPos,m_lstLights[i]->m_vecColor,m_lstLights[i]->m_fRange,4);
}
}
}
if(WBLightMapGenerator::m_iShadowSamples)
{
for( i=0;i< m_iLightMaps;i++ )
{
sprintf(strObjectInfo,"Calc %d / %d Global Shadow",i+1,m_iLightMaps);
cd.X=0;
cd.Y=5;
WriteConsoleOutputCharacter(hStdOut,strObjectInfo,strlen(strObjectInfo),cd,&dwWordLens);
((WBLightMapBuild *)m_lstLightMaps[i])->compute_bgshadow();
((WBLightMapBuild *)m_lstLightMaps[i])->Blurring();
}
}
for( i = 0; i < m_iLightMaps; i++ )
{
((WBLightMapBuild *)m_lstLightMaps[i])->save_to_lightmap(m_fExposure);
}
for( i = 0; i < m_iLightMaps; i++ )
{
int iPicId = m_lstLightMaps[i]->pic;
m_lstLightMaps[i]->save(m_lstLightMapTexs[iPicId]);
}
}
float WBLightMapGenerator::compute_bgshadow(D3DXVECTOR3& ip,D3DXVECTOR3& n)
{
D3DXVECTOR3 dir,p;
float dot;
int i,j;
j=0;
for( i=0;i<m_iShadowSamples;i++ )
{
do
{
dir.x=RLIGHT_FRAND;
dir.y=RLIGHT_FRAND;
} while (dir.x*dir.x+dir.y*dir.y>1.0f);
dir.z=(float)cos(dir.x*RPI2)*(float)cos(dir.y*RPI2);
D3DXVec3Normalize(&dir,&dir);
dot=D3DXVec3Dot(&dir,&n);
if (dot<0)
{
dot=-dot;
dir *= -1.0f;
}
dir+=n*0.2f;
D3DXVec3Normalize(&dir,&dir);
if (m_iShadowFull==0 && dir.z<0)
continue;
// <20><20><><EFBFBD><EFBFBD>
if (collision_test(ip+n-dir,ip+dir*m_fShadowDist,-1,1)==0 &&
collision_test(ip+dir*m_fShadowDist,ip+n+dir,-1,1)==0)
j++;
}
return (1.0f-m_fShadowFactor) + m_fShadowFactor*((float)j/m_iShadowSamples);
}
WBLightMap *WBLightMapGenerator::BuildLightMap(WBLightMapFace *pFace,WBLightVertex **ppVerts,int iVerts)
{
static float quad_uv[8]={ 0,0, 0,1, 1,1, 1,0 };
D3DXVECTOR3 v,v1,v2;
WBLightMap *lightmap;
int sizex, sizey, i=0;
float f;
if (iVerts==4)
{
v1= (ppVerts[1]->m_vecPos) - (ppVerts[0]->m_vecPos);
v2= (ppVerts[3]->m_vecPos) - (ppVerts[0]->m_vecPos);
if (fabs(D3DXVec3Dot(&v1,&v2))<0.01f)
{
v= (ppVerts[0]->m_vecPos) + v1 + v2 - (ppVerts[2]->m_vecPos);
if (D3DXVec3Length(&v) < 0.1f)
i=1; // rect!
}
}
if (i)
{
f=D3DXVec3Length(&v2)/m_iLightMapPixel;
sizex=(int)f;
if (f-sizex>0.5f) sizex++;
f=D3DXVec3Length(&v1)/m_iLightMapPixel;
sizey=(int)f;
if (f-sizey>0.5f) sizey++;
if (sizex<3) sizex=3;
if (sizey<3) sizey=3;
if (sizex>m_iLightMapSize) sizex=m_iLightMapSize;
if (sizey>m_iLightMapSize) sizey=m_iLightMapSize;
lightmap=new WBLightMapBuild(-1, -1, 0, 0, sizex, sizey);
float f1x=(float)(sizex-1)/sizex;
float f2x=0.5f/sizex;
float f1y=(float)(sizey-1)/sizey;
float f2y=0.5f/sizey;
for( i=0;i<iVerts;i++ )
{
ppVerts[i]->m_vecTexcoord.x=quad_uv[2*i]*f1x+f2x;
ppVerts[i]->m_vecTexcoord.y=quad_uv[2*i+1]*f1y+f2y;
}
}
else
{
D3DXVECTOR3 diag;
int ui,vi;
i=(fabs(pFace->m_vecNormal.x)>fabs(pFace->m_vecNormal.y))?0:1;
if( i == 0)
i=(fabs(pFace->m_vecNormal.x)>fabs(pFace->m_vecNormal.z))?i:2;
else
i=(fabs(pFace->m_vecNormal.y)>fabs(pFace->m_vecNormal.z))?i:2;
if (i==0)
{ ui=1; vi=2; }
else if (i==1)
{ ui=0; vi=2; }
else { ui=0; vi=1; }
diag= (pFace->m_vecMax) - (pFace->m_vecMin);
f=diag[ui]/m_iLightMapPixel;
sizex=(int)f;
if (f-sizex>0.5f) sizex++;
f=diag[vi]/m_iLightMapPixel;
sizey=(int)f;
if (f-sizey>0.5f) sizey++;
if (sizex<3) sizex=3;
if (sizey<3) sizey=3;
if (sizex>m_iLightMapSize) sizex=m_iLightMapSize;
if (sizey>m_iLightMapSize) sizey=m_iLightMapSize;
lightmap=new WBLightMapBuild(-1, -1, 0, 0, sizex, sizey);
float f1x=(float)(sizex-1)/sizex;
float f2x=0.5f/sizex;
float f1y=(float)(sizey-1)/sizey;
float f2y=0.5f/sizey;
for( i=0;i<iVerts;i++ )
{
v=ppVerts[i]->m_vecPos - pFace->m_vecMin;
if(fabs(diag[ui]) <= 0.000001)
{
f = 0.0;
}
else
{
f=v[ui]/diag[ui];
}
ppVerts[i]->m_vecTexcoord.x=f*f1x+f2x;
if(fabs(diag[vi]) <= 0.000001)
{
f = 0.0f;
}
else
{
f=v[vi]/diag[vi];
}
ppVerts[i]->m_vecTexcoord.y=f*f1y+f2y;
}
}
return lightmap;
}
WBLightMap *WBLightMapGenerator::BuildLightMap(WBLightMapFace *pFace)
{
static float quad_uv[8]={ 0,0, 0,1, 1,1, 1,0 };
D3DXVECTOR3 v,v1,v2;
WBLightMap *lightmap;
int sizex, sizey, i=0;
float f;
if (pFace->m_iVerts==4)
{
v1= (pFace->m_pVerts[1].m_vecPos) - (pFace->m_pVerts[0].m_vecPos);
v2= (pFace->m_pVerts[3].m_vecPos) - (pFace->m_pVerts[0].m_vecPos);
if (fabs(D3DXVec3Dot(&v1,&v2))<0.01f)
{
v= (pFace->m_pVerts[0].m_vecPos) + v1 + v2 - (pFace->m_pVerts[2].m_vecPos);
if (D3DXVec3Length(&v) < 0.1f)
i=1; // rect!
}
}
if (i)
{
f=D3DXVec3Length(&v2)/m_iLightMapPixel;
sizex=(int)f;
if (f-sizex>0.5f) sizex++;
f=D3DXVec3Length(&v1)/m_iLightMapPixel;
sizey=(int)f;
if (f-sizey>0.5f) sizey++;
if (sizex<3) sizex=3;
if (sizey<3) sizey=3;
if (sizex>m_iLightMapSize) sizex=m_iLightMapSize;
if (sizey>m_iLightMapSize) sizey=m_iLightMapSize;
lightmap=new WBLightMapBuild(-1, -1, 0, 0, sizex, sizey);
float f1x=(float)(sizex-1)/sizex;
float f2x=0.5f/sizex;
float f1y=(float)(sizey-1)/sizey;
float f2y=0.5f/sizey;
for( i=0;i<pFace->m_iVerts;i++ )
{
pFace->m_pVerts[i].m_vecTexcoord.x=quad_uv[2*i]*f1x+f2x;
pFace->m_pVerts[i].m_vecTexcoord.y=quad_uv[2*i+1]*f1y+f2y;
}
}
else
{
D3DXVECTOR3 diag;
int ui,vi;
i=(fabs(pFace->m_vecNormal.x)>fabs(pFace->m_vecNormal.y))?0:1;
if( i == 0)
i=(fabs(pFace->m_vecNormal.x)>fabs(pFace->m_vecNormal.z))?i:2;
else
i=(fabs(pFace->m_vecNormal.y)>fabs(pFace->m_vecNormal.z))?i:2;
if (i==0)
{ ui=1; vi=2; }
else if (i==1)
{ ui=0; vi=2; }
else { ui=0; vi=1; }
diag= (pFace->m_vecMax) - (pFace->m_vecMin);
f=diag[ui]/m_iLightMapPixel;
sizex=(int)f;
if (f-sizex>0.5f) sizex++;
f=diag[vi]/m_iLightMapPixel;
sizey=(int)f;
if (f-sizey>0.5f) sizey++;
if (sizex<3) sizex=3;
if (sizey<3) sizey=3;
if (sizex>m_iLightMapSize) sizex=m_iLightMapSize;
if (sizey>m_iLightMapSize) sizey=m_iLightMapSize;
lightmap=new WBLightMapBuild(-1, -1, 0, 0, sizex, sizey);
float f1x=(float)(sizex-1)/sizex;
float f2x=0.5f/sizex;
float f1y=(float)(sizey-1)/sizey;
float f2y=0.5f/sizey;
for( i=0;i<pFace->m_iVerts;i++ )
{
v=pFace->m_pVerts[i].m_vecPos - pFace->m_vecMin;
if(fabs(diag[ui]) <= 0.000001)
{
f = 0.0;
}
else
{
f=v[ui]/diag[ui];
}
pFace->m_pVerts[i].m_vecTexcoord.x=f*f1x+f2x;
if(fabs(diag[vi]) <= 0.000001)
{
f = 0.0f;
}
else
{
f=v[vi]/diag[vi];
}
pFace->m_pVerts[i].m_vecTexcoord.y=f*f1y+f2y;
}
}
return lightmap;
}
void WBLightMapGenerator::CleanStatic()
{
int i;
for( i = 0 ; i < m_iFaces; i++ )
{
delete m_lstFaces[i];
m_lstFaces[i] = NULL;
}
m_lstFaces.clear();
m_iFaces = 0;
delete[] emm;
emm = NULL;
delete[] rad;
rad = NULL;
}