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

4224 lines
116 KiB
C++

// BspScene.cpp: implementation of the CBspScene class.
//
//////////////////////////////////////////////////////////////////////
#include "BspScene.h"
#include <stdio.h>
#include "SceneManager.h"
#include "RenderOption.h"
#include "SceneStateMgr.h"
//#define MAX_EXPANDED_AXIS 50
int originalWidths[MAX_EXPANDED_AXIS];
int originalHeights[MAX_EXPANDED_AXIS];
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CBspScene::CBspScene()
{
m_SurfaceInc=NULL;
m_EyeCluster=-1;
m_Shaders=NULL;
m_nShader=0;
m_DrawVerts=NULL;
m_nDrawVerts=0;
m_Planes=NULL;
m_nPlanes=0;
m_Leafs=NULL;
m_nLeafs=0;
m_Nodes=NULL;
m_nNodes=0;
m_DrawSurfaces=NULL;
m_nDrawSurfaces=0;
m_LeafSurfaces=NULL;
m_nLeafSurfaces=0;
m_DrawIndex=NULL;
m_nDrawIndex=0;
m_Visibility=NULL;
m_nVisibility=0;
m_SelectLight=-1;
}
CBspScene::~CBspScene()
{
/*
for(int i=0;i<m_nShader;i++)
{
delete m_TextureList[i];
}
for(i=0;i<m_LightmapList.num;i++)
{
delete m_LightmapList[i];
}
*/
delete [] m_SurfaceInc;
for(int i=0;i<m_CurveBufferList.num;i++)
{
delete [] m_CurveBufferList[i]->m_pVertex;
delete [] m_CurveBufferList[i]->m_pIndices;
delete [] m_CurveBufferList[i]->m_pControlPoint;
}
/*
for(i=0;i<m_nShader;i++)
{
for(int c=0;c<m_nLightmap;c++)
{
delete [] m_RenderSurfacesList.pDrawSurfaces[i][c];
}
delete [] m_RenderSurfacesList.pDrawSurfaces[i];
delete [] m_RenderSurfacesList.nSurfaces[i];
}
if(m_pVertexBuffer)
m_pVertexBuffer->Release();
if(m_pIndicesBuffer)
m_pIndicesBuffer->Release();
*/
}
void CBspScene::Load(char *strFilename)
{
DHeader *pHeader;
FILE *fp;
int nLength;
void *pBuffer;
fp=fopen(strFilename,"rb");
fseek(fp,0,SEEK_END);
nLength=ftell(fp);
fseek(fp,0,SEEK_SET);
pBuffer=new char[nLength+1];
((char *)pBuffer)[nLength]=0;
fread(pBuffer,nLength,1,fp);
fclose(fp);
pHeader=(DHeader*)pBuffer;
m_nShader=CopyLump(pHeader,LUMP_SHADERS,(void**)&m_Shaders,sizeof(*(m_Shaders)));
m_nPlanes=CopyLump(pHeader,LUMP_PLANES,(void**)&m_Planes,sizeof(*(m_Planes)));
m_nNodes=CopyLump(pHeader,LUMP_NODES,(void**)&m_Nodes,sizeof(*(m_Nodes)));
m_nLeafs=CopyLump(pHeader,LUMP_LEAFS,(void**)&m_Leafs,sizeof(*(m_Leafs)));
m_nLeafSurfaces=CopyLump(pHeader,LUMP_LEAFSURFACES,(void**)&m_LeafSurfaces,sizeof(m_LeafSurfaces[0]));//LFaces
m_nDrawVerts=CopyLump(pHeader,LUMP_DRAWVERTS,(void**)&m_DrawVerts,sizeof(BspVertex));
m_nDrawSurfaces=CopyLump(pHeader,LUMP_SURFACES,(void**)&m_DrawSurfaces,sizeof(DSurface));
m_nDrawIndex=CopyLump(pHeader,LUMP_DRAWINDEXES,(void**)&m_DrawIndex,sizeof(m_DrawIndex[0]));
m_nVisibility=CopyLump(pHeader,LUMP_VISIBILITY,(void**)&m_Visibility,1);
m_nLight=CopyLump(pHeader,LUMP_LIGHT,(void**)&m_Light,sizeof(DLight));
float fTemp;
for(int cLight=0;cLight<m_nLight;cLight++)
{
fTemp=m_Light[cLight].m_vecLightPos.y;
m_Light[cLight].m_vecLightPos.y=m_Light[cLight].m_vecLightPos.z;
m_Light[cLight].m_vecLightPos.z=fTemp;
}
m_vecMinBox=m_vecMaxBox=m_DrawVerts[0].v;
for(int cVertex=0;cVertex<m_nDrawVerts;cVertex++)
{
m_DrawVerts[cVertex].diff.r=rand()%255;
m_DrawVerts[cVertex].diff.g=rand()%255;
m_DrawVerts[cVertex].diff.b=rand()%255;
if(m_DrawVerts[cVertex].v.x >= m_vecMaxBox.x)
m_vecMaxBox.x=m_DrawVerts[cVertex].v.x;
if(m_DrawVerts[cVertex].v.y >= m_vecMaxBox.y)
m_vecMaxBox.y=m_DrawVerts[cVertex].v.y;
if(m_DrawVerts[cVertex].v.z >= m_vecMaxBox.z)
m_vecMaxBox.z=m_DrawVerts[cVertex].v.z;
if(m_DrawVerts[cVertex].v.x <= m_vecMinBox.x)
m_vecMinBox.x=m_DrawVerts[cVertex].v.x;
if(m_DrawVerts[cVertex].v.y <= m_vecMinBox.y)
m_vecMinBox.y=m_DrawVerts[cVertex].v.y;
if(m_DrawVerts[cVertex].v.z <= m_vecMinBox.z)
m_vecMinBox.z=m_DrawVerts[cVertex].v.z;
}
m_vecMax=m_vecMaxBox;
m_vecMax.y=m_vecMaxBox.z;
m_vecMax.z=m_vecMaxBox.y;
m_vecMin=m_vecMinBox;
m_vecMin.y=m_vecMin.z;
m_vecMin.z=m_vecMin.y;
m_vecMaxBox=m_vecMax;
m_vecMinBox=m_vecMin;
int nLightmap=0;
for(int cDrawSurface=0;cDrawSurface<m_nDrawSurfaces;cDrawSurface++)
{
if(nLightmap < m_DrawSurfaces[cDrawSurface].m_nLightmap)
{
nLightmap=m_DrawSurfaces[cDrawSurface].m_nLightmap;
}
}
m_nLightmap=nLightmap+1;
m_bLightmapVector=false;
delete [] pBuffer;
InitTrace();
RenderInit();
}
int CBspScene::CopyLump(DHeader *header, int lump, void **dest, int size)
{
int len=header->m_Lump[lump].m_Filelen;
*dest=malloc(len);
int ofs=header->m_Lump[lump].m_Fileofs;
memcpy(*dest,(BYTE*)header+ofs,len);
return len/size;
}
void CBspScene::Render(LPDIRECT3DDEVICE8 pd3dDevice, vector3 vecViewPos)
{
//vecViewPos=vector3(56,32,32);
m_Camera.BuildFrustum(CSceneManager::GetCamera()->m_fAspect,3.14159f/3.0f,CSceneManager::GetCamera()->m_fNearPlane,CSceneManager::GetCamera()->m_fFarPlane);
matrix matHousePos;
pd3dDevice->GetTransform(D3DTS_WORLD,matHousePos);
matrix *matViewPosition=CSceneManager::GetCamera()->GetMatPosition();
matrix matInvTM,matPos;
matInvTM.Inverse(matHousePos);
matPos=(*matViewPosition)*matInvTM;
m_Camera.m_matPosition=matPos;
m_Camera.MoveFrustum();
m_vecViewPos=vecViewPos;
CSceneStateMgr::_SetD3DTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
CSceneStateMgr::_SetD3DTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
CSceneStateMgr::_SetD3DTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
//CSceneStateMgr::_SetD3DTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
//CSceneStateMgr::_SetD3DTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_TFACTOR );
//CSceneStateMgr::_SetD3DRenderState( D3DRS_TEXTUREFACTOR,0xffdddddd);
//CSceneStateMgr::_SetD3DTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_ADDSIGNED );
//CSceneStateMgr::_SetD3DTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
//CSceneStateMgr::_SetD3DTextureStageState( 1, D3DTSS_COLORARG1, D3DTA_TEXTURE );
//CSceneStateMgr::_SetD3DTextureStageState( 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
//CSceneStateMgr::_SetD3DTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_MODULATE4X);
//CSceneStateMgr::_SetD3DTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_SELECTARG2);
CSceneStateMgr::_SetD3DRenderState( D3DRS_LIGHTING,FALSE);
//CSceneStateMgr::_SetD3DRenderState( D3DRS_FOGENABLE,FALSE);
pd3dDevice->SetTexture(0,NULL);
pd3dDevice->SetTexture(1,NULL);
m_EyeCluster=FindCluster(vecViewPos);
memset(m_SurfaceInc,0,sizeof(int)*m_nDrawSurfaces);
//memset(m_RenderSurfacesList.nSurfaces,0,sizeof(int)*100);
m_bCull=true;
/*
for(int i=0;i<m_nShader;i++)
{
for(int cLightmap=0;cLightmap<m_nLightmap;cLightmap++)
//for(int cLightmap=0;cLightmap<m_LightmapList.num;cLightmap++)
{
m_RenderSurfacesList.nSurfaces[i][cLightmap]=0;
}
}
*/
RenderWalkNode(0);
RenderBackend(pd3dDevice);
pd3dDevice->SetTexture(1,NULL);
CSceneStateMgr::_SetD3DTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_MODULATE);
CSceneStateMgr::_SetD3DTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
CSceneStateMgr::_SetD3DTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
CSceneStateMgr::_SetD3DTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
RenderLight(pd3dDevice);
//if(m_bLightmapVector)
// RenderLight(pd3dDevice);
}
int CBspScene::FindCluster(vector3 vecPos)
{
DNode *pNode;
int nCluster=-1;
int nLeaf=-1;
pNode=&m_Nodes[0];
while(1)
{
if(ClassfyPoint(vecPos,pNode->m_nPlane)>0)
{
if(pNode->m_Children[0] < 0)
{
nLeaf=-(pNode->m_Children[0]+1);
break;
}
else
{
pNode=&m_Nodes[pNode->m_Children[0]];
}
}
else
{
if(pNode->m_Children[1]<0)
{
nLeaf=-(pNode->m_Children[1]+1);
break;
}
else
{
pNode=&m_Nodes[pNode->m_Children[1]];
}
}
}
if(nLeaf>=0)
nCluster=m_Leafs[nLeaf].m_Cluster;
return nCluster;
}
int CBspScene::ClassfyPoint(vector3 p, int nPlane)
{
DPlane *plane=&m_Planes[nPlane];
vector3 test;
test.x=plane->m_vecNormal.x;
test.z=plane->m_vecNormal.y;
test.y=plane->m_vecNormal.z;
if( (p*test) < plane->m_fDist)
return -1;
else
return 1;
return -1;
}
void CBspScene::RenderWalkNode(int n)
{
DNode *pNode=&m_Nodes[n];
/*
vector3 m_MinBox;
m_MinBox.x=pNode->Min[0];
m_MinBox.y=pNode->Min[2];
m_MinBox.z=pNode->Min[1];
vector3 m_MaxBox;
m_MaxBox.x=pNode->Max[0];
m_MaxBox.y=pNode->Max[2];
m_MaxBox.z=pNode->Max[1];
if( m_MinBox.x <= m_vecViewPos.x && m_vecViewPos.x <= m_MaxBox.x &&
m_MinBox.y <= m_vecViewPos.y && m_vecViewPos.y <= m_MaxBox.y &&
m_MinBox.z <= m_vecViewPos.z && m_vecViewPos.z <= m_MaxBox.z)
*/
{
if(ClassfyPoint(m_vecViewPos,pNode->m_nPlane)>0)
{
if(pNode->m_Children[0]<0)
RenderWalkLeaf(-(pNode->m_Children[0]+1));
else
RenderWalkNode(pNode->m_Children[0]);
if(pNode->m_Children[1]<0)
RenderWalkLeaf(-(pNode->m_Children[1]+1));
else
RenderWalkNode(pNode->m_Children[1]);
}
else
{
if(pNode->m_Children[1]<0)
RenderWalkLeaf(-(pNode->m_Children[1]+1));
else
RenderWalkNode(pNode->m_Children[1]);
if(pNode->m_Children[0]<0)
RenderWalkLeaf(-(pNode->m_Children[0]+1));
else
RenderWalkNode(pNode->m_Children[0]);
}
}
}
#define BSP_TESTVIS(from,to) \
(*(m_Visibility->data+(from)*m_Visibility->RowSize+\
((to)>>3)) & (1<<((to)&7)))
void CBspScene::RenderWalkLeaf(int n)
{
DLeaf *pLeaf=&m_Leafs[n];
if(m_EyeCluster >= 0)
{
if(!BSP_TESTVIS(m_EyeCluster,pLeaf->m_Cluster))
return;
}
CViewCamera *pCamera=&m_Camera;
/*
*/
vector3 m_MinBox;
m_MinBox.x=pLeaf->m_min.x;
m_MinBox.z=pLeaf->m_min.y;
m_MinBox.y=pLeaf->m_min.z;
vector3 m_MaxBox;
m_MaxBox.x=pLeaf->m_max.x;
m_MaxBox.z=pLeaf->m_max.y;
m_MaxBox.y=pLeaf->m_max.z;
if(m_bCull)
{
if( CIntersection::PlaneAABBBox(pCamera->m_vecFrustumTop,-pCamera->m_vecFrustumNormal[0],m_MaxBox,m_MinBox) < 0.0f &&
CIntersection::PlaneAABBBox(pCamera->m_vecFrustumBottom,-pCamera->m_vecFrustumNormal[1],m_MaxBox,m_MinBox) < 0.0f &&
CIntersection::PlaneAABBBox(pCamera->m_vecFrustumLeft,-pCamera->m_vecFrustumNormal[2],m_MaxBox,m_MinBox) < 0.0f &&
CIntersection::PlaneAABBBox(pCamera->m_vecFrustumRight,-pCamera->m_vecFrustumNormal[3],m_MaxBox,m_MinBox) < 0.0f)
{
for(int i=0;i<pLeaf->m_nLeafSurfaces;i++)
{
RenderWalkFace(m_LeafSurfaces[i+pLeaf->m_FirstLeafSurface]);
}
}
else
{
int a=0;
}
}
else
{
for(int i=0;i<pLeaf->m_nLeafSurfaces;i++)
{
RenderWalkFace(m_LeafSurfaces[i+pLeaf->m_FirstLeafSurface]);
}
}
}
void CBspScene::RenderWalkFace(int n)
{
DSurface *pSurface=&m_DrawSurfaces[n];
if(m_SurfaceInc[n]>0)
return;
CViewCamera *pCamera=&m_Camera;
vector3 m_MinBox;
vector3 m_MaxBox;
m_MinBox=m_DSurfaceEx[n]->m_vecMin;
m_MaxBox=m_DSurfaceEx[n]->m_vecMax;
if( CIntersection::PlaneAABBBox(pCamera->m_vecFrustumTop,-pCamera->m_vecFrustumNormal[0],m_MaxBox,m_MinBox) < 0.0f &&
CIntersection::PlaneAABBBox(pCamera->m_vecFrustumBottom,-pCamera->m_vecFrustumNormal[1],m_MaxBox,m_MinBox) < 0.0f &&
CIntersection::PlaneAABBBox(pCamera->m_vecFrustumLeft,-pCamera->m_vecFrustumNormal[2],m_MaxBox,m_MinBox) < 0.0f &&
CIntersection::PlaneAABBBox(pCamera->m_vecFrustumRight,-pCamera->m_vecFrustumNormal[3],m_MaxBox,m_MinBox) < 0.0f)
{
m_SurfaceInc[n]=1;
}
else
{
m_SurfaceInc[n]=2;
}
if(pSurface->m_nLightmap<0)
return;
if(pSurface->m_nShader<0)
return;
/*
m_RenderSurfacesList.pDrawSurfaces[pSurface->m_nShader][pSurface->m_nLightmap]
[m_RenderSurfacesList.nSurfaces[pSurface->m_nShader][pSurface->m_nLightmap]]=n;
m_RenderSurfacesList.nSurfaces[pSurface->m_nShader][pSurface->m_nLightmap]++;
*/
}
void CBspScene::RenderInit()
{
CTexture::SetPath("c:\\MP-Project\\Texture\\BSP");
m_SurfaceInc=new int[m_nDrawSurfaces];
int cSurface=0;
for(cSurface=0;cSurface<m_nDrawSurfaces;cSurface++)
{
DSurfaceEx *AddNode=new DSurfaceEx;
AddNode->m_pSurface=&m_DrawSurfaces[cSurface];
AddNode->m_pShadowVertexBuffer=NULL;
AddNode->m_vecMax=m_DrawVerts[AddNode->m_pSurface->m_FirstVert].v;
AddNode->m_vecMin=m_DrawVerts[AddNode->m_pSurface->m_FirstVert].v;
for(int cVertex=0;cVertex<AddNode->m_pSurface->m_nVerts;cVertex++)
{
if(AddNode->m_vecMax.x <= m_DrawVerts[AddNode->m_pSurface->m_FirstVert+cVertex].v.x)
AddNode->m_vecMax.x=m_DrawVerts[AddNode->m_pSurface->m_FirstVert+cVertex].v.x;
if(AddNode->m_vecMax.y <= m_DrawVerts[AddNode->m_pSurface->m_FirstVert+cVertex].v.y)
AddNode->m_vecMax.y=m_DrawVerts[AddNode->m_pSurface->m_FirstVert+cVertex].v.y;
if(AddNode->m_vecMax.z <= m_DrawVerts[AddNode->m_pSurface->m_FirstVert+cVertex].v.z)
AddNode->m_vecMax.z=m_DrawVerts[AddNode->m_pSurface->m_FirstVert+cVertex].v.z;
if(AddNode->m_vecMin.x >= m_DrawVerts[AddNode->m_pSurface->m_FirstVert+cVertex].v.x)
AddNode->m_vecMin.x = m_DrawVerts[AddNode->m_pSurface->m_FirstVert+cVertex].v.x;
if(AddNode->m_vecMin.y >= m_DrawVerts[AddNode->m_pSurface->m_FirstVert+cVertex].v.y)
AddNode->m_vecMin.y = m_DrawVerts[AddNode->m_pSurface->m_FirstVert+cVertex].v.y;
if(AddNode->m_vecMin.z >= m_DrawVerts[AddNode->m_pSurface->m_FirstVert+cVertex].v.z)
AddNode->m_vecMin.z = m_DrawVerts[AddNode->m_pSurface->m_FirstVert+cVertex].v.z;
}
vector3 vecTemp;
vecTemp=AddNode->m_vecMax;
AddNode->m_vecMax.y=vecTemp.z;
AddNode->m_vecMax.z=vecTemp.y;
vecTemp=AddNode->m_vecMin;
AddNode->m_vecMin.y=vecTemp.z;
AddNode->m_vecMin.z=vecTemp.y;
DSurface *pSurface=&m_DrawSurfaces[cSurface];
//CalcShadowVolume(&m_DrawVerts[pSurface->m_FirstVert],pSurface->m_nVerts,
// &m_DrawIndex[pSurface->m_FirstIndex],pSurface->m_nIndex,AddNode);
m_DSurfaceEx.Add(AddNode);
//CalcShadowVolume(&m_DrawVerts[pSurface->m_FirstVert],pSurface->m_nVerts,
//&m_DrawIndex[pSurface->m_FirstIndex],pSurface->m_nIndex,m_DSurfaceEx[cSurface]);
CalcShadowVolume(&m_DrawVerts[pSurface->m_FirstVert],pSurface->m_nVerts,
&m_DrawIndex[pSurface->m_FirstIndex],pSurface->m_nIndex,*m_DSurfaceEx[cSurface]);
}
BspShadowVertex *pVertexData;
CSceneManager::GetDevice()->CreateVertexBuffer(m_SurfaceEdgeVertexList.num*sizeof(BspShadowVertex),
D3DUSAGE_WRITEONLY,BSPSHADOWVERTEX,D3DPOOL_MANAGED,&m_pEdgeVertexBuffer);
m_pEdgeVertexBuffer->Lock(0,0,(BYTE**)&pVertexData,0);
memcpy(pVertexData,&m_SurfaceEdgeVertexList[0],sizeof(BspShadowVertex)*m_SurfaceEdgeVertexList.num);
m_pEdgeVertexBuffer->Unlock();
for(int i=0;i<m_nShader;i++)
{
CTexture *pDiffuseTexture=new CTexture();
pDiffuseTexture->Load(m_Shaders[i].m_strTextureName);
CTexture *pBumpTexture=new CTexture();
char strBumpTexture[256];
strcpy(strBumpTexture,m_Shaders[i].m_strTextureName);
int nLens=strlen(strBumpTexture);
strBumpTexture[nLens-4]='_';
strBumpTexture[nLens-3]='b';
strBumpTexture[nLens-2]='u';
strBumpTexture[nLens-1]='m';
strBumpTexture[nLens-0]='p';
strBumpTexture[nLens+1]='.';
strBumpTexture[nLens+2]='d';
strBumpTexture[nLens+3]='d';
strBumpTexture[nLens+4]='s';
strBumpTexture[nLens+5]=0;
pBumpTexture->Load(strBumpTexture);
CBSPShader AddShader;
AddShader.m_DiffuseTexture=pDiffuseTexture;
AddShader.m_BumpTexture=pBumpTexture;
AddShader.m_nPoly=0;
AddShader.m_pIndicesBuffer=NULL;
AddShader.m_pVertexBuffer=NULL;
AddShader.m_nVertex=0;
AddShader.m_nIndices=0;
DSurface *pSurface=NULL;
for(int cSurface=0;cSurface<m_nDrawSurfaces;cSurface++)
{
pSurface=&m_DrawSurfaces[cSurface];
if(i==pSurface->m_nShader)
{
AddShader.m_nVertex+=pSurface->m_nVerts;
AddShader.m_nIndices+=pSurface->m_nIndex;
}
}
CSceneManager::GetDevice()->CreateVertexBuffer(AddShader.m_nVertex*sizeof(BspVertex),D3DUSAGE_DYNAMIC|D3DUSAGE_WRITEONLY,BSPVERTEXFVF,D3DPOOL_DEFAULT,&AddShader.m_pVertexBuffer);
CSceneManager::GetDevice()->CreateIndexBuffer(AddShader.m_nIndices*sizeof(WORD),D3DUSAGE_DYNAMIC|D3DUSAGE_WRITEONLY,D3DFMT_INDEX16,D3DPOOL_DEFAULT,&AddShader.m_pIndicesBuffer);
BspVertex *pVertex;
AddShader.m_pVertexBuffer->Lock(0,0,(BYTE**)&pVertex,D3DLOCK_DISCARD);
int nTotalVertex=0;
for(cSurface=0;cSurface<m_nDrawSurfaces;cSurface++)
{
pSurface=&m_DrawSurfaces[cSurface];
if(i==pSurface->m_nShader)
{
//CalcShadowVolume(&m_DrawVerts[pSurface->m_FirstVert],pSurface->m_nVerts,
//&m_DrawIndex[pSurface->m_FirstIndex],pSurface->m_nIndex,m_DSurfaceEx[cSurface]);
for(int cIndices=0;cIndices<pSurface->m_nIndex;cIndices++)
{
m_DrawIndex[pSurface->m_FirstIndex+cIndices]=nTotalVertex+m_DrawIndex[pSurface->m_FirstIndex+cIndices];
}
for(int cVertex=0;cVertex<pSurface->m_nVerts;cVertex++)
{
pVertex[nTotalVertex].v.x=m_DrawVerts[pSurface->m_FirstVert+cVertex].v.x;
pVertex[nTotalVertex].v.y=m_DrawVerts[pSurface->m_FirstVert+cVertex].v.z;
pVertex[nTotalVertex].v.z=m_DrawVerts[pSurface->m_FirstVert+cVertex].v.y;
pVertex[nTotalVertex].normal.x=m_DrawVerts[pSurface->m_FirstVert+cVertex].normal.x;
pVertex[nTotalVertex].normal.y=m_DrawVerts[pSurface->m_FirstVert+cVertex].normal.z;
pVertex[nTotalVertex].normal.z=m_DrawVerts[pSurface->m_FirstVert+cVertex].normal.y;
pVertex[nTotalVertex].tu=m_DrawVerts[pSurface->m_FirstVert+cVertex].tu;
pVertex[nTotalVertex].tv=m_DrawVerts[pSurface->m_FirstVert+cVertex].tv;
pVertex[nTotalVertex].tu1=m_DrawVerts[pSurface->m_FirstVert+cVertex].tu1;
pVertex[nTotalVertex].tv1=m_DrawVerts[pSurface->m_FirstVert+cVertex].tv1;
pVertex[nTotalVertex].diff.c=0x0;
pVertex[nTotalVertex].u.x=m_DrawVerts[pSurface->m_FirstVert+cVertex].u.x;
pVertex[nTotalVertex].u.y=m_DrawVerts[pSurface->m_FirstVert+cVertex].u.z;
pVertex[nTotalVertex].u.z=m_DrawVerts[pSurface->m_FirstVert+cVertex].u.y;
nTotalVertex++;
}
}
}
AddShader.m_pVertexBuffer->Unlock();
AddShader.m_nDrawIndices=0;
AddShader.m_pIndices=NULL;
m_ShaderList.Add(AddShader);
}
InitShader();
SurfaceLightArrange();
}
void CBspScene::RenderBackend(LPDIRECT3DDEVICE8 pd3dDevice)
{
DSurface *pSurface;
WORD *pIndices;
BspVertex *pVertex;
List<DSurface*> CurveRenderList;
bool bSkyRender=false;
m_bSkyRender=false;
int nRenderSurface=0;
int nRenderPoly=0;
List<int> LightRenderList;
for(int nSurface=0;nSurface<m_nDrawSurfaces;nSurface++)
{
if(m_SurfaceInc[nSurface]!=1)
continue;
pSurface=&m_DrawSurfaces[nSurface];
if(m_ShaderList[pSurface->m_nShader].m_nDrawIndices==0)
{
m_ShaderList[pSurface->m_nShader].m_pIndicesBuffer->Lock(0,
m_ShaderList[pSurface->m_nShader].m_nIndices*sizeof(WORD),
(BYTE**)&m_ShaderList[pSurface->m_nShader].m_pIndices,D3DLOCK_DISCARD);
}
for(int cIndices=0;cIndices<pSurface->m_nIndex;cIndices++)
{
m_ShaderList[pSurface->m_nShader].m_pIndices[m_ShaderList[pSurface->m_nShader].m_nDrawIndices]
=m_DrawIndex[pSurface->m_FirstIndex+cIndices];
m_ShaderList[pSurface->m_nShader].m_nDrawIndices++;
}
nRenderPoly+=pSurface->m_nIndex/3;
nRenderSurface++;
for(int cLight=0;cLight<m_DSurfaceEx[nSurface]->m_ApplyLightList.num;cLight++)
{
LightRenderList.AddUnique(m_DSurfaceEx[nSurface]->m_ApplyLightList[cLight]);
m_ShaderList[pSurface->m_nShader].m_ApplyLightList.AddUnique(
m_DSurfaceEx[nSurface]->m_ApplyLightList[cLight]);
}
}
for(int cShader=0;cShader<m_ShaderList.num;cShader++)
{
if(m_ShaderList[cShader].m_nDrawIndices)
m_ShaderList[cShader].m_pIndicesBuffer->Unlock();
}
CSceneStateMgr::_SetD3DRenderState( D3DRS_FOGENABLE,FALSE);
matrix matView,matProjection,matWorld,matWVP;
pd3dDevice->GetTransform(D3DTS_VIEW,matView);
pd3dDevice->GetTransform(D3DTS_PROJECTION,matProjection);
pd3dDevice->GetTransform(D3DTS_WORLD,matWorld);
matWVP=matWorld*matView*matProjection;
matWVP.Transpose();
CSceneStateMgr::_SetD3DRenderState( D3DRS_ALPHABLENDENABLE,FALSE);
CSceneStateMgr::_SetD3DRenderState( D3DRS_FOGENABLE,FALSE);
CSceneStateMgr::_SetD3DRenderState(D3DRS_ZWRITEENABLE,TRUE);
for(cShader=0;cShader<m_ShaderList.num;cShader++)
{
if(m_ShaderList[cShader].m_nDrawIndices==0)
continue;
pd3dDevice->SetTexture(0,m_ShaderList[cShader].m_DiffuseTexture->GetTexture());
pd3dDevice->SetVertexShaderConstant(16,&matWVP, 4);
pd3dDevice->SetVertexShader(m_dwBSPAmbientVertexShader);
pd3dDevice->SetPixelShader(m_dwBSPAmbientPixelShader);
pd3dDevice->SetStreamSource(0,m_ShaderList[cShader].m_pVertexBuffer,sizeof(BspVertex));
pd3dDevice->SetIndices(m_ShaderList[cShader].m_pIndicesBuffer,0);
pd3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,0,m_ShaderList[cShader].m_nVertex,0,m_ShaderList[cShader].m_nDrawIndices/3);
}
for(int cLight=0;cLight<LightRenderList.num;cLight++)
//for(int cLight=0;cLight<1;cLight++)
{
pd3dDevice->Clear( 0L, NULL, D3DCLEAR_STENCIL , 0x000000ff, 1.0f, 0x80L );
CSceneStateMgr::_SetD3DRenderState(D3DRS_COLORWRITEENABLE,0);
CSceneStateMgr::_SetD3DRenderState(D3DRS_ZWRITEENABLE,FALSE);
CSceneStateMgr::_SetD3DRenderState(D3DRS_STENCILENABLE,TRUE);
CSceneStateMgr::_SetD3DRenderState( D3DRS_STENCILFUNC, D3DCMP_ALWAYS );
CSceneStateMgr::_SetD3DRenderState( D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP );
CSceneStateMgr::_SetD3DRenderState( D3DRS_STENCILPASS, D3DSTENCILOP_KEEP );
CSceneStateMgr::_SetD3DRenderState( D3DRS_STENCILZFAIL,D3DSTENCILOP_KEEP);
CSceneStateMgr::_SetD3DRenderState( D3DRS_STENCILREF, 0x1 );
CSceneStateMgr::_SetD3DRenderState( D3DRS_STENCILMASK, 0xffffffff );
CSceneStateMgr::_SetD3DRenderState( D3DRS_STENCILWRITEMASK, 0xffffffff );
pd3dDevice->SetPixelShader(NULL);
CSceneStateMgr::_SetD3DTextureStageState(0,D3DTSS_COLORARG1,D3DTA_TFACTOR);
CSceneStateMgr::_SetD3DTextureStageState(0,D3DTSS_COLOROP,D3DTOP_SELECTARG1);
CSceneStateMgr::_SetD3DTextureStageState(1,D3DTSS_COLOROP,D3DTOP_DISABLE);
CSceneStateMgr::_SetD3DRenderState(D3DRS_TEXTUREFACTOR,0xffff0000);
DLightEx *pLight=&m_LightEx[LightRenderList[cLight]];
vector3 vecLightPosition=pLight->m_pLight->m_vecLightPos;
static float fRate=0.0f;
fRate+=0.05f;
/*
vecLightPosition.x+=sinf(fRate)*100.0f;
vecLightPosition.z+=cosf(fRate)*100.0f;
vecLightPosition.y+=cosf(fRate)*100.0f;
*/
float fLightPos[4]={vecLightPosition.x,vecLightPosition.y,vecLightPosition.z,1.0f};
pd3dDevice->SetVertexShaderConstant(1,&matWVP, 4);
pd3dDevice->SetVertexShaderConstant(10,fLightPos,1);
pd3dDevice->SetVertexShader(m_dwBSPShadowVertexShader);
CSceneStateMgr::_SetD3DRenderState(D3DRS_CULLMODE,D3DCULL_CCW);
//CSceneStateMgr::_SetD3DRenderState(D3DRS_CULLMODE,D3DCULL_NONE);
pd3dDevice->SetStreamSource(0,m_pEdgeVertexBuffer,sizeof(BspShadowVertex));
pd3dDevice->SetIndices(pLight->m_pEdgeIndexBuffer,0);
///*
CSceneStateMgr::_SetD3DRenderState( D3DRS_STENCILPASS,D3DSTENCILOP_INCR);
pd3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,0,m_SurfaceEdgeVertexList.num,0,pLight->m_nEdgePoly/3);
CSceneStateMgr::_SetD3DRenderState(D3DRS_CULLMODE,D3DCULL_CW);
CSceneStateMgr::_SetD3DRenderState( D3DRS_STENCILPASS,D3DSTENCILOP_DECR);
pd3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,0,m_SurfaceEdgeVertexList.num,0,pLight->m_nEdgePoly/3);
//*/
//////////////////////////////
CSceneStateMgr::_SetD3DRenderState(D3DRS_CULLMODE,D3DCULL_CCW);
CSceneStateMgr::_SetD3DRenderState(D3DRS_COLORWRITEENABLE,D3DCOLORWRITEENABLE_BLUE|D3DCOLORWRITEENABLE_GREEN|D3DCOLORWRITEENABLE_RED);
CSceneStateMgr::_SetD3DRenderState( D3DRS_STENCILREF, 0x80 );
CSceneStateMgr::_SetD3DRenderState( D3DRS_STENCILPASS, D3DSTENCILOP_KEEP );
CSceneStateMgr::_SetD3DRenderState( D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP );
CSceneStateMgr::_SetD3DRenderState( D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP );
CSceneStateMgr::_SetD3DRenderState(D3DRS_STENCILENABLE,TRUE);
TraceT trace;
TraceWorkT tw;
vector3 vecCheckViewPos;
vecCheckViewPos.x=m_vecViewPos.x;
vecCheckViewPos.y=m_vecViewPos.z;
vecCheckViewPos.z=m_vecViewPos.y;
vector3 vecCheckLightPos;
vecCheckLightPos.x=vecLightPosition.x;
vecCheckLightPos.y=vecLightPosition.z;
vecCheckLightPos.z=vecLightPosition.y;
TraceLine(vecCheckViewPos,vecCheckLightPos,&trace,false,&tw);
if(trace.m_bPassSolid)
CSceneStateMgr::_SetD3DRenderState( D3DRS_STENCILFUNC, D3DCMP_GREATER);
else
CSceneStateMgr::_SetD3DRenderState( D3DRS_STENCILFUNC, D3DCMP_EQUAL);
float fObjectSpaceLightPosition[4]={vecLightPosition.x,vecLightPosition.y,vecLightPosition.z,1.0f};
float fLightSettingValue[4]={1.0f/4000.0f,0.0f,0.0f,0.0f};
float fObjectSpaceViewPosition[4]={m_Camera.m_matPosition.GetLoc().x,m_Camera.m_matPosition.GetLoc().y,m_Camera.m_matPosition.GetLoc().z,0.0f};
float fLightPosAdder[4]={0.5f,0.5f,0.5f,0.5f};
pd3dDevice->SetVertexShaderConstant(16,&matWVP, 4);
pd3dDevice->SetVertexShaderConstant(32,fObjectSpaceLightPosition,1);
pd3dDevice->SetVertexShaderConstant(33,fLightSettingValue,1);
pd3dDevice->SetVertexShaderConstant(35,fObjectSpaceViewPosition,1);
pd3dDevice->SetVertexShaderConstant(36,fLightPosAdder,1);
CSceneStateMgr::_SetD3DRenderState( D3DRS_SRCBLEND,D3DBLEND_ONE);
CSceneStateMgr::_SetD3DRenderState( D3DRS_DESTBLEND,D3DBLEND_ONE);
CSceneStateMgr::_SetD3DRenderState( D3DRS_ALPHABLENDENABLE,TRUE);
CSceneStateMgr::_SetD3DRenderState(D3DRS_ZWRITEENABLE,FALSE);
for(int cShader=0;cShader<m_ShaderList.num;cShader++)
{
if(m_ShaderList[cShader].m_nDrawIndices==0)
continue;
if(m_ShaderList[cShader].m_ApplyLightList.Contains(LightRenderList[cLight])==0)
continue;
///////////Diffuse //////////////
pd3dDevice->SetTexture(0,m_pPointFalloffMap);
pd3dDevice->SetTexture(1,m_ShaderList[cShader].m_BumpTexture->GetTexture());
pd3dDevice->SetTexture(2,m_pNormalizeCubeMap);
pd3dDevice->SetTexture(3,m_ShaderList[cShader].m_DiffuseTexture->GetTexture());
pd3dDevice->SetVertexShader(m_dwBSPDiffuseVertexShader);
pd3dDevice->SetPixelShader(m_dwBSPDiffusePixelShader);
CSceneStateMgr::_SetD3DTextureStageState(0,D3DTSS_ADDRESSU,D3DTADDRESS_MIRROR);
CSceneStateMgr::_SetD3DTextureStageState(0,D3DTSS_ADDRESSV,D3DTADDRESS_MIRROR);
CSceneStateMgr::_SetD3DTextureStageState(0,D3DTSS_ADDRESSW,D3DTADDRESS_MIRROR);
CSceneStateMgr::_SetD3DTextureStageState(2,D3DTSS_ADDRESSU,D3DTADDRESS_CLAMP);
CSceneStateMgr::_SetD3DTextureStageState(2,D3DTSS_ADDRESSV,D3DTADDRESS_CLAMP);
CSceneStateMgr::_SetD3DTextureStageState(2,D3DTSS_ADDRESSW,D3DTADDRESS_CLAMP);
pd3dDevice->SetStreamSource(0,m_ShaderList[cShader].m_pVertexBuffer,sizeof(BspVertex));
pd3dDevice->SetIndices(m_ShaderList[cShader].m_pIndicesBuffer,0);
pd3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,0,m_ShaderList[cShader].m_nVertex,0,m_ShaderList[cShader].m_nDrawIndices/3);
///////////Specluar/////////////
pd3dDevice->SetTexture(0,m_ShaderList[cShader].m_BumpTexture->GetTexture());
pd3dDevice->SetTexture(1,m_pPointFalloffMap);
pd3dDevice->SetTexture(2,m_pNormalizeCubeMap);
pd3dDevice->SetTexture(3,m_pNormalizeCubeMap);
pd3dDevice->SetVertexShader(m_dwBSPSpecularVertexShader);
pd3dDevice->SetPixelShader(m_dwBSPSpecularPixelShader);
CSceneStateMgr::_SetD3DTextureStageState(0,D3DTSS_ADDRESSU,D3DTADDRESS_WRAP);
CSceneStateMgr::_SetD3DTextureStageState(0,D3DTSS_ADDRESSV,D3DTADDRESS_WRAP);
CSceneStateMgr::_SetD3DTextureStageState(0,D3DTSS_ADDRESSW,D3DTADDRESS_WRAP);
CSceneStateMgr::_SetD3DTextureStageState(1,D3DTSS_ADDRESSU,D3DTADDRESS_MIRROR);
CSceneStateMgr::_SetD3DTextureStageState(1,D3DTSS_ADDRESSV,D3DTADDRESS_MIRROR);
CSceneStateMgr::_SetD3DTextureStageState(1,D3DTSS_ADDRESSW,D3DTADDRESS_MIRROR);
CSceneStateMgr::_SetD3DTextureStageState(2,D3DTSS_ADDRESSU,D3DTADDRESS_CLAMP);
CSceneStateMgr::_SetD3DTextureStageState(2,D3DTSS_ADDRESSV,D3DTADDRESS_CLAMP);
CSceneStateMgr::_SetD3DTextureStageState(2,D3DTSS_ADDRESSW,D3DTADDRESS_CLAMP);
CSceneStateMgr::_SetD3DTextureStageState(3,D3DTSS_ADDRESSU,D3DTADDRESS_CLAMP);
CSceneStateMgr::_SetD3DTextureStageState(3,D3DTSS_ADDRESSV,D3DTADDRESS_CLAMP);
CSceneStateMgr::_SetD3DTextureStageState(3,D3DTSS_ADDRESSW,D3DTADDRESS_CLAMP);
pd3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,0,m_ShaderList[cShader].m_nVertex,0,m_ShaderList[cShader].m_nDrawIndices/3);
CSceneStateMgr::_SetD3DTextureStageState(0,D3DTSS_ADDRESSU,D3DTADDRESS_WRAP);
CSceneStateMgr::_SetD3DTextureStageState(0,D3DTSS_ADDRESSV,D3DTADDRESS_WRAP);
CSceneStateMgr::_SetD3DTextureStageState(0,D3DTSS_ADDRESSW,D3DTADDRESS_WRAP);
CSceneStateMgr::_SetD3DTextureStageState(1,D3DTSS_ADDRESSU,D3DTADDRESS_WRAP);
CSceneStateMgr::_SetD3DTextureStageState(1,D3DTSS_ADDRESSV,D3DTADDRESS_WRAP);
CSceneStateMgr::_SetD3DTextureStageState(1,D3DTSS_ADDRESSW,D3DTADDRESS_WRAP);
CSceneStateMgr::_SetD3DTextureStageState(2,D3DTSS_ADDRESSU,D3DTADDRESS_WRAP);
CSceneStateMgr::_SetD3DTextureStageState(2,D3DTSS_ADDRESSV,D3DTADDRESS_WRAP);
CSceneStateMgr::_SetD3DTextureStageState(2,D3DTSS_ADDRESSW,D3DTADDRESS_WRAP);
CSceneStateMgr::_SetD3DTextureStageState(3,D3DTSS_ADDRESSU,D3DTADDRESS_WRAP);
CSceneStateMgr::_SetD3DTextureStageState(3,D3DTSS_ADDRESSV,D3DTADDRESS_WRAP);
CSceneStateMgr::_SetD3DTextureStageState(3,D3DTSS_ADDRESSW,D3DTADDRESS_WRAP);
}
//pd3dDevice->SetTexture(0,m_pPointFalloffMap);
//pd3dDevice->SetTexture(1,m_ShaderList[cShader].m_BumpTexture->GetTexture());
//pd3dDevice->SetTexture(2,m_pNormalizeCubeMap);
//pd3dDevice->SetTexture(3,m_ShaderList[cShader].m_DiffuseTexture->GetTexture());
//pd3dDevice->SetVertexShader(m_dwBSPDiffuseVertexShader);
//pd3dDevice->SetPixelShader(m_dwBSPDiffusePixelShader);
}
for(cShader=0;cShader<m_ShaderList.num;cShader++)
{
m_ShaderList[cShader].m_ApplyLightList.num=0;
m_ShaderList[cShader].m_nDrawIndices=0;
}
CSceneStateMgr::_SetD3DRenderState(D3DRS_ZWRITEENABLE,TRUE);
CSceneStateMgr::_SetD3DRenderState( D3DRS_ALPHABLENDENABLE,FALSE);
CSceneStateMgr::_SetD3DRenderState(D3DRS_STENCILENABLE,FALSE);
/*
for(cShader=0;cShader<m_ShaderList.num;cShader++)
{
pd3dDevice->SetTexture(0,m_ShaderList[cShader].m_DiffuseTexture->GetTexture());
pd3dDevice->SetVertexShaderConstant(16,&matWVP, 4);
//pd3dDevice->SetVertexShader(BSPVERTEXFVF);
//Ambient Base Light
pd3dDevice->SetVertexShader(m_dwBSPAmbientVertexShader);
pd3dDevice->SetPixelShader(m_dwBSPAmbientPixelShader);
CSceneStateMgr::_SetD3DRenderState( D3DRS_ALPHABLENDENABLE,FALSE);
CSceneStateMgr::_SetD3DRenderState( D3DRS_FOGENABLE,FALSE);
CSceneStateMgr::_SetD3DRenderState(D3DRS_ZWRITEENABLE,TRUE);
pd3dDevice->SetStreamSource(0,m_ShaderList[cShader].m_pVertexBuffer,sizeof(BspVertex));
pd3dDevice->SetIndices(m_ShaderList[cShader].m_pIndicesBuffer,0);
pd3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,0,
m_ShaderList[cShader].m_nVertex,0,
m_ShaderList[cShader].m_nDrawIndices/3);
for(int cLight=0;cLight<m_ShaderList[cShader].m_ApplyLightList.num;cLight++)
{
pd3dDevice->Clear( 0L, NULL, D3DCLEAR_STENCIL , 0x000000ff, 1.0f, 0x80L );
CSceneStateMgr::_SetD3DRenderState(D3DRS_COLORWRITEENABLE,0);
CSceneStateMgr::_SetD3DRenderState(D3DRS_ZWRITEENABLE,TRUE);
CSceneStateMgr::_SetD3DRenderState(D3DRS_STENCILENABLE,TRUE);
CSceneStateMgr::_SetD3DRenderState( D3DRS_STENCILFUNC, D3DCMP_ALWAYS );
CSceneStateMgr::_SetD3DRenderState( D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP );
CSceneStateMgr::_SetD3DRenderState( D3DRS_STENCILPASS, D3DSTENCILOP_KEEP );
// If ztest passes, inc/decrement stencil buffer value
CSceneStateMgr::_SetD3DRenderState( D3DRS_STENCILREF, 0x1 );
CSceneStateMgr::_SetD3DRenderState( D3DRS_STENCILMASK, 0xffffffff );
CSceneStateMgr::_SetD3DRenderState( D3DRS_STENCILWRITEMASK, 0xffffffff );
pd3dDevice->SetPixelShader(NULL);
CSceneStateMgr::_SetD3DTextureStageState(0,D3DTSS_COLORARG1,D3DTA_TFACTOR);
CSceneStateMgr::_SetD3DTextureStageState(0,D3DTSS_COLOROP,D3DTOP_SELECTARG1);
CSceneStateMgr::_SetD3DTextureStageState(1,D3DTSS_COLOROP,D3DTOP_DISABLE);
CSceneStateMgr::_SetD3DRenderState(D3DRS_TEXTUREFACTOR,0xffff0000);
DLightEx *pLight=&m_LightEx[m_ShaderList[cShader].m_ApplyLightList[cLight]];
vector3 vecLightPosition=pLight->m_pLight->m_vecLightPos;
static float fRate=0.0f;
fRate+=0.05f;
vecLightPosition.x+=sinf(fRate)*100.0f;
vecLightPosition.z+=cosf(fRate)*100.0f;
vecLightPosition.y+=cosf(fRate)*100.0f;
CSceneStateMgr::_SetD3DRenderState( D3DRS_STENCILZFAIL,D3DSTENCILOP_KEEP);
CSceneStateMgr::_SetD3DRenderState(D3DRS_ZWRITEENABLE,FALSE);
////////////////////
float fLightPos[4]={vecLightPosition.x,
vecLightPosition.y,
vecLightPosition.z,1.0f};
pd3dDevice->SetVertexShaderConstant(10,fLightPos,1);
pd3dDevice->SetVertexShaderConstant(1,&matWVP, 4);
CSceneStateMgr::_SetD3DRenderState(D3DRS_CULLMODE,D3DCULL_CCW);
pd3dDevice->SetStreamSource(0,m_pEdgeVertexBuffer,sizeof(BspShadowVertex));
pd3dDevice->SetIndices(m_LightEx[m_ShaderList[cShader].m_ApplyLightList[cLight]].m_pEdgeIndexBuffer,0);
pd3dDevice->SetVertexShader(m_dwBSPShadowVertexShader);
CSceneStateMgr::_SetD3DRenderState( D3DRS_STENCILPASS,D3DSTENCILOP_INCR);
pd3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,0,m_SurfaceEdgeVertexList.num,0,m_LightEx[m_ShaderList[cShader].m_ApplyLightList[cLight]].m_nEdgePoly/3);
CSceneStateMgr::_SetD3DRenderState(D3DRS_CULLMODE,D3DCULL_CW);
CSceneStateMgr::_SetD3DRenderState( D3DRS_STENCILPASS,D3DSTENCILOP_DECR);
pd3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,0,m_SurfaceEdgeVertexList.num,0,m_LightEx[m_ShaderList[cShader].m_ApplyLightList[cLight]].m_nEdgePoly/3);
////////////////////
CSceneStateMgr::_SetD3DRenderState( D3DRS_STENCILZFAIL,D3DSTENCILOP_KEEP);
CSceneStateMgr::_SetD3DRenderState(D3DRS_CULLMODE,D3DCULL_CCW);
CSceneStateMgr::_SetD3DRenderState(D3DRS_COLORWRITEENABLE,D3DCOLORWRITEENABLE_BLUE|D3DCOLORWRITEENABLE_GREEN|D3DCOLORWRITEENABLE_RED);
CSceneStateMgr::_SetD3DRenderState( D3DRS_STENCILREF, 0x80 );
//bool bCollision=TraceLineCollision(m_vecViewPos,vecLightPosition);
TraceT trace;
TraceWorkT tw;
vector3 vecCheckViewPos;
vecCheckViewPos.x=m_vecViewPos.x;
vecCheckViewPos.y=m_vecViewPos.z;
vecCheckViewPos.z=m_vecViewPos.y;
vector3 vecCheckLightPos;
vecCheckLightPos.x=vecLightPosition.x;
vecCheckLightPos.y=vecLightPosition.z;
vecCheckLightPos.z=vecLightPosition.y;
TraceLine(vecCheckViewPos,vecCheckLightPos,&trace,false,&tw);
if(trace.m_bPassSolid)
CSceneStateMgr::_SetD3DRenderState( D3DRS_STENCILFUNC, D3DCMP_GREATER);
else
CSceneStateMgr::_SetD3DRenderState( D3DRS_STENCILFUNC, D3DCMP_EQUAL);
//In Shadow
//CSceneStateMgr::_SetD3DRenderState( D3DRS_STENCILFUNC, D3DCMP_NOTEQUAL);
//out shadow
CSceneStateMgr::_SetD3DRenderState( D3DRS_STENCILPASS, D3DSTENCILOP_KEEP );
CSceneStateMgr::_SetD3DRenderState( D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP );
CSceneStateMgr::_SetD3DRenderState( D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP );
CSceneStateMgr::_SetD3DRenderState(D3DRS_STENCILENABLE,TRUE);
//CSceneStateMgr::_SetD3DRenderState(D3DRS_STENCILENABLE,FALSE);
//CSceneStateMgr::_SetD3DRenderState(D3DRS_STENCILFUNC,D3DCMP_EQUAL);
//CSceneStateMgr::_SetD3DRenderState(D3DRS_STENCILREF ,0x01);
pd3dDevice->SetStreamSource(0,m_ShaderList[cShader].m_pVertexBuffer,sizeof(BspVertex));
pd3dDevice->SetIndices(m_ShaderList[cShader].m_pIndicesBuffer,0);
pd3dDevice->SetVertexShaderConstant(16,&matWVP, 4);
float fObjectSpaceLightPosition[4]={vecLightPosition.x,
vecLightPosition.y,
vecLightPosition.z,1.0f};
pd3dDevice->SetVertexShaderConstant(32,fObjectSpaceLightPosition,1);
//m_Light[m_ShaderList[cShader].m_ApplyLightList[cLight]].m_fLightRange
float fLightSettingValue[4]={1.0f/4000.0f,0.0f,0.0f,0.0f};
pd3dDevice->SetVertexShaderConstant(33,fLightSettingValue,1);
float fObjectSpaceViewPosition[4]={
m_Camera.m_matPosition.GetLoc().x,
m_Camera.m_matPosition.GetLoc().y,
m_Camera.m_matPosition.GetLoc().z,
0.0f};
pd3dDevice->SetVertexShaderConstant(35,fObjectSpaceViewPosition,1);
float fLightPosAdder[4]={0.5f,0.5f,0.5f,0.5f};
pd3dDevice->SetVertexShaderConstant(36,fLightPosAdder,1);
pd3dDevice->SetTexture(0,m_pPointFalloffMap);
pd3dDevice->SetTexture(1,m_ShaderList[cShader].m_BumpTexture->GetTexture());
pd3dDevice->SetTexture(2,m_pNormalizeCubeMap);
pd3dDevice->SetTexture(3,m_ShaderList[cShader].m_DiffuseTexture->GetTexture());
pd3dDevice->SetVertexShader(m_dwBSPDiffuseVertexShader);
pd3dDevice->SetPixelShader(m_dwBSPDiffusePixelShader);
CSceneStateMgr::_SetD3DTextureStageState(0,D3DTSS_ADDRESSU,D3DTADDRESS_MIRROR);
CSceneStateMgr::_SetD3DTextureStageState(0,D3DTSS_ADDRESSV,D3DTADDRESS_MIRROR);
CSceneStateMgr::_SetD3DTextureStageState(0,D3DTSS_ADDRESSW,D3DTADDRESS_MIRROR);
CSceneStateMgr::_SetD3DTextureStageState(2,D3DTSS_ADDRESSU,D3DTADDRESS_CLAMP);
CSceneStateMgr::_SetD3DTextureStageState(2,D3DTSS_ADDRESSV,D3DTADDRESS_CLAMP);
CSceneStateMgr::_SetD3DTextureStageState(2,D3DTSS_ADDRESSW,D3DTADDRESS_CLAMP);
CSceneStateMgr::_SetD3DRenderState( D3DRS_SRCBLEND,D3DBLEND_ONE);
CSceneStateMgr::_SetD3DRenderState( D3DRS_DESTBLEND,D3DBLEND_ONE);
CSceneStateMgr::_SetD3DRenderState( D3DRS_ALPHABLENDENABLE,TRUE);
CSceneStateMgr::_SetD3DRenderState(D3DRS_ZWRITEENABLE,FALSE);
pd3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,0,
m_ShaderList[cShader].m_nVertex,0,
m_ShaderList[cShader].m_nDrawIndices/3);
pd3dDevice->SetVertexShader(m_dwBSPSpecularVertexShader);
pd3dDevice->SetPixelShader(m_dwBSPSpecularPixelShader);
pd3dDevice->SetTexture(0,m_ShaderList[cShader].m_BumpTexture->GetTexture());
pd3dDevice->SetTexture(1,m_pPointFalloffMap);
pd3dDevice->SetTexture(2,m_pNormalizeCubeMap);
pd3dDevice->SetTexture(3,m_pNormalizeCubeMap);
CSceneStateMgr::_SetD3DTextureStageState(0,D3DTSS_ADDRESSU,D3DTADDRESS_WRAP);
CSceneStateMgr::_SetD3DTextureStageState(0,D3DTSS_ADDRESSV,D3DTADDRESS_WRAP);
CSceneStateMgr::_SetD3DTextureStageState(0,D3DTSS_ADDRESSW,D3DTADDRESS_WRAP);
CSceneStateMgr::_SetD3DTextureStageState(1,D3DTSS_ADDRESSU,D3DTADDRESS_MIRROR);
CSceneStateMgr::_SetD3DTextureStageState(1,D3DTSS_ADDRESSV,D3DTADDRESS_MIRROR);
CSceneStateMgr::_SetD3DTextureStageState(1,D3DTSS_ADDRESSW,D3DTADDRESS_MIRROR);
CSceneStateMgr::_SetD3DTextureStageState(2,D3DTSS_ADDRESSU,D3DTADDRESS_CLAMP);
CSceneStateMgr::_SetD3DTextureStageState(2,D3DTSS_ADDRESSV,D3DTADDRESS_CLAMP);
CSceneStateMgr::_SetD3DTextureStageState(2,D3DTSS_ADDRESSW,D3DTADDRESS_CLAMP);
CSceneStateMgr::_SetD3DTextureStageState(3,D3DTSS_ADDRESSU,D3DTADDRESS_CLAMP);
CSceneStateMgr::_SetD3DTextureStageState(3,D3DTSS_ADDRESSV,D3DTADDRESS_CLAMP);
CSceneStateMgr::_SetD3DTextureStageState(3,D3DTSS_ADDRESSW,D3DTADDRESS_CLAMP);
pd3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,0,
m_ShaderList[cShader].m_nVertex,0,
m_ShaderList[cShader].m_nDrawIndices/3);
CSceneStateMgr::_SetD3DTextureStageState(0,D3DTSS_ADDRESSU,D3DTADDRESS_WRAP);
CSceneStateMgr::_SetD3DTextureStageState(0,D3DTSS_ADDRESSV,D3DTADDRESS_WRAP);
CSceneStateMgr::_SetD3DTextureStageState(0,D3DTSS_ADDRESSW,D3DTADDRESS_WRAP);
CSceneStateMgr::_SetD3DTextureStageState(1,D3DTSS_ADDRESSU,D3DTADDRESS_WRAP);
CSceneStateMgr::_SetD3DTextureStageState(1,D3DTSS_ADDRESSV,D3DTADDRESS_WRAP);
CSceneStateMgr::_SetD3DTextureStageState(1,D3DTSS_ADDRESSW,D3DTADDRESS_WRAP);
CSceneStateMgr::_SetD3DTextureStageState(2,D3DTSS_ADDRESSU,D3DTADDRESS_WRAP);
CSceneStateMgr::_SetD3DTextureStageState(2,D3DTSS_ADDRESSV,D3DTADDRESS_WRAP);
CSceneStateMgr::_SetD3DTextureStageState(2,D3DTSS_ADDRESSW,D3DTADDRESS_WRAP);
CSceneStateMgr::_SetD3DTextureStageState(3,D3DTSS_ADDRESSU,D3DTADDRESS_WRAP);
CSceneStateMgr::_SetD3DTextureStageState(3,D3DTSS_ADDRESSV,D3DTADDRESS_WRAP);
CSceneStateMgr::_SetD3DTextureStageState(3,D3DTSS_ADDRESSW,D3DTADDRESS_WRAP);
CSceneStateMgr::_SetD3DRenderState(D3DRS_ZWRITEENABLE,TRUE);
CSceneStateMgr::_SetD3DRenderState( D3DRS_ALPHABLENDENABLE,FALSE);
CSceneStateMgr::_SetD3DRenderState(D3DRS_STENCILENABLE,FALSE);
}
m_ShaderList[pSurface->m_nShader].m_ApplyLightList.num=0;
m_ShaderList[cShader].m_nDrawIndices=0;
}
/*
for(cShader=0;cShader<m_ShaderList.num;cShader++)
{
if(m_ShaderList[cShader].m_nDrawIndices==0)
continue;
pd3dDevice->SetTexture(0,m_ShaderList[cShader].m_DiffuseTexture->GetTexture());
matrix matView,matProjection,matWorld,matWVP;
pd3dDevice->GetTransform(D3DTS_VIEW,matView);
pd3dDevice->GetTransform(D3DTS_PROJECTION,matProjection);
pd3dDevice->GetTransform(D3DTS_WORLD,matWorld);
matWVP=matWorld*matView*matProjection;
matWVP.Transpose();
pd3dDevice->SetVertexShaderConstant(16,&matWVP, 4);
//pd3dDevice->SetVertexShader(BSPVERTEXFVF);
//Ambient Base Light
pd3dDevice->SetVertexShader(m_dwBSPAmbientVertexShader);
pd3dDevice->SetPixelShader(m_dwBSPAmbientPixelShader);
CSceneStateMgr::_SetD3DRenderState( D3DRS_ALPHABLENDENABLE,FALSE);
CSceneStateMgr::_SetD3DRenderState( D3DRS_FOGENABLE,FALSE);
CSceneStateMgr::_SetD3DRenderState(D3DRS_ZWRITEENABLE,TRUE);
pd3dDevice->SetStreamSource(0,m_ShaderList[cShader].m_pVertexBuffer,sizeof(BspVertex));
pd3dDevice->SetIndices(m_ShaderList[cShader].m_pIndicesBuffer,0);
pd3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,0,
m_ShaderList[cShader].m_nVertex,0,
m_ShaderList[cShader].m_nDrawIndices/3);
for(int cLight=0;cLight<m_ShaderList[cShader].m_ApplyLightList.num;cLight++)
{
pd3dDevice->Clear( 0L, NULL, D3DCLEAR_STENCIL , 0x000000ff, 1.0f, 0x80L );
CSceneStateMgr::_SetD3DRenderState(D3DRS_COLORWRITEENABLE,0);
CSceneStateMgr::_SetD3DRenderState(D3DRS_ZWRITEENABLE,TRUE);
CSceneStateMgr::_SetD3DRenderState(D3DRS_STENCILENABLE,TRUE);
CSceneStateMgr::_SetD3DRenderState( D3DRS_STENCILFUNC, D3DCMP_ALWAYS );
CSceneStateMgr::_SetD3DRenderState( D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP );
CSceneStateMgr::_SetD3DRenderState( D3DRS_STENCILPASS, D3DSTENCILOP_KEEP );
// If ztest passes, inc/decrement stencil buffer value
CSceneStateMgr::_SetD3DRenderState( D3DRS_STENCILREF, 0x1 );
CSceneStateMgr::_SetD3DRenderState( D3DRS_STENCILMASK, 0xffffffff );
CSceneStateMgr::_SetD3DRenderState( D3DRS_STENCILWRITEMASK, 0xffffffff );
pd3dDevice->SetPixelShader(NULL);
CSceneStateMgr::_SetD3DTextureStageState(0,D3DTSS_COLORARG1,D3DTA_TFACTOR);
CSceneStateMgr::_SetD3DTextureStageState(0,D3DTSS_COLOROP,D3DTOP_SELECTARG1);
CSceneStateMgr::_SetD3DTextureStageState(1,D3DTSS_COLOROP,D3DTOP_DISABLE);
CSceneStateMgr::_SetD3DRenderState(D3DRS_TEXTUREFACTOR,0xffff0000);
DLightEx *pLight=&m_LightEx[m_ShaderList[cShader].m_ApplyLightList[cLight]];
vector3 vecLightPosition=pLight->m_pLight->m_vecLightPos;
static float fRate=0.0f;
fRate+=0.05f;
vecLightPosition.x+=sinf(fRate)*100.0f;
vecLightPosition.z+=cosf(fRate)*100.0f;
vecLightPosition.y+=cosf(fRate)*100.0f;
CSceneStateMgr::_SetD3DRenderState( D3DRS_STENCILZFAIL,D3DSTENCILOP_KEEP);
CSceneStateMgr::_SetD3DRenderState(D3DRS_ZWRITEENABLE,FALSE);
for(int cShadowSurface=0;cShadowSurface<pLight->m_ApplySurface.num;cShadowSurface++)
{
float fLightPos[4]={vecLightPosition.x,
vecLightPosition.y,
vecLightPosition.z,1.0f};
pd3dDevice->SetVertexShaderConstant(10,fLightPos,1);
pd3dDevice->SetVertexShaderConstant(1,&matWVP, 4);
//CSceneStateMgr::_SetD3DRenderState( D3DRS_STENCILZFAIL,D3DSTENCILOP_INCR);
CSceneStateMgr::_SetD3DRenderState(D3DRS_ZFUNC,D3DCMP_LESS);
CSceneStateMgr::_SetD3DRenderState( D3DRS_STENCILPASS,D3DSTENCILOP_INCR);
CSceneStateMgr::_SetD3DRenderState(D3DRS_CULLMODE,D3DCULL_CCW);
if(m_DSurfaceEx[pLight->m_ApplySurface[cShadowSurface]].m_pShadowVertexBuffer)
{
pd3dDevice->SetStreamSource(0,m_DSurfaceEx[pLight->m_ApplySurface[cShadowSurface]].m_pShadowVertexBuffer,sizeof(BspShadowVertex));
pd3dDevice->SetIndices(NULL,0);
pd3dDevice->SetVertexShader(m_dwBSPShadowVertexShader);
pd3dDevice->DrawPrimitive(D3DPT_TRIANGLELIST,0,m_DSurfaceEx[pLight->m_ApplySurface[cShadowSurface]].m_nShadowVertex/3);
}
CSceneStateMgr::_SetD3DRenderState(D3DRS_CULLMODE,D3DCULL_CW);
CSceneStateMgr::_SetD3DRenderState( D3DRS_STENCILPASS, D3DSTENCILOP_DECR);
//CSceneStateMgr::_SetD3DRenderState( D3DRS_STENCILZFAIL,D3DSTENCILOP_INCR);
//CSceneStateMgr::_SetD3DRenderState( D3DRS_STENCILZFAIL, D3DSTENCILOP_DECR );
//CSceneStateMgr::_SetD3DRenderState(D3DRS_STENCILZFAIL,D3DSTENCILOP_DECRSAT);
if(m_DSurfaceEx[pLight->m_ApplySurface[cShadowSurface]].m_pShadowVertexBuffer)
{
pd3dDevice->SetStreamSource(0,m_DSurfaceEx[pLight->m_ApplySurface[cShadowSurface]].m_pShadowVertexBuffer,sizeof(BspShadowVertex));
pd3dDevice->SetIndices(NULL,0);
pd3dDevice->SetVertexShader(m_dwBSPShadowVertexShader);
pd3dDevice->DrawPrimitive(D3DPT_TRIANGLELIST,0,m_DSurfaceEx[pLight->m_ApplySurface[cShadowSurface]].m_nShadowVertex/3);
}
CSceneStateMgr::_SetD3DRenderState(D3DRS_ZFUNC,D3DCMP_LESSEQUAL);
CSceneStateMgr::_SetD3DRenderState(D3DRS_ZBIAS,0);
}
CSceneStateMgr::_SetD3DRenderState(D3DRS_CULLMODE,D3DCULL_CCW);
CSceneStateMgr::_SetD3DRenderState(D3DRS_COLORWRITEENABLE,D3DCOLORWRITEENABLE_BLUE|D3DCOLORWRITEENABLE_GREEN|D3DCOLORWRITEENABLE_RED);
CSceneStateMgr::_SetD3DRenderState( D3DRS_STENCILREF, 0x80 );
//bool bCollision=TraceLineCollision(m_vecViewPos,vecLightPosition);
TraceT trace;
TraceWorkT tw;
vector3 vecCheckViewPos;
vecCheckViewPos.x=m_vecViewPos.x;
vecCheckViewPos.y=m_vecViewPos.z;
vecCheckViewPos.z=m_vecViewPos.y;
vector3 vecCheckLightPos;
vecCheckLightPos.x=vecLightPosition.x;
vecCheckLightPos.y=vecLightPosition.z;
vecCheckLightPos.z=vecLightPosition.y;
TraceLine(vecCheckViewPos,vecCheckLightPos,&trace,false,&tw);
if(trace.m_bPassSolid)
CSceneStateMgr::_SetD3DRenderState( D3DRS_STENCILFUNC, D3DCMP_GREATER);
else
CSceneStateMgr::_SetD3DRenderState( D3DRS_STENCILFUNC, D3DCMP_EQUAL);
//In Shadow
//CSceneStateMgr::_SetD3DRenderState( D3DRS_STENCILFUNC, D3DCMP_NOTEQUAL);
//out shadow
CSceneStateMgr::_SetD3DRenderState( D3DRS_STENCILPASS, D3DSTENCILOP_KEEP );
CSceneStateMgr::_SetD3DRenderState( D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP );
CSceneStateMgr::_SetD3DRenderState( D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP );
CSceneStateMgr::_SetD3DRenderState(D3DRS_STENCILENABLE,TRUE);
//CSceneStateMgr::_SetD3DRenderState(D3DRS_STENCILENABLE,FALSE);
//CSceneStateMgr::_SetD3DRenderState(D3DRS_STENCILFUNC,D3DCMP_EQUAL);
//CSceneStateMgr::_SetD3DRenderState(D3DRS_STENCILREF ,0x01);
pd3dDevice->SetStreamSource(0,m_ShaderList[cShader].m_pVertexBuffer,sizeof(BspVertex));
pd3dDevice->SetIndices(m_ShaderList[cShader].m_pIndicesBuffer,0);
float fObjectSpaceLightPosition[4]={vecLightPosition.x,
vecLightPosition.y,
vecLightPosition.z,1.0f};
pd3dDevice->SetVertexShaderConstant(32,fObjectSpaceLightPosition,1);
//m_Light[m_ShaderList[cShader].m_ApplyLightList[cLight]].m_fLightRange
float fLightSettingValue[4]={1.0f/4000.0f,0.0f,0.0f,0.0f};
pd3dDevice->SetVertexShaderConstant(33,fLightSettingValue,1);
float fObjectSpaceViewPosition[4]={
m_Camera.m_matPosition.GetLoc().x,
m_Camera.m_matPosition.GetLoc().y,
m_Camera.m_matPosition.GetLoc().z,
0.0f};
pd3dDevice->SetVertexShaderConstant(35,fObjectSpaceViewPosition,1);
float fLightPosAdder[4]={0.5f,0.5f,0.5f,0.5f};
pd3dDevice->SetVertexShaderConstant(36,fLightPosAdder,1);
pd3dDevice->SetTexture(0,m_pPointFalloffMap);
pd3dDevice->SetTexture(1,m_ShaderList[cShader].m_BumpTexture->GetTexture());
pd3dDevice->SetTexture(2,m_pNormalizeCubeMap);
pd3dDevice->SetTexture(3,m_ShaderList[cShader].m_DiffuseTexture->GetTexture());
pd3dDevice->SetVertexShader(m_dwBSPDiffuseVertexShader);
pd3dDevice->SetPixelShader(m_dwBSPDiffusePixelShader);
CSceneStateMgr::_SetD3DRenderState( D3DRS_FOGENABLE,FALSE);
CSceneStateMgr::_SetD3DTextureStageState(0,D3DTSS_ADDRESSU,D3DTADDRESS_MIRROR);
CSceneStateMgr::_SetD3DTextureStageState(0,D3DTSS_ADDRESSV,D3DTADDRESS_MIRROR);
CSceneStateMgr::_SetD3DTextureStageState(0,D3DTSS_ADDRESSW,D3DTADDRESS_MIRROR);
CSceneStateMgr::_SetD3DTextureStageState(2,D3DTSS_ADDRESSU,D3DTADDRESS_CLAMP);
CSceneStateMgr::_SetD3DTextureStageState(2,D3DTSS_ADDRESSV,D3DTADDRESS_CLAMP);
CSceneStateMgr::_SetD3DTextureStageState(2,D3DTSS_ADDRESSW,D3DTADDRESS_CLAMP);
CSceneStateMgr::_SetD3DRenderState( D3DRS_SRCBLEND,D3DBLEND_ONE);
CSceneStateMgr::_SetD3DRenderState( D3DRS_DESTBLEND,D3DBLEND_ONE);
CSceneStateMgr::_SetD3DRenderState( D3DRS_ALPHABLENDENABLE,TRUE);
CSceneStateMgr::_SetD3DRenderState(D3DRS_ZWRITEENABLE,FALSE);
pd3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,0,
m_ShaderList[cShader].m_nVertex,0,
m_ShaderList[cShader].m_nDrawIndices/3);
pd3dDevice->SetVertexShader(m_dwBSPSpecularVertexShader);
pd3dDevice->SetPixelShader(m_dwBSPSpecularPixelShader);
pd3dDevice->SetTexture(0,m_ShaderList[cShader].m_BumpTexture->GetTexture());
pd3dDevice->SetTexture(1,m_pPointFalloffMap);
pd3dDevice->SetTexture(2,m_pNormalizeCubeMap);
pd3dDevice->SetTexture(3,m_pNormalizeCubeMap);
CSceneStateMgr::_SetD3DTextureStageState(0,D3DTSS_ADDRESSU,D3DTADDRESS_WRAP);
CSceneStateMgr::_SetD3DTextureStageState(0,D3DTSS_ADDRESSV,D3DTADDRESS_WRAP);
CSceneStateMgr::_SetD3DTextureStageState(0,D3DTSS_ADDRESSW,D3DTADDRESS_WRAP);
CSceneStateMgr::_SetD3DTextureStageState(1,D3DTSS_ADDRESSU,D3DTADDRESS_MIRROR);
CSceneStateMgr::_SetD3DTextureStageState(1,D3DTSS_ADDRESSV,D3DTADDRESS_MIRROR);
CSceneStateMgr::_SetD3DTextureStageState(1,D3DTSS_ADDRESSW,D3DTADDRESS_MIRROR);
CSceneStateMgr::_SetD3DTextureStageState(2,D3DTSS_ADDRESSU,D3DTADDRESS_CLAMP);
CSceneStateMgr::_SetD3DTextureStageState(2,D3DTSS_ADDRESSV,D3DTADDRESS_CLAMP);
CSceneStateMgr::_SetD3DTextureStageState(2,D3DTSS_ADDRESSW,D3DTADDRESS_CLAMP);
CSceneStateMgr::_SetD3DTextureStageState(3,D3DTSS_ADDRESSU,D3DTADDRESS_CLAMP);
CSceneStateMgr::_SetD3DTextureStageState(3,D3DTSS_ADDRESSV,D3DTADDRESS_CLAMP);
CSceneStateMgr::_SetD3DTextureStageState(3,D3DTSS_ADDRESSW,D3DTADDRESS_CLAMP);
pd3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,0,
m_ShaderList[cShader].m_nVertex,0,
m_ShaderList[cShader].m_nDrawIndices/3);
CSceneStateMgr::_SetD3DTextureStageState(0,D3DTSS_ADDRESSU,D3DTADDRESS_WRAP);
CSceneStateMgr::_SetD3DTextureStageState(0,D3DTSS_ADDRESSV,D3DTADDRESS_WRAP);
CSceneStateMgr::_SetD3DTextureStageState(0,D3DTSS_ADDRESSW,D3DTADDRESS_WRAP);
CSceneStateMgr::_SetD3DTextureStageState(1,D3DTSS_ADDRESSU,D3DTADDRESS_WRAP);
CSceneStateMgr::_SetD3DTextureStageState(1,D3DTSS_ADDRESSV,D3DTADDRESS_WRAP);
CSceneStateMgr::_SetD3DTextureStageState(1,D3DTSS_ADDRESSW,D3DTADDRESS_WRAP);
CSceneStateMgr::_SetD3DTextureStageState(2,D3DTSS_ADDRESSU,D3DTADDRESS_WRAP);
CSceneStateMgr::_SetD3DTextureStageState(2,D3DTSS_ADDRESSV,D3DTADDRESS_WRAP);
CSceneStateMgr::_SetD3DTextureStageState(2,D3DTSS_ADDRESSW,D3DTADDRESS_WRAP);
CSceneStateMgr::_SetD3DTextureStageState(3,D3DTSS_ADDRESSU,D3DTADDRESS_WRAP);
CSceneStateMgr::_SetD3DTextureStageState(3,D3DTSS_ADDRESSV,D3DTADDRESS_WRAP);
CSceneStateMgr::_SetD3DTextureStageState(3,D3DTSS_ADDRESSW,D3DTADDRESS_WRAP);
CSceneStateMgr::_SetD3DRenderState(D3DRS_ZWRITEENABLE,TRUE);
CSceneStateMgr::_SetD3DRenderState( D3DRS_ALPHABLENDENABLE,FALSE);
CSceneStateMgr::_SetD3DRenderState(D3DRS_STENCILENABLE,FALSE);
}
m_ShaderList[pSurface->m_nShader].m_ApplyLightList.num=0;
m_ShaderList[cShader].m_nDrawIndices=0;
}
*/
/*
for(int i=0;i<m_nShader;i++)
{
if(strstr(m_Shaders[i].m_strTextureName,"sky")!=NULL)
{
bSkyRender=true;
}
else
bSkyRender=false;
pd3dDevice->SetTexture(0,m_TextureList[i]->GetTexture());
//for(int cLightmap=0;cLightmap<m_LightmapList.num;cLightmap++)
for(int cLightmap=0;cLightmap<m_nLightmap;cLightmap++)
{
if(m_RenderSurfacesList.nSurfaces[i][cLightmap]==0)
continue;
if(bSkyRender==true)
{
m_bSkyRender=true;
continue;
}
m_pVertexBuffer->Lock(0,0,(BYTE**)&pVertex,D3DLOCK_DISCARD);
m_pIndicesBuffer->Lock(0,m_nMaxIndices*sizeof(WORD),(BYTE**)&pIndices,D3DLOCK_DISCARD);
int cTotalVertex=0;
int cTotalIndex=0;
int cSurfaceVertex=0;
if(m_bLightmapVector)
{
//pd3dDevice->SetTexture(1,m_LightmapVectorList[cLightmap]->GetTexture());
}
else
{
//pd3dDevice->SetTexture(1,m_LightmapList[cLightmap]->GetTexture());
}
pd3dDevice->SetTexture(1,NULL);
for(int cSurface=0;cSurface<m_RenderSurfacesList.nSurfaces[i][cLightmap];cSurface++)
{
pSurface=&m_DrawSurfaces[m_RenderSurfacesList.pDrawSurfaces[i][cLightmap][cSurface]];
if(pSurface->m_SurfaceType==0)
{
for(int cVertex=0;cVertex<pSurface->m_nVerts;cVertex++)
{
pVertex[cTotalVertex].v.x=m_DrawVerts[pSurface->m_FirstVert+cVertex].v.x;
pVertex[cTotalVertex].v.y=m_DrawVerts[pSurface->m_FirstVert+cVertex].v.z;
pVertex[cTotalVertex].v.z=m_DrawVerts[pSurface->m_FirstVert+cVertex].v.y;
pVertex[cTotalVertex].normal.x=m_DrawVerts[pSurface->m_FirstVert+cVertex].normal.x;
pVertex[cTotalVertex].normal.y=m_DrawVerts[pSurface->m_FirstVert+cVertex].normal.z;
pVertex[cTotalVertex].normal.z=m_DrawVerts[pSurface->m_FirstVert+cVertex].normal.y;
pVertex[cTotalVertex].tu=m_DrawVerts[pSurface->m_FirstVert+cVertex].tu;
pVertex[cTotalVertex].tv=m_DrawVerts[pSurface->m_FirstVert+cVertex].tv;
pVertex[cTotalVertex].tu1=m_DrawVerts[pSurface->m_FirstVert+cVertex].tu1;
pVertex[cTotalVertex].tv1=m_DrawVerts[pSurface->m_FirstVert+cVertex].tv1;
pVertex[cTotalVertex].diff.c=0xffffffff;
pVertex[cTotalVertex].u=m_DrawVerts[pSurface->m_FirstVert+cVertex].u;
cTotalVertex++;
}
for(int cIndices=0;cIndices<pSurface->m_nIndex;cIndices++)
{
pIndices[cTotalIndex]=m_DrawIndex[pSurface->m_FirstIndex+cIndices]+cSurfaceVertex;
cTotalIndex++;
}
cSurfaceVertex+=pSurface->m_nVerts;
}
if(pSurface->m_SurfaceType==1)
{
CurveRenderList.Add(pSurface);
}
}
m_pVertexBuffer->Unlock();
m_pIndicesBuffer->Unlock();
if(cTotalVertex==0)
continue;
pd3dDevice->SetStreamSource(0,m_pVertexBuffer,sizeof(BspVertex));
pd3dDevice->SetIndices(m_pIndicesBuffer,0);
if(CRenderOption::m_BSPDiffusePerPixel)
{
matrix matView,matProjection,matWorld,matWVP;
pd3dDevice->GetTransform(D3DTS_VIEW,matView);
pd3dDevice->GetTransform(D3DTS_PROJECTION,matProjection);
pd3dDevice->GetTransform(D3DTS_WORLD,matWorld);
matWVP=matWorld*matView*matProjection;
matWVP.Transpose();
pd3dDevice->SetVertexShaderConstant(16,&matWVP, 4);
//; 33 - {1/light range, light range, 1/attenuation2, attenuation2}
pd3dDevice->SetTexture(0,m_TextureList[i]->GetTexture());
CSceneStateMgr::_SetD3DTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
CSceneStateMgr::_SetD3DTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
CSceneStateMgr::_SetD3DTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
pd3dDevice->SetVertexShader(BSPVERTEXFVF);
CSceneStateMgr::_SetD3DRenderState(D3DRS_ZWRITEENABLE,TRUE);
pd3dDevice->SetVertexShader(m_dwBSPAmbientVertexShader);
pd3dDevice->SetPixelShader(m_dwBSPAmbientPixelShader);
CSceneStateMgr::_SetD3DRenderState( D3DRS_ALPHABLENDENABLE,FALSE);
CSceneStateMgr::_SetD3DRenderState( D3DRS_FOGENABLE,FALSE);
pd3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,
0,cTotalVertex,
0,cTotalIndex/3);
for(int cLight=0;cLight<m_nLight;cLight++)
{
//m_Light[cLight].m_vecLightPos;
float fObjectSpaceLightPosition[4]={m_Light[cLight].m_vecLightPos.x,m_Light[cLight].m_vecLightPos.y,m_Light[cLight].m_vecLightPos.z,1.0f};
pd3dDevice->SetVertexShaderConstant(32,fObjectSpaceLightPosition,1);
float fLightSettingValue[4]={1.0f/m_Light[cLight].m_fLightRange,0.0f,0.0f,0.0f};
pd3dDevice->SetVertexShaderConstant(33,fLightSettingValue,1);
float fObjectSpaceViewPosition[4]={
m_Camera.m_matPosition.GetLoc().x,
m_Camera.m_matPosition.GetLoc().y,
m_Camera.m_matPosition.GetLoc().z,
0.0f};
pd3dDevice->SetVertexShaderConstant(35,fObjectSpaceViewPosition,1);
float fLightPosAdder[4]={0.5f,0.5f,0.5f,0.5f};
pd3dDevice->SetVertexShaderConstant(36,fLightPosAdder,1);
pd3dDevice->SetTexture(0,m_pPointFalloffMap);
pd3dDevice->SetTexture(1,m_BumpTextureList[i]->GetTexture());
pd3dDevice->SetTexture(2,m_pNormalizeCubeMap);
pd3dDevice->SetTexture(3,m_TextureList[i]->GetTexture());
pd3dDevice->SetVertexShader(m_dwBSPDiffuseVertexShader);
pd3dDevice->SetPixelShader(m_dwBSPDiffusePixelShader);
CSceneStateMgr::_SetD3DRenderState( D3DRS_FOGENABLE,FALSE);
CSceneStateMgr::_SetD3DTextureStageState(0,D3DTSS_ADDRESSU,D3DTADDRESS_MIRROR);
CSceneStateMgr::_SetD3DTextureStageState(0,D3DTSS_ADDRESSV,D3DTADDRESS_MIRROR);
CSceneStateMgr::_SetD3DTextureStageState(0,D3DTSS_ADDRESSW,D3DTADDRESS_MIRROR);
CSceneStateMgr::_SetD3DTextureStageState(2,D3DTSS_ADDRESSU,D3DTADDRESS_CLAMP);
CSceneStateMgr::_SetD3DTextureStageState(2,D3DTSS_ADDRESSV,D3DTADDRESS_CLAMP);
CSceneStateMgr::_SetD3DTextureStageState(2,D3DTSS_ADDRESSW,D3DTADDRESS_CLAMP);
CSceneStateMgr::_SetD3DRenderState( D3DRS_SRCBLEND,D3DBLEND_ONE);
CSceneStateMgr::_SetD3DRenderState( D3DRS_DESTBLEND,D3DBLEND_ONE);
CSceneStateMgr::_SetD3DRenderState( D3DRS_ALPHABLENDENABLE,TRUE);
CSceneStateMgr::_SetD3DRenderState(D3DRS_ZWRITEENABLE,FALSE);
pd3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,
0,cTotalVertex,
0,cTotalIndex/3);
pd3dDevice->SetVertexShader(m_dwBSPSpecularVertexShader);
pd3dDevice->SetPixelShader(m_dwBSPSpecularPixelShader);
pd3dDevice->SetTexture(0,m_BumpTextureList[i]->GetTexture());
pd3dDevice->SetTexture(1,m_pPointFalloffMap);
pd3dDevice->SetTexture(2,m_pNormalizeCubeMap);
pd3dDevice->SetTexture(3,m_pNormalizeCubeMap);
CSceneStateMgr::_SetD3DTextureStageState(0,D3DTSS_ADDRESSU,D3DTADDRESS_WRAP);
CSceneStateMgr::_SetD3DTextureStageState(0,D3DTSS_ADDRESSV,D3DTADDRESS_WRAP);
CSceneStateMgr::_SetD3DTextureStageState(0,D3DTSS_ADDRESSW,D3DTADDRESS_WRAP);
CSceneStateMgr::_SetD3DTextureStageState(1,D3DTSS_ADDRESSU,D3DTADDRESS_MIRROR);
CSceneStateMgr::_SetD3DTextureStageState(1,D3DTSS_ADDRESSV,D3DTADDRESS_MIRROR);
CSceneStateMgr::_SetD3DTextureStageState(1,D3DTSS_ADDRESSW,D3DTADDRESS_MIRROR);
CSceneStateMgr::_SetD3DTextureStageState(2,D3DTSS_ADDRESSU,D3DTADDRESS_CLAMP);
CSceneStateMgr::_SetD3DTextureStageState(2,D3DTSS_ADDRESSV,D3DTADDRESS_CLAMP);
CSceneStateMgr::_SetD3DTextureStageState(2,D3DTSS_ADDRESSW,D3DTADDRESS_CLAMP);
CSceneStateMgr::_SetD3DTextureStageState(3,D3DTSS_ADDRESSU,D3DTADDRESS_CLAMP);
CSceneStateMgr::_SetD3DTextureStageState(3,D3DTSS_ADDRESSV,D3DTADDRESS_CLAMP);
CSceneStateMgr::_SetD3DTextureStageState(3,D3DTSS_ADDRESSW,D3DTADDRESS_CLAMP);
pd3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,
0,cTotalVertex,
0,cTotalIndex/3);
CSceneStateMgr::_SetD3DTextureStageState(0,D3DTSS_ADDRESSU,D3DTADDRESS_WRAP);
CSceneStateMgr::_SetD3DTextureStageState(0,D3DTSS_ADDRESSV,D3DTADDRESS_WRAP);
CSceneStateMgr::_SetD3DTextureStageState(0,D3DTSS_ADDRESSW,D3DTADDRESS_WRAP);
CSceneStateMgr::_SetD3DTextureStageState(1,D3DTSS_ADDRESSU,D3DTADDRESS_WRAP);
CSceneStateMgr::_SetD3DTextureStageState(1,D3DTSS_ADDRESSV,D3DTADDRESS_WRAP);
CSceneStateMgr::_SetD3DTextureStageState(1,D3DTSS_ADDRESSW,D3DTADDRESS_WRAP);
CSceneStateMgr::_SetD3DTextureStageState(2,D3DTSS_ADDRESSU,D3DTADDRESS_WRAP);
CSceneStateMgr::_SetD3DTextureStageState(2,D3DTSS_ADDRESSV,D3DTADDRESS_WRAP);
CSceneStateMgr::_SetD3DTextureStageState(2,D3DTSS_ADDRESSW,D3DTADDRESS_WRAP);
CSceneStateMgr::_SetD3DTextureStageState(3,D3DTSS_ADDRESSU,D3DTADDRESS_WRAP);
CSceneStateMgr::_SetD3DTextureStageState(3,D3DTSS_ADDRESSV,D3DTADDRESS_WRAP);
CSceneStateMgr::_SetD3DTextureStageState(3,D3DTSS_ADDRESSW,D3DTADDRESS_WRAP);
CSceneStateMgr::_SetD3DRenderState(D3DRS_ZWRITEENABLE,TRUE);
}
}
else
{
pd3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,
0,cTotalVertex,
0,cTotalIndex/3);
}
CSceneManager::m_cRenderPolygon++;
}
}
for(i=0;i<CurveRenderList.num;i++)
{
for(int j=0;j<m_CurveBufferList.num;j++)
{
if(m_CurveBufferList[j]->m_pSurface==CurveRenderList[i])
{
pd3dDevice->SetTexture(0,m_TextureList[m_CurveBufferList[j]->m_pSurface->m_nShader]->GetTexture());
pd3dDevice->SetTexture(1,m_LightmapList[m_CurveBufferList[j]->m_pSurface->m_nLightmap]->GetTexture());
//pd3dDevice->SetTexture(1,NULL);
m_CurveBufferList[j]->Render(pd3dDevice);
}
}
}
*/
}
bool CBspScene::LeafInFrustum(vector3 &vecMax, vector3 &vecMin)
{
return true;
}
void CBspScene::CullPoly(vector3 vecMax, vector3 vecMin,List<vector3> &PolyList)
{
vector3 vecCenter=(vecMax+vecMin)/2.0f;
m_EyeCluster=FindCluster(vecCenter);
memset(m_SurfaceInc,0,sizeof(int)*m_nDrawSurfaces);
m_vecCenter=vecCenter;
m_vecMax=vecMax;
m_vecMin=vecMin;
CullWalkNodes(0);
}
void CBspScene::CullWalkNodes(int n)
{
DNode *pNode=&m_Nodes[n];
vector3 MinNodeBox;
vector3 MaxNodeBox;
MinNodeBox.x=pNode->m_min.x;
MinNodeBox.y=pNode->m_min.z;
MinNodeBox.z=pNode->m_min.y;
MaxNodeBox.x=pNode->m_max.x;
MaxNodeBox.y=pNode->m_max.z;
MaxNodeBox.z=pNode->m_max.y;
if( m_vecMin.x >= MaxNodeBox.x ||
m_vecMax.x <= MinNodeBox.x ||
m_vecMin.y >= MaxNodeBox.y ||
m_vecMax.y <= MinNodeBox.y ||
m_vecMin.z >= MaxNodeBox.z ||
m_vecMax.z <= MinNodeBox.z )
{
return;
}
if(ClassfyPoint(m_vecCenter,pNode->m_nPlane)>0)
{
if(pNode->m_Children[0]<0)
CullWalkLeaf(-(pNode->m_Children[0]+1));
else
CullWalkNodes(pNode->m_Children[0]);
if(pNode->m_Children[1]<0)
CullWalkLeaf(-(pNode->m_Children[1]+1));
else
CullWalkNodes(pNode->m_Children[1]);
}
else
{
if(pNode->m_Children[1]<0)
CullWalkLeaf(-(pNode->m_Children[1]+1));
else
CullWalkNodes(pNode->m_Children[1]);
if(pNode->m_Children[0]<0)
CullWalkLeaf(-(pNode->m_Children[0]+1));
else
CullWalkNodes(pNode->m_Children[0]);
}
}
void CBspScene::CullWalkLeaf(int n)
{
DLeaf *pLeaf=&m_Leafs[n];
if(m_EyeCluster >= 0)
{
if(!BSP_TESTVIS(m_EyeCluster,pLeaf->m_Cluster))
return;
}
vector3 MinLeafBox;
vector3 MaxLeafBox;
MinLeafBox.x=pLeaf->m_min.x;
MinLeafBox.y=pLeaf->m_min.z;
MinLeafBox.z=pLeaf->m_min.y;
MaxLeafBox.x=pLeaf->m_max.x;
MaxLeafBox.y=pLeaf->m_max.z;
MaxLeafBox.z=pLeaf->m_max.y;
if( m_vecMin.x >= MaxLeafBox.x ||
m_vecMax.x <= MinLeafBox.x ||
m_vecMin.y >= MaxLeafBox.y ||
m_vecMax.y <= MinLeafBox.y ||
m_vecMin.z >= MaxLeafBox.z ||
m_vecMax.z <= MinLeafBox.z )
{
return;
}
int nSurface;
for(int i=0;i<pLeaf->m_nLeafSurfaces;i++)
{
nSurface=m_LeafSurfaces[i+pLeaf->m_FirstLeafSurface];
if(m_SurfaceInc[nSurface])
{
continue;
}
if( m_vecMin.x >= m_pSurfaceMaxBox[nSurface].x ||
m_vecMax.x <= m_pSurfaceMinBox[nSurface].x ||
m_vecMin.y >= m_pSurfaceMaxBox[nSurface].z ||
m_vecMax.y <= m_pSurfaceMinBox[nSurface].z ||
m_vecMin.z >= m_pSurfaceMaxBox[nSurface].y ||
m_vecMax.z <= m_pSurfaceMinBox[nSurface].y )
{
m_SurfaceInc[nSurface]=2;
}
else
{
m_SurfaceInc[nSurface]=1;
}
//RenderWalkFace(m_LeafSurfaces[i+pLeaf->m_FirstLeafSurface]);
}
}
void CBspScene::CurveBuffer::CreateCurveBuffer(DSurface *pSurface, BspVertex *pControlPointVertex)
{
//pSurface->
m_pSurface=pSurface;
m_pControlPoint=new vector3[m_pSurface->m_nVerts];
for(int i=0;i<m_pSurface->m_nVerts;i++)
{
m_pControlPoint[i]=pControlPointVertex[m_pSurface->m_FirstVert+i].v;
}
FindSize();
int len=m_PatchSizeWidth*m_PatchSizeHeight;
vector3 *Point=new vector3[len];
vector2 *TextureUV=new vector2[len];
vector2 *LightmapUV=new vector2[len];
m_pVertex=new BspVertex[len];
//m_pVertex=new BspVertex[len];
int StepWidth,StepHeight;
StepWidth=(m_PatchSizeWidth-1)/(m_pSurface->m_PatchWidth-1);
StepHeight=(m_PatchSizeHeight-1)/(m_pSurface->m_PatchHeight-1);
BspVertex *pVert=pControlPointVertex+m_pSurface->m_FirstVert;
for(int v=0;v<m_PatchSizeHeight;v+=StepHeight)
{
for(int u=0;u<m_PatchSizeWidth;u+=StepWidth)
{
int p=v*m_PatchSizeWidth+u;
Point[p]=pVert->v;
TextureUV[p][0]=pVert->tu;
TextureUV[p][1]=pVert->tv;
LightmapUV[p][0]=pVert->tu1;
LightmapUV[p][1]=pVert->tv1;
pVert++;
}
}
int CP[2],Size[2];
CP[0]=m_pSurface->m_PatchWidth;
CP[1]=m_pSurface->m_PatchHeight;
Size[0]=m_PatchSizeWidth;
Size[1]=m_PatchSizeHeight;
FillPatch3(CP,Size,Point);
FillPatch2(CP,Size,TextureUV);
FillPatch2(CP,Size,LightmapUV);
for(i=0;i<len;i++)
{
m_pVertex[i].v.x=Point[i].x;
m_pVertex[i].v.y=Point[i].z;
m_pVertex[i].v.z=Point[i].y;
m_pVertex[i].tu=TextureUV[i][0];
m_pVertex[i].tv=TextureUV[i][1];
m_pVertex[i].tu1=LightmapUV[i][0];
m_pVertex[i].tv1=LightmapUV[i][1];
}
delete [] Point;
delete [] TextureUV;
delete [] LightmapUV;
m_nIndices=(m_PatchSizeWidth-1)*(m_PatchSizeHeight-1)*6;
m_pIndices=new WORD[m_nIndices];
i=0;
for(v=0;v<m_PatchSizeHeight-1;++v)
{
for(int u=0;u<m_PatchSizeWidth-1;++u)
{
m_pIndices[i++]=v*m_PatchSizeWidth+u;
m_pIndices[i++]=(v+1)*m_PatchSizeWidth+u;
m_pIndices[i++]=v*m_PatchSizeWidth+u+1;
m_pIndices[i++]=v*m_PatchSizeWidth+u+1;
m_pIndices[i++]=(v+1)*m_PatchSizeWidth+u;
m_pIndices[i++]=(v+1)*m_PatchSizeWidth+u+1;
}
}
/*
FillCurve
*/
}
const int MAX_MESHLEVEL=10;
const float SUBDIVISIONTOL=5.0f;
#define LEVEL_WIDTH(lvl) ((1 << (lvl+1)) + 1)
void CBspScene::CurveBuffer::FindSize()
{
float *a,*b;
bool bFound=false;
for(int v=0;v<m_pSurface->m_PatchHeight;v++)
{
for(int u=0;u<m_pSurface->m_PatchWidth-1;u+=2)
{
a=(float*)&m_pControlPoint[v*m_pSurface->m_PatchWidth+u];
b=(float*)&m_pControlPoint[v*m_pSurface->m_PatchWidth+u+2];
if(!(a==b))
{
bFound=true;
break;
}
}
if(bFound)
break;
}
vector3 test[3];
test[0].x=*(a);
test[0].y=*(a+1);
test[0].z=*(a+2);
test[1].x=*(a+3);
test[1].y=*(a+4);
test[1].z=*(a+5);
test[2].x=*(b);
test[2].y=*(b+1);
test[2].z=*(b+2);
int level=FindLevel(test);
m_PatchSizeWidth=(LEVEL_WIDTH(level)-1)*((m_pSurface->m_PatchWidth-1)/2)+1;
bFound=false;
for(int u=0;u<m_pSurface->m_PatchWidth;u++)
{
for(int v=0;v<m_pSurface->m_PatchHeight-1;v+=2)
{
a=(float*)&m_pControlPoint[v*m_pSurface->m_PatchWidth+u];
b=(float*)&m_pControlPoint[(v+2)*m_pSurface->m_PatchWidth+u];
if(!(a==b))
{
bFound=true;
break;
}
}
if(bFound)
break;
}
test[0].x=*(a);
test[0].y=*(a+1);
test[0].z=*(a+2);
test[1].x=*(a+m_pSurface->m_PatchWidth*3);
test[1].y=*(a+m_pSurface->m_PatchWidth*3+1);
test[1].z=*(a+m_pSurface->m_PatchWidth*3+2);
test[2].x=*(b);
test[2].y=*(b+1);
test[2].z=*(b+2);
level=FindLevel(test);
m_PatchSizeHeight=(LEVEL_WIDTH(level)-1)*((m_pSurface->m_PatchHeight-1)/2)+1;
}
int CBspScene::CurveBuffer::FindLevel(vector3 *v)
{
int level;
vector3 a,b,dist;
for(level=0;level<MAX_MESHLEVEL-1;level++)
{
a=(v[0]+v[1])*0.5f;
b=(v[1]+v[2])*0.5f;
v[2]=(a+b)*0.5f;
dist=v[2]-v[1];
if(dist*dist < SUBDIVISIONTOL*SUBDIVISIONTOL )
break;
v[1]=a;
}
return level;
}
void CBspScene::CurveBuffer::FillPatchVertex()
{
}
void CBspScene::CurveBuffer::FillCurve2(int numcp, int size, int stride, vector2 *p)
{
int step,halfstep,i,mid;
vector2 a,b;
step=(size-1)/(numcp-1);
while(step>0)
{
halfstep=step/2;
for(i=0;i<size-1;i+=step*2)
{
mid=(i+step)*stride;
a[0]=(p[i*stride][0]+p[mid][0])*0.5f;
a[1]=(p[i*stride][1]+p[mid][1])*0.5f;
b[0]=(p[mid][0] + p[(i+step*2)*stride][0] )*0.5f;
b[1]=(p[mid][1] + p[(i+step*2)*stride][1] )*0.5f;
p[mid][0]=(a[0]+b[0])*0.5f;
p[mid][1]=(a[1]+b[1])*0.5f;
if(halfstep > 0)
{
p[(i+halfstep)*stride][0]=a[0];
p[(i+halfstep)*stride][1]=a[1];
p[(i+3*halfstep)*stride][0]=b[0];
p[(i+3*halfstep)*stride][1]=b[1];
}
}
step/=2;
}
}
void CBspScene::CurveBuffer::FillCurve3(int numcp, int size, int stride, vector3 *p)
{
int step,halfstep,i,mid;
vector3 a,b;
step = (size-1) / (numcp-1);
while(step>0)
{
halfstep=step/2;
for(i=0;i<size-1;i+=step*2)
{
mid=(i+step)*stride;
a=(p[i*stride]+p[mid])*0.5f;
b=(p[mid]+p[(i+step*2)*stride])*0.5f;
p[mid]=(a+b)*0.5f;
if(halfstep>0)
{
p[(i+halfstep)*stride]=a;
p[(i+3*halfstep)*stride]=b;
}
}
step/=2;
}
}
void CBspScene::CurveBuffer::FillPatch2(int *numcp, int *size, vector2 *p)
{
int step,u,v;
step=(size[0]-1)/(numcp[0]-1);
for(u=0;u<size[0];u+=step)
{
FillCurve2(numcp[1],size[1],size[0],p+u);
}
for(v=0;v<size[1];v++)
{
FillCurve2(numcp[0],size[0],1,p+v*size[0]);
}
}
void CBspScene::CurveBuffer::FillPatch3(int *numcp, int *size, vector3 *p)
{
int step,u,v;
step=(size[0]-1)/(numcp[0]-1);
for(u=0;u<size[0];u+=step)
{
FillCurve3(numcp[1],size[1],size[0],p+u);
}
for(v=0;v<size[1];v++)
{
FillCurve3(numcp[0],size[0],1,p+v*size[0]);
}
}
void CBspScene::CurveBuffer::Render(LPDIRECT3DDEVICE8 pd3dDevice)
{
pd3dDevice->SetVertexShader(BSPVERTEXFVF);
pd3dDevice->DrawIndexedPrimitiveUP(D3DPT_TRIANGLELIST,0,m_PatchSizeHeight*m_PatchSizeWidth,
m_nIndices/3,m_pIndices,D3DFMT_INDEX16,m_pVertex,sizeof(BspVertex));
}
void CBspScene::RenderBox(LPDIRECT3DDEVICE8 pd3dDevice,DWORD dwColor)
{
LPDIRECT3DVERTEXBUFFER8 pBoxVB;
MultiVertex *BoxVertex;
LPDIRECT3DINDEXBUFFER8 pBoxIB;
WORD *pIndices;
CSceneManager::GetDevice()->CreateVertexBuffer(8*sizeof(MultiVertex),D3DUSAGE_WRITEONLY,
MultiFVF,D3DPOOL_MANAGED,&pBoxVB);
CSceneManager::GetDevice()->CreateIndexBuffer(24*sizeof(WORD),D3DUSAGE_WRITEONLY,
D3DFMT_INDEX16,D3DPOOL_MANAGED,&pBoxIB);
pBoxVB->Lock(0,0,(BYTE**)&BoxVertex,0);
pBoxIB->Lock(0, 24*sizeof(WORD),(BYTE**)&pIndices,0);
BoxVertex[0].v.x=m_vecMaxBox.x;
BoxVertex[0].v.y=m_vecMaxBox.y;
BoxVertex[0].v.z=m_vecMaxBox.z;
BoxVertex[1].v.x=m_vecMinBox.x;
BoxVertex[1].v.y=m_vecMaxBox.y;
BoxVertex[1].v.z=m_vecMaxBox.z;
BoxVertex[2].v.x=m_vecMaxBox.x;
BoxVertex[2].v.y=m_vecMaxBox.y;
BoxVertex[2].v.z=m_vecMinBox.z;
BoxVertex[3].v.x=m_vecMinBox.x;
BoxVertex[3].v.y=m_vecMaxBox.y;
BoxVertex[3].v.z=m_vecMinBox.z;
BoxVertex[4].v.x=m_vecMaxBox.x;
BoxVertex[4].v.y=m_vecMinBox.y;
BoxVertex[4].v.z=m_vecMaxBox.z;
BoxVertex[5].v.x=m_vecMinBox.x;
BoxVertex[5].v.y=m_vecMinBox.y;
BoxVertex[5].v.z=m_vecMaxBox.z;
BoxVertex[6].v.x=m_vecMaxBox.x;
BoxVertex[6].v.y=m_vecMinBox.y;
BoxVertex[6].v.z=m_vecMinBox.z;
BoxVertex[7].v.x=m_vecMinBox.x;
BoxVertex[7].v.y=m_vecMinBox.y;
BoxVertex[7].v.z=m_vecMinBox.z;
for(int i=0;i<8;i++)
{
BoxVertex[i].diff.c=dwColor;
BoxVertex[i].spec.c=dwColor;
}
*(pIndices++)=0;
*(pIndices++)=1;
*(pIndices++)=1;
*(pIndices++)=3;
*(pIndices++)=3;
*(pIndices++)=2;
*(pIndices++)=2;
*(pIndices++)=0;
*(pIndices++)=4;
*(pIndices++)=5;
*(pIndices++)=5;
*(pIndices++)=7;
*(pIndices++)=7;
*(pIndices++)=6;
*(pIndices++)=6;
*(pIndices++)=4;
*(pIndices++)=0;
*(pIndices++)=4;
*(pIndices++)=1;
*(pIndices++)=5;
*(pIndices++)=3;
*(pIndices++)=7;
*(pIndices++)=2;
*(pIndices++)=6;
pBoxVB->Unlock();
pBoxIB->Unlock();
pd3dDevice->SetTexture(0,NULL);
pd3dDevice->SetTexture(1,NULL);
pd3dDevice->SetVertexShader(MultiFVF);
pd3dDevice->SetStreamSource(0,pBoxVB,sizeof(MultiVertex));
pd3dDevice->SetIndices(pBoxIB,0);
pd3dDevice->DrawIndexedPrimitive(D3DPT_LINELIST,
0,8,
0,12);
pBoxVB->Release();
pBoxIB->Release();
}
void CBspScene::LoadLightmapVector3()
{
m_bLightmapVector=true;
int i=0;
/*
vector3 vecLightmap[128*128];
vector3 *vecLight;
DWORD *pTexture;
color lc;
for(int i=0;i<m_nLightmap;i++)
{
CTexture *AddNode=new CTexture();
m_LightmapVectorList.Add(AddNode);
char strFilename[256];
sprintf(strFilename,"%s\\%s%d.lmd","c:\\","tower3",i);
FILE *fp=fopen(strFilename,"rb");
if(fp==NULL)
return;
fread(vecLightmap,sizeof(vector3)*128*128,1,fp);
fclose(fp);
vecLight=new vector3[128*128];
memcpy(vecLight,vecLightmap,sizeof(vector3)*128*128);
m_vecLightmapList.Add(vecLight);
AddNode->CreateEmpty(128,128);
pTexture=(DWORD*)AddNode->Lock();
for(int ix=0;ix<128;ix++)
{
for(int iy=0;iy<128;iy++)
{
lc.a=0;
if(vecLightmap[ix+iy*128].x>255)
lc.r=255;
else
lc.r=vecLightmap[ix+iy*128].x;
if(vecLightmap[ix+iy*128].y>255)
lc.g=255;
else
lc.g=vecLightmap[ix+iy*128].y;
if(vecLightmap[ix+iy*128].z>255)
lc.b=255;
else
lc.b=vecLightmap[ix+iy*128].z;
pTexture[ix+iy*128]=lc.c;
}
}
AddNode->Unlock();
}
*/
for(i=0;i<m_nLight;i++)
{
m_EditLightList.Add(m_Light[i]);
}
CSceneManager::m_MeshObjectContainer.SetPath(LIGHTOBJECTPATH);
m_pLightObject=CSceneManager::m_MeshObjectContainer.GetMeshObject("lamp_1.R3S");
}
void CBspScene::AddLight(vector3 vecLightPos, float fRange,color clr)
{
}
void CBspScene::UpdateLightmapVector3(int n)
{
}
void CBspScene::RenderLight(LPDIRECT3DDEVICE8 pd3dDevice)
{
matrix matWorld,matPos;
pd3dDevice->GetTransform(D3DTS_WORLD,matWorld);
pd3dDevice->SetPixelShader(NULL);
CSceneStateMgr::_SetD3DRenderState( D3DRS_ALPHABLENDENABLE,FALSE);
for(int i=0;i<m_EditLightList.num;i++)
{
matPos.Translation(m_EditLightList[i].m_vecLightPos);
matPos=matPos*matWorld;
pd3dDevice->SetTransform(D3DTS_WORLD,matPos);
if(m_SelectLight==i)
{
m_pLightObject->RenderBox(pd3dDevice);
}
m_pLightObject->Render(pd3dDevice);
}
pd3dDevice->SetTransform(D3DTS_WORLD,matWorld);
}
void CBspScene::DeleteLight()
{
}
void CBspScene::CullCollisionPoly(vector3 vecPos)
{
}
/*
char strBSPDiffusePixelShader[]=
"ps.1.1\n"
"tex t0\n"// Light Range
"tex t1\n"// normal
"tex t2\n"// Tagent Light
"tex t3\n"// base
"dp3_sat r0,t1_bx2,t2_bx2\n"
"mul r0,r0,t3\n"
"mul_x2 r0,r0,t0.a\n";
*/
char strBSPAmbientPixelShader[]=
"ps.1.1\n"
"def c0, 0.2f, 0.2f, 0.2f, 0.2f\n"
"tex t0\n"
"mul r0,t0,c0\n";
char strBSPAmbientVertexShader[]=
"vs.1.1\n"
"m4x4 oPos, v0, c16\n"
"mov oT0.xy, v7.xy\n";
char strBSPDiffusePixelShader[]=
"ps.1.1\n"
"tex t0\n"// Light Range
"tex t1\n"// normal
"tex t2\n"// Tagent Light
"tex t3\n"// base
"dp3_sat r0,t1_bx2,t2_bx2\n"
"mul r0,r0,t3\n"
"mul_x2 r0,r0,t0.a\n";
//"mov r0,t0.a\n";
char strBSPDiffuseVertexShader[]=
"vs.1.1\n"
"m4x4 oPos, v0, c16\n"
"mov oT1.xy, v7.xy\n"
"mov oT3.xy, v7.xy\n"
"mov r8, v9\n"
"mul r9, r8.yzxw, v3.zxyw\n"
"mad r9, -r8.zxyw, v3.yzxw, r9\n"
"sub r1, c32, v0\n"
"dp3 r5.x, r9, r1\n"
"dp3 r5.y, r8, r1\n"
"dp3 r5.z, v3, r1\n"
"mov oT2.xyz, r5.xyz\n"
"mul oT0.xyz, c33.x, r1\n";
char strBSPSpecularPixelShader[]=
"ps.1.1\n"
"tex t0\n"//Normal
"tex t1\n"//Light Space Position
"tex t2\n"//Tangent Light Direction
"tex t3\n"//Tangent Halfway
"dp3_sat r0,t0_bx2,t3_bx2\n"//N.H
"mul r1,r0,r0\n"
"mul r0,r1,r1\n"
"mul r1,r0,r0\n"
"mul r0,r1,r1\n"
"mul r1,r0,r0\n"
"mul_x2 r0,r1,t1.a\n";
char strBSPSpecularVertexShader[]=
"vs.1.0\n"
"m4x4 oPos, v0, c16\n"
"mov oT0.xy, v7.xy\n" // Texture Coords
"sub r1, c32, v0\n" // Light direction
"mul oT1.xyz, c33.x, r1\n" // Light Space Position
//;r9 = tangent U vector = normal cross tangent V vector
"mov r8, v9\n"
"mul r9, r8.yzxw, v3.zxyw\n"
"mad r9, -r8.zxyw, v3.yzxw, r9\n"
//;r5 = tangent space light vector
"dp3 r5.x, r9, r1\n"
"dp3 r5.y, r8, r1\n"
"dp3 r5.z, v3, r1\n"
"mov oT2.xyz, r5.xyz\n" //Tangent Space Light direction to be renormalized by cube map
"sub r0, c35, v0\n" //Viewer direction
"add r4.xyz, r0.xyz, r1.xyz\n" //Halfway
//;r4 = tangent space halfway vector
"dp3 r6.x, r9, r4\n"
"dp3 r6.y, r8, r4\n"
"dp3 r6.z, v3, r4\n"
"mov oT3.xyz, r6.xyz\n"; // Halfway vector to be renormalized by cube map
//v0 Pos;
//v1 fShadowWeight
//v2 Normal;
//c0 0.0f,0.0f,0.0f,1.0f;
//c1~4 World*View*Projection
//c5~8 World
//c10 LightPos;
//c11 LightRagne,0.0f,0.0f,0.0f;
//*
char strBSPShadowVertexShader[]=
"vs.1.0\n"
"def c0,0.0f,0.0f,0.0f,0.0f"
"sub r0,v0,c10\n"// Light Position - Vertex Position
"dp3 r2.x,r0,r0\n"// Length^2
"rsq r2.y,r2.x\n"// 1/Length
"mul r1,r0,r2.y\n"// LV Normalized
//r1 is Light Position - Vertex Position Normal Vector
"dp3 r3.x,r1,v2\n"
//"sge r3.y,c0.x,r3.x\n"
"sge r3.y,c0.x,r3.x\n"
"mul r4.x,r3.y,v1.x\n"
"mul r3,r1,r4.x\n"// LV*fWeight
"add r0,v0,r3\n"// Pos+LV*fWeight
"m4x4 oPos,r0,c1\n";
/*/
/*
char strBSPShadowVertexShader[]=
"vs.1.0\n"
"def c0,0.0f,0.0f,0.0f,0.0f"
"sub r0,v0,c10\n"// Light Position - Vertex Position
"dp3 r2.x,r0,r0\n"// Length^2
"rsq r2.y,r2.x\n"// 1/Length
"mul r1,r0,r2.y\n"// LV Normalized
//r1 is Light Position - Vertex Position Normal Vector
//"dp3 r3.x,r1,v2\n"
//"sge r3.y,c0.x,r3.x\n"
//"sge r3.y,c0.x,r3.x\n"
//"mul r4.x,r3.y,v1.x\n"
"mov r4.x,v1.x\n"
"mul r3,r1,r4.x\n"// LV*fWeight
"add r0,v0,r3\n"// Pos+LV*fWeight
"m4x4 oPos,r0,c1\n";
*/
/*
// 16 WVP
// 20 WV
// 24 Projection
// 28 Inv WV
// 90 LightRange in x component
// 91 Light Position in View space
char strBSPShadowVertexShader[]=
"vs.1.0\n"
"def c0,0,0,0,1\n"
"m4x4 r0,v0,c20\n"//World * View Transform Vertex
"m3x3 r3,v2,c28\n"//World * View Transform Normal
"sub r1,r0,c91\n"// Light to Vertex in view space
"dp3 r11.x,r1,r1\n"
"rsq r11.y,r11.x\n"
"mul r1,r1,r11.y\n"//normalized Light to Vertex vector
"rcp r11.y,r11.y\n"
"sub r11.z,c90.x,r11.y\n" //light range - len (vLV)
"max r11.z,r11.z,c0.x\n"
"dp3 r10.z,r3,r1\n" // vLV . Normal
"slt r10.x,r10.z,c0.x\n" //
"mad r2,r1,r11.z,r0\n"
"m4x4 r3,r2,c24\n"
"m4x4 r0,v0,c16\n"
"sub r10.y,c0.w,r10.x\n"
"mul r1,r3,r10.y\n"
"mad oPos,r0,r10.x,r1\n";
*/
void CBspScene::InitShader()
{
LPD3DXBUFFER pCode;
DWORD dwDecl[] =
{
D3DVSD_STREAM(0),
D3DVSD_REG(0, D3DVSDT_FLOAT3), // position
D3DVSD_REG(3, D3DVSDT_FLOAT3), // normal
D3DVSD_REG(4, D3DVSDT_D3DCOLOR),//Diffuse Vertex Color
D3DVSD_REG(7, D3DVSDT_FLOAT2), // Diffuse Texture
D3DVSD_REG(8, D3DVSDT_FLOAT2), // Lightmap Texture
D3DVSD_REG(9, D3DVSDT_FLOAT3), // S
D3DVSD_END()
};
D3DXAssembleShader(strBSPAmbientPixelShader,strlen(strBSPAmbientPixelShader),0,NULL,&pCode,NULL);
CSceneManager::GetDevice()->CreatePixelShader((DWORD*)pCode->GetBufferPointer(),&m_dwBSPAmbientPixelShader);
pCode->Release();
D3DXAssembleShader(strBSPAmbientVertexShader,strlen(strBSPAmbientVertexShader),0,NULL,&pCode,NULL);
CSceneManager::GetDevice()->CreateVertexShader( dwDecl, (DWORD*)pCode->GetBufferPointer(), &m_dwBSPAmbientVertexShader, 0 );
pCode->Release();
D3DXAssembleShader(strBSPDiffusePixelShader,strlen(strBSPDiffusePixelShader),0,NULL,&pCode,NULL);
CSceneManager::GetDevice()->CreatePixelShader((DWORD*)pCode->GetBufferPointer(),&m_dwBSPDiffusePixelShader);
pCode->Release();
D3DXAssembleShader(strBSPDiffuseVertexShader,strlen(strBSPDiffuseVertexShader),0,NULL,&pCode,NULL);
CSceneManager::GetDevice()->CreateVertexShader( dwDecl, (DWORD*)pCode->GetBufferPointer(), &m_dwBSPDiffuseVertexShader, 0 );
pCode->Release();
D3DXAssembleShader(strBSPSpecularPixelShader,strlen(strBSPSpecularPixelShader),0,NULL,&pCode,NULL);
CSceneManager::GetDevice()->CreatePixelShader((DWORD*)pCode->GetBufferPointer(),&m_dwBSPSpecularPixelShader);
pCode->Release();
D3DXAssembleShader(strBSPSpecularVertexShader,strlen(strBSPSpecularVertexShader),0,NULL,&pCode,NULL);
CSceneManager::GetDevice()->CreateVertexShader( dwDecl, (DWORD*)pCode->GetBufferPointer(), &m_dwBSPSpecularVertexShader, 0 );
pCode->Release();
DWORD dwShadowDecl[] =
{
D3DVSD_STREAM(0),
D3DVSD_REG(0, D3DVSDT_FLOAT3), // position
D3DVSD_REG(1, D3DVSDT_FLOAT1), // Weight
D3DVSD_REG(2, D3DVSDT_FLOAT3), // Normal;
D3DVSD_END()
};
D3DXAssembleShader(strBSPShadowVertexShader,strlen(strBSPShadowVertexShader),0,NULL,&pCode,NULL);
CSceneManager::GetDevice()->CreateVertexShader( dwShadowDecl, (DWORD*)pCode->GetBufferPointer(), &m_dwBSPShadowVertexShader, 0 );
pCode->Release();
D3DXCreateCubeTextureFromFile(CSceneManager::GetDevice(),"c:/NormalizeCubeMap.dds",&m_pNormalizeCubeMap);
D3DXCreateVolumeTextureFromFile(CSceneManager::GetDevice(),"c:/PointFalloff.dds",&m_pPointFalloffMap);
}
void CBspScene::SurfaceLightArrange()
{
for(int cLight=0;cLight<m_nLight;cLight++)
{
DLightEx AddLight;
AddLight.m_pLight=&m_Light[cLight];
m_LightEx.Add(AddLight);
}
for(int cSurface=0;cSurface<m_nDrawSurfaces;cSurface++)
{
for(int cLight=0;cLight<m_nLight;cLight++)
{
//float fRadius=m_Light[cLight].m_fLightRange;
float fRadius=1000.0f;
vector3 vecMaxBox=m_DSurfaceEx[cSurface]->m_vecMax+vector3(fRadius,fRadius,fRadius);
vector3 vecMinBox=m_DSurfaceEx[cSurface]->m_vecMin-vector3(fRadius,fRadius,fRadius);
bool bBoxIntersection=false;
vector3 vecLightPos=m_Light[cLight].m_vecLightPos;
if( vecMinBox.x <= vecLightPos.x && vecLightPos.x <= vecMaxBox.x &&
vecMinBox.y <= vecLightPos.y && vecLightPos.y <= vecMaxBox.y &&
vecMinBox.z <= vecLightPos.z && vecLightPos.z <= vecMaxBox.z )
{
m_DSurfaceEx[cSurface]->m_ApplyLightList.Add(cLight);
m_LightEx[cLight].m_ApplySurface.AddUnique(cSurface);
}
}
}
for(cLight=0;cLight<m_nLight;cLight++)
{
int nShadowEdge=0;
for(int cSurface=0;cSurface<m_LightEx[cLight].m_ApplySurface.num;cSurface++)
{
nShadowEdge+=m_DSurfaceEx[m_LightEx[cLight].m_ApplySurface[cSurface]]->m_ShadowIndicesList.num;
}
CSceneManager::GetDevice()->CreateIndexBuffer(nShadowEdge*sizeof(WORD),D3DUSAGE_WRITEONLY,D3DFMT_INDEX16,D3DPOOL_MANAGED,&m_LightEx[cLight].m_pEdgeIndexBuffer);
WORD *pIndices;
m_LightEx[cLight].m_pEdgeIndexBuffer->Lock(0,nShadowEdge*sizeof(WORD),(BYTE**)&pIndices,0);
for(cSurface=0;cSurface<m_LightEx[cLight].m_ApplySurface.num;cSurface++)
{
for(int cIndices=0;cIndices<m_DSurfaceEx[m_LightEx[cLight].m_ApplySurface[cSurface]]->m_ShadowIndicesList.num;cIndices++)
{
pIndices[cIndices]=m_DSurfaceEx[m_LightEx[cLight].m_ApplySurface[cSurface]]->m_ShadowIndicesList[cIndices];
}
//mcpy(pIndices,&m_DSurfaceEx[m_LightEx[cLight].m_ApplySurface[cSurface]]->m_ShadowIndicesList.element[0],
//_DSurfaceEx[m_LightEx[cLight].m_ApplySurface[cSurface]]->m_ShadowIndicesList.num);
pIndices+=m_DSurfaceEx[m_LightEx[cLight].m_ApplySurface[cSurface]]->m_ShadowIndicesList.num;
//nShadowEdge+=m_DSurfaceEx[m_LightEx[cLight].m_ApplySurface[cSurface]]->m_ShadowIndicesList.num;
}
m_LightEx[cLight].m_pEdgeIndexBuffer->Unlock();
m_LightEx[cLight].m_nEdgePoly=nShadowEdge;
}
}
void AddEdge(int *pEdges,int &nEdges,int v0,int v1)
{
for(int i=0;i<nEdges;i++)
{
if( (pEdges[2*i+0] == v0 && pEdges[2*i+1] == v1 ) ||
(pEdges[2*i+0] == v1 && pEdges[2*i+1] == v0 ) )
{
if(nEdges>1)
{
pEdges[2*i+0]=pEdges[2*(nEdges-1)+0];
pEdges[2*i+1]=pEdges[2*(nEdges-1)+1];
}
nEdges--;
return;
}
}
pEdges[2*nEdges+0]=v0;
pEdges[2*nEdges+1]=v1;
nEdges++;
}
void CBspScene::CalcShadowVolume(BspVertex *pVertex,int nVertex,int *pIndices,int nIndices,DSurfaceEx &Surface)
{
int *pEdges=new int[nIndices*6];
int nEdges=0;
vector3 n;
int nFace0,nFace1,nFace2;
for(int i=0;i<nIndices/3;i++)
{
nFace0=pIndices[i*3+0];
nFace1=pIndices[i*3+2];
nFace2=pIndices[i*3+1];
vector3 vecNormal(pVertex[nFace0].normal.x,pVertex[nFace0].normal.z,pVertex[nFace0].normal.y);
vector3 vecOrigin(pVertex[nFace0].v.x,pVertex[nFace0].v.z,pVertex[nFace0].v.y);
AddEdge(pEdges,nEdges,nFace0,nFace1);
AddEdge(pEdges,nEdges,nFace1,nFace2);
AddEdge(pEdges,nEdges,nFace2,nFace0);
/*
{
DetectEdge(pEdges,nEdges,nFace0,nFace1,Surface.m_pSurface,vecNormal,vecOrigin);
DetectEdge(pEdges,nEdges,nFace1,nFace2,Surface.m_pSurface,vecNormal,vecOrigin);
DetectEdge(pEdges,nEdges,nFace2,nFace0,Surface.m_pSurface,vecNormal,vecOrigin);
}
*/
}
if(nEdges==0)
return;
Surface.m_nShadowVertex=nEdges*6;
int nVertexPos;
for(int cEdge=0;cEdge<nEdges;cEdge++)
{
BspShadowVertex v1,v2,v3,v4;
v1.v.x=pVertex[pEdges[2*cEdge+0]].v.x;
v1.v.y=pVertex[pEdges[2*cEdge+0]].v.z;
v1.v.z=pVertex[pEdges[2*cEdge+0]].v.y;
v1.n.x=pVertex[pEdges[2*cEdge+0]].normal.x;
v1.n.y=pVertex[pEdges[2*cEdge+0]].normal.z;
v1.n.z=pVertex[pEdges[2*cEdge+0]].normal.y;
v2.v.x=pVertex[pEdges[2*cEdge+1]].v.x;
v2.v.y=pVertex[pEdges[2*cEdge+1]].v.z;
v2.v.z=pVertex[pEdges[2*cEdge+1]].v.y;
v2.n.x=pVertex[pEdges[2*cEdge+1]].normal.x;
v2.n.y=pVertex[pEdges[2*cEdge+1]].normal.z;
v2.n.z=pVertex[pEdges[2*cEdge+1]].normal.y;
v1.fWeight=v2.fWeight=0.0f;
v3.v.x=pVertex[pEdges[2*cEdge+0]].v.x;
v3.v.y=pVertex[pEdges[2*cEdge+0]].v.z;
v3.v.z=pVertex[pEdges[2*cEdge+0]].v.y;
v3.n.x=pVertex[pEdges[2*cEdge+0]].normal.x;
v3.n.y=pVertex[pEdges[2*cEdge+0]].normal.z;
v3.n.z=pVertex[pEdges[2*cEdge+0]].normal.y;
v4.v.x=pVertex[pEdges[2*cEdge+1]].v.x;
v4.v.y=pVertex[pEdges[2*cEdge+1]].v.z;
v4.v.z=pVertex[pEdges[2*cEdge+1]].v.y;
v4.n.x=pVertex[pEdges[2*cEdge+1]].normal.x;
v4.n.y=pVertex[pEdges[2*cEdge+1]].normal.z;
v4.n.z=pVertex[pEdges[2*cEdge+1]].normal.y;
v3.fWeight=v4.fWeight=10000.0f;
/*
m_SurfaceEdgeVertexList.Add(v1);
Surface.m_ShadowIndicesList.Add(m_SurfaceEdgeVertexList.num-1);
m_SurfaceEdgeVertexList.Add(v2);
Surface.m_ShadowIndicesList.Add(m_SurfaceEdgeVertexList.num-1);
m_SurfaceEdgeVertexList.Add(v3);
Surface.m_ShadowIndicesList.Add(m_SurfaceEdgeVertexList.num-1);
m_SurfaceEdgeVertexList.Add(v2);
Surface.m_ShadowIndicesList.Add(m_SurfaceEdgeVertexList.num-1);
m_SurfaceEdgeVertexList.Add(v4);
Surface.m_ShadowIndicesList.Add(m_SurfaceEdgeVertexList.num-1);
m_SurfaceEdgeVertexList.Add(v3);
Surface.m_ShadowIndicesList.Add(m_SurfaceEdgeVertexList.num-1);
*/
nVertexPos=FindShadowEdgeVertex(v1);
if(nVertexPos!=-1)
Surface.m_ShadowIndicesList.Add(nVertexPos);
else
{
m_SurfaceEdgeVertexList.Add(v1);
Surface.m_ShadowIndicesList.Add(m_SurfaceEdgeVertexList.num-1);
}
nVertexPos=FindShadowEdgeVertex(v2);
if(nVertexPos!=-1)
Surface.m_ShadowIndicesList.Add(nVertexPos);
else
{
m_SurfaceEdgeVertexList.Add(v2);
Surface.m_ShadowIndicesList.Add(m_SurfaceEdgeVertexList.num-1);
}
nVertexPos=FindShadowEdgeVertex(v3);
if(nVertexPos!=-1)
Surface.m_ShadowIndicesList.Add(nVertexPos);
else
{
m_SurfaceEdgeVertexList.Add(v3);
Surface.m_ShadowIndicesList.Add(m_SurfaceEdgeVertexList.num-1);
}
nVertexPos=FindShadowEdgeVertex(v2);
if(nVertexPos!=-1)
Surface.m_ShadowIndicesList.Add(nVertexPos);
else
{
m_SurfaceEdgeVertexList.Add(v2);
Surface.m_ShadowIndicesList.Add(m_SurfaceEdgeVertexList.num-1);
}
nVertexPos=FindShadowEdgeVertex(v4);
if(nVertexPos!=-1)
Surface.m_ShadowIndicesList.Add(nVertexPos);
else
{
m_SurfaceEdgeVertexList.Add(v4);
Surface.m_ShadowIndicesList.Add(m_SurfaceEdgeVertexList.num-1);
}
nVertexPos=FindShadowEdgeVertex(v3);
if(nVertexPos!=-1)
Surface.m_ShadowIndicesList.Add(nVertexPos);
else
{
m_SurfaceEdgeVertexList.Add(v3);
Surface.m_ShadowIndicesList.Add(m_SurfaceEdgeVertexList.num-1);
}
}
delete [] pEdges;
}
void CBspScene::DetectEdge(int *pEdges,int &nEdges,int nEdge0, int nEdge1,DSurface *pSrcSurface,vector3 vecPlaneNormal,vector3 vecPlaneOrigin)
{
//DSurface *pSrcSurface=&m_DrawSurfaces[nSurface];
vector3 vecEdgeVertex[2];
vecEdgeVertex[0].x=m_DrawVerts[pSrcSurface->m_FirstVert+nEdge0].v.x;
vecEdgeVertex[0].y=m_DrawVerts[pSrcSurface->m_FirstVert+nEdge0].v.z;
vecEdgeVertex[0].z=m_DrawVerts[pSrcSurface->m_FirstVert+nEdge0].v.y;
vecEdgeVertex[1].x=m_DrawVerts[pSrcSurface->m_FirstVert+nEdge1].v.x;
vecEdgeVertex[1].y=m_DrawVerts[pSrcSurface->m_FirstVert+nEdge1].v.z;
vecEdgeVertex[1].z=m_DrawVerts[pSrcSurface->m_FirstVert+nEdge1].v.y;
float fPlaneDistance[3];
for(int i=0;i<m_nDrawSurfaces;i++)
{
DSurface *pTarSurface=&m_DrawSurfaces[i];
vector3 vecTarVertex[3];
for(int cIndices=0;cIndices<pTarSurface->m_nIndex/3;cIndices++)
{
vecTarVertex[0].x=m_DrawVerts[ pTarSurface->m_FirstVert + m_DrawIndex[pTarSurface->m_FirstIndex+cIndices*3+0] ].v.x;
vecTarVertex[0].y=m_DrawVerts[ pTarSurface->m_FirstVert + m_DrawIndex[pTarSurface->m_FirstIndex+cIndices*3+0] ].v.z;
vecTarVertex[0].z=m_DrawVerts[ pTarSurface->m_FirstVert + m_DrawIndex[pTarSurface->m_FirstIndex+cIndices*3+0] ].v.y;
vecTarVertex[1].x=m_DrawVerts[ pTarSurface->m_FirstVert + m_DrawIndex[pTarSurface->m_FirstIndex+cIndices*3+1] ].v.x;
vecTarVertex[1].y=m_DrawVerts[ pTarSurface->m_FirstVert + m_DrawIndex[pTarSurface->m_FirstIndex+cIndices*3+1] ].v.z;
vecTarVertex[1].z=m_DrawVerts[ pTarSurface->m_FirstVert + m_DrawIndex[pTarSurface->m_FirstIndex+cIndices*3+1] ].v.y;
vecTarVertex[2].x=m_DrawVerts[ pTarSurface->m_FirstVert + m_DrawIndex[pTarSurface->m_FirstIndex+cIndices*3+2] ].v.x;
vecTarVertex[2].y=m_DrawVerts[ pTarSurface->m_FirstVert + m_DrawIndex[pTarSurface->m_FirstIndex+cIndices*3+2] ].v.z;
vecTarVertex[2].z=m_DrawVerts[ pTarSurface->m_FirstVert + m_DrawIndex[pTarSurface->m_FirstIndex+cIndices*3+2] ].v.y;
/*
if( (vecEdgeVertex[0] == vecTarVertex[0] &&
vecEdgeVertex[1] == vecTarVertex[1]) ||
(vecEdgeVertex[1] == vecTarVertex[0] &&
vecEdgeVertex[0] == vecTarVertex[1]) ||
(vecEdgeVertex[1] == vecTarVertex[1] &&
vecEdgeVertex[0] == vecTarVertex[2]) ||
(vecEdgeVertex[1] == vecTarVertex[1] &&
vecEdgeVertex[0] == vecTarVertex[2]) ||
(vecEdgeVertex[0] == vecTarVertex[2] &&
vecEdgeVertex[1] == vecTarVertex[1]) ||
(vecEdgeVertex[1] == vecTarVertex[2] &&
vecEdgeVertex[0] == vecTarVertex[1]) )
*/
if( vecEdgeVertex[0] == vecTarVertex[0] ||
vecEdgeVertex[0] == vecTarVertex[1] ||
vecEdgeVertex[0] == vecTarVertex[2] ||
vecEdgeVertex[1] == vecTarVertex[0] ||
vecEdgeVertex[1] == vecTarVertex[1] ||
vecEdgeVertex[1] == vecTarVertex[2] )
{
fPlaneDistance[0]=CIntersection::PointFromPlane(vecPlaneNormal,vecPlaneOrigin,vecTarVertex[0]);
fPlaneDistance[1]=CIntersection::PointFromPlane(vecPlaneNormal,vecPlaneOrigin,vecTarVertex[1]);
fPlaneDistance[2]=CIntersection::PointFromPlane(vecPlaneNormal,vecPlaneOrigin,vecTarVertex[2]);
if( fPlaneDistance[0] <= -0.0001f ||
fPlaneDistance[1] <= -0.0001f ||
fPlaneDistance[2] <= -0.0001f )
{
/*
static int n=0;
if(n==0 || n==2 || n==3 || n==4)
*/
{
pEdges[nEdges*2+0]=nEdge0;
pEdges[nEdges*2+1]=nEdge1;
nEdges++;
}
//n++;
return;
}
}
}
}
}
bool CBspScene::TraceLineCollision(vector3 &vecStart, vector3 vecEnd)
{
/*
DNode *pNode;
int nCluster=-1;
int nLeaf=-1;
pNode=&m_Nodes[0];
while(1)
{
int nStartPos=ClassfyPoint(vecStart,pNode->m_nPlane);
int nEndPos=ClassfyPoint(vecEnd,pNode->m_nPlane);
if(nStartPos == nEndPos)
{
if(nStartPos>0)
{
if(pNode->m_Children[0] < 0 )
return true;
else
pNode=&m_Nodes[pNode->m_Children[0]];
}
else
{
if(pNode->m_Children[1]<0)
return true;
else
pNode=&m_Nodes[pNode->m_Children[1]];
}
}
else
return false;
}
return false;
//return RecurTraceLine(0,vecStart,vecEnd);
*/
return RecurTraceLine(0,vecStart,vecEnd);
}
bool CBspScene::RecurTraceLine(int nNode,vector3 &vecStart, vector3 &vecEnd)
{
//return false;
DNode *pNode=&m_Nodes[nNode];
int nLeaf;
int nStartPos=ClassfyPoint(vecStart,pNode->m_nPlane);
int nEndPos=ClassfyPoint(vecEnd,pNode->m_nPlane);
if(nStartPos==nEndPos)
{
if(nStartPos>0)
{
if(pNode->m_Children[0]<0)
{
nLeaf=-pNode->m_Children[0]-1;
if(m_Leafs[nLeaf].m_Cluster==-1)
return true;
else
return false;
}
else
return RecurTraceLine(pNode->m_Children[0],vecStart,vecEnd);
}
else
{
if(pNode->m_Children[1]<0)
{
nLeaf=-pNode->m_Children[1]-1;
if(m_Leafs[nLeaf].m_Cluster==-1)
return true;
else
return false;
}
else
return RecurTraceLine(pNode->m_Children[1],vecStart,vecEnd);
}
}
else
{
DPlane *plane=&m_Planes[pNode->m_nPlane];
vector3 vecPlaneNormal;
vecPlaneNormal.x=plane->m_vecNormal.x;
vecPlaneNormal.y=plane->m_vecNormal.z;
vecPlaneNormal.z=plane->m_vecNormal.y;
//float fStartDistance=vecStart*vecPlaneNormal-plane->m_fDist;
float fStartDistance;
vector3 vecDir=vecEnd-vecStart;
vecDir.Normalize();
fStartDistance=((plane->m_fDist)-(vecStart*vecPlaneNormal))/(vecPlaneNormal*vecDir);
fStartDistance=fabsf(fStartDistance);
/*
float h=( (n.x*poly[0].x+n.y*poly[0].y+n.z*poly[0].z) - (n.x*vecStart.x+n.y*vecStart.y+n.z*vecStart.z) )
/ (n.x*vecDir.x + n.y*vecDir.y + n.z*vecDir.z);
fInterLens=h;
*/
//fStartDistance+=1.0f;
vector3 vecMid;
//if(nStartPos > 0 )
fStartDistance-=1.0f;
vecMid=vecStart+(fStartDistance*vecDir);
//else
// vecMid=vecStart+(fStartDistance*vecPlaneNormal);
int nMidPos=ClassfyPoint(vecMid,pNode->m_nPlane);//for debugging
if(RecurTraceLine(nNode,vecStart,vecMid)==true)
return true;
fStartDistance+=2.0f;
vecMid=vecStart+(fStartDistance*vecDir);
/*
if(nStartPos > 0 )
vecMid=vecStart-(fStartDistance*vecPlaneNormal);
else
vecMid=vecStart+(fStartDistance*vecPlaneNormal);
*/
nMidPos=ClassfyPoint(vecMid,pNode->m_nPlane);//for debugging
return RecurTraceLine(nNode,vecMid,vecEnd);
}
}
void CBspScene::InitTrace()
{
m_TNodes=(TNode*)malloc( (MAX_TNODES+1) *sizeof(TNode));
m_TNodes=(TNode*)(((int)m_TNodes+31)&~31);
m_TNodes_p=m_TNodes;
MakeTnode(0);
InitSurfacesForTesting();
}
void CBspScene::MakeTnode(int nodenum)
{
TNode *t;
DPlane *plane;
int i;
DNode *node;
int leafNum;
t=m_TNodes_p++;
node=m_Nodes+nodenum;
plane=m_Planes+node->m_nPlane;
t->m_nPlaneNum=node->m_nPlane;
t->m_Type=PlaneTypeForNormal(plane->m_vecNormal);
t->m_vecNormal=plane->m_vecNormal;
t->m_fDist=plane->m_fDist;
for(i=0;i<2;i++)
{
if(node->m_Children[i]<0)
{
leafNum=-node->m_Children[i]-1;
if(m_Leafs[leafNum].m_Cluster==-1)
{
t->m_Children[i]=leafNum|(1<<31)|(1<<30);
}
else
{
t->m_Children[i]=leafNum|(1<<31);
}
}
else
{
t->m_Children[i]=m_TNodes_p-m_TNodes;
MakeTnode(node->m_Children[i]);
}
}
}
void CBspScene::TraceLine(vector3 &start, vector3 &stop, TraceT *trace, bool testAll, TraceWorkT *tw)
{
int r,i,j;
DLeaf *leaf;
float oldHitFrac;
int surfaceNum;
unsigned char surfaceTested[MAX_MAP_DRAW_SURFS/8];
SurfaceTestT *test;
trace->m_vecFilter.v[0]=1.0f;
trace->m_vecFilter.v[1]=1.0f;
trace->m_vecFilter.v[2]=1.0f;
tw->m_vecStart=start;
tw->m_vecEnd=stop;
tw->m_Trace=trace;
tw->m_nOpenLeafs=0;
trace->m_bPassSolid=false;
trace->m_fHitFraction=1.0f;
//r = TraceLine_r( 0, start, stop, tw );
r=RecurTraceLine(0,start,stop,tw);
if(r && !testAll)
{
return;
}
memset(surfaceTested,0,(m_nDrawSurfaces+7)/8);
oldHitFrac=trace->m_fHitFraction;
for(i=0;i<tw->m_nOpenLeafs;i++)
{
leaf=&m_Leafs[tw->m_OpenLeafNumbers[i]];
for(j=0;j<leaf->m_nLeafSurfaces;j++)
{
surfaceNum=m_LeafSurfaces[leaf->m_FirstLeafSurface+j];
if(surfaceTested[surfaceNum>>3] & (1<<(surfaceNum&7)))
{
continue;
}
surfaceTested[surfaceNum>>3]|=(1<<(surfaceNum&7));
test=m_SurfaceTest[surfaceNum];
if(!test)
continue;
TraceAgainstSurface(tw,test);
}
if(trace->m_fHitFraction < oldHitFrac)
{
trace->m_bPassSolid=true;
break;
}
}
for(i=0;i<3;i++)
{
trace->m_vecHit.v[i]=start.v[i]+(stop.v[i]-start.v[i])*trace->m_fHitFraction;
}
}
int CBspScene::RecurTraceLine(int node, vector3 &start, vector3 &stop, TraceWorkT *tw)
{
TNode *tnode;
float front,back;
vector3 mid;
float frac;
int side;
int r;
if(node & (1<<31))
{
if(node & (1 << 30))
{
tw->m_Trace->m_vecHit=start;
tw->m_Trace->m_bPassSolid=true;
return true;
}
else
{
if(tw->m_nOpenLeafs== MAX_MAP_LEAFS)
{
return false;
}
tw->m_OpenLeafNumbers[tw->m_nOpenLeafs]= node & ~(3 << 30);
tw->m_nOpenLeafs++;
return false;
}
}
tnode=&m_TNodes[node];
switch(tnode->m_Type)
{
case PLANE_X:
front=start.v[0]-tnode->m_fDist;
back=stop.v[0]-tnode->m_fDist;
break;
case PLANE_Y:
front=start.v[1]-tnode->m_fDist;
back=stop.v[1]-tnode->m_fDist;
break;
case PLANE_Z:
front=start.v[2]-tnode->m_fDist;
back=stop.v[2]-tnode->m_fDist;
break;
default:
front=(start*tnode->m_vecNormal)-tnode->m_fDist;
back=(stop*tnode->m_vecNormal)-tnode->m_fDist;
break;
}
if(front>=-TRACE_ON_EPSILON && back>=-TRACE_ON_EPSILON)
{
return RecurTraceLine(tnode->m_Children[0],start,stop,tw);
}
if(front<TRACE_ON_EPSILON && back<TRACE_ON_EPSILON)
{
return RecurTraceLine(tnode->m_Children[1],start,stop,tw);
}
side=front<0;
frac=front/(front-back);
mid.x=start.x+(stop.x-start.x)*frac;
mid.y=start.y+(stop.y-start.y)*frac;
mid.z=start.z+(stop.z-start.z)*frac;
r=RecurTraceLine(tnode->m_Children[side],start,mid,tw);
if(r)
{
return r;
}
return RecurTraceLine(tnode->m_Children[!side],mid,stop,tw);
}
void CBspScene::TraceAgainstSurface(TraceWorkT *tw, SurfaceTestT *surf)
{
int i;
if(SphereCull(tw->m_vecStart,tw->m_vecEnd,surf->m_vecOrigins,surf->m_fRadius))
{
return;
}
for(i=0;i<surf->m_nFacets;i++)
{
TraceAgainstFacet(tw,surf->m_nShader,surf->m_Facets+i);
}
}
bool CBspScene::SphereCull(vector3 &start, vector3 &stop, vector3 &origin, float radius)
{
vector3 v;
float d;
vector3 dir;
float len;
vector3 on;
dir=stop-start;
len=dir.GetLens();
dir.Normalize();
v=origin-start;
d=v*dir;
if(d>len+radius)
return true;
if(d<-radius)
return true;
on=start+d*dir;
v=on-origin;
len=v.GetLens();
if(len>radius)
return true;
return false;
}
void CBspScene::TraceAgainstFacet(TraceWorkT *tr, int nShader, CFaceT *facet)
{
int j;
float d1,d2,d,f;
vector3 point;
float dist;
if(facet->m_nBoundaries < 3)
return;
dist=facet->m_fSurface[3];
vector3 vecSurface(facet->m_fSurface[0],facet->m_fSurface[1],facet->m_fSurface[2]);
d1=(tr->m_vecStart*vecSurface)-dist;
if(d1>-1 && d1<1)
return;
d2=(tr->m_vecEnd*vecSurface)-dist;
if(d2>-1 && d2<1)
{
return;
}
f=(d1-ON_EPSILON)/(d1-d2);
if(f<=0)
return;
if(f>=tr->m_Trace->m_fHitFraction)
return;
point=tr->m_vecStart+f*(tr->m_vecEnd-tr->m_vecStart);
for(j=0;j<facet->m_nBoundaries;j++)
{
dist=facet->m_fBoundaries[j][3];
vector3 vecBound(facet->m_fBoundaries[j][0],facet->m_fBoundaries[j][1],facet->m_fBoundaries[j][2]);
d=point*vecBound;
if(d>dist+ON_EPSILON)
break;
}
if(j!=facet->m_nBoundaries)
return;
tr->m_Trace->m_vecFilter=vector3(0.0f,0.0f,0.0f);
tr->m_Trace->m_fHitFraction=f;
}
void CBspScene::InitSurfacesForTesting()
{
int i,j;
DSurface *dsurf;
SurfaceTestT *test;
BspVertex *dvert;
for(i=0;i<m_nDrawSurfaces;i++)
{
dsurf=&m_DrawSurfaces[i];
if(!dsurf->m_nIndex && !dsurf->m_PatchWidth)
continue;
test=(SurfaceTestT*)malloc(sizeof(*test));
m_SurfaceTest[i]=test;
//test->m_vecMaxs=test->m_vecMins=vector3(0.0f,0.0f,0.0f);
test->m_vecMaxs=vector3(-99999,-99999,-99999);
test->m_vecMins=vector3(99999,99999,99999);
dvert=&m_DrawVerts[dsurf->m_FirstVert];
for(j=0;j<dsurf->m_nVerts;j++,dvert++)
{
AddPointToBounds(dvert->v,test->m_vecMaxs,test->m_vecMins);
}
vector3 vecOrigin=test->m_vecMaxs+test->m_vecMins;
vecOrigin=0.5f*vecOrigin;
vector3 vecTemp=test->m_vecMaxs-vecOrigin;
test->m_fRadius=vecTemp.GetLens();
test->m_vecOrigins=vecOrigin;
if(dsurf->m_SurfaceType==0)//Planar
{
FacetsForTriangleSurface(dsurf,dsurf->m_nShader,test);
}
else if(dsurf->m_SurfaceType==1)
{
FacetsForPatch(dsurf,dsurf->m_nShader,test);
}
}
}
void CBspScene::FacetsForTriangleSurface(DSurface *dsurf, int nShader, SurfaceTestT *test)
{
int i;
BspVertex *v1,*v2,*v3,*v4;
int count;
int i1,i2,i3,i4,i5,i6;
test->m_bPatch=false;
test->m_nFacets=dsurf->m_nIndex/3;
test->m_Facets=(CFaceT*)malloc(sizeof(test->m_Facets[0])*test->m_nFacets);
test->m_nShader=nShader;
count=0;
for(i=0;i<test->m_nFacets;i++)
{
i1=m_DrawIndex[dsurf->m_FirstIndex+i*3];
i2=m_DrawIndex[dsurf->m_FirstIndex+i*3+1];
i3=m_DrawIndex[dsurf->m_FirstIndex+i*3+2];
v1=&m_DrawVerts[dsurf->m_FirstVert+i1];
v2=&m_DrawVerts[dsurf->m_FirstVert+i2];
v3=&m_DrawVerts[dsurf->m_FirstVert+i3];
if(i!=test->m_nFacets-1)
{
i4=m_DrawIndex[dsurf->m_FirstIndex+i*3+3];
i5=m_DrawIndex[dsurf->m_FirstIndex+i*3+4];
i6=m_DrawIndex[dsurf->m_FirstIndex+i*3+5];
if(i4==i3 && i5==i2)
{
v4=&m_DrawVerts[dsurf->m_FirstVert+i6];
if(CM_GenerateFacetFor4Points(&test->m_Facets[count],v1,v2,v4,v3))
{
count++;
i++;
continue;
}
}
}
if(CM_GenerateFacetFor3Points(&test->m_Facets[count],v1,v2,v3))
count++;
}
test->m_nFacets=count;
}
bool CBspScene::CM_GenerateFacetFor3Points(CFaceT *f, BspVertex *a, BspVertex *b, BspVertex *c)
{
if(!PlaneFromPoints(f->m_fSurface,a->v,b->v,c->v))
{
f->m_nBoundaries=0;
return false;
}
f->m_nBoundaries=3;
CM_GenerateBoundaryForPoints(f->m_fBoundaries[0],f->m_fSurface,a->v,b->v);
CM_GenerateBoundaryForPoints(f->m_fBoundaries[1],f->m_fSurface,b->v,c->v);
CM_GenerateBoundaryForPoints(f->m_fBoundaries[2],f->m_fSurface,c->v,a->v);
f->m_vecPoint[0]=a->v;
f->m_vecPoint[1]=b->v;
f->m_vecPoint[2]=c->v;
TextureMatrixFromPoints( f, a, b, c );
return true;
}
bool CBspScene::PlaneFromPoints(float *plane, vector3 &a, vector3 &b, vector3 &c)
{
vector3 d1,d2;
d1=b-a;
d2=c-a;
vector3 vecNormal;
vecNormal=d2^d1;
if(vecNormal.GetLens()==0)
{
return false;
}
vecNormal.Normalize();
plane[0]=vecNormal.x;
plane[1]=vecNormal.y;
plane[2]=vecNormal.z;
plane[3]=a*vecNormal;
return true;
}
void CBspScene::CM_GenerateBoundaryForPoints(float boundary[], float plane[], vector3 &a, vector3 &b)
{
vector3 d1;
d1=b-a;
vector3 vecNormal,vecPlane,vecBoundary;
vecBoundary=vector3(boundary[0],boundary[1],boundary[2]);
vecPlane=vector3(plane[0],plane[1],plane[2]);
vecNormal=vecPlane^d1;
vecNormal.Normalize();
vecBoundary=vecNormal;
boundary[3]=a*vecBoundary;
boundary[0]=vecBoundary.x;
boundary[1]=vecBoundary.y;
boundary[2]=vecBoundary.z;
}
void CBspScene::TextureMatrixFromPoints(CFaceT *f, BspVertex *a, BspVertex *b, BspVertex *c)
{
int i, j;
float t;
float m[3][4];
float s;
// This is an incredibly stupid way of solving a three variable equation
for ( i = 0 ; i < 2 ; i++ ) {
m[0][0] = a->v.v[0];
m[0][1] = a->v.v[1];
m[0][2] = a->v.v[2];
if(i==0)
m[0][3] = a->tu;
else
m[0][3] = a->tv;
m[1][0] = b->v.v[0];
m[1][1] = b->v.v[1];
m[1][2] = b->v.v[2];
if(i==0)
m[1][3] = b->tu;
else
m[1][3] = b->tv;
m[2][0] = c->v.v[0];
m[2][1] = c->v.v[1];
m[2][2] = c->v.v[2];
if(i==0)
m[2][3]=c->tu;
else
m[2][3]=c->tv;
if ( fabs(m[1][0]) > fabs(m[0][0]) && fabs(m[1][0]) > fabs(m[2][0]) ) {
for ( j = 0 ; j < 4 ; j ++ ) {
t = m[0][j];
m[0][j] = m[1][j];
m[1][j] = t;
}
} else if ( fabs(m[2][0]) > fabs(m[0][0]) && fabs(m[2][0]) > fabs(m[1][0]) ) {
for ( j = 0 ; j < 4 ; j ++ ) {
t = m[0][j];
m[0][j] = m[2][j];
m[2][j] = t;
}
}
s = 1.0 / m[0][0];
m[0][0] *= s;
m[0][1] *= s;
m[0][2] *= s;
m[0][3] *= s;
s = m[1][0];
m[1][0] -= m[0][0] * s;
m[1][1] -= m[0][1] * s;
m[1][2] -= m[0][2] * s;
m[1][3] -= m[0][3] * s;
s = m[2][0];
m[2][0] -= m[0][0] * s;
m[2][1] -= m[0][1] * s;
m[2][2] -= m[0][2] * s;
m[2][3] -= m[0][3] * s;
if ( fabs(m[2][1]) > fabs(m[1][1]) ) {
for ( j = 0 ; j < 4 ; j ++ ) {
t = m[1][j];
m[1][j] = m[2][j];
m[2][j] = t;
}
}
s = 1.0 / m[1][1];
m[1][0] *= s;
m[1][1] *= s;
m[1][2] *= s;
m[1][3] *= s;
s = m[2][1];
m[2][0] -= m[1][0] * s;
m[2][1] -= m[1][1] * s;
m[2][2] -= m[1][2] * s;
m[2][3] -= m[1][3] * s;
s = 1.0 / m[2][2];
m[2][0] *= s;
m[2][1] *= s;
m[2][2] *= s;
m[2][3] *= s;
f->m_fTextureMatrix[i][2] = m[2][3];
f->m_fTextureMatrix[i][1] = m[1][3] - f->m_fTextureMatrix[i][2] * m[1][2];
f->m_fTextureMatrix[i][0] = m[0][3] - f->m_fTextureMatrix[i][2] * m[0][2] - f->m_fTextureMatrix[i][1] * m[0][1];
f->m_fTextureMatrix[i][3] = 0;
}
}
#define PLANAR_EPSILON 0.1
bool CBspScene::CM_GenerateFacetFor4Points(CFaceT *f, BspVertex *a, BspVertex *b, BspVertex *c, BspVertex *d)
{
float dist;
int i;
float plane[4];
if(!PlaneFromPoints(f->m_fSurface,a->v,b->v,c->v))
{
f->m_nBoundaries=0;
return false;
}
vector3 vecSurface(f->m_fSurface[0],f->m_fSurface[1],f->m_fSurface[2]);
dist=(d->v*vecSurface)-f->m_fSurface[3];
if(fabsf(dist) > PLANAR_EPSILON)
{
f->m_nBoundaries=0;
return false;
}
f->m_nBoundaries=4;
CM_GenerateBoundaryForPoints(f->m_fBoundaries[0],f->m_fSurface,a->v,b->v);
CM_GenerateBoundaryForPoints(f->m_fBoundaries[1],f->m_fSurface,b->v,c->v);
CM_GenerateBoundaryForPoints(f->m_fBoundaries[2],f->m_fSurface,c->v,d->v);
CM_GenerateBoundaryForPoints(f->m_fBoundaries[3],f->m_fSurface,d->v,a->v);
f->m_vecPoint[0]=a->v;
f->m_vecPoint[1]=b->v;
f->m_vecPoint[2]=c->v;
f->m_vecPoint[3]=d->v;
for(i=1;i<4;i++)
{
if(!PlaneFromPoints(plane,f->m_vecPoint[i],f->m_vecPoint[(i+1)%4],f->m_vecPoint[(i+2)%4]))
{
f->m_nBoundaries=0;
return false;
}
vecSurface=vector3(f->m_fSurface[0],f->m_fSurface[1],f->m_fSurface[2]);
vector3 vecPlane(plane[0],plane[1],plane[2]);
if((vecSurface*vecPlane) < 0.9f)
{
f->m_nBoundaries=0;
return false;
}
}
TextureMatrixFromPoints(f,a,b,c);
return true;
}
void CBspScene::FacetsForPatch(DSurface *dsurf, int nShader, SurfaceTestT *test)
{
int i,j;
BspVertex *v1,*v2,*v3,*v4;
int count;
SMesh srcMesh,*subdivided,*mesh;
srcMesh.m_nWidth=dsurf->m_PatchWidth;
srcMesh.m_nHeight=dsurf->m_PatchHeight;
srcMesh.m_pVerts=&m_DrawVerts[dsurf->m_FirstVert];
mesh=SubdivideMesh(srcMesh,8,999);
PutMeshOnCurve(*mesh);
MakeMeshNormals(*mesh);
subdivided=RemoveLinearMeshColumnsRows(mesh);
FreeMesh(mesh);
test->m_bPatch=true;
test->m_nFacets=(subdivided->m_nWidth-1)*(subdivided->m_nHeight-1)*2;
test->m_Facets=(CFaceT*)malloc(sizeof(test->m_Facets[0])*test->m_nFacets);
test->m_nShader=-1;
count=0;
for(i=0;i<subdivided->m_nWidth-1;i++)
{
for(j=0;j<subdivided->m_nHeight-1;j++)
{
v1=subdivided->m_pVerts+j*subdivided->m_nWidth+i;
v2=v1+1;
v3=v1+subdivided->m_nWidth+1;
v4=v1+subdivided->m_nWidth;
if(CM_GenerateFacetFor4Points(&test->m_Facets[count],v1,v4,v3,v2))
{
count++;
}
else
{
if(CM_GenerateFacetFor3Points(&test->m_Facets[count],v1,v4,v3))
count++;
if(CM_GenerateFacetFor3Points(&test->m_Facets[count],v1,v3,v2))
count++;
}
}
}
test->m_nFacets=count;
FreeMesh(subdivided);
}
SMesh* CBspScene::RemoveLinearMeshColumnsRows(SMesh *in)
{
int i,j,k;
float len,maxLength;
vector3 proj,dir;
SMesh out;
BspVertex expand[MAX_EXPANDED_AXIS][MAX_EXPANDED_AXIS];
out.m_nWidth=in->m_nWidth;
out.m_nHeight=in->m_nHeight;
for(i=0;i<in->m_nWidth;i++)
{
for(j=0;j<in->m_nHeight;j++)
{
expand[j][i]=in->m_pVerts[j*in->m_nWidth+i];
}
}
for(j=1;j<out.m_nWidth-1;j++)
{
maxLength=0.0f;
for(i=0;i<out.m_nHeight;i++)
{
ProjectPointOntoVector(expand[i][j].v,expand[i][j-1].v,expand[i][j+1].v,proj);
dir=expand[i][j].v-proj;
len=dir.GetLens();
if(len>maxLength)
maxLength=len;
}
if(maxLength<0.1f)
{
out.m_nWidth--;
for(i=0;i<out.m_nHeight;i++)
{
for(k=j;k<out.m_nWidth;k++)
{
expand[i][k]=expand[i][k+1];
}
}
for(k=j;k<out.m_nWidth;k++)
{
originalWidths[k]=originalWidths[k+1];
}
j--;
}
}
for(j=1;j<out.m_nHeight-1;j++)
{
maxLength=0.0f;
for(i=0;i<out.m_nWidth;i++)
{
ProjectPointOntoVector(expand[j][i].v,expand[j-1][i].v,expand[j+1][i].v,proj);
dir=expand[j][i].v-proj;
len=dir.GetLens();
if(len>maxLength)
maxLength=len;
}
if(maxLength<0.1)
{
out.m_nHeight--;
for(i=0;i<out.m_nWidth;i++)
{
for(k=j;k<out.m_nHeight;k++)
{
expand[k][i]=expand[k+1][i];
}
}
for(k=j;k<out.m_nHeight;k++)
{
originalHeights[k]=originalHeights[k+1];
}
j--;
}
}
out.m_pVerts=&expand[0][0];
for(i=1;i<out.m_nHeight;i++)
{
memmove(&out.m_pVerts[i*out.m_nWidth],expand[i],out.m_nWidth*sizeof(BspVertex));
}
return CopyMesh(&out);
}
int CBspScene::PlaneTypeForNormal(vector3 p)
{
if(p.x==1.0f || p.x==-1.0f)
return PLANE_X;
if(p.y==1.0f || p.y==-1.0f)
return PLANE_Y;
if(p.z==1.0f || p.z==-1.0f)
return PLANE_Z;
return PLANE_NON_AXIAL;
}
void CBspScene::AddPointToBounds(vector3 &v, vector3 &max, vector3 &min)
{
float val;
for(int i=0;i<3;i++)
{
val=v.v[i];
if(val<min.v[i])
min.v[i]=val;
if(val>max.v[i])
max.v[i]=val;
}
}
SMesh* CBspScene::SubdivideMesh(SMesh in, float maxError, float minLength)
{
int i,j,k,l;
BspVertex prev,next,mid;
vector3 prevxyz,nextxyz,midxyz;
vector3 delta;
float len;
SMesh out;
BspVertex expand[MAX_EXPANDED_AXIS][MAX_EXPANDED_AXIS];
out.m_nWidth=in.m_nWidth;
out.m_nHeight=in.m_nHeight;
for(i=0;i<in.m_nWidth;i++)
{
for(j=0;j<in.m_nHeight;j++)
{
expand[j][i]=in.m_pVerts[j*in.m_nWidth+i];
}
}
for(i=0;i<in.m_nHeight;i++)
{
originalHeights[i]=i;
}
for(i=0;i<in.m_nWidth;i++)
{
originalWidths[i]=i;
}
for(j=0;j+2<out.m_nWidth;j+=2)
{
for(i=0;i<out.m_nHeight;i++)
{
for(l=0;l<3;l++)
{
prevxyz.v[l]=expand[i][j+1].v.v[l]-expand[i][j].v.v[l];
nextxyz.v[l]=expand[i][j+2].v.v[l]-expand[i][j+1].v.v[l];
midxyz.v[l]=(expand[i][j].v.v[l]+expand[i][j+1].v.v[l]*2+expand[i][j+2].v.v[l])*0.25f;
}
if( prevxyz.GetLens() > minLength ||
nextxyz.GetLens() > minLength )
break;
delta=expand[i][j+1].v-midxyz;
len=delta.GetLens();
if(len>maxError)
break;
}
if(out.m_nWidth+2 >=MAX_EXPANDED_AXIS)
break;
if(i==out.m_nHeight)
continue;
out.m_nWidth+=2;
for(k=out.m_nWidth-1;k>j+3;k--)
{
originalWidths[k]=originalWidths[k-2];
}
originalWidths[j+3]=originalWidths[j+1];
originalWidths[j+2]=originalWidths[j+1];
originalWidths[j+1]=originalWidths[j];
for(i=0;i<out.m_nHeight;i++)
{
LerpDrawVert(&expand[i][j],&expand[i][j+1],&prev);
LerpDrawVert(&expand[i][j+1],&expand[i][j+2],&next);
LerpDrawVert(&prev,&next,&mid);
for(k=out.m_nWidth-1;k>j+3;k--)
{
expand[i][k]=expand[i][k-2];
}
expand[i][j+1]=prev;
expand[i][j+2]=mid;
expand[i][j+3]=next;
}
j-=2;
}
for(j=0;j+2<out.m_nHeight;j+=2)
{
for(i=0;i<out.m_nWidth;i++)
{
for(l=0;l<3;l++)
{
prevxyz.v[l]=expand[j+1][i].v.v[l]-expand[j][i].v.v[l];
nextxyz.v[l]=expand[j+2][i].v.v[l]-expand[j+1][i].v.v[l];
midxyz.v[l]=(expand[j][i].v.v[l] + expand[j+1][i].v.v[l]*2+ expand[j+2][i].v.v[l])*0.25f;
}
if( prevxyz.GetLens() > minLength ||
nextxyz.GetLens() > minLength )
break;
delta=expand[j+1][i].v-midxyz;
len=delta.GetLens();
if(len>maxError)
break;
}
if(out.m_nHeight+2>=MAX_EXPANDED_AXIS)
break;
if(i==out.m_nWidth)
continue;
out.m_nHeight+=2;
for(k=out.m_nHeight-1;k>j+3;k--)
originalHeights[k]=originalHeights[k-2];
originalHeights[j+3]=originalHeights[j+1];
originalHeights[j+2]=originalHeights[j+1];
originalHeights[j+1]=originalHeights[j];
for(i=0;i<out.m_nWidth;i++)
{
LerpDrawVert(&expand[j][i],&expand[j+1][i],&prev);
LerpDrawVert(&expand[j+1][i],&expand[j+2][i],&next);
LerpDrawVert(&prev,&next,&mid);
for(k=out.m_nHeight-1;k>j+3;k--)
expand[k][i]=expand[k-2][i];
expand[j+1][i]=prev;
expand[j+2][i]=mid;
expand[j+3][i]=next;
}
j-=2;
}
out.m_pVerts=&expand[0][0];
for(i=1;i<out.m_nHeight;i++)
{
memmove(&out.m_pVerts[i*out.m_nWidth],expand[i],out.m_nWidth*sizeof(BspVertex));
}
return CopyMesh(&out);
}
void CBspScene::PutMeshOnCurve(SMesh in)
{
int i,j,l;
float prev,next;
for(i=0;i<in.m_nWidth;i++)
{
for(j=1;j<in.m_nHeight;j+=2)
{
for(l=0;l<3;l++)
{
prev=(in.m_pVerts[j*in.m_nWidth+i].v.v[l]+in.m_pVerts[(j+1)*in.m_nWidth+i].v.v[l])*0.5f;
next=(in.m_pVerts[j*in.m_nWidth+i].v.v[l]+in.m_pVerts[(j-1)*in.m_nWidth+i].v.v[l])*0.5f;
in.m_pVerts[j*in.m_nWidth+i].v.v[l]=(prev+next)*0.5f;
}
}
}
/*
int i, j, l;
float prev, next;
// put all the aproximating points on the curve
for ( i = 0 ; i < in.width ; i++ ) {
for ( j = 1 ; j < in.height ; j += 2 ) {
for ( l = 0 ; l < 3 ; l++ ) {
prev = ( in.verts[j*in.width+i].xyz[l] + in.verts[(j+1)*in.width+i].xyz[l] ) * 0.5;
next = ( in.verts[j*in.width+i].xyz[l] + in.verts[(j-1)*in.width+i].xyz[l] ) * 0.5;
in.verts[j*in.width+i].xyz[l] = ( prev + next ) * 0.5;
}
}
}
for ( j = 0 ; j < in.height ; j++ ) {
for ( i = 1 ; i < in.width ; i += 2 ) {
for ( l = 0 ; l < 3 ; l++ ) {
prev = ( in.verts[j*in.width+i].xyz[l] + in.verts[j*in.width+i+1].xyz[l] ) * 0.5;
next = ( in.verts[j*in.width+i].xyz[l] + in.verts[j*in.width+i-1].xyz[l] ) * 0.5;
in.verts[j*in.width+i].xyz[l] = ( prev + next ) * 0.5;
}
}
}
*/
for(j=0;j<in.m_nHeight;j++)
{
for(i=1;i<in.m_nWidth;i+=2)
{
for(l=0;l<3;l++)
{
prev=(in.m_pVerts[j*in.m_nWidth+i].v.v[l]+in.m_pVerts[j*in.m_nWidth+i+1].v.v[l])*0.5f;
next=(in.m_pVerts[j*in.m_nWidth+i].v.v[l]+in.m_pVerts[j*in.m_nWidth+i-1].v.v[l])*0.5f;
in.m_pVerts[j*in.m_nWidth+i].v.v[l]=(prev+next)*0.5f;
}
}
}
}
int neighbors[8][2] = {
{0,1}, {1,1}, {1,0}, {1,-1}, {0,-1}, {-1,-1}, {-1,0}, {-1,1}
};
void CBspScene::MakeMeshNormals(SMesh in)
{
int i,j,k,dist;
vector3 normal;
vector3 sum;
int count;
vector3 base;
vector3 delta;
int x,y;
BspVertex *dv;
vector3 around[8],temp;
bool good[8];
bool wrapWidth,wrapHeight;
float len;
wrapWidth=false;
for(i=0;i<in.m_nHeight;i++)
{
delta=in.m_pVerts[i*in.m_nWidth].v-in.m_pVerts[i*in.m_nWidth+in.m_nWidth-1].v;
len=delta.GetLens();
if(len>1.0f)
break;
}
if(i==in.m_nHeight)
{
wrapWidth=true;
}
wrapHeight=false;
for(i=0;i<in.m_nWidth;i++)
{
delta=in.m_pVerts[i].v-in.m_pVerts[i+(in.m_nHeight-1)*in.m_nWidth].v;
len=delta.GetLens();
if(len>1.0f)
break;
}
if(i==in.m_nWidth)
{
wrapHeight=true;
}
for(i=0;i<in.m_nWidth;i++)
{
for(j=0;j<in.m_nHeight;j++)
{
count=0;
dv=&in.m_pVerts[j*in.m_nWidth+i];
base=dv->v;
for(k=0;k<8;k++)
{
around[k]=vector3(0.0f,0.0f,0.0f);
good[k]=false;
for(dist=1;dist<=3;dist++)
{
x=i+neighbors[k][0]*dist;
y=j+neighbors[k][1]*dist;
if(wrapWidth)
{
if(x<0)
x=in.m_nWidth-1+x;
else if(x>=in.m_nWidth)
x=1+x-in.m_nWidth;
}
if(wrapHeight)
{
if(y<0)
y=in.m_nHeight-1+y;
else if(y>=in.m_nHeight)
y=1+y-in.m_nHeight;
}
if(x<0 || x>=in.m_nWidth || y<0 || y>=in.m_nHeight)
break;
temp=in.m_pVerts[y*in.m_nWidth+x].v-base;
//temp.Normalize()
if(temp.Mag()==0)
continue;
else
{
good[k]=true;
temp.Normalize();
around[k]=temp;
break;
}
}
}
sum=vector3(0.0f,0.0f,0.0f);
for(k=0;k<8;k++)
{
if(!good[k] || !good[(k+1)&7])
continue;
normal=around[(k+1)&7]^around[k];
if(normal.Mag()==0)
continue;
normal.Normalize();
sum=sum+normal;
count++;
}
if(count==0)
{
count=1;
}
dv->normal=sum.Normalized();
}
}
}
void CBspScene::FreeMesh(SMesh *m)
{
delete [] m->m_pVerts;
delete m;
}
void CBspScene::ProjectPointOntoVector(vector3 &point, vector3 &vStart, vector3 &vEnd, vector3 &vProj)
{
vector3 pVec,vec;
pVec=point-vStart;
vec=vEnd-vStart;
vec.Normalize();
float f=pVec*vec;
vProj=vStart+vec*f;
}
SMesh* CBspScene::CopyMesh(SMesh *mesh)
{
SMesh *out;
int size;
out=new SMesh;
out->m_nWidth=mesh->m_nWidth;
out->m_nHeight=mesh->m_nHeight;
//size=out->m_nWidth*out->m_nHeight*sizeof(*out->m_pVerts);
out->m_pVerts=new BspVertex[out->m_nWidth*out->m_nHeight];
memcpy(out->m_pVerts,mesh->m_pVerts,sizeof(BspVertex)*out->m_nWidth*out->m_nHeight);
return out;
}
void CBspScene::LerpDrawVert(BspVertex *a, BspVertex *b, BspVertex *out)
{
out->v.v[0]=0.5f*(a->v.v[0]+b->v.v[0]);
out->v.v[1]=0.5f*(a->v.v[1]+b->v.v[1]);
out->v.v[2]=0.5f*(a->v.v[2]+b->v.v[2]);
out->tu=0.5f*(a->tu+b->tu);
out->tv=0.5f*(a->tv+b->tv);
out->tu1=0.5f*(a->tu1+b->tu1);
out->tv1=0.5f*(a->tv1+b->tv1);
}
int CBspScene::FindShadowEdgeVertex(BspShadowVertex Vertex)
{
for(int i=0;i<m_SurfaceEdgeVertexList.num;i++)
{
if( m_SurfaceEdgeVertexList[i].v==Vertex.v &&
m_SurfaceEdgeVertexList[i].n==Vertex.n &&
fabsf(m_SurfaceEdgeVertexList[i].fWeight-Vertex.fWeight) <= 0.01f)
{
return i;
}
}
return -1;
}