184 lines
4.8 KiB
C++
184 lines
4.8 KiB
C++
#ifndef IObjectMesh_h__
|
|||
|
|
#define IObjectMesh_h__
|
||
|
|
|
||
|
|
#include "IObject.h"
|
||
|
|
#include "LString.h"
|
||
|
|
#include "Globals.h"
|
||
|
|
#include "render/IMaterial.h"
|
||
|
|
#include <vector>
|
||
|
|
|
||
|
|
namespace LifeGraphics
|
||
|
|
{
|
||
|
|
#define MAX_BONES_COUNT 128
|
||
|
|
static const int PerObjectSkinningVSDataSize = 4 * 4 * 4 * MAX_BONES_COUNT;
|
||
|
|
|
||
|
|
struct PerObjectSkinningVSData
|
||
|
|
{
|
||
|
|
LifeMath::float4x4* mWorld;
|
||
|
|
};
|
||
|
|
|
||
|
|
struct MeshLOD
|
||
|
|
{
|
||
|
|
IMesh* mesh;
|
||
|
|
float distance;
|
||
|
|
};
|
||
|
|
class IObjectMesh : public IObject
|
||
|
|
{
|
||
|
|
private:
|
||
|
|
std::vector<MeshLOD> lods;
|
||
|
|
IMesh* mesh;
|
||
|
|
IConstantBuffer* skinBuffer;
|
||
|
|
LifeMath::float4x4* skinTempBuffer;
|
||
|
|
public:
|
||
|
|
IObjectMesh(IMesh* mesh)
|
||
|
|
{
|
||
|
|
setLod(mesh, 0.0f);
|
||
|
|
selectLod(0);
|
||
|
|
|
||
|
|
materials = new IMaterialProxy*[mesh->subsetCount];
|
||
|
|
memset(materials, 0, mesh->subsetCount * sizeof(materials[0]));
|
||
|
|
|
||
|
|
//HACK
|
||
|
|
for(int i = 0; i < mesh->subsetCount; i++)
|
||
|
|
{
|
||
|
|
materials[i] = ResourceManager::me()->getDefaultMaterial()->CreateProxy(this);
|
||
|
|
}
|
||
|
|
|
||
|
|
if(mesh->IsSkinned)
|
||
|
|
{
|
||
|
|
skinBuffer = CG::me()->GetRenderer()->CreateConstantBuffer(PerObjectSkinningVSDataSize);
|
||
|
|
skinTempBuffer = new LifeMath::float4x4[MAX_BONES_COUNT];
|
||
|
|
|
||
|
|
AnimationTrack* track = ResourceManager::me()->LoadAnimatrionTrack(AS_STRING("root/Data/Animations/miranda.sat"));
|
||
|
|
mesh->skin.controller.AddTrack(track);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
IObjectMesh(String path)
|
||
|
|
{
|
||
|
|
IMesh* mesh = ResourceManager::me()->GetMesh(path);
|
||
|
|
setLod(mesh, 0.0f);
|
||
|
|
selectLod(0);
|
||
|
|
|
||
|
|
materials = new IMaterialProxy*[mesh->subsetCount];
|
||
|
|
memset(materials, 0, mesh->subsetCount * sizeof(materials[0]));
|
||
|
|
//HACK
|
||
|
|
for(int i = 0; i < mesh->subsetCount; i++)
|
||
|
|
{
|
||
|
|
materials[i] = ResourceManager::me()->getDefaultMaterial()->CreateProxy(this);
|
||
|
|
}
|
||
|
|
if(mesh->IsSkinned)
|
||
|
|
{
|
||
|
|
skinBuffer = CG::me()->GetRenderer()->CreateConstantBuffer(PerObjectSkinningVSDataSize);
|
||
|
|
skinTempBuffer = new LifeMath::float4x4[MAX_BONES_COUNT];
|
||
|
|
|
||
|
|
AnimationTrack* track = ResourceManager::me()->LoadAnimatrionTrack(AS_STRING("root/Data/Animations/miranda.sat"));
|
||
|
|
mesh->skin.controller.AddTrack(track);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
~IObjectMesh()
|
||
|
|
{
|
||
|
|
}
|
||
|
|
void setMaterial(IMaterial* mat, int submesh, bool genShaders)
|
||
|
|
{
|
||
|
|
materials[submesh] = mat->CreateProxy(this);
|
||
|
|
//NEED FIXUP SHADERS
|
||
|
|
/*EFFECT_FLAGS flags = EF_NONE;
|
||
|
|
if(mesh->IsSkinned)
|
||
|
|
{
|
||
|
|
flags = EF_SKINNING;
|
||
|
|
}
|
||
|
|
*/
|
||
|
|
// materials[submesh]->pixelShader = ResourceManager::me()->getShader(materials[submesh],flags, ST_PS);
|
||
|
|
// materials[submesh]->vertexShader = ResourceManager::me()->getShader(materials[submesh],flags, ST_VS);
|
||
|
|
|
||
|
|
// materials[submesh]->vertexShaderLinearDepth = ResourceManager::me()->getShader(materials[submesh],flags | EF_LINEAR_DEPTH, ST_VS);
|
||
|
|
if(genShaders)
|
||
|
|
{
|
||
|
|
//materials[submesh]->g_buffer_pass_ps = ResourceManager::me()->getShader(materials[submesh],flags | EF_G_BUFFER_PREPASS, ST_PS);
|
||
|
|
//materials[submesh]->g_buffer_pass_vs = ResourceManager::me()->getShader(materials[submesh],flags | EF_G_BUFFER_PREPASS, ST_VS);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
void update(float dt)
|
||
|
|
{
|
||
|
|
PER_OBJECT_CONSTANTS objConst;
|
||
|
|
objConst.mWorld = getTransform()->GetMatrix();
|
||
|
|
perObjectCb->Update(&objConst, sizeof(PER_OBJECT_CONSTANTS));
|
||
|
|
|
||
|
|
for(int i = 0; i< getSumbeshCount(); i++)
|
||
|
|
{
|
||
|
|
IMaterialProxy* mat = getMaterial(i);
|
||
|
|
/////////*if(mat->diffuseMap.ptr() && mat->diffuseMap->IsVideoTexture())
|
||
|
|
////////{
|
||
|
|
//////// IVideoTexture* tex = static_cast<IVideoTexture*>(mat->diffuseMap.ptr());
|
||
|
|
//////// tex->Update(dt);
|
||
|
|
////////}*/
|
||
|
|
}
|
||
|
|
|
||
|
|
if (mesh->IsSkinned)
|
||
|
|
{
|
||
|
|
mesh->skin.controller.AdvanceTime(dt);
|
||
|
|
|
||
|
|
mesh->skin.skeleton.GetMatrices(skinTempBuffer);
|
||
|
|
|
||
|
|
skinBuffer->Update(skinTempBuffer, PerObjectSkinningVSDataSize);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
void bind()
|
||
|
|
{
|
||
|
|
IRenderer* renderer = CG::me()->GetRenderer();
|
||
|
|
renderer->SetVSConstantBuffer(perObjectCb, 0);
|
||
|
|
renderer->SetVertexBuffer(mesh->vertexData);
|
||
|
|
renderer->SetIndexBuffer(mesh->indexData);
|
||
|
|
|
||
|
|
renderer->SetInputLayout(mesh->inputLayout);
|
||
|
|
renderer->SetPrimitiveTopology(PT_TRIANGLE_LIST);
|
||
|
|
|
||
|
|
if(mesh->IsSkinned)
|
||
|
|
CG::me()->GetRenderer()->SetVSConstantBuffer(skinBuffer, 5);
|
||
|
|
}
|
||
|
|
void render(int submesh)
|
||
|
|
{
|
||
|
|
CG::me()->GetRenderer()->DrawIndexed(mesh->subsets[submesh].Offset,mesh->subsets[submesh].Length);
|
||
|
|
}
|
||
|
|
int getSumbeshCount() const
|
||
|
|
{
|
||
|
|
return mesh->subsetCount;
|
||
|
|
}
|
||
|
|
void selectLod(int lodNum)
|
||
|
|
{
|
||
|
|
mesh = lods[lodNum].mesh;
|
||
|
|
bBox = mesh->bBox;
|
||
|
|
}
|
||
|
|
void selectLod(const Camera* cam)
|
||
|
|
{
|
||
|
|
}
|
||
|
|
void setLod(IMesh* _mesh, float distance)
|
||
|
|
{
|
||
|
|
MeshLOD lod;
|
||
|
|
lod.distance = distance;
|
||
|
|
lod.mesh = _mesh;
|
||
|
|
|
||
|
|
int lodCount = lods.size();
|
||
|
|
if(!lodCount)
|
||
|
|
{
|
||
|
|
mesh = _mesh;
|
||
|
|
lods.push_back(lod);
|
||
|
|
Name = lods[0].mesh->Name;
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
for(std::vector<MeshLOD>::iterator iter = lods.begin(); iter!= lods.end(); ++iter)
|
||
|
|
{
|
||
|
|
if(iter->distance > distance)
|
||
|
|
lods.insert(iter,1,lod);
|
||
|
|
}
|
||
|
|
Name = lods[0].mesh->Name;
|
||
|
|
}
|
||
|
|
NodeType getType()
|
||
|
|
{
|
||
|
|
return NT_MESH;
|
||
|
|
}
|
||
|
|
};
|
||
|
|
}
|
||
|
|
#endif // IObjectMesh_h__
|