#ifndef IObjectMesh_h__ #define IObjectMesh_h__ #include "IObject.h" #include "LString.h" #include "Globals.h" #include "render/IMaterial.h" #include 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 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(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::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__