Files
Client/Engine/Zalla3D Scene Class/NMesh.cpp
LGram16 e067522598 Initial commit: ROW Client source code
Game client codebase including:
- CharacterActionControl: Character and creature management
- GlobalScript: Network, items, skills, quests, utilities
- RYLClient: Main client application with GUI and event handlers
- Engine: 3D rendering engine (RYLGL)
- MemoryManager: Custom memory allocation
- Library: Third-party dependencies (DirectX, boost, etc.)
- Tools: Development utilities

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-29 16:24:34 +09:00

961 lines
26 KiB
C++
Raw Blame History

#include ".\nmesh.h"
#include "./SceneManager.h"
#include "./RenderBoundingBox.h"
#include "../zalla3d base class/BaseGraphicsLayer.h"
#include "GMMemory.h"
namespace CROSSM {
CNMesh::CNMesh(void)
{
m_MaxBox.x=-1.0f;
m_MinBox.x=-1.0f;
m_isAlreadyLock=false;
m_dwConvertShader = MultiFVF;
m_iObjectMethod = 0;
m_pMatName.clear();
}
CNMesh::~CNMesh(void)
{
int i;
if(CSceneManager::ms_pBufferPools)
{
for(i=0;i<(int)m_pVertexBuffer.size();i++)
{
if(m_pVertexBuffer[i])
{
CSceneManager::ms_pBufferPools->UnRef(Caldron::Scene::D3DBUFFEROBJ_VERTEX,m_pVertexBuffer[i]);
m_pVertexBuffer[i] = NULL;
}
}
for(i=0;i<(int)m_pIndicesBuffer.size();i++)
{
if(m_pIndicesBuffer[i])
{
CSceneManager::ms_pBufferPools->UnRef(Caldron::Scene::D3DBUFFEROBJ_INDEX,m_pIndicesBuffer[i]);
m_pIndicesBuffer[i] = NULL;
}
}
}
else
{
for(i=0;i<(int)m_pVertexBuffer.size();i++)
{
if(m_pVertexBuffer[i])
{
m_pVertexBuffer[i]->Release();
m_pVertexBuffer[i] = NULL;
}
}
for(i=0;i<(int)m_pIndicesBuffer.size();i++)
{
if(m_pIndicesBuffer[i])
{
m_pIndicesBuffer[i]->Release();
m_pIndicesBuffer[i] = NULL;
}
}
}
m_pVertexBuffer.clear();
m_pIndicesBuffer.clear();
for(i = 0; i < (int)m_pMat.size(); i++)
{
if(m_pMat[i])
{
CSceneManager::_ReleaseResource(CROSSM::RESOURCE_TEXTURE,m_pMat[i]);
m_pMat[i] = NULL;
}
}
m_pMat.clear();
for(i = 0; i < (int)m_pMatName.size(); i++)
{
if(m_pMatName[i])
{
delete[] m_pMatName[i];
}
}
m_pMatName.clear();
for(i = 0; i < (int)m_pIndices.size(); i++ )
{
m_pIndices[i] = NULL;
}
m_pIndices.clear();
for(i = 0; i < (int)m_pVertex.size(); i++ )
{
m_pVertex[i] = NULL;
}
m_pVertex.clear();
for(i = 0; i < (int)m_pLoadedIndices.size(); i++ )
{
if(m_pLoadedIndices[i])
{
delete[] m_pLoadedIndices[i];
m_pLoadedIndices[i] = NULL;
}
}
m_pLoadedIndices.clear();
for(i = 0; i < (int)m_pLoadedVertex.size(); i++ )
{
if(m_pLoadedVertex[i])
{
delete[] m_pLoadedVertex[i];
m_pLoadedVertex[i] = NULL;
}
}
m_pLoadedVertex.clear();
}
bool CNMesh::Load()
{
if(!m_pByteDataObj)
return false;
int nObject,nMat,ObjectMethod;
m_pByteDataObj->Read(&nObject,sizeof(int),1);
m_pByteDataObj->Read(&nMat,sizeof(int),1);
m_pByteDataObj->Read(&ObjectMethod,sizeof(int),1);
m_bRender=true;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> min-max <20>ڽ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>Ʈ <20>ʱ<EFBFBD>ȭ
m_vecMeshPieceBoundingBoxInfo.resize(nObject);
if(COLLISIONOBJECTVIEW==0 && strstr(m_strName,"collision")!=NULL)
{
m_bRender=false;
}
m_iObjectMethod = ObjectMethod;
if(ObjectMethod==0)
{
m_bCompleteMesh=false;
char strTextureName[256];
//CNTexture::SetPath(OBJECTTEXTUREPATH);
for(int i = 0; i < nMat; i++ )
{
m_pByteDataObj->Read(strTextureName,sizeof(char) * 256,1);
char *pName = new char[256];
strcpy(pName,strTextureName);
m_pMatName.push_back(pName);
if(strcmp(strTextureName,"")==0)
continue;
//CNTexture *pTexture = (CNTexture *)CSceneManager::_GetResource(CROSSM::RESOURCE_TEXTURE,strTextureName);
//m_pMat.push_back(pTexture);
}
char strObjectName[256];
int MatRef,cVertex,cIndices;
for(int i=0;i<nObject;i++)
{
m_pByteDataObj->Read(strObjectName,sizeof(char)*256,1);
m_pByteDataObj->Read(&MatRef,sizeof(long),1);
m_pByteDataObj->Read(&cVertex,sizeof(long),1);
m_pByteDataObj->Read(&cIndices,sizeof(int),1);
MultiVertex *pTempVertex=new MultiVertex[cVertex];
WORD *pTempIndices=new WORD[cIndices*3];
m_pByteDataObj->Read(pTempVertex,sizeof(MultiVertex) * cVertex,1);
m_pByteDataObj->Read(pTempIndices,sizeof(WORD)* cIndices * 3,1);
//calc box
if(m_MaxBox.x==-1.0f && m_MinBox.x==-1.0f)
{
m_MinBox.x=m_MaxBox.x=pTempVertex[0].v.x;
m_MinBox.y=m_MaxBox.y=pTempVertex[0].v.y;
m_MinBox.z=m_MaxBox.z=pTempVertex[0].v.z;
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ٿ<EFBFBD><D9BF><EFBFBD> min-max <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>ʱ<EFBFBD>ȭ
m_vecMeshPieceBoundingBoxInfo[i].vBoxMin = pTempVertex[0].v;
m_vecMeshPieceBoundingBoxInfo[i].vBoxMax = pTempVertex[0].v;
for(int cv = 0; cv < cVertex; cv++)
{
// <20><>ü <20>޽ô<DEBD><C3B4><EFBFBD> <20>ٿ<EFBFBD><D9BF><EFBFBD> min-max <20><><EFBFBD><EFBFBD>
m_MinBox.x = min(m_MinBox.x, pTempVertex[cv].v.x);
m_MinBox.y = min(m_MinBox.y, pTempVertex[cv].v.y);
m_MinBox.z = min(m_MinBox.z, pTempVertex[cv].v.z);
m_MaxBox.x = max(m_MaxBox.x, pTempVertex[cv].v.x);
m_MaxBox.y = max(m_MaxBox.y, pTempVertex[cv].v.y);
m_MaxBox.z = max(m_MaxBox.z, pTempVertex[cv].v.z);
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ٿ<EFBFBD><D9BF><EFBFBD> min-max <20><><EFBFBD><EFBFBD>
vector3 &vPerObjectMin = m_vecMeshPieceBoundingBoxInfo[i].vBoxMin; // alias
vector3 &vPerObjectMax = m_vecMeshPieceBoundingBoxInfo[i].vBoxMax; // alias
vPerObjectMin.x = min(vPerObjectMin.x, pTempVertex[cv].v.x);
vPerObjectMin.y = min(vPerObjectMin.y, pTempVertex[cv].v.y);
vPerObjectMin.z = min(vPerObjectMin.z, pTempVertex[cv].v.z);
vPerObjectMax.x = max(vPerObjectMax.x, pTempVertex[cv].v.x);
vPerObjectMax.y = max(vPerObjectMax.y, pTempVertex[cv].v.y);
vPerObjectMax.z = max(vPerObjectMax.z, pTempVertex[cv].v.z);
}
m_nVertex.push_back(cVertex);
m_nIndices.push_back(cIndices);
m_pMatRef.push_back(MatRef);
m_pIndices.push_back(pTempIndices);
m_pVertex.push_back(pTempVertex);
}
}
else if(m_iObjectMethod == 3)
{
m_bCompleteMesh=false;
char strTextureName[256];
//CNTexture::SetPath(OBJECTTEXTUREPATH);
for(int i = 0; i < nMat; i++ )
{
m_pByteDataObj->Read(strTextureName,sizeof(char) * 256,1);
char *pName = new char[256];
strcpy(pName,strTextureName);
m_pMatName.push_back(pName);
if(strcmp(strTextureName,"")==0)
continue;
//CNTexture *pTexture = (CNTexture *)CSceneManager::_GetResource(CROSSM::RESOURCE_TEXTURE,strTextureName);
//m_pMat.push_back(pTexture);
}
char strObjectName[256];
int MatRef,cVertex,cIndices;
for(int i=0;i<nObject;i++)
{
m_pByteDataObj->Read(strObjectName,sizeof(char)*256,1);
m_pByteDataObj->Read(&MatRef,sizeof(long),1);
m_pByteDataObj->Read(&cVertex,sizeof(long),1);
m_pByteDataObj->Read(&cIndices,sizeof(int),1);
LightVertex *pTempVertex=new LightVertex[cVertex];
WORD *pTempIndices=new WORD[cIndices*3];
m_pByteDataObj->Read(pTempVertex,sizeof(LightVertex) * cVertex,1);
m_pByteDataObj->Read(pTempIndices,sizeof(WORD)* cIndices * 3,1);
//calc box
if(m_MaxBox.x==-1.0f && m_MinBox.x==-1.0f)
{
m_MinBox.x=m_MaxBox.x=pTempVertex[0].v.x;
m_MinBox.y=m_MaxBox.y=pTempVertex[0].v.y;
m_MinBox.z=m_MaxBox.z=pTempVertex[0].v.z;
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ٿ<EFBFBD><D9BF><EFBFBD> min-max <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>ʱ<EFBFBD>ȭ
m_vecMeshPieceBoundingBoxInfo[i].vBoxMin = pTempVertex[0].v;
m_vecMeshPieceBoundingBoxInfo[i].vBoxMax = pTempVertex[0].v;
for(int cv = 0; cv < cVertex; cv++)
{
vector3 &vPerObjectMin = m_vecMeshPieceBoundingBoxInfo[i].vBoxMin;
vector3 &vPerObjectMax = m_vecMeshPieceBoundingBoxInfo[i].vBoxMax;
// <20><>ü <20>޽ô<DEBD><C3B4><EFBFBD> <20>ٿ<EFBFBD><D9BF><EFBFBD> min-max <20><><EFBFBD><EFBFBD>
m_MinBox.x = min(m_MinBox.x, pTempVertex[cv].v.x);
m_MinBox.y = min(m_MinBox.y, pTempVertex[cv].v.y);
m_MinBox.z = min(m_MinBox.z, pTempVertex[cv].v.z);
m_MaxBox.x = max(m_MaxBox.x, pTempVertex[cv].v.x);
m_MaxBox.y = max(m_MaxBox.y, pTempVertex[cv].v.y);
m_MaxBox.z = max(m_MaxBox.z, pTempVertex[cv].v.z);
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ٿ<EFBFBD><D9BF><EFBFBD> min-max <20><><EFBFBD><EFBFBD>
vPerObjectMin.x = min(vPerObjectMin.x, pTempVertex[cv].v.x);
vPerObjectMin.y = min(vPerObjectMin.y, pTempVertex[cv].v.y);
vPerObjectMin.z = min(vPerObjectMin.z, pTempVertex[cv].v.z);
vPerObjectMax.x = max(vPerObjectMax.x, pTempVertex[cv].v.x);
vPerObjectMax.y = max(vPerObjectMax.y, pTempVertex[cv].v.y);
vPerObjectMax.z = max(vPerObjectMax.z, pTempVertex[cv].v.z);
// if(m_MaxBox.x < pTempVertex[cv].v.x)
// m_MaxBox.x=pTempVertex[cv].v.x;
// if(m_MaxBox.y < pTempVertex[cv].v.y)
// m_MaxBox.y=pTempVertex[cv].v.y;
// if(m_MaxBox.z < pTempVertex[cv].v.z)
// m_MaxBox.z=pTempVertex[cv].v.z;
//
// if(m_MinBox.x > pTempVertex[cv].v.x)
// m_MinBox.x=pTempVertex[cv].v.x;
// if(m_MinBox.y > pTempVertex[cv].v.y)
// m_MinBox.y=pTempVertex[cv].v.y;
// if(m_MinBox.z > pTempVertex[cv].v.z)
// m_MinBox.z=pTempVertex[cv].v.z;
}
m_nVertex.push_back(cVertex);
m_nIndices.push_back(cIndices);
m_pMatRef.push_back(MatRef);
m_pIndices.push_back(pTempIndices);
m_pVertex.push_back(pTempVertex);
}
}
else
{
return false;
}
return true;
}
bool CNMesh::Unload()
{
return true;
}
bool CNMesh::PostLoad()
{
int i;
int cVertex,cIndices;
if(m_iObjectMethod == 0)
{
MultiVertex *pVertexData = NULL;
WORD *pIndicesData = NULL;
m_dwShader = MultiFVF;
for(i = 0;i < (int)m_pVertex.size(); i++ ) // object number
{
cVertex = m_nVertex[i];
cIndices = m_nIndices[i];
LPDIRECT3DVERTEXBUFFER8 pAllocVB;
LPDIRECT3DINDEXBUFFER8 pAllocIB;
pAllocVB = CSceneManager::ms_pBufferPools->GetVertexBuffer(cVertex*sizeof(MultiVertex),MultiFVF,false);
pAllocIB = CSceneManager::ms_pBufferPools->GetIndexBuffer(cIndices*3*sizeof(WORD),D3DFMT_INDEX16,false);
pAllocVB->Lock(0,0,(BYTE**)&pVertexData,0);
pAllocIB->Lock(0,cIndices*3*sizeof(WORD),(BYTE**)&pIndicesData,0);
memcpy(pVertexData,(MultiVertex *)m_pVertex[i],cVertex*sizeof(MultiVertex));
memcpy(pIndicesData,m_pIndices[i],cIndices*3*sizeof(WORD));
pAllocVB->Unlock();
pAllocIB->Unlock();
m_pVertexBuffer.push_back(pAllocVB);
m_pIndicesBuffer.push_back(pAllocIB);
delete[] m_pVertex[i];
m_pVertex[i] = NULL;
delete[] m_pIndices[i];
m_pIndices[i] = NULL;
}
m_pVertex.clear();
m_pIndices.clear();
}
else if(m_iObjectMethod == 3)
{
LightVertex *pVertexData = NULL;
WORD *pIndicesData = NULL;
m_dwShader = LightFVF;
for(i = 0;i < (int)m_pVertex.size(); i++ ) // object number
{
cVertex = m_nVertex[i];
cIndices = m_nIndices[i];
LPDIRECT3DVERTEXBUFFER8 pAllocVB;
LPDIRECT3DINDEXBUFFER8 pAllocIB;
pAllocVB = CSceneManager::ms_pBufferPools->GetVertexBuffer(cVertex*sizeof(LightVertex),LightFVF,false);
pAllocIB = CSceneManager::ms_pBufferPools->GetIndexBuffer(cIndices*3*sizeof(WORD),D3DFMT_INDEX16,false);
pAllocVB->Lock(0,0,(BYTE**)&pVertexData,0);
pAllocIB->Lock(0,cIndices*3*sizeof(WORD),(BYTE**)&pIndicesData,0);
memcpy(pVertexData,(LightVertex *)m_pVertex[i],cVertex*sizeof(LightVertex));
memcpy(pIndicesData,m_pIndices[i],cIndices*3*sizeof(WORD));
pAllocVB->Unlock();
pAllocIB->Unlock();
m_pVertexBuffer.push_back(pAllocVB);
m_pIndicesBuffer.push_back(pAllocIB);
delete[] m_pVertex[i];
m_pVertex[i] = NULL;
delete[] m_pIndices[i];
m_pIndices[i] = NULL;
}
m_pVertex.clear();
m_pIndices.clear();
}
CNTexture::SetPath(OBJECTTEXTUREPATH);
for(int i = 0; i < (int)m_pMatName.size(); i++ )
{
if(strcmp(m_pMatName[i],"")==0)
continue;
CNTexture *pTexture = (CNTexture *)CSceneManager::_GetResource(CROSSM::RESOURCE_TEXTURE,m_pMatName[i]);
m_pMat.push_back(pTexture);
}
if(strstr(m_strName,"tournament_arena_stage1.r3s"))
{
ConvertNormal();
}
/*
if(m_dwConvertShader == LightFVF)
{
ConvertNormal();
}
*/
return true;
}
void CNMesh::ConvertNormal()
{
if(m_bCompleteMesh)
return;
if(m_dwShader==LightFVF)
return;
SetShader(LightFVF);
LightVertex *pVertexNormalData;
MultiVertex *pVertexData;
WORD *pIndicesData;
vector3 vecNormal;
vector3 *v[3];
for(int i=0;i<(int)m_nVertex.size();i++)
{
LPDIRECT3DVERTEXBUFFER8 pAllocVB;
pAllocVB = CSceneManager::ms_pBufferPools->GetVertexBuffer(m_nVertex[i]*sizeof(LightVertex),LightFVF,false);
pAllocVB->Lock(0,0,(BYTE**)&pVertexNormalData,0);
m_pIndicesBuffer[i]->Lock(0,m_nIndices[i]*3*sizeof(WORD),(BYTE**)&pIndicesData,0);
m_pVertexBuffer[i]->Lock(0,0,(BYTE**)&pVertexData,0);
for(int cIndices=0;cIndices<m_nIndices[i];cIndices++)
{
v[0]=(vector3*)&pVertexData[ pIndicesData[cIndices*3+0] ].v;
v[1]=(vector3*)&pVertexData[ pIndicesData[cIndices*3+1] ].v;
v[2]=(vector3*)&pVertexData[ pIndicesData[cIndices*3+2] ].v;
vecNormal= (*v[1]-*v[0])^(*v[2]-*v[1]);
vecNormal.Normalize();
pVertexData[ pIndicesData[cIndices*3+0] ].v;
pVertexData[ pIndicesData[cIndices*3+1] ].v;
pVertexData[ pIndicesData[cIndices*3+2] ].v;
pVertexNormalData[pIndicesData[cIndices*3+0]].v=pVertexData[ pIndicesData[cIndices*3+0] ].v;
pVertexNormalData[pIndicesData[cIndices*3+0]].tu=pVertexData[ pIndicesData[cIndices*3+0] ].tu;
pVertexNormalData[pIndicesData[cIndices*3+0]].tv=pVertexData[ pIndicesData[cIndices*3+0] ].tv;
pVertexNormalData[pIndicesData[cIndices*3+0]].spec.c=0x0;
pVertexNormalData[pIndicesData[cIndices*3+0]].n=vecNormal;
pVertexNormalData[pIndicesData[cIndices*3+1]].v=pVertexData[ pIndicesData[cIndices*3+1] ].v;
pVertexNormalData[pIndicesData[cIndices*3+1]].tu=pVertexData[ pIndicesData[cIndices*3+1] ].tu;
pVertexNormalData[pIndicesData[cIndices*3+1]].tv=pVertexData[ pIndicesData[cIndices*3+1] ].tv;
pVertexNormalData[pIndicesData[cIndices*3+1]].spec.c=0x0;
pVertexNormalData[pIndicesData[cIndices*3+1]].n=vecNormal;
pVertexNormalData[pIndicesData[cIndices*3+2]].v=pVertexData[ pIndicesData[cIndices*3+2] ].v;
pVertexNormalData[pIndicesData[cIndices*3+2]].tu=pVertexData[ pIndicesData[cIndices*3+2] ].tu;
pVertexNormalData[pIndicesData[cIndices*3+2]].tv=pVertexData[ pIndicesData[cIndices*3+2] ].tv;
pVertexNormalData[pIndicesData[cIndices*3+2]].spec.c=0x0;
pVertexNormalData[pIndicesData[cIndices*3+2]].n=vecNormal;
}
#ifndef _DEBUG
// smoothing
int *iTmp = new int[m_nVertex[i]];
int iCount;
for(int iVert = 0; iVert < m_nVertex[i]; iVert++)
{
memset(iTmp,0,sizeof(int) * m_nVertex[i]);
iCount = 0;
vector3 vecPos = pVertexNormalData[iVert].v;
vector3 vecNormal = vector3(0.0f,0.0f,0.0f);
for(int j = 0; j < m_nVertex[i]; j++ )
{
if(pVertexNormalData[j].v.x == pVertexNormalData[iVert].v.x &&
pVertexNormalData[j].v.y == pVertexNormalData[iVert].v.y &&
pVertexNormalData[j].v.z == pVertexNormalData[iVert].v.z)
{
if(D3DXVec3Dot((D3DXVECTOR3 *)(&pVertexNormalData[j].n),(D3DXVECTOR3 *)(&pVertexNormalData[iVert].n)) >= 0.5f)
{
iTmp[iCount++] = j;
vecNormal += pVertexNormalData[j].n;
}
}
}
vecNormal.Normalize();
for(int iT = 0; iT < iCount; iT++)
{
pVertexNormalData[iTmp[iT]].n = vecNormal;
}
}
delete[] iTmp;
iTmp = NULL;
#endif
pAllocVB->Unlock();
m_pIndicesBuffer[i]->Unlock();
m_pVertexBuffer[i]->Unlock();
//m_pVertexBuffer[i]->Release();
CSceneManager::ms_pBufferPools->UnRef(Caldron::Scene::D3DBUFFEROBJ_VERTEX,m_pVertexBuffer[i]);
m_pVertexBuffer[i]=pAllocVB;
}
}
void CNMesh::ConvertMulti()
{
if(m_bCompleteMesh)
return;
if(MultiFVF==m_dwShader)
return;
if(LightFVF==m_dwShader)
{
SetShader(MultiFVF);
LightVertex *pVertexNormalData;
MultiVertex *pVertexData;
for(int i=0;i<(int)m_nVertex.size();i++)
{
LPDIRECT3DVERTEXBUFFER8 pAllocVB;
pAllocVB = CSceneManager::ms_pBufferPools->GetVertexBuffer(m_nVertex[i]*sizeof(MultiVertex),MultiFVF,false);
pAllocVB->Lock(0,0,(BYTE**)&pVertexData,0);
m_pVertexBuffer[i]->Lock(0,0,(BYTE**)&pVertexNormalData,0);
for(int cVertex=0;cVertex<m_nVertex[i];cVertex++)
{
pVertexData[cVertex].v=pVertexNormalData[cVertex].v;
pVertexData[cVertex].tu=pVertexNormalData[cVertex].tu;
pVertexData[cVertex].tv=pVertexNormalData[cVertex].tv;
pVertexData[cVertex].spec.c=0x0;
pVertexData[cVertex].diff.c=0xffffffff;
}
pAllocVB->Unlock();
m_pVertexBuffer[i]->Unlock();
CSceneManager::ms_pBufferPools->UnRef(Caldron::Scene::D3DBUFFEROBJ_VERTEX,m_pVertexBuffer[i]);
//m_pVertexBuffer[i]->Release();
m_pVertexBuffer[i]=pAllocVB;
}
}
else
{
SetShader(MultiFVF);
DetailVertex *pVertexNormalData;
MultiVertex *pVertexData;
for(int i=0;i<(int)m_nVertex.size();i++)
{
LPDIRECT3DVERTEXBUFFER8 pAllocVB;
pAllocVB = CSceneManager::ms_pBufferPools->GetVertexBuffer(m_nVertex[i]*sizeof(MultiVertex),MultiFVF,false);
pAllocVB->Lock(0,0,(BYTE**)&pVertexData,0);
m_pVertexBuffer[i]->Lock(0,0,(BYTE**)&pVertexNormalData,0);
for(int cVertex=0;cVertex<m_nVertex[i];cVertex++)
{
pVertexData[cVertex].v=pVertexNormalData[cVertex].v;
pVertexData[cVertex].tu=pVertexNormalData[cVertex].tu;
pVertexData[cVertex].tv=pVertexNormalData[cVertex].tv;
pVertexData[cVertex].spec.c=0x0;
pVertexData[cVertex].diff.c=0xffffffff;
}
pAllocVB->Unlock();
m_pVertexBuffer[i]->Unlock();
//m_pVertexBuffer[i]->Release();
CSceneManager::ms_pBufferPools->UnRef(Caldron::Scene::D3DBUFFEROBJ_VERTEX,m_pVertexBuffer[i]);
m_pVertexBuffer[i]=pAllocVB;
}
}
}
void CNMesh::ConvertTree()
{
SetShader(TREEVERTEXFVF);
TreeVertex *pVertexNormalData;
MultiVertex *pVertexData;
WORD *pIndicesData;
vector3 vecNormal;
vector3 *v[3];
float fMaxY,fMinY;
fMaxY=-100000000000.0f;
fMinY=100000000000.0f;
for(int i=0;i<(int)m_nVertex.size();i++)
{
m_pVertexBuffer[i]->Lock(0,0,(BYTE**)&pVertexData,0);
for(int cVertex=0;cVertex<m_nVertex[i];cVertex++)
{
if(fMaxY<pVertexData[cVertex].v.y)
fMaxY=pVertexData[cVertex].v.y;
if(fMinY>pVertexData[cVertex].v.y)
fMinY=pVertexData[cVertex].v.y;
}
m_pVertexBuffer[i]->Unlock();
}
float fSize=fMaxY-fMinY;
float fRate;//,fEnd;
for(int i=0;i<(int)m_nVertex.size();i++)
{
LPDIRECT3DVERTEXBUFFER8 pAllocVB;
pAllocVB = CSceneManager::ms_pBufferPools->GetVertexBuffer(m_nVertex[i]*sizeof(TreeVertex),TREEVERTEXFVF,false);
/*
CSceneManager::GetDevice()->CreateVertexBuffer(m_nVertex[i]*sizeof(TreeVertex),D3DUSAGE_WRITEONLY,
TREEVERTEXFVF,D3DPOOL_MANAGED,&pAllocVB);
*/
pAllocVB->Lock(0,0,(BYTE**)&pVertexNormalData,0);
m_pIndicesBuffer[i]->Lock(0,m_nIndices[i]*3*sizeof(WORD),(BYTE**)&pIndicesData,0);
m_pVertexBuffer[i]->Lock(0,0,(BYTE**)&pVertexData,0);
for(int cIndices=0;cIndices<m_nIndices[i];cIndices++)
{
v[0]=(vector3*)&pVertexData[ pIndicesData[cIndices*3+0] ].v;
v[1]=(vector3*)&pVertexData[ pIndicesData[cIndices*3+1] ].v;
v[2]=(vector3*)&pVertexData[ pIndicesData[cIndices*3+2] ].v;
vecNormal= (*v[1]-*v[0])^(*v[2]-*v[1]);
vecNormal.Normalize();
pVertexData[ pIndicesData[cIndices*3+0] ].v;
pVertexData[ pIndicesData[cIndices*3+1] ].v;
pVertexData[ pIndicesData[cIndices*3+2] ].v;
pVertexNormalData[pIndicesData[cIndices*3+0]].v=pVertexData[ pIndicesData[cIndices*3+0] ].v;
pVertexNormalData[pIndicesData[cIndices*3+0]].tu=pVertexData[ pIndicesData[cIndices*3+0] ].tu;
pVertexNormalData[pIndicesData[cIndices*3+0]].tv=pVertexData[ pIndicesData[cIndices*3+0] ].tv;
pVertexNormalData[pIndicesData[cIndices*3+0]].n=vecNormal;
fRate=(pVertexNormalData[pIndicesData[cIndices*3+0]].v.y-fMinY)/fSize;
pVertexNormalData[pIndicesData[cIndices*3+0]].fWeight=fRate*fRate;
pVertexNormalData[pIndicesData[cIndices*3+1]].v=pVertexData[ pIndicesData[cIndices*3+1] ].v;
pVertexNormalData[pIndicesData[cIndices*3+1]].tu=pVertexData[ pIndicesData[cIndices*3+1] ].tu;
pVertexNormalData[pIndicesData[cIndices*3+1]].tv=pVertexData[ pIndicesData[cIndices*3+1] ].tv;
pVertexNormalData[pIndicesData[cIndices*3+1]].n=vecNormal;
fRate=(pVertexNormalData[pIndicesData[cIndices*3+1]].v.y-fMinY)/fSize;
pVertexNormalData[pIndicesData[cIndices*3+1]].fWeight=fRate*fRate;
pVertexNormalData[pIndicesData[cIndices*3+2]].v=pVertexData[ pIndicesData[cIndices*3+2] ].v;
pVertexNormalData[pIndicesData[cIndices*3+2]].tu=pVertexData[ pIndicesData[cIndices*3+2] ].tu;
pVertexNormalData[pIndicesData[cIndices*3+2]].tv=pVertexData[ pIndicesData[cIndices*3+2] ].tv;
pVertexNormalData[pIndicesData[cIndices*3+2]].n=vecNormal;
fRate=(pVertexNormalData[pIndicesData[cIndices*3+2]].v.y-fMinY)/fSize;
pVertexNormalData[pIndicesData[cIndices*3+2]].fWeight=fRate*fRate;
}
// smoothing
int *iTmp = new int[m_nVertex[i]];
int iCount;
for(int iVert = 0; iVert < m_nVertex[i]; iVert++)
{
memset(iTmp,0,sizeof(int) * m_nVertex[i]);
iCount = 0;
vector3 vecPos = pVertexNormalData[iVert].v;
vector3 vecNormal = vector3(0.0f,0.0f,0.0f);
for(int j = 0; j < m_nVertex[i]; j++ )
{
if(pVertexNormalData[j].v.x == pVertexNormalData[iVert].v.x &&
pVertexNormalData[j].v.y == pVertexNormalData[iVert].v.y &&
pVertexNormalData[j].v.z == pVertexNormalData[iVert].v.z)
{
iTmp[iCount++] = j;
vecNormal += pVertexNormalData[j].n;
}
}
vecNormal.Normalize();
for(int iT = 0; iT < iCount; iT++)
{
pVertexNormalData[iTmp[iT]].n = vecNormal;
}
}
delete[] iTmp;
iTmp = NULL;
//
pAllocVB->Unlock();
m_pIndicesBuffer[i]->Unlock();
m_pVertexBuffer[i]->Unlock();
//m_pVertexBuffer[i]->Release();
CSceneManager::ms_pBufferPools->UnRef(Caldron::Scene::D3DBUFFEROBJ_VERTEX,m_pVertexBuffer[i]);
m_pVertexBuffer[i] = NULL;
m_pVertexBuffer[i]=pAllocVB;
}
}
void CNMesh::AllUnlockBuffer()
{
if(m_bCompleteMesh)
return;
for(int cVB=0;cVB<(int)m_pVertexBuffer.size();cVB++)
m_pVertexBuffer[cVB]->Unlock();
for(int cIB=0;cIB<(int)m_pIndicesBuffer.size();cIB++)
m_pIndicesBuffer[cIB]->Unlock();
m_pVertex.clear();
m_pIndices.clear();
m_isAlreadyLock=false;
}
void CNMesh::AllLockBuffer()
{
if(m_bCompleteMesh)
return;
if(m_isAlreadyLock==true)
return;
m_isAlreadyLock=true;
if(m_dwShader==LightFVF)
{
LightVertex *pVertexData;
m_pVertex.clear();
for(int cVB=0;cVB<(int)m_pVertexBuffer.size();cVB++)
{
m_pVertexBuffer[cVB]->Lock(0,0,(BYTE**)&pVertexData,NULL);
m_pVertex.push_back(pVertexData);
}
}
else
{
MultiVertex *pVertexData;
m_pVertex.clear();
for(int cVB=0;cVB<(int)m_pVertexBuffer.size();cVB++)
{
m_pVertexBuffer[cVB]->Lock(0,0,(BYTE**)&pVertexData,NULL);
m_pVertex.push_back(pVertexData);
}
}
WORD *pIndicesData;
m_pIndices.clear();
for(int cIB=0;cIB<(int)m_pIndicesBuffer.size();cIB++)
{
m_pIndicesBuffer[cIB]->Lock(0,m_nIndices[cIB]*3*sizeof(WORD),(BYTE**)&pIndicesData,0);
m_pIndices.push_back(pIndicesData);
}
}
void CNMesh::RenderBox(LPDIRECT3DDEVICE8 pd3dDevice)
{
CRenderBoundingBox::Render(pd3dDevice, m_MinBox, m_MaxBox);
// for(size_t i = 0; i < m_vecMeshPieceBoundingBoxInfo.size(); ++i)
// {
// CRenderBoundingBox::Render(pd3dDevice, m_vecMeshPieceBoundingBoxInfo[i].vBoxMin, m_vecMeshPieceBoundingBoxInfo[i].vBoxMax);
// }
}
void CNMesh::Render(LPDIRECT3DDEVICE8 pd3dDevice)
{
static int only = 1;
if(!m_bRender)
return;
// R3S mesh bounding box render. <20>׽<EFBFBD>Ʈ<EFBFBD>ø<EFBFBD> on
//RenderBox(pd3dDevice);
// R3S mesh name render. <20>׽<EFBFBD>Ʈ<EFBFBD>ø<EFBFBD> on
//RenderName(pd3dDevice);
pd3dDevice->SetVertexShader(m_dwShader);
if(m_dwShader==MultiFVF)
{
for(int i=0;i<(int)m_pVertexBuffer.size();i++)
{
//if (i != only) continue;
if(m_pMat[m_pMatRef[i]])
pd3dDevice->SetTexture(0,m_pMat[m_pMatRef[i]]->GetTexture());
else
pd3dDevice->SetTexture(0,NULL);
pd3dDevice->SetStreamSource(0,m_pVertexBuffer[i],sizeof(MultiVertex));
pd3dDevice->SetIndices(m_pIndicesBuffer[i],0);
pd3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,
0,m_nVertex[i],
0,m_nIndices[i]);
CSceneManager::m_cRenderPolygon+=m_nIndices[i];
CSceneManager::m_cRenderVertex+=m_nVertex[i];
}
return;
}
if(m_dwShader==LightFVF)
{
for(int i=0;i<(int)m_pVertexBuffer.size();i++)
{
if(m_pMat[m_pMatRef[i]])
pd3dDevice->SetTexture(0,m_pMat[m_pMatRef[i]]->GetTexture());
else
pd3dDevice->SetTexture(0,NULL);
pd3dDevice->SetStreamSource(0,m_pVertexBuffer[i],sizeof(LightVertex));
pd3dDevice->SetIndices(m_pIndicesBuffer[i],0);
pd3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,
0,m_nVertex[i],
0,m_nIndices[i]);
CSceneManager::m_cRenderPolygon+=m_nIndices[i];
CSceneManager::m_cRenderVertex+=m_nVertex[i];
}
return;
}
if(m_dwShader==TREEVERTEXFVF)
{
for(int i=0;i<(int)m_pVertexBuffer.size();i++)
{
if(m_pMat[m_pMatRef[i]])
pd3dDevice->SetTexture(0,m_pMat[m_pMatRef[i]]->GetTexture());
else
pd3dDevice->SetTexture(0,NULL);
pd3dDevice->SetStreamSource(0,m_pVertexBuffer[i],sizeof(LightVertex));
pd3dDevice->SetIndices(m_pIndicesBuffer[i],0);
pd3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,
0,m_nVertex[i],
0,m_nIndices[i]);
CSceneManager::m_cRenderPolygon+=m_nIndices[i];
CSceneManager::m_cRenderVertex+=m_nVertex[i];
}
return;
}
}
void CNMesh::CalcBox()
{
if(m_bCompleteMesh)
return;
MultiVertex *pVertexData;
if(m_pVertexBuffer.size()==0)
{
throw CSceneLayerError("CMeshObject:CalcBox, This meshobject have not vertex");
}
for(int i=0;i<(int)m_pVertexBuffer.size();i++)
{
m_pVertexBuffer[i]->Lock(0,0,(BYTE**)&pVertexData,0);
if(m_MaxBox.x==-1.0f && m_MinBox.x==-1.0f)
{
m_MinBox.x=m_MaxBox.x=pVertexData[0].v.x;
m_MinBox.y=m_MaxBox.y=pVertexData[0].v.y;
m_MinBox.z=m_MaxBox.z=pVertexData[0].v.z;
}
for(int cv=0;cv<m_nVertex[i];cv++)
{
if(m_MaxBox.x < pVertexData[cv].v.x)
m_MaxBox.x=pVertexData[cv].v.x;
if(m_MaxBox.y < pVertexData[cv].v.y)
m_MaxBox.y=pVertexData[cv].v.y;
if(m_MaxBox.z < pVertexData[cv].v.z)
m_MaxBox.z=pVertexData[cv].v.z;
if(m_MinBox.x > pVertexData[cv].v.x)
m_MinBox.x=pVertexData[cv].v.x;
if(m_MinBox.y > pVertexData[cv].v.y)
m_MinBox.y=pVertexData[cv].v.y;
if(m_MinBox.z > pVertexData[cv].v.z)
m_MinBox.z=pVertexData[cv].v.z;
pVertexData[cv].diff.a=0xaa;
}
m_pVertexBuffer[i]->Unlock();
}
}
void CNMesh::RenderName(IDirect3DDevice8* pDevice)
{
vector3 vPosition ,vPos2D;
vPosition.x = (m_MinBox.x + m_MaxBox.x)/2.0f;
vPosition.z = (m_MinBox.z + m_MaxBox.z)/2.0f;
vPosition.y = m_MaxBox.y;
float w;
D3DMATRIX mat;
pDevice->GetTransform(D3DTS_WORLD, &mat);
vPosition.x += mat._41;
vPosition.y += mat._42;
vPosition.z += mat._43;
if (false == BaseGraphicsLayer::TransformVector(vPosition, vPos2D,w))
{
return;
}
if (vPos2D.z < 0.0f || vPos2D.z > 1.0f)
{
return;
}
BaseGraphicsLayer::DrawText(vPos2D.x, vPos2D.y, D3DCOLOR_ARGB(0xFF, 0, 0x60, 0xFF), m_strName);
}
}