Files

184 lines
4.8 KiB
C++
Raw Permalink Normal View History

2025-05-13 02:46:21 +03:00
#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__