Advertisement
Guest User

md5animation.cpp

a guest
Mar 5th, 2013
107
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 16.38 KB | None | 0 0
  1. /*-----------------------------------------*\
  2. |             md5animation.cpp              |
  3. |                                           |
  4. |                                           |
  5. \*-----------------------------------------*/
  6.  
  7. #include "md5animation.h"
  8.  
  9. /* CONSTRUCTOR & DECONSTRUCTOR */
  10. md5animation::md5animation()
  11. {
  12.     m_smilesWorld = 0;
  13.     m_texture     = 0;
  14. }
  15. md5animation::~md5animation(){}
  16.  
  17. /* INITIALIZATION */
  18. bool md5animation::Init(ID3D11Device* device, WCHAR* modelFilename, WCHAR* textureFilename)
  19. {
  20.     bool r;
  21.  
  22.     r = LoadMD5Model(device, modelFilename, m_NewMD5Model, m_meshSRV, m_textureNameArray);
  23.     if(!r)
  24.     {return false;}
  25.  
  26.     r = InitBuffers(device);
  27.     if(!r)
  28.     {return false;}
  29.  
  30.     r = LoadTexture(device, textureFilename);
  31.     if(!r)
  32.     {return false;}
  33.  
  34.     return true;
  35. }
  36.  
  37. bool md5animation::InitBuffers(ID3D11Device* device)
  38. {
  39.     return true;
  40. }
  41.  
  42. /* RENDER */
  43. void md5animation::Render(ID3D11DeviceContext* deviceContext)
  44. {
  45.     RenderBuffers(deviceContext);
  46.     return;
  47. }
  48.  
  49. void md5animation::RenderBuffers(ID3D11DeviceContext* deviceContext)
  50. {
  51.     unsigned int stride;
  52.     unsigned int offset;
  53.  
  54.     //Set vertex buffer stride and offset
  55.     stride = sizeof(VertexType);
  56.     offset = 0;
  57.    
  58.     for(int i = 0; i < m_NewMD5Model.numSubsets; i ++)
  59.     {
  60.         //Set the grounds index buffer
  61.         deviceContext->IASetIndexBuffer( m_NewMD5Model.subsets[i].indexBuff, DXGI_FORMAT_R32_UINT, 0);
  62.         //Set the grounds vertex buffer
  63.         deviceContext->IASetVertexBuffers( 0, 1, &m_NewMD5Model.subsets[i].vertBuff, &stride, &offset );
  64.  
  65.         deviceContext->UpdateSubresource( cbPerObjectBuffer, 0, NULL, &m_cbPerObj, 0, 0 );
  66.         deviceContext->VSSetConstantBuffers( 0, 1, &cbPerObjectBuffer );
  67.         deviceContext->PSSetConstantBuffers( 1, 1, &cbPerObjectBuffer );
  68.         deviceContext->PSSetShaderResources( 0, 1, &m_meshSRV[m_NewMD5Model.subsets[i].texArrayIndex] );
  69.         deviceContext->DrawIndexed( m_NewMD5Model.subsets[i].indices.size(), 0, 0 );
  70.     }
  71.     return;
  72. }
  73.  
  74.  
  75. int md5animation::GetIndexCount()
  76. {
  77.     return m_indexCount;
  78. }
  79.  
  80. ID3D11ShaderResourceView* md5animation::GetTexture()
  81. {
  82.     return m_texture->GetTexture();
  83. }
  84.  
  85. /* LOADER */
  86. bool md5animation::LoadMD5Model(ID3D11Device* device, std::wstring filename, Model3D& MD5Model,
  87.                                 std::vector<ID3D11ShaderResourceView*>& shaderResourceViewArray, std::vector<std::wstring> texFileNameArray)
  88. {
  89.     HRESULT hr;
  90.  
  91.     std::wifstream fileIn (filename.c_str());       //Open file
  92.     std::wstring checkString;                       //Store next string
  93.  
  94.     if(fileIn)          //Check if file was loaded
  95.     {
  96.         while(fileIn)   //Loop untill file is finished
  97.         {
  98.             fileIn >> checkString;  //Get next string
  99.  
  100.             if(checkString == L"MD5Version")    //Get Version
  101.             {
  102.                 /*
  103.                 fileIn >> checkString;
  104.                 MessageBox(0, checkString.c_str(), "MD5Version", MB_OK);    //Display Version
  105.                 */
  106.             }
  107.             else if (checkString == L"commandline")
  108.             {
  109.                 std::getline(fileIn, checkString);      //Ignore rest of line
  110.             }
  111.             else if (checkString == L"numJoints")
  112.             {
  113.                 fileIn >> MD5Model.numJoints;           //Store joints
  114.             }
  115.             else if (checkString == L"numMeshes")
  116.             {
  117.                 fileIn >> MD5Model.numSubsets;          //Store Subsets on Meshes
  118.             }
  119.             else if (checkString == L"joints")
  120.             {
  121.                 Joint tempJoint;
  122.                 fileIn >> checkString;
  123.  
  124.                 for(int i=0; i<MD5Model.numJoints; i++)
  125.                 {
  126.                     fileIn >> tempJoint.name;
  127.  
  128.                     if(tempJoint.name[tempJoint.name.size()-1] != '"')  //Skip spaces while reading in
  129.                     {
  130.                         wchar_t checkChar;
  131.                         bool jointNameFound = false;
  132.                         while(!jointNameFound)
  133.                         {
  134.                             checkChar = fileIn.get();
  135.  
  136.                             if(checkChar == '"')
  137.                                 jointNameFound = true;     
  138.  
  139.                             tempJoint.name += checkChar;                                                           
  140.                         }
  141.                     }
  142.  
  143.                     fileIn >> tempJoint.parentID;   //Store parent joint's ID
  144.                     fileIn >> checkString;
  145.                     fileIn >> tempJoint.pos.x >> tempJoint.pos.z >> tempJoint.pos.y;
  146.                     fileIn >> checkString >> checkString;
  147.                     fileIn >> tempJoint.orientation.x >> tempJoint.orientation.z >> tempJoint.orientation.y;
  148.  
  149.                     tempJoint.name.erase(0, 1); //Erase quotation marks from the joints name
  150.  
  151.                     float t = 1.0f - (tempJoint.orientation.x * tempJoint.orientation.x)
  152.                         - (tempJoint.orientation.y * tempJoint.orientation.y)
  153.                         - (tempJoint.orientation.z * tempJoint.orientation.z);
  154.                     if (t<0.0f)
  155.                     {
  156.                         tempJoint.orientation.w = 0.0f;
  157.                     }
  158.                     else
  159.                     {
  160.                         tempJoint.orientation.w = -sqrtf(t);
  161.                     }
  162.                     std::getline(fileIn, checkString);      //Skip
  163.                     MD5Model.joints.push_back(tempJoint);   //Store joint into the models joint vector
  164.                 }
  165.                 fileIn >> checkString;
  166.             }
  167.             else if (checkString == L"mesh")
  168.             {
  169.                 ModelSubset subset;
  170.                 int numVerts, numTris, numWeights;
  171.  
  172.                 fileIn >> checkString;
  173.                 fileIn >> checkString;
  174.                 while(checkString != L"}")  //Read untill }
  175.                 {
  176.                     if(checkString == L"shader")    //Load texture/material
  177.                     {
  178.                         std::wstring fileNamePath;
  179.                         fileIn >> fileNamePath;     //Get texture's filename
  180.  
  181.                         //Ignore spaces
  182.                         if(fileNamePath[fileNamePath.size()-1] != '"')
  183.                         {
  184.                             wchar_t checkChar;
  185.                             bool fileNameFound = false;
  186.                             while(!fileNameFound)
  187.                             {
  188.                                 checkChar = fileIn.get();
  189.  
  190.                                 if(checkChar == '"')
  191.                                     fileNameFound = true;
  192.  
  193.                                 fileNamePath += checkChar;                                                                 
  194.                             }
  195.                         }
  196.  
  197.                         fileNamePath.erase(0,1);
  198.                         fileNamePath.erase(fileNamePath.size()-1, 1);
  199.  
  200.                         //Check to see if texture has loaded
  201.                         bool alreadyLoaded = false;
  202.                         for(int i = 0; i < texFileNameArray.size(); ++i)
  203.                         {
  204.                             if(fileNamePath == texFileNameArray[i])
  205.                             {
  206.                                 alreadyLoaded = true;
  207.                                 subset.texArrayIndex = i;
  208.                             }
  209.                         }
  210.  
  211.                         //Load texture if not loaded
  212.                         if(!alreadyLoaded)
  213.                         {
  214.                             ID3D11ShaderResourceView* tempMeshSRV;
  215.                             hr = D3DX11CreateShaderResourceViewFromFile(device, fileNamePath.c_str(),
  216.                                 NULL, NULL, &tempMeshSRV, NULL);
  217.  
  218.                             if(SUCCEEDED(hr))
  219.                             {
  220.                                 texFileNameArray.push_back(fileNamePath.c_str());
  221.                                 subset.texArrayIndex = shaderResourceViewArray.size();
  222.                                 shaderResourceViewArray.push_back(tempMeshSRV);
  223.                             }
  224.                             else
  225.                             {
  226.                                 MessageBox(0, fileNamePath.c_str(),     //display message
  227.                                     L"Could Not Open:", MB_OK);
  228.                                 return false;
  229.                             }
  230.                         }  
  231.  
  232.                         std::getline(fileIn, checkString);
  233.                     }
  234.                     else if (checkString == L"numverts")
  235.                     {
  236.                         fileIn >> numVerts;
  237.  
  238.                         std::getline(fileIn, checkString);
  239.  
  240.                         for(int i = 0; i < numVerts; i++)
  241.                         {
  242.                             VertexType tempVert;
  243.  
  244.                             fileIn >> checkString >> checkString >> checkString;    //Store tex coords
  245.                             fileIn >> tempVert.texCoord.x >> tempVert.texCoord.y;
  246.                             fileIn >> checkString;                                  //Skip )
  247.                             fileIn >> tempVert.StartWeight;                         //Index of first weight this vert will be weighted to
  248.                             fileIn >> tempVert.WeightCount;                         //Number of weights for this vertex
  249.                             std::getline(fileIn, checkString);                      //Skip rest of this line
  250.                             subset.vertices.push_back(tempVert);                    //Push back this vertex into subsets vertex vector
  251.                         }
  252.                     }
  253.                     else if (checkString == L"numtris")
  254.                     {
  255.                         fileIn >> numTris;
  256.                         subset.numTriangles = numTris;
  257.  
  258.                         std::getline(fileIn, checkString);      //Skip
  259.  
  260.                         for(int i = 0; i < numTris; i++)        //Loop through each triangle
  261.                         {
  262.                             DWORD tempIndex;
  263.                             fileIn >> checkString;              //Skip "tri"
  264.                             fileIn >> checkString;              //Skip tri counter
  265.  
  266.                             for (int k = 0; k < 3; k++)         //Store the 3 indices
  267.                             {
  268.                                 fileIn >> tempIndex;
  269.                                 subset.indices.push_back(tempIndex);
  270.                             }
  271.                             std::getline(fileIn, checkString);  //Skip rest
  272.                         }
  273.                     }
  274.                     else if ( checkString == L"numweights")
  275.                     {
  276.                             fileIn >> numWeights;
  277.  
  278.                             std::getline(fileIn, checkString);              //Skip rest of this line
  279.  
  280.                             for(int i = 0; i < numWeights; i++)
  281.                             {
  282.                                 Weight tempWeight;
  283.  
  284.                                 fileIn >> checkString >> checkString;       //Skip "weight #"
  285.                                 fileIn >> tempWeight.jointID;               //Store weight's joint ID
  286.                                 fileIn >> tempWeight.bias;                  //Store weight's influence over a vertex
  287.                                 fileIn >> checkString;                      //Skip "("
  288.                                 fileIn >> tempWeight.pos.x                  //Store weight's pos in joint's local space
  289.                                     >> tempWeight.pos.z
  290.                                     >> tempWeight.pos.y;
  291.  
  292.                                 std::getline(fileIn, checkString);          //Skip rest of this line
  293.  
  294.                                 subset.weights.push_back(tempWeight);       //Push back tempWeight into subsets Weight array
  295.                             }
  296.                         }
  297.                         else
  298.  
  299.                             std::getline(fileIn, checkString);              //Skip anything else
  300.                             fileIn >> checkString;                          //Skip "}"
  301.                     }
  302.  
  303.                     //Find each vertex's position using the joints and weights
  304.                     for (int i = 0; i < subset.vertices.size(); ++i)
  305.                     {
  306.                         VertexType tempVert = subset.vertices[i];
  307.                         tempVert.pos = XMFLOAT3(0, 0, 0);           //Clear Vertex's position
  308.  
  309.                         //Sum up the joints and weights information to get vertex's position
  310.                         for ( int j = 0; j < tempVert.WeightCount; ++j )
  311.                         {
  312.                             Weight tempWeight = subset.weights[tempVert.StartWeight + j];
  313.                             Joint tempJoint = MD5Model.joints[tempWeight.jointID];
  314.  
  315.                             //Convert joint orientation and weight pos to vectors for easier computation
  316.                             XMVECTOR tempJointOrientation = XMVectorSet(tempJoint.orientation.x, tempJoint.orientation.y, tempJoint.orientation.z, tempJoint.orientation.w);
  317.                             XMVECTOR tempWeightPos = XMVectorSet(tempWeight.pos.x, tempWeight.pos.y, tempWeight.pos.z, 0.0f);
  318.  
  319.                             //Inverse the x, y, and z
  320.                             XMVECTOR tempJointOrientationConjugate = XMVectorSet(-tempJoint.orientation.x, -tempJoint.orientation.y, -tempJoint.orientation.z, tempJoint.orientation.w);
  321.  
  322.                             //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
  323.                             XMFLOAT3 rotatedPoint;
  324.                             XMStoreFloat3(&rotatedPoint, XMQuaternionMultiply(XMQuaternionMultiply(tempJointOrientation, tempWeightPos), tempJointOrientationConjugate));
  325.  
  326.                             //Move the verices position from joint space (0,0,0) to the joints position in world space, taking the weights bias into account
  327.                             tempVert.pos.x += ( tempJoint.pos.x + rotatedPoint.x ) * tempWeight.bias;
  328.                             tempVert.pos.y += ( tempJoint.pos.y + rotatedPoint.y ) * tempWeight.bias;
  329.                             tempVert.pos.z += ( tempJoint.pos.z + rotatedPoint.z ) * tempWeight.bias;
  330.                         }
  331.                         subset.positions.push_back(tempVert.pos);           //Store the vertices position in the position vector instead of straight into the vertex vector
  332.                     }
  333.  
  334.                     //Put the positions into the vertices for this subset
  335.                     for(int i = 0; i < subset.vertices.size(); i++)
  336.                     {
  337.                         subset.vertices[i].pos = subset.positions[i];
  338.                     }
  339.  
  340.                     //Calculate vertex normals using normal averaging
  341.                     std::vector<XMFLOAT3> tempNormal;
  342.  
  343.                     //normalized and unnormalized normals
  344.                     XMFLOAT3 unnormalized = XMFLOAT3(0.0f, 0.0f, 0.0f);
  345.  
  346.                     //Used to get vectors (sides) from the position of the verts
  347.                     float vecX, vecY, vecZ;
  348.  
  349.                     //Two edges of our triangle
  350.                     XMVECTOR edge1 = XMVectorSet(0.0f, 0.0f, 0.0f, 0.0f);
  351.                     XMVECTOR edge2 = XMVectorSet(0.0f, 0.0f, 0.0f, 0.0f);
  352.  
  353.                     //Compute face normals
  354.                     for(int i = 0; i < subset.numTriangles; ++i)
  355.                     {
  356.                         //Get the vector describing one edge of our triangle (edge 0,2)
  357.                         vecX = subset.vertices[subset.indices[(i*3)]].pos.x - subset.vertices[subset.indices[(i*3)+2]].pos.x;
  358.                         vecY = subset.vertices[subset.indices[(i*3)]].pos.y - subset.vertices[subset.indices[(i*3)+2]].pos.y;
  359.                         vecZ = subset.vertices[subset.indices[(i*3)]].pos.z - subset.vertices[subset.indices[(i*3)+2]].pos.z;      
  360.                         edge1 = XMVectorSet(vecX, vecY, vecZ, 0.0f);    //Create our first edge
  361.  
  362.                         //Get the vector describing another edge of our triangle (edge 2,1)
  363.                         vecX = subset.vertices[subset.indices[(i*3)+2]].pos.x - subset.vertices[subset.indices[(i*3)+1]].pos.x;
  364.                         vecY = subset.vertices[subset.indices[(i*3)+2]].pos.y - subset.vertices[subset.indices[(i*3)+1]].pos.y;
  365.                         vecZ = subset.vertices[subset.indices[(i*3)+2]].pos.z - subset.vertices[subset.indices[(i*3)+1]].pos.z;    
  366.                         edge2 = XMVectorSet(vecX, vecY, vecZ, 0.0f);    //Create our second edge
  367.  
  368.                         //Cross multiply the two edge vectors to get the un-normalized face normal
  369.                         XMStoreFloat3(&unnormalized, XMVector3Cross(edge1, edge2));
  370.  
  371.                         tempNormal.push_back(unnormalized);
  372.                     }
  373.  
  374.                     //Compute vertex normals (normal Averaging)
  375.                     XMVECTOR normalSum = XMVectorSet(0.0f, 0.0f, 0.0f, 0.0f);
  376.                     int facesUsing = 0;
  377.                     float tX, tY, tZ;   //temp axis variables
  378.  
  379.                     //Go through each vertex
  380.                     for(int i = 0; i < subset.vertices.size(); ++i)
  381.                     {
  382.                         //Check which triangles use this vertex
  383.                         for(int j = 0; j < subset.numTriangles; ++j)
  384.                         {
  385.                             if(subset.indices[j*3] == i ||
  386.                                 subset.indices[(j*3)+1] == i ||
  387.                                 subset.indices[(j*3)+2] == i)
  388.                             {
  389.                                 tX = XMVectorGetX(normalSum) + tempNormal[j].x;
  390.                                 tY = XMVectorGetY(normalSum) + tempNormal[j].y;
  391.                                 tZ = XMVectorGetZ(normalSum) + tempNormal[j].z;
  392.  
  393.                                 normalSum = XMVectorSet(tX, tY, tZ, 0.0f);  //If a face is using the vertex, add the unormalized face normal to the normalSum
  394.  
  395.                                 facesUsing++;
  396.                             }
  397.                         }
  398.  
  399.                         //Get the actual normal by dividing the normalSum by the number of faces sharing the vertex
  400.                         normalSum = normalSum / facesUsing;
  401.  
  402.                         //Normalize the normalSum vector
  403.                         normalSum = XMVector3Normalize(normalSum);
  404.  
  405.                         //Store the normal and tangent in our current vertex
  406.                         subset.vertices[i].normal.x = -XMVectorGetX(normalSum);
  407.                         subset.vertices[i].normal.y = -XMVectorGetY(normalSum);
  408.                         subset.vertices[i].normal.z = -XMVectorGetZ(normalSum);
  409.  
  410.                         //Clear normalSum, facesUsing for next vertex
  411.                         normalSum = XMVectorSet(0.0f, 0.0f, 0.0f, 0.0f);
  412.                         facesUsing = 0;
  413.                     }
  414.  
  415.                     //Create index buffer
  416.                     D3D11_BUFFER_DESC indexBufferDesc;
  417.                     ZeroMemory( &indexBufferDesc, sizeof(indexBufferDesc) );
  418.  
  419.                     indexBufferDesc.Usage = D3D11_USAGE_DEFAULT;
  420.                     indexBufferDesc.ByteWidth = sizeof(DWORD) * subset.numTriangles * 3;
  421.                     indexBufferDesc.BindFlags = D3D11_BIND_INDEX_BUFFER;
  422.                     indexBufferDesc.CPUAccessFlags = 0;
  423.                     indexBufferDesc.MiscFlags = 0;
  424.  
  425.                     D3D11_SUBRESOURCE_DATA iinitData;
  426.  
  427.                     iinitData.pSysMem = &subset.indices[0];
  428.                     device->CreateBuffer(&indexBufferDesc, &iinitData, &subset.indexBuff);
  429.  
  430.                     //Create Vertex Buffer
  431.                     D3D11_BUFFER_DESC vertexBufferDesc;
  432.                     ZeroMemory( &vertexBufferDesc, sizeof(vertexBufferDesc) );
  433.  
  434.                     vertexBufferDesc.Usage = D3D11_USAGE_DYNAMIC;
  435.                     vertexBufferDesc.ByteWidth = sizeof( VertexType ) * subset.vertices.size();
  436.                     vertexBufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
  437.                     vertexBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
  438.                     vertexBufferDesc.MiscFlags = 0;
  439.  
  440.                     D3D11_SUBRESOURCE_DATA vertexBufferData;
  441.  
  442.                     ZeroMemory( &vertexBufferData, sizeof(vertexBufferData) );
  443.                     vertexBufferData.pSysMem = &subset.vertices[0];
  444.                     hr = device->CreateBuffer( &vertexBufferDesc, &vertexBufferData, &subset.vertBuff);
  445.  
  446.                     //Push back the temp subset into the models subset vector
  447.                     MD5Model.subsets.push_back(subset);
  448.                 }
  449.             }
  450.         }
  451.         else
  452.         {
  453.             //SwapChain->SetFullscreenState(false, NULL);   // Make sure we are out of fullscreen
  454.  
  455.             //Create message
  456.             std::wstring message = L"Could not open: ";
  457.             message += filename;
  458.  
  459.             MessageBox(0, message.c_str()//display message
  460.                 L"Error", MB_OK);
  461.  
  462.             return false;
  463.         }
  464.         return true;
  465. }
  466.  
  467. bool md5animation::LoadTexture(ID3D11Device* device, WCHAR* filename)
  468. {
  469.     bool r;
  470.  
  471.     //Create the texture object
  472.     m_texture = new Texture;
  473.     if(!m_texture)
  474.     {return false;}
  475.  
  476.     //Initialize the texture object
  477.     r = m_texture->Init(device, filename);
  478.     if(!r)
  479.     {return false;}
  480.  
  481.     return true;
  482. }
  483.  
  484. /* SHUTDOWN */
  485. void md5animation::Shutdown()
  486. {
  487.     ReleaseTexture();
  488.     ShutdownBuffers();
  489.     ReleaseModel();
  490. }
  491.  
  492. void md5animation::ShutdownBuffers()
  493. {
  494.     if(m_indexBuffer)
  495.     {
  496.         m_indexBuffer->Release();
  497.         m_indexBuffer = 0;
  498.     }
  499.  
  500.     if(m_vertexBuffer)
  501.     {
  502.         m_vertexBuffer->Release();
  503.         m_vertexBuffer = 0;
  504.     }
  505.  
  506.     return;
  507. }
  508.  
  509. void md5animation::ReleaseModel()
  510. {
  511.     for (int i = 0; i < m_NewMD5Model.numSubsets; i++)
  512.     {
  513.         m_NewMD5Model.subsets[i].indexBuff->Release();
  514.         m_NewMD5Model.subsets[i].vertBuff->Release();
  515.     }  
  516. }
  517.  
  518. void md5animation::ReleaseTexture()
  519. {
  520.     if(m_texture)
  521.     {
  522.         m_texture->Shutdown();
  523.         delete m_texture;
  524.         m_texture = 0;
  525.     }
  526.     return;
  527. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement