#include "ModelEntity.h" #include "Services.h" #include "Renderer.h" #include "ResourceManager.h" #include "Material.h" #include "Shader.h" #include "Mesh.h" #include using namespace std; /*---------------------------------------------------- * Constructor * @SetShaderValuesFunc - function pointer that points * to a function that will be * responsible for setting all the * shader params for the shader set * on this model entity *----------------------------------------------------*/ ModelEntity::ModelEntity( void (*SetShaderValuesFunc)(ShaderPtr& shader, ModelEntity* mesh) ) { SetShaderValues = SetShaderValuesFunc; D3DXMatrixIdentity(&mWorld); D3DXQuaternionIdentity(&mOrientation); mScale = D3DXVECTOR3(1.0f, 1.0f, 1.0f); mPosition = D3DXVECTOR3(0.0f, 0.0f, 0.0f); mCanDraw = true; } /*---------------------------------------------------- * Destructor. Removes this model's mesh and shader * from the mesh and shader resource managers. *----------------------------------------------------*/ ModelEntity::~ModelEntity() { //don't manually release the mesh or shader, call the material managers instead ShaderRCManagerPtr shaders = boost::static_pointer_cast>(Services::GetService(ShaderResService)); MeshRCManagerPtr meshes = boost::static_pointer_cast>(Services::GetService(MeshResService)); shaders->Remove(mShader); meshes->Remove(mMesh); } /*---------------------------------------------------- * Create the world matrix from the scale, position, * and orientation. And perform any other initialization *----------------------------------------------------*/ void ModelEntity::Initialize() { RendererPtr renderer = boost::static_pointer_cast(Services::GetService(RendererService)); mGDevice = renderer->GetDevice(); //create our world matrix D3DXMatrixIdentity(&mWorld); D3DXMATRIX scale; D3DXMatrixScaling(&scale, mScale.x, mScale.y, mScale.z); D3DXMATRIX trans; D3DXMatrixTranslation(&trans, mPosition.x, mPosition.y, mPosition.z); D3DXMATRIX orient; D3DXVECTOR3 axis; float angle = 0.0f; D3DXQuaternionToAxisAngle(&mOrientation, &axis, &angle); D3DXMatrixRotationAxis(&orient, &axis, angle); mWorld = scale * orient * trans; } /*---------------------------------------------------- * Update the world matrix *----------------------------------------------------*/ void ModelEntity::Update(float dt) { //rebuild world matrix D3DXMatrixIdentity(&mWorld); D3DXMATRIX scale; D3DXMatrixScaling(&scale, mScale.x, mScale.y, mScale.z); D3DXMATRIX trans; D3DXMatrixTranslation(&trans, mPosition.x, mPosition.y, mPosition.z); D3DXMATRIX orient; D3DXVECTOR3 axis; float angle = 0.0f; D3DXQuaternionToAxisAngle(&mOrientation, &axis, &angle); D3DXMatrixRotationAxis(&orient, &axis, angle); mWorld = scale * orient * trans; } /*---------------------------------------------------- * Draw the model *----------------------------------------------------*/ void ModelEntity::Draw(float dt) { if(!mCanDraw) return; //if we have a shader, draw with a shader applied //else just draw it. if(mShader) { DrawShader(dt); } else { HR(mGDevice->SetTransform(D3DTS_WORLD, &mWorld)); mMesh->Draw(0); } } /*---------------------------------------------------- * Draws a model with the shader set on the model ent. *----------------------------------------------------*/ void ModelEntity::DrawShader(float dt) { //set shader values that this object doesn't know about if(SetShaderValues != 0) SetShaderValues(mShader, this); vector mtrls = mMesh->GetMaterials(); mShader->ApplyLights(); mShader->Begin(); mShader->BeginPass(0); for(UINT j = 0; j < mtrls.size(); ++j) { mShader->SetMtrl(mtrls[j]->GetMaterial()); // If there is a texture, then use. if(mtrls[j]->GetTexture() != 0) { mShader->SetTexture(mtrls[j]->GetTexture()); } mShader->Update(dt); //commit values mMesh->Draw(j); } mShader->EndPass(); mShader->End(); } /*---------------------------------------------------- * Notify the mesh and shader of the lost device *----------------------------------------------------*/ void ModelEntity::OnLostDevice() { mMesh->OnLostDevice(); mShader->OnLostDevice(); } /*---------------------------------------------------- * Notify the mesh and shader of the reset device *----------------------------------------------------*/ void ModelEntity::OnResetDevice() { mMesh->OnResetDevice(); mShader->OnResetDevice(); } /*---------------------------------------------------- * Set the shader for the model. Use the name and path * to find the shader in the shader resource manager. * If it's not there already the manager is respoinsible * for creating the shader. *----------------------------------------------------*/ void ModelEntity::SetShader(const std::string& name, const std::string& path) { ShaderRCManagerPtr shaders = boost::static_pointer_cast>(Services::GetService(ShaderResService)); //if a shader already existed, remove its reference from the manager if(mShader) shaders->Remove(mShader); mShader = shaders->Add(name, path); } /*---------------------------------------------------- * Set the mesh for the model. Use the name and path * to find the mesh in the mesh resource manager. * If it's not there already the manager is respoinsible * for creating the mesh. *----------------------------------------------------*/ void ModelEntity::SetMesh(const std::string& name, const std::string& path) { MeshRCManagerPtr meshes = boost::static_pointer_cast>(Services::GetService(MeshResService)); //if a mesh already existed, remove its reference from the manager if(mMesh) meshes->Remove(mMesh); mMesh = meshes->Add(name, path); }