Advertisement
Guest User

model.cpp

a guest
Aug 1st, 2012
11
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 11.29 KB | None | 0 0
  1. #include <iostream>
  2. #include <vector>
  3. #include <fstream>
  4. #include <limits>
  5. #include <stdint.h>
  6.  
  7. #include <assimp/Importer.hpp>      // C++ importer interface
  8. #include <assimp/scene.h>           // Output data structure
  9. #include <assimp/postprocess.h>     // Post processing flags
  10. #include <assimp/ai_assert.h>
  11.  
  12. #pragma comment (lib, "assimp.lib")
  13.  
  14. ////////////////////////////////////////////////////////////
  15. // Load
  16. ////////////////////////////////////////////////////////////
  17. bool Load(const std::string& pFile)
  18. {
  19.     // Create an instance of the Importer class
  20.     Assimp::Importer importer;
  21.     // And have it read the given file with some example postprocessing
  22.     // Usually - if speed is not the most important aspect for you - you'll
  23.     // propably to request more postprocessing than we do in this example.
  24.     scene = importer.ReadFile(pFile,
  25.                             aiProcess_CalcTangentSpace       |
  26.                             aiProcess_Triangulate            |
  27.                             aiProcess_JoinIdenticalVertices  |
  28.                             aiProcess_FlipUVs);
  29.  
  30.     // If the import failed, report it
  31.     if(!scene)
  32.     {
  33.         std::string s = "Error in load the " + pFile;
  34.         MessageBoxA(NULL, s.c_str(), "Error mesh", MB_OK);
  35.         return false;
  36.     }
  37.  
  38.     // allocate a new MeshHelper array and build a new instance
  39.     // for each mesh in the original asset
  40.     apcMeshes = new MeshHelper*[scene->mNumMeshes]();
  41.     for (unsigned int i = 0; i < scene->mNumMeshes;++i)
  42.         apcMeshes[i] = new MeshHelper();
  43.  
  44.     for (unsigned int i = 0; i < scene->mNumMeshes;++i)
  45.     {
  46.         const aiMesh* mesh = scene->mMeshes[i];
  47.  
  48.         /*
  49.         // create the material for the mesh
  50.         if (!apcMeshes[i]->piEffect)    {
  51.             CMaterialManager::Instance().CreateMaterial(apcMeshes[i], mesh);
  52.         }
  53.         */
  54.  
  55.         // create vertex buffer
  56.         if(FAILED( devices.d3ddev->CreateVertexBuffer(sizeof(Vertex) *
  57.                                                         mesh->mNumVertices,
  58.                                                         D3DUSAGE_WRITEONLY,
  59.                                                         0,
  60.                                                         D3DPOOL_DEFAULT, &apcMeshes[i]->piVB,NULL)))   
  61.         {
  62.             MessageBoxA(NULL, "Failed to create vertex buffer", "Error Model", MB_OK);
  63.             return false;
  64.         }
  65.  
  66.         DWORD dwUsage = 0;
  67.         if (apcMeshes[i]->piOpacityTexture || 1.0f != apcMeshes[i]->fOpacity)
  68.             dwUsage |= D3DUSAGE_DYNAMIC;
  69.  
  70.         unsigned int nidx;
  71.         switch (mesh->mPrimitiveTypes)
  72.         {
  73.             case aiPrimitiveType_POINT:
  74.                 nidx = 1;
  75.                 break;
  76.             case aiPrimitiveType_LINE:
  77.                 nidx = 2;
  78.                 break;
  79.             case aiPrimitiveType_TRIANGLE:
  80.                 nidx = 3;
  81.                 break;
  82.             default:
  83.                 ai_assert(false);
  84.         };
  85.  
  86.  
  87.         // check whether we can use 16 bit indices
  88.         if (mesh->mNumFaces * 3 >= 65536)   {
  89.             // create 32 bit index buffer
  90.             if(FAILED( devices.d3ddev->CreateIndexBuffer( 4 * mesh->mNumFaces * nidx,
  91.                                                         D3DUSAGE_WRITEONLY | dwUsage,
  92.                                                         D3DFMT_INDEX32,
  93.                                                         D3DPOOL_DEFAULT,
  94.                                                         &apcMeshes[i]->piIB,
  95.                                                         NULL)))
  96.             {
  97.                 MessageBoxA(NULL, "Failed to create 32 Bit index buffer", "Error model", MB_OK);
  98.                 return false;
  99.             }
  100.  
  101.             // now fill the index buffer
  102.             unsigned int* pbData;
  103.             apcMeshes[i]->piIB->Lock(0,0,(void**)&pbData,0);
  104.             for (unsigned int x = 0; x < mesh->mNumFaces;++x)
  105.             {
  106.                 for (unsigned int a = 0; a < nidx;++a)
  107.                 {
  108.                     *pbData++ = mesh->mFaces[x].mIndices[a];
  109.                 }
  110.             }
  111.         }
  112.         else    {
  113.             // create 16 bit index buffer
  114.             if(FAILED( devices.d3ddev->CreateIndexBuffer( 2 * mesh->mNumFaces * nidx,
  115.                                                         D3DUSAGE_WRITEONLY | dwUsage,
  116.                                                         D3DFMT_INDEX16,
  117.                                                         D3DPOOL_DEFAULT,
  118.                                                         &apcMeshes[i]->piIB,
  119.                                                         NULL)))
  120.             {
  121.                 MessageBoxA(NULL, "Failed to create 16 Bit index buffer", "Error model", MB_OK);
  122.                 return false;
  123.             }
  124.  
  125.             // now fill the index buffer
  126.             uint16_t* pbData;
  127.             apcMeshes[i]->piIB->Lock(0,0,(void**)&pbData,0);
  128.             for (unsigned int x = 0; x < mesh->mNumFaces;++x)
  129.             {
  130.                 for (unsigned int a = 0; a < nidx;++a)
  131.                 {
  132.                     *pbData++ = (uint16_t)mesh->mFaces[x].mIndices[a];
  133.                 }
  134.             }
  135.         }
  136.         apcMeshes[i]->piIB->Unlock();
  137.  
  138.         // collect weights on all vertices. Quick and careless
  139.         std::vector<std::vector<aiVertexWeight>> weightsPerVertex( mesh->mNumVertices);
  140.         for( unsigned int a = 0; a < mesh->mNumBones; a++)  {
  141.             const aiBone* bone = mesh->mBones[a];
  142.             for( unsigned int b = 0; b < bone->mNumWeights; b++)
  143.                 weightsPerVertex[bone->mWeights[b].mVertexId].push_back( aiVertexWeight( a, bone->mWeights[b].mWeight));
  144.         }
  145.  
  146.         // now fill the vertex buffer
  147.         Vertex* pbData2;
  148.         apcMeshes[i]->piVB->Lock(0,0,(void**)&pbData2,0);
  149.         for (unsigned int x = 0; x < mesh->mNumVertices;++x)
  150.         {
  151.             pbData2->vPosition = mesh->mVertices[x];
  152.  
  153.             if (NULL == mesh->mNormals)
  154.                 pbData2->vNormal = aiVector3D(0.0f,0.0f,0.0f);
  155.             else pbData2->vNormal = mesh->mNormals[x];
  156.  
  157.             if (NULL == mesh->mTangents)    {
  158.                 pbData2->vTangent = aiVector3D(0.0f,0.0f,0.0f);
  159.                 pbData2->vBitangent = aiVector3D(0.0f,0.0f,0.0f);
  160.             }
  161.             else    {
  162.                 pbData2->vTangent = mesh->mTangents[x];
  163.                 pbData2->vBitangent = mesh->mBitangents[x];
  164.             }
  165.  
  166.             if (mesh->HasVertexColors( 0 )) {
  167.                 using std::min;
  168.                 using std::max;
  169.                 unsigned char m_argb[4];
  170.                 m_argb[0] = (unsigned char)max( min( mesh->mColors[0][x].a * 255.0f, 255.0f), 0.0f);
  171.                 m_argb[1] = (unsigned char)max( min( mesh->mColors[0][x].r * 255.0f, 255.0f), 0.0f);
  172.                 m_argb[2] = (unsigned char)max( min( mesh->mColors[0][x].g * 255.0f, 255.0f), 0.0f);
  173.                 m_argb[3] = (unsigned char)max( min( mesh->mColors[0][x].b * 255.0f, 255.0f), 0.0f);
  174.  
  175.                 pbData2->dColorDiffuse = D3DCOLOR_ARGB(m_argb[0],m_argb[1],m_argb[2],m_argb[3]);
  176.             }
  177.             else pbData2->dColorDiffuse = D3DCOLOR_ARGB(0xFF,0xff,0xff,0xff);
  178.  
  179.             // ignore a third texture coordinate component
  180.             if (mesh->HasTextureCoords( 0)) {
  181.                 pbData2->vTextureUV = aiVector2D(
  182.                     mesh->mTextureCoords[0][x].x,
  183.                     mesh->mTextureCoords[0][x].y);
  184.             }
  185.             else pbData2->vTextureUV = aiVector2D(0.5f,0.5f);
  186.  
  187.             if (mesh->HasTextureCoords( 1)) {
  188.                 pbData2->vTextureUV2 = aiVector2D(
  189.                     mesh->mTextureCoords[1][x].x,
  190.                     mesh->mTextureCoords[1][x].y);
  191.             }
  192.             else pbData2->vTextureUV2 = aiVector2D(0.5f,0.5f);
  193.  
  194.             // Bone indices and weights
  195.             if( mesh->HasBones())   {
  196.                 unsigned char boneIndices[4] = { 0, 0, 0, 0 };
  197.                 unsigned char boneWeights[4] = { 0, 0, 0, 0 };
  198.                 ai_assert( weightsPerVertex[x].size() <= 4);
  199.                 for( unsigned int a = 0; a < weightsPerVertex[x].size(); a++)
  200.                 {
  201.                     boneIndices[a] = weightsPerVertex[x][a].mVertexId;
  202.                     boneWeights[a] = (unsigned char) (weightsPerVertex[x][a].mWeight * 255.0f);
  203.                 }
  204.  
  205.                 memcpy( pbData2->mBoneIndices, boneIndices, sizeof( boneIndices));
  206.                 memcpy( pbData2->mBoneWeights, boneWeights, sizeof( boneWeights));
  207.             } else
  208.             {
  209.                 memset( pbData2->mBoneIndices, 0, sizeof( pbData2->mBoneIndices));
  210.                 memset( pbData2->mBoneWeights, 0, sizeof( pbData2->mBoneWeights));
  211.             }
  212.  
  213.             ++pbData2;
  214.         }
  215.         apcMeshes[i]->piVB->Unlock();
  216.  
  217.         // now generate the second vertex buffer, holding all normals
  218.         if (!apcMeshes[i]->piVBNormals) {
  219.             //GenerateNormalsAsLineList(apcMeshes[i],mesh);
  220.  
  221.             ai_assert(NULL != apcMeshes[i]);
  222.             ai_assert(NULL != mesh);
  223.  
  224.             if (!mesh->mNormals)return 0;
  225.  
  226.             // create vertex buffer
  227.             if(FAILED( devices.d3ddev->CreateVertexBuffer(sizeof(LineVertex) *
  228.                                                         mesh->mNumVertices * 2,
  229.                                                         D3DUSAGE_WRITEONLY,
  230.                                                         LineVertex::GetFVF(),
  231.                                                         D3DPOOL_DEFAULT, &apcMeshes[i]->piVBNormals,NULL)))
  232.             {
  233.                 MessageBoxA(NULL,"Failed to create vertex buffer for the normal list", "Error model", MB_OK);
  234.                 return false;
  235.             }
  236.  
  237.             // now fill the vertex buffer with data
  238.             LineVertex* pbData2;
  239.             apcMeshes[i]->piVBNormals->Lock(0,0,(void**)&pbData2,0);
  240.             for (unsigned int x = 0; x < mesh->mNumVertices;++x)
  241.             {
  242.                 pbData2->vPosition = mesh->mVertices[x];
  243.  
  244.                 ++pbData2;
  245.  
  246.                 aiVector3D vNormal = mesh->mNormals[x];
  247.                 vNormal.Normalize();
  248.  
  249.                 // scalo with the inverse of the world scaling to make sure
  250.                 // the normals have equal length in each case
  251.                 // TODO: Check whether this works in every case, I don't think so
  252.                 //vNormal.x /= g_mWorld.a1*4;
  253.                 //vNormal.y /= g_mWorld.b2*4;
  254.                 //vNormal.z /= g_mWorld.c3*4;
  255.  
  256.                 pbData2->vPosition = mesh->mVertices[x] + vNormal;
  257.  
  258.                 ++pbData2;
  259.             }
  260.             apcMeshes[i]->piVBNormals->Unlock();
  261.         }
  262.     }
  263.  
  264.     // get the number of vertices/faces in the model
  265.     unsigned int iNumVert = 0;
  266.     unsigned int iNumFaces = 0;
  267.     for (unsigned int i = 0; i < scene->mNumMeshes;++i)
  268.     {
  269.         iNumVert += scene->mMeshes[i]->mNumVertices;
  270.         iNumFaces += scene->mMeshes[i]->mNumFaces;
  271.     }
  272.  
  273.     meshrender = new MeshRender(devices, scene, apcMeshes);
  274.  
  275.     return true;
  276. }
  277.  
  278. ////////////////////////////////////////////////////////////
  279. // Render
  280. ////////////////////////////////////////////////////////////
  281. void Render(bool wireframe)
  282. {
  283.     if(wireframe)
  284.     {
  285.         devices.d3ddev->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME);
  286.     }
  287.  
  288.     aiMatrix4x4 m;
  289.     RenderNode(scene->mRootNode, true);
  290.     // render all child nodes
  291.     for (unsigned int i = 0; i < scene->mRootNode->mNumChildren;++i)
  292.         RenderNode(scene->mRootNode->mChildren[i], true );
  293.  
  294.     if(wireframe)
  295.     {
  296.         devices.d3ddev->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
  297.     }
  298. }
  299.  
  300. ////////////////////////////////////////////////////////////
  301. // Render a single node
  302. ////////////////////////////////////////////////////////////
  303. bool RenderNode(aiNode* piNode, bool bAlpha)
  304. {
  305.     aiMatrix4x4 aiMe;
  306.     aiMatrix4x4* piMatrix = new aiMatrix4x4();
  307.  
  308.     for (unsigned int i = 0; i < piNode->mNumMeshes;++i)
  309.     {
  310.         if (bAlpha)
  311.             meshrender->DrawSorted(piNode->mMeshes[i], aiMe);
  312.         else
  313.             meshrender->DrawUnsorted(piNode->mMeshes[i]);
  314.     }
  315.  
  316.  
  317.     return true;
  318. }
  319.  
  320. ////////////////////////////////////////////////////////////
  321. // Release
  322. ////////////////////////////////////////////////////////////
  323. void Release()
  324. {
  325.     bool bNoMaterials = false;
  326.     if (!scene)
  327.         return;
  328.  
  329.     // TODO: Move this to a proper destructor
  330.     for (unsigned int i = 0; i < scene->mNumMeshes;++i)
  331.     {
  332.         if(apcMeshes[i]->piVB)
  333.         {
  334.             apcMeshes[i]->piVB->Release();
  335.             apcMeshes[i]->piVB = NULL;
  336.         }
  337.         if(apcMeshes[i]->piVBNormals)
  338.         {
  339.             apcMeshes[i]->piVBNormals->Release();
  340.             apcMeshes[i]->piVBNormals = NULL;
  341.         }
  342.         if(apcMeshes[i]->piIB)
  343.         {
  344.             apcMeshes[i]->piIB->Release();
  345.             apcMeshes[i]->piIB = NULL;
  346.         }
  347.  
  348.         if (!bNoMaterials)
  349.         {
  350.             if(apcMeshes[i]->piEffect)
  351.             {
  352.                 apcMeshes[i]->piEffect->Release();
  353.                 apcMeshes[i]->piEffect = NULL;
  354.             }
  355.             if(apcMeshes[i]->piDiffuseTexture)
  356.             {
  357.                 apcMeshes[i]->piDiffuseTexture->Release();
  358.                 apcMeshes[i]->piDiffuseTexture = NULL;
  359.             }
  360.             if(apcMeshes[i]->piNormalTexture)
  361.             {
  362.                 apcMeshes[i]->piNormalTexture->Release();
  363.                 apcMeshes[i]->piNormalTexture = NULL;
  364.             }
  365.             if(apcMeshes[i]->piSpecularTexture)
  366.             {
  367.                 apcMeshes[i]->piSpecularTexture->Release();
  368.                 apcMeshes[i]->piSpecularTexture = NULL;
  369.             }
  370.             if(apcMeshes[i]->piAmbientTexture)
  371.             {
  372.                 apcMeshes[i]->piAmbientTexture->Release();
  373.                 apcMeshes[i]->piAmbientTexture = NULL;
  374.             }
  375.             if(apcMeshes[i]->piEmissiveTexture)
  376.             {
  377.                 apcMeshes[i]->piEmissiveTexture->Release();
  378.                 apcMeshes[i]->piEmissiveTexture = NULL;
  379.             }
  380.             if(apcMeshes[i]->piOpacityTexture)
  381.             {
  382.                 apcMeshes[i]->piOpacityTexture->Release();
  383.                 apcMeshes[i]->piOpacityTexture = NULL;
  384.             }
  385.             if(apcMeshes[i]->piShininessTexture)
  386.             {
  387.                 apcMeshes[i]->piShininessTexture->Release();
  388.                 apcMeshes[i]->piShininessTexture = NULL;
  389.             }
  390.         }
  391.     }
  392. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement