Advertisement
Guest User

Untitled

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