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>
961 lines
26 KiB
C++
961 lines
26 KiB
C++
#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);
|
||
}
|
||
|
||
|
||
|
||
|
||
}
|
||
|