Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*-----------------------------------------*\
- | md5animation.cpp |
- | |
- | |
- \*-----------------------------------------*/
- #include "md5animation.h"
- /* CONSTRUCTOR & DECONSTRUCTOR */
- md5animation::md5animation()
- {
- m_smilesWorld = 0;
- m_texture = 0;
- }
- md5animation::~md5animation(){}
- /* INITIALIZATION */
- bool md5animation::Init(ID3D11Device* device, WCHAR* modelFilename, WCHAR* textureFilename)
- {
- bool r;
- r = LoadMD5Model(device, modelFilename, m_NewMD5Model, m_meshSRV, m_textureNameArray);
- if(!r)
- {return false;}
- r = InitBuffers(device);
- if(!r)
- {return false;}
- r = LoadTexture(device, textureFilename);
- if(!r)
- {return false;}
- return true;
- }
- bool md5animation::InitBuffers(ID3D11Device* device)
- {
- return true;
- }
- /* RENDER */
- void md5animation::Render(ID3D11DeviceContext* deviceContext)
- {
- RenderBuffers(deviceContext);
- return;
- }
- void md5animation::RenderBuffers(ID3D11DeviceContext* deviceContext)
- {
- unsigned int stride;
- unsigned int offset;
- //Set vertex buffer stride and offset
- stride = sizeof(VertexType);
- offset = 0;
- for(int i = 0; i < m_NewMD5Model.numSubsets; i ++)
- {
- //Set the grounds index buffer
- deviceContext->IASetIndexBuffer( m_NewMD5Model.subsets[i].indexBuff, DXGI_FORMAT_R32_UINT, 0);
- //Set the grounds vertex buffer
- deviceContext->IASetVertexBuffers( 0, 1, &m_NewMD5Model.subsets[i].vertBuff, &stride, &offset );
- deviceContext->UpdateSubresource( cbPerObjectBuffer, 0, NULL, &m_cbPerObj, 0, 0 );
- deviceContext->VSSetConstantBuffers( 0, 1, &cbPerObjectBuffer );
- deviceContext->PSSetConstantBuffers( 1, 1, &cbPerObjectBuffer );
- deviceContext->PSSetShaderResources( 0, 1, &m_meshSRV[m_NewMD5Model.subsets[i].texArrayIndex] );
- deviceContext->DrawIndexed( m_NewMD5Model.subsets[i].indices.size(), 0, 0 );
- }
- return;
- }
- int md5animation::GetIndexCount()
- {
- return m_indexCount;
- }
- ID3D11ShaderResourceView* md5animation::GetTexture()
- {
- return m_texture->GetTexture();
- }
- /* LOADER */
- bool md5animation::LoadMD5Model(ID3D11Device* device, std::wstring filename, Model3D& MD5Model,
- std::vector<ID3D11ShaderResourceView*>& shaderResourceViewArray, std::vector<std::wstring> texFileNameArray)
- {
- HRESULT hr;
- std::wifstream fileIn (filename.c_str()); //Open file
- std::wstring checkString; //Store next string
- if(fileIn) //Check if file was loaded
- {
- while(fileIn) //Loop untill file is finished
- {
- fileIn >> checkString; //Get next string
- if(checkString == L"MD5Version") //Get Version
- {
- /*
- fileIn >> checkString;
- MessageBox(0, checkString.c_str(), "MD5Version", MB_OK); //Display Version
- */
- }
- else if (checkString == L"commandline")
- {
- std::getline(fileIn, checkString); //Ignore rest of line
- }
- else if (checkString == L"numJoints")
- {
- fileIn >> MD5Model.numJoints; //Store joints
- }
- else if (checkString == L"numMeshes")
- {
- fileIn >> MD5Model.numSubsets; //Store Subsets on Meshes
- }
- else if (checkString == L"joints")
- {
- Joint tempJoint;
- fileIn >> checkString;
- for(int i=0; i<MD5Model.numJoints; i++)
- {
- fileIn >> tempJoint.name;
- if(tempJoint.name[tempJoint.name.size()-1] != '"') //Skip spaces while reading in
- {
- wchar_t checkChar;
- bool jointNameFound = false;
- while(!jointNameFound)
- {
- checkChar = fileIn.get();
- if(checkChar == '"')
- jointNameFound = true;
- tempJoint.name += checkChar;
- }
- }
- fileIn >> tempJoint.parentID; //Store parent joint's ID
- fileIn >> checkString;
- fileIn >> tempJoint.pos.x >> tempJoint.pos.z >> tempJoint.pos.y;
- fileIn >> checkString >> checkString;
- fileIn >> tempJoint.orientation.x >> tempJoint.orientation.z >> tempJoint.orientation.y;
- tempJoint.name.erase(0, 1); //Erase quotation marks from the joints name
- float t = 1.0f - (tempJoint.orientation.x * tempJoint.orientation.x)
- - (tempJoint.orientation.y * tempJoint.orientation.y)
- - (tempJoint.orientation.z * tempJoint.orientation.z);
- if (t<0.0f)
- {
- tempJoint.orientation.w = 0.0f;
- }
- else
- {
- tempJoint.orientation.w = -sqrtf(t);
- }
- std::getline(fileIn, checkString); //Skip
- MD5Model.joints.push_back(tempJoint); //Store joint into the models joint vector
- }
- fileIn >> checkString;
- }
- else if (checkString == L"mesh")
- {
- ModelSubset subset;
- int numVerts, numTris, numWeights;
- fileIn >> checkString;
- fileIn >> checkString;
- while(checkString != L"}") //Read untill }
- {
- if(checkString == L"shader") //Load texture/material
- {
- std::wstring fileNamePath;
- fileIn >> fileNamePath; //Get texture's filename
- //Ignore spaces
- if(fileNamePath[fileNamePath.size()-1] != '"')
- {
- wchar_t checkChar;
- bool fileNameFound = false;
- while(!fileNameFound)
- {
- checkChar = fileIn.get();
- if(checkChar == '"')
- fileNameFound = true;
- fileNamePath += checkChar;
- }
- }
- fileNamePath.erase(0,1);
- fileNamePath.erase(fileNamePath.size()-1, 1);
- //Check to see if texture has loaded
- bool alreadyLoaded = false;
- for(int i = 0; i < texFileNameArray.size(); ++i)
- {
- if(fileNamePath == texFileNameArray[i])
- {
- alreadyLoaded = true;
- subset.texArrayIndex = i;
- }
- }
- //Load texture if not loaded
- if(!alreadyLoaded)
- {
- ID3D11ShaderResourceView* tempMeshSRV;
- hr = D3DX11CreateShaderResourceViewFromFile(device, fileNamePath.c_str(),
- NULL, NULL, &tempMeshSRV, NULL);
- if(SUCCEEDED(hr))
- {
- texFileNameArray.push_back(fileNamePath.c_str());
- subset.texArrayIndex = shaderResourceViewArray.size();
- shaderResourceViewArray.push_back(tempMeshSRV);
- }
- else
- {
- MessageBox(0, fileNamePath.c_str(), //display message
- L"Could Not Open:", MB_OK);
- return false;
- }
- }
- std::getline(fileIn, checkString);
- }
- else if (checkString == L"numverts")
- {
- fileIn >> numVerts;
- std::getline(fileIn, checkString);
- for(int i = 0; i < numVerts; i++)
- {
- VertexType tempVert;
- fileIn >> checkString >> checkString >> checkString; //Store tex coords
- fileIn >> tempVert.texCoord.x >> tempVert.texCoord.y;
- fileIn >> checkString; //Skip )
- fileIn >> tempVert.StartWeight; //Index of first weight this vert will be weighted to
- fileIn >> tempVert.WeightCount; //Number of weights for this vertex
- std::getline(fileIn, checkString); //Skip rest of this line
- subset.vertices.push_back(tempVert); //Push back this vertex into subsets vertex vector
- }
- }
- else if (checkString == L"numtris")
- {
- fileIn >> numTris;
- subset.numTriangles = numTris;
- std::getline(fileIn, checkString); //Skip
- for(int i = 0; i < numTris; i++) //Loop through each triangle
- {
- DWORD tempIndex;
- fileIn >> checkString; //Skip "tri"
- fileIn >> checkString; //Skip tri counter
- for (int k = 0; k < 3; k++) //Store the 3 indices
- {
- fileIn >> tempIndex;
- subset.indices.push_back(tempIndex);
- }
- std::getline(fileIn, checkString); //Skip rest
- }
- }
- else if ( checkString == L"numweights")
- {
- fileIn >> numWeights;
- std::getline(fileIn, checkString); //Skip rest of this line
- for(int i = 0; i < numWeights; i++)
- {
- Weight tempWeight;
- fileIn >> checkString >> checkString; //Skip "weight #"
- fileIn >> tempWeight.jointID; //Store weight's joint ID
- fileIn >> tempWeight.bias; //Store weight's influence over a vertex
- fileIn >> checkString; //Skip "("
- fileIn >> tempWeight.pos.x //Store weight's pos in joint's local space
- >> tempWeight.pos.z
- >> tempWeight.pos.y;
- std::getline(fileIn, checkString); //Skip rest of this line
- subset.weights.push_back(tempWeight); //Push back tempWeight into subsets Weight array
- }
- }
- else
- std::getline(fileIn, checkString); //Skip anything else
- fileIn >> checkString; //Skip "}"
- }
- //Find each vertex's position using the joints and weights
- for (int i = 0; i < subset.vertices.size(); ++i)
- {
- VertexType tempVert = subset.vertices[i];
- tempVert.pos = XMFLOAT3(0, 0, 0); //Clear Vertex's position
- //Sum up the joints and weights information to get vertex's position
- for ( int j = 0; j < tempVert.WeightCount; ++j )
- {
- Weight tempWeight = subset.weights[tempVert.StartWeight + j];
- Joint tempJoint = MD5Model.joints[tempWeight.jointID];
- //Convert joint orientation and weight pos to vectors for easier computation
- XMVECTOR tempJointOrientation = XMVectorSet(tempJoint.orientation.x, tempJoint.orientation.y, tempJoint.orientation.z, tempJoint.orientation.w);
- XMVECTOR tempWeightPos = XMVectorSet(tempWeight.pos.x, tempWeight.pos.y, tempWeight.pos.z, 0.0f);
- //Inverse the x, y, and z
- XMVECTOR tempJointOrientationConjugate = XMVectorSet(-tempJoint.orientation.x, -tempJoint.orientation.y, -tempJoint.orientation.z, tempJoint.orientation.w);
- //Calculate vertex position (in joint space, eg. rotate the point around (0,0,0)) for this weight using the joint orientation quaternion and its conjugate
- XMFLOAT3 rotatedPoint;
- XMStoreFloat3(&rotatedPoint, XMQuaternionMultiply(XMQuaternionMultiply(tempJointOrientation, tempWeightPos), tempJointOrientationConjugate));
- //Move the verices position from joint space (0,0,0) to the joints position in world space, taking the weights bias into account
- tempVert.pos.x += ( tempJoint.pos.x + rotatedPoint.x ) * tempWeight.bias;
- tempVert.pos.y += ( tempJoint.pos.y + rotatedPoint.y ) * tempWeight.bias;
- tempVert.pos.z += ( tempJoint.pos.z + rotatedPoint.z ) * tempWeight.bias;
- }
- subset.positions.push_back(tempVert.pos); //Store the vertices position in the position vector instead of straight into the vertex vector
- }
- //Put the positions into the vertices for this subset
- for(int i = 0; i < subset.vertices.size(); i++)
- {
- subset.vertices[i].pos = subset.positions[i];
- }
- //Calculate vertex normals using normal averaging
- std::vector<XMFLOAT3> tempNormal;
- //normalized and unnormalized normals
- XMFLOAT3 unnormalized = XMFLOAT3(0.0f, 0.0f, 0.0f);
- //Used to get vectors (sides) from the position of the verts
- float vecX, vecY, vecZ;
- //Two edges of our triangle
- XMVECTOR edge1 = XMVectorSet(0.0f, 0.0f, 0.0f, 0.0f);
- XMVECTOR edge2 = XMVectorSet(0.0f, 0.0f, 0.0f, 0.0f);
- //Compute face normals
- for(int i = 0; i < subset.numTriangles; ++i)
- {
- //Get the vector describing one edge of our triangle (edge 0,2)
- vecX = subset.vertices[subset.indices[(i*3)]].pos.x - subset.vertices[subset.indices[(i*3)+2]].pos.x;
- vecY = subset.vertices[subset.indices[(i*3)]].pos.y - subset.vertices[subset.indices[(i*3)+2]].pos.y;
- vecZ = subset.vertices[subset.indices[(i*3)]].pos.z - subset.vertices[subset.indices[(i*3)+2]].pos.z;
- edge1 = XMVectorSet(vecX, vecY, vecZ, 0.0f); //Create our first edge
- //Get the vector describing another edge of our triangle (edge 2,1)
- vecX = subset.vertices[subset.indices[(i*3)+2]].pos.x - subset.vertices[subset.indices[(i*3)+1]].pos.x;
- vecY = subset.vertices[subset.indices[(i*3)+2]].pos.y - subset.vertices[subset.indices[(i*3)+1]].pos.y;
- vecZ = subset.vertices[subset.indices[(i*3)+2]].pos.z - subset.vertices[subset.indices[(i*3)+1]].pos.z;
- edge2 = XMVectorSet(vecX, vecY, vecZ, 0.0f); //Create our second edge
- //Cross multiply the two edge vectors to get the un-normalized face normal
- XMStoreFloat3(&unnormalized, XMVector3Cross(edge1, edge2));
- tempNormal.push_back(unnormalized);
- }
- //Compute vertex normals (normal Averaging)
- XMVECTOR normalSum = XMVectorSet(0.0f, 0.0f, 0.0f, 0.0f);
- int facesUsing = 0;
- float tX, tY, tZ; //temp axis variables
- //Go through each vertex
- for(int i = 0; i < subset.vertices.size(); ++i)
- {
- //Check which triangles use this vertex
- for(int j = 0; j < subset.numTriangles; ++j)
- {
- if(subset.indices[j*3] == i ||
- subset.indices[(j*3)+1] == i ||
- subset.indices[(j*3)+2] == i)
- {
- tX = XMVectorGetX(normalSum) + tempNormal[j].x;
- tY = XMVectorGetY(normalSum) + tempNormal[j].y;
- tZ = XMVectorGetZ(normalSum) + tempNormal[j].z;
- normalSum = XMVectorSet(tX, tY, tZ, 0.0f); //If a face is using the vertex, add the unormalized face normal to the normalSum
- facesUsing++;
- }
- }
- //Get the actual normal by dividing the normalSum by the number of faces sharing the vertex
- normalSum = normalSum / facesUsing;
- //Normalize the normalSum vector
- normalSum = XMVector3Normalize(normalSum);
- //Store the normal and tangent in our current vertex
- subset.vertices[i].normal.x = -XMVectorGetX(normalSum);
- subset.vertices[i].normal.y = -XMVectorGetY(normalSum);
- subset.vertices[i].normal.z = -XMVectorGetZ(normalSum);
- //Clear normalSum, facesUsing for next vertex
- normalSum = XMVectorSet(0.0f, 0.0f, 0.0f, 0.0f);
- facesUsing = 0;
- }
- //Create index buffer
- D3D11_BUFFER_DESC indexBufferDesc;
- ZeroMemory( &indexBufferDesc, sizeof(indexBufferDesc) );
- indexBufferDesc.Usage = D3D11_USAGE_DEFAULT;
- indexBufferDesc.ByteWidth = sizeof(DWORD) * subset.numTriangles * 3;
- indexBufferDesc.BindFlags = D3D11_BIND_INDEX_BUFFER;
- indexBufferDesc.CPUAccessFlags = 0;
- indexBufferDesc.MiscFlags = 0;
- D3D11_SUBRESOURCE_DATA iinitData;
- iinitData.pSysMem = &subset.indices[0];
- device->CreateBuffer(&indexBufferDesc, &iinitData, &subset.indexBuff);
- //Create Vertex Buffer
- D3D11_BUFFER_DESC vertexBufferDesc;
- ZeroMemory( &vertexBufferDesc, sizeof(vertexBufferDesc) );
- vertexBufferDesc.Usage = D3D11_USAGE_DYNAMIC;
- vertexBufferDesc.ByteWidth = sizeof( VertexType ) * subset.vertices.size();
- vertexBufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
- vertexBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
- vertexBufferDesc.MiscFlags = 0;
- D3D11_SUBRESOURCE_DATA vertexBufferData;
- ZeroMemory( &vertexBufferData, sizeof(vertexBufferData) );
- vertexBufferData.pSysMem = &subset.vertices[0];
- hr = device->CreateBuffer( &vertexBufferDesc, &vertexBufferData, &subset.vertBuff);
- //Push back the temp subset into the models subset vector
- MD5Model.subsets.push_back(subset);
- }
- }
- }
- else
- {
- //SwapChain->SetFullscreenState(false, NULL); // Make sure we are out of fullscreen
- //Create message
- std::wstring message = L"Could not open: ";
- message += filename;
- MessageBox(0, message.c_str(), //display message
- L"Error", MB_OK);
- return false;
- }
- return true;
- }
- bool md5animation::LoadTexture(ID3D11Device* device, WCHAR* filename)
- {
- bool r;
- //Create the texture object
- m_texture = new Texture;
- if(!m_texture)
- {return false;}
- //Initialize the texture object
- r = m_texture->Init(device, filename);
- if(!r)
- {return false;}
- return true;
- }
- /* SHUTDOWN */
- void md5animation::Shutdown()
- {
- ReleaseTexture();
- ShutdownBuffers();
- ReleaseModel();
- }
- void md5animation::ShutdownBuffers()
- {
- if(m_indexBuffer)
- {
- m_indexBuffer->Release();
- m_indexBuffer = 0;
- }
- if(m_vertexBuffer)
- {
- m_vertexBuffer->Release();
- m_vertexBuffer = 0;
- }
- return;
- }
- void md5animation::ReleaseModel()
- {
- for (int i = 0; i < m_NewMD5Model.numSubsets; i++)
- {
- m_NewMD5Model.subsets[i].indexBuff->Release();
- m_NewMD5Model.subsets[i].vertBuff->Release();
- }
- }
- void md5animation::ReleaseTexture()
- {
- if(m_texture)
- {
- m_texture->Shutdown();
- delete m_texture;
- m_texture = 0;
- }
- return;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement