Want more features on Pastebin? Sign Up, it's FREE!
Guest

Untitled

By: a guest on Aug 1st, 2012  |  syntax: C++  |  size: 11.40 KB  |  views: 90  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
This paste has a previous version, view the difference. Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  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. }
clone this paste RAW Paste Data