void FBXImporter::ProcessMesh(FbxNodeAttribute* nodeAttribute) { FbxMesh* mesh = (FbxMesh*)nodeAttribute; // 网格是否三角化的?如果不是先将其转为三角化的。 // 注意:一步其实应该在建模软件导出的时候进行。 if (!mesh->IsTriangleMesh()) { FbxGeometryConverter converter(mSDKManager); // #1 // For FBX SDK 2015.1 nodeAttribute = converter.Triangulate(nodeAttribute, true, false); // For FBX SDK 2013.3 //converter.TriangulateInPlace(nodeAttribute->GetNode()); mesh = (FbxMesh*)nodeAttribute; } FBXMeshData* fbxMeshData = new FBXMeshData(); fbxMeshData->mMesh = mesh; mFBXMeshDatas.push_back(fbxMeshData); Log("TriangleCount:%d\n", mesh->GetPolygonCount()); Log("VertexCount:%d\n", mesh->GetControlPointsCount()); Log("IndexCount:%d\n", mesh->GetPolygonVertexCount()); Log("Layer:%d\n", mesh->GetLayerCount()); Log("DeformerCount:%d\n", mesh->GetDeformerCount()); Log("MaterialCount%d\n", mesh->GetNode()->GetMaterialCount()); Log("\n"); }
void FBXSceneEncoder::loadModel(FbxNode* fbxNode, Node* node) { FbxMesh* fbxMesh = fbxNode->GetMesh(); if (!fbxMesh || fbxMesh->GetPolygonVertexCount() == 0) { return; } if (fbxMesh->IsTriangleMesh()) { Mesh* mesh = loadMesh(fbxMesh); Model* model = new Model(); model->setMesh(mesh); node->setModel(model); loadSkin(fbxMesh, model); if (model->getSkin()) { node->resetTransformMatrix(); } } }
void FBXScene::ProcessMesh(FbxNode* pNode) { FbxMesh* pFBXMesh = pNode->GetMesh(); if( !pFBXMesh ) return; if ( pFBXMesh->GetPolygonVertexCount() != pFBXMesh->GetPolygonCount() * 3 ) { FbxGeometryConverter GeometryConverter(pNode->GetFbxManager()); if( !GeometryConverter.TriangulateInPlace( pNode ) ) { return; } pFBXMesh = pNode->GetMesh(); } pFBXMesh->InitNormals(); pFBXMesh->ComputeVertexNormals(true); pFBXMesh->GenerateTangentsDataForAllUVSets(); int nVertexCount = pFBXMesh->GetControlPointsCount(); if( nVertexCount <= 0 ) return; std::vector<BoneWeights> boneWeights(nVertexCount); ProcessBoneWeights(pFBXMesh, boneWeights); Model* pModel = new Model(pNode->GetName(), m_Models.GetCount(), false); FbxVector4* aControlPoints = pFBXMesh->GetControlPoints(); for( int pi = 0; pi < pFBXMesh->GetPolygonCount(); ++pi ) // Whole for-loop takes some time too, investigate further. { // Material Material* pMaterial = NULL; for( unsigned int pvi = 0; pvi < 3; ++pvi ) { int nVertexIndex = pFBXMesh->GetPolygonVertex(pi, pvi); if( nVertexIndex < 0 || nVertexIndex >= nVertexCount ) continue; // Material if( pMaterial == NULL ) pMaterial = GetMaterialLinkedWithPolygon(pFBXMesh, 0, pi, 0, nVertexIndex); // Position FbxVector4 fbxPosition = aControlPoints[nVertexIndex]; // Normals And Tangents FbxVector4 fbxNormal, fbxTangent; fbxNormal = GetNormal(pFBXMesh, 0, pi, pvi, nVertexIndex); fbxTangent = GetTangent(pFBXMesh, 0, pi, pvi, nVertexIndex); // Add Vertex pModel->AddVertex(pMaterial, FbxVector4ToBTHFBX_VEC3(fbxPosition), FbxVector4ToBTHFBX_VEC3(fbxNormal), FbxVector4ToBTHFBX_VEC3(fbxTangent), GetTexCoord(pFBXMesh, 0, pi, pvi, nVertexIndex), boneWeights[nVertexIndex]); // Update Bounding Box UpdateBoundingBoxDataFromVertex(FbxVector4ToBTHFBX_VEC3(fbxPosition)); } } // Geometric Offset pModel->SetGeometricOffset2(GetGeometricOffset2(pNode)); // Insert Model m_Models.Add(pModel->GetName(), pModel); }
void MeshImporter::LoadNodeMesh(FbxNode* node, ID3D11Device3* device, ID3D11DeviceContext3* context) { unsigned int numPolygons = 0; unsigned int numVertices = 0; unsigned int numIndices = 0; unsigned int numPolygonVert = 0; if (node->GetNodeAttribute() != NULL && node->GetNodeAttribute()->GetAttributeType() == FbxNodeAttribute::eMesh) { //PrintNode(node); // Create meshes FbxMesh* fbxMesh = node->GetMesh(); numPolygons = fbxMesh->GetPolygonCount(); numIndices = fbxMesh->GetPolygonVertexCount(); numVertices = fbxMesh->GetControlPointsCount(); // Do not use indexed drawing method numVertices = numIndices; vector<Vertex> vertices(numVertices); vector<unsigned int> indices(numIndices); numPolygonVert = 3; //assert(numPolygonVert == 3); FbxVector4* controlPoints = fbxMesh->GetControlPoints(); int* indices_array = fbxMesh->GetPolygonVertices(); // Need to be changed for optimization for (unsigned int i = 0; i < numIndices; i++) { indices[i] = indices_array[i]; vertices[i].pos.x = (float)fbxMesh->GetControlPointAt(indices[i]).mData[0];// / 1000.0f; vertices[i].pos.y = (float)fbxMesh->GetControlPointAt(indices[i]).mData[1];// / 1000.0f; vertices[i].pos.z = (float)fbxMesh->GetControlPointAt(indices[i]).mData[2];// / 1000.0f; } // For indexed drawing /*for (unsigned int i = 0; i < numVertices; i++) { vertices[i].pos.x = (float)controlPoints[i].mData[0]; vertices[i].pos.y = (float)controlPoints[i].mData[1]; vertices[i].pos.z = (float)controlPoints[i].mData[2]; }*/ LoadUV(fbxMesh, &vertices[0], &indices[0]); //OutputDebugStringA(("\n number of polygons: " + to_string(numPolygons) + " \n").c_str()); //OutputDebugStringA(("\n number of indices: " + to_string(numIndices) + " \n").c_str()); //OutputDebugStringA(("\n number of vertices: " + to_string(vertices.size()) + " \n").c_str()); // Read mesh base transform matrix FbxAMatrix fbxGlobalMeshBaseMatrix = node->EvaluateGlobalTransform().Inverse().Transpose(); XMFLOAT4X4 globalMeshBaseMatrix; for (int r = 0; r < 4; r++) { //PrintTab("Global mesh base mat: " + to_string(fbxGlobalMeshBaseMatrix.mData[r][0])); for (int c = 0; c < 4; c++) { globalMeshBaseMatrix.m[r][c] = (float)fbxGlobalMeshBaseMatrix.mData[r][c]; } } // To be considered when importing Maya fbx model //FbxAMatrix geoMatrix = GetTransformMatrix(node); //ConvertFbxAMatrixToDXMatrix(&globalMeshBaseMatrix, fbxGlobalMeshBaseMatrix); MeshEntry mesh; mesh.vertices = vertices; mesh.indices = indices; mesh.numVertices = numVertices; mesh.numIndices = numIndices; mesh.fbxNode = node; mesh.globalMeshBaseMatrix = globalMeshBaseMatrix; // Load materials and textures LoadMaterials(node, &mesh, device, context); // Load weights LoadWeight(fbxMesh, &mesh); // Set to be clockwise, must be done after reading uvs, normals, weights and etc for (auto it = mesh.vertices.begin(); it != mesh.vertices.end(); it += 3) { swap(*it, *(it + 2)); } model->entries.push_back(mesh); } int numChild = node->GetChildCount(); for (int i = 0; i < numChild; i++) { LoadNodeMesh(node->GetChild(i), device, context); } }
MeshData* FBXImporter::GetMeshInfo() { mMeshData = new MeshData(); int indicesIndexOffset = 0; // 记录当前mesh在整个ib中的索引位移。 int verticesIndexOffset = 0; // 记录当前mesh在整个vb中的顶点位移。 for (int meshIndex = 0; meshIndex < mFBXMeshDatas.size(); meshIndex++) { FbxMesh* mesh = mFBXMeshDatas[meshIndex]->mMesh; FBXMeshData* fbxMeshData = mFBXMeshDatas[meshIndex]; fbxMeshData->mVerticesCount = mesh->GetControlPointsCount(); fbxMeshData->mIndicesCount = mesh->GetPolygonVertexCount(); fbxMeshData->mTrianglesCount = mesh->GetPolygonCount(); // 获取3dsmax中的全局变换矩阵,稍后可以在DX中还原。 FbxMatrix gloableTransform = mesh->GetNode()->EvaluateGlobalTransform(); FbxAMatrix matrixGeo; matrixGeo.SetIdentity(); const FbxVector4 lT = mesh->GetNode()->GetGeometricTranslation(FbxNode::eSourcePivot); const FbxVector4 lR = mesh->GetNode()->GetGeometricRotation(FbxNode::eSourcePivot); const FbxVector4 lS = mesh->GetNode()->GetGeometricScaling(FbxNode::eSourcePivot); matrixGeo.SetT(lT); matrixGeo.SetR(lR); matrixGeo.SetS(lS); FbxAMatrix matrixL2W; matrixL2W.SetIdentity(); matrixL2W = mesh->GetNode()->EvaluateGlobalTransform(); matrixL2W *= matrixGeo; XMMATRIX globalTransform = XMLoadFloat4x4(&fbxMeshData->globalTransform); FbxMatrixToXMMATRIX(globalTransform, matrixL2W); XMStoreFloat4x4(&fbxMeshData->globalTransform, globalTransform); // 读取顶点。 ReadVertices(fbxMeshData); // 读取索引。 ReadIndices(fbxMeshData); // 先读取网格对应的材质索引信息,以便优化稍后纹理读取。 // 一个网格可能只对应一个materialId,也可能对应多个materialId(3dsmax里的Multi/Sub-Object材质)。 // 如果只对应一个材质,简单的读取就行,不过普遍情况可能是为了优化渲染合并mesh从而拥有多材质。 // 这个函数调用完毕我们会得到materialId和拥有这个materialId的三角形列表(三角形编号列表),保存在vector<MaterialIdOffset>的容器中。 //struct Material //{ // Material() {} // Material(int id, string diffuse, string normalMap) // : materialId(id), // diffuseTextureFile(diffuse), // normalMapTextureFile(normalMap) // {} // // int materialId; // string diffuseTextureFile; // string normalMapTextureFile; //}; // struct MaterialIdOffset //{ // MaterialIdOffset() // : polygonCount(0) // {} // int polygonCount; // Material material; //}; ConnectMaterialsToMesh(mesh, fbxMeshData->mTrianglesCount); // 根据ConnectMaterialsToMesh得到的信息读取材质纹理信息,同样存入vector<MaterialIdOffset>容器。 LoadMaterials(fbxMeshData); int triangleCount = mesh->GetPolygonCount(); int controlPointIndex = 0; int normalIndex = 0; fbxMeshData->mUVs.resize(fbxMeshData->mIndicesCount, XMFLOAT2(-1.0f, -1.0f)); // Extract normals and uvs from FbxMesh. for (int i = 0; i < triangleCount; i++) { int polygonSize = mesh->GetPolygonSize(i); for (int j = 0; j < polygonSize; j++) { controlPointIndex = mesh->GetPolygonVertex(i, j); ReadNormals(fbxMeshData, controlPointIndex, normalIndex); // 有纹理我们才读取uv,tangent以及binormal。 if (fbxMeshData->hasDiffuseTexture()) { ReadUVs(fbxMeshData, controlPointIndex, normalIndex, mesh->GetTextureUVIndex(i, j), 0); ReadTangents(fbxMeshData, controlPointIndex, normalIndex); ReadBinormals(fbxMeshData, controlPointIndex, normalIndex); } normalIndex++; } } SplitVertexByNormal(fbxMeshData); if (fbxMeshData->hasDiffuseTexture()) { SplitVertexByUV(fbxMeshData); } else { fbxMeshData->mUVs.resize(fbxMeshData->mVerticesCount); } if (fbxMeshData->hasNormalMapTexture()) { SplitVertexByTangent(fbxMeshData); SplitVertexByBinormal(fbxMeshData); } else { fbxMeshData->mTangents.resize(fbxMeshData->mVerticesCount); fbxMeshData->mBinormals.resize(fbxMeshData->mVerticesCount); } // 如果.fbx包含一个以上的mesh,需要计算当前FBXMeshData的索引在全局索引中的位置。 for (int i = 0; i < fbxMeshData->mIndicesCount; i++) { fbxMeshData->mIndices[i] = fbxMeshData->mIndices[i] + verticesIndexOffset; } mMeshData->verticesCount += fbxMeshData->mVerticesCount; mMeshData->indicesCount += fbxMeshData->mIndicesCount; mMeshData->meshesCount++; // 多材质的情况。 // 根据之前填充的materialIdOffsets容器保存的materialId和三角形的对应关系, // 计算每个RenderPackage渲染所需的索引数量和索引起始位置(偏移)。 if (isByPolygon && fbxMeshData->hasDiffuseTexture()) { vector<MaterialIdOffset> materialIdOffsets = mMeshData->materialIdOffsets; for (int i = 0; i < materialIdOffsets.size(); i++) { RenderPackage renderPacakge; renderPacakge.globalTransform = fbxMeshData->globalTransform; renderPacakge.indicesCount = materialIdOffsets[i].polygonCount * 3; if (i == 0) { renderPacakge.indicesOffset = indicesIndexOffset; } else { renderPacakge.indicesOffset += indicesIndexOffset; } renderPacakge.material = materialIdOffsets[i].material; mMeshData->renderPackages.push_back(renderPacakge); indicesIndexOffset += renderPacakge.indicesCount; } } else // 单一材质的情况。 { RenderPackage renderPackage; renderPackage.indicesCount = fbxMeshData->mIndicesCount; renderPackage.indicesOffset = indicesIndexOffset; renderPackage.material = fbxMeshData->mMaterial; renderPackage.globalTransform = fbxMeshData->globalTransform; mMeshData->renderPackages.push_back(renderPackage); indicesIndexOffset += fbxMeshData->mIndices.size(); } verticesIndexOffset += fbxMeshData->mVertices.size(); // 将当前mesh的数据追加到全局数据容器。 Merge(mMeshData->vertices, fbxMeshData->mVertices); Merge(mMeshData->indices, fbxMeshData->mIndices); Merge(mMeshData->normals, fbxMeshData->mNormals); Merge(mMeshData->uvs, fbxMeshData->mUVs); Merge(mMeshData->tangents, fbxMeshData->mTangents); Merge(mMeshData->binormals, fbxMeshData->mBinormals); mMeshData->materialIdOffsets.clear(); } clear(); return mMeshData; }
void MeshImporter::LoadNodeMesh(FbxNode* node, ID3D11Device3* device, ID3D11DeviceContext3* context) { unsigned int numPolygons = 0; unsigned int numVertices = 0; unsigned int numIndices = 0; unsigned int numPolygonVert = 0; if (node->GetNodeAttribute() != NULL && node->GetNodeAttribute()->GetAttributeType() == FbxNodeAttribute::eMesh) { //PrintNode(node); // Create meshes FbxMesh* fbxMesh = node->GetMesh(); numPolygons = fbxMesh->GetPolygonCount(); numIndices = fbxMesh->GetPolygonVertexCount(); numVertices = fbxMesh->GetControlPointsCount(); // Do not use indexed drawing method numVertices = numIndices; vector<Vertex> vertices(numVertices); vector<unsigned int> indices(numIndices); numPolygonVert = 3; //assert(numPolygonVert == 3); FbxVector4* controlPoints = fbxMesh->GetControlPoints(); int* indices_array = fbxMesh->GetPolygonVertices(); // Need to be changed for optimization for (unsigned int i = 0; i < numIndices; i++) { indices[i] = indices_array[i]; vertices[i].pos.x = (float)fbxMesh->GetControlPointAt(indices[i]).mData[0] / 10000.0f; vertices[i].pos.y = (float)fbxMesh->GetControlPointAt(indices[i]).mData[1] / 10000.0f; vertices[i].pos.z = (float)fbxMesh->GetControlPointAt(indices[i]).mData[2] / 10000.0f; } // For indexed drawing /*for (unsigned int i = 0; i < numVertices; i++) { vertices[i].pos.x = (float)controlPoints[i].mData[0];// / 25.0f; vertices[i].pos.y = (float)controlPoints[i].mData[1];// / 25.0f; vertices[i].pos.z = (float)controlPoints[i].mData[2];// / 25.0f; }*/ LoadUV(fbxMesh, &vertices[0], &indices[0]); // Set to be clockwise, must be done after reading uvs and normals for (auto it = vertices.begin(); it != vertices.end(); it += 3) { std::swap(*it, *(it + 2)); } //OutputDebugStringA(("\n number of polygons: " + to_string(numPolygons) + " \n").c_str()); //OutputDebugStringA(("\n number of indices: " + to_string(numIndices) + " \n").c_str()); //OutputDebugStringA(("\n number of vertices: " + to_string(vertices.size()) + " \n").c_str()); ModelObj::MeshEntry mesh; mesh.vertices = vertices; mesh.indices = indices; mesh.numVertices = numVertices; mesh.numIndices = numIndices; LoadMaterials(node, &mesh, device, context); model->entries.push_back(mesh); } for (int i = 0; i < node->GetChildCount(); i++) { LoadNodeMesh(node->GetChild(i), device, context); } }
HRESULT FBXLoader::loadFBXFile(char* filePath, VertexBuffer** vBuf, IndexBuffer** iBuf, Renderer* renderer, bool centerShift) { if (g_pFbxSdkManager == nullptr) { g_pFbxSdkManager = FbxManager::Create(); FbxIOSettings* pIOsettings = FbxIOSettings::Create(g_pFbxSdkManager, IOSROOT); g_pFbxSdkManager->SetIOSettings(pIOsettings); } this->shiftCenter = centerShift; FbxImporter* pImporter = FbxImporter::Create(g_pFbxSdkManager, ""); FbxScene* pFbxScene = FbxScene::Create(g_pFbxSdkManager, ""); bool bSuccess = pImporter->Initialize(filePath, -1, g_pFbxSdkManager->GetIOSettings()); if (!bSuccess) return E_FAIL; bSuccess = pImporter->Import(pFbxScene); if (!bSuccess) return E_FAIL; FbxAxisSystem sceneAxisSystem = pFbxScene->GetGlobalSettings().GetAxisSystem(); FbxAxisSystem DirectXAxisSystem(FbxAxisSystem::eYAxis, FbxAxisSystem::eParityOdd, FbxAxisSystem::eLeftHanded); if (sceneAxisSystem != DirectXAxisSystem) { DirectXAxisSystem.ConvertScene(pFbxScene); } pImporter->Destroy(); FbxNode* pFbxRootNode = pFbxScene->GetRootNode(); if (pFbxRootNode) { // Check if the getChildCount is > 1 TODO int test = pFbxRootNode->GetChildCount(); for (int i = 0; i < pFbxRootNode->GetChildCount(); i++) { FbxNode* pFbxChildNode = pFbxRootNode->GetChild(i); if (pFbxChildNode->GetNodeAttribute() == NULL) continue; FbxNodeAttribute::EType AttributeType = pFbxChildNode->GetNodeAttribute()->GetAttributeType(); if (AttributeType != FbxNodeAttribute::eMesh) continue; FbxMesh* pMesh = (FbxMesh*)pFbxChildNode->GetNodeAttribute(); int numControlPoints = pMesh->GetControlPointsCount(); bool initial = true; float xMin, yMin, zMin; float xMax, yMax, zMax; float xIn, yIn, zIn; float xCenter, yCenter, zCenter; if (this->shiftCenter){ for (int c = 0; c < numControlPoints; c++) { xIn = (float)pMesh->GetControlPointAt(c).mData[0]; yIn = (float)pMesh->GetControlPointAt(c).mData[1]; zIn = (float)pMesh->GetControlPointAt(c).mData[2]; if (initial) { xMin = xIn; yMin = yIn; zMin = zIn; xMax = xIn; yMax = yIn; zMax = zIn; initial = false; } else { if (xIn < xMin) { xMin = xIn; } if (yIn < yMin) { yMin = yIn; } if (zIn < zMin) { zMin = zIn; } if (xIn > xMax) { xMax = xIn; } if (yIn > yMax) { yMax = yIn; } if (zIn > zMax) { zMax = zIn; } } } xCenter = (xMin + xMax) / 2.0f; yCenter = (yMin + yMax) / 2.0f; zCenter = (zMin + zMax) / 2.0f; } else { xCenter = 0; yCenter = 0; zCenter = 0; } FbxVector4* pVertices = pMesh->GetControlPoints(); int vertexCount = pMesh->GetPolygonVertexCount(); //Vertex vertex; Vertex* vertexArray = new Vertex[vertexCount]; //Vertex vertexArray[2592]; int numIndices = vertexCount; unsigned int* indexArray = new unsigned int[numIndices]; FbxVector4 fbxNorm(0, 0, 0, 0); FbxVector2 fbxUV(0, 0); bool isMapped; int vertexIndex = 0; // Loop iterates through the polygons and fills the vertex and index arrays for the buffers for (int j = 0; j < pMesh->GetPolygonCount(); j++) { int iNumVertices = pMesh->GetPolygonSize(j); assert(iNumVertices == 3); //1st vertex int controlIndex = pMesh->GetPolygonVertex(j, 2); pMesh->GetPolygonVertexUV(j, 2, "map1", fbxUV, isMapped); pMesh->GetPolygonVertexNormal(j, 2, fbxNorm); vertexArray[vertexIndex].point[0] = (float)pVertices[controlIndex].mData[0] - xCenter; vertexArray[vertexIndex].point[1] = (float)pVertices[controlIndex].mData[1] - yCenter; vertexArray[vertexIndex].point[2] = -(float)pVertices[controlIndex].mData[2] - zCenter; vertexArray[vertexIndex].texCoord[0] = (float)fbxUV[0]; vertexArray[vertexIndex].texCoord[1] = 1.0f - (float)fbxUV[1]; vertexArray[vertexIndex].normal[0] = (float)fbxNorm[0]; vertexArray[vertexIndex].normal[1] = (float)fbxNorm[1]; vertexArray[vertexIndex].normal[2] = -(float)fbxNorm[2]; indexArray[vertexIndex] = vertexIndex; vertexIndex++; //2nd vertex controlIndex = pMesh->GetPolygonVertex(j, 1); pMesh->GetPolygonVertexUV(j, 1, "map1", fbxUV, isMapped); pMesh->GetPolygonVertexNormal(j, 1, fbxNorm); vertexArray[vertexIndex].point[0] = (float)pVertices[controlIndex].mData[0] - xCenter; vertexArray[vertexIndex].point[1] = (float)pVertices[controlIndex].mData[1] - yCenter; vertexArray[vertexIndex].point[2] = -(float)pVertices[controlIndex].mData[2] - zCenter; vertexArray[vertexIndex].texCoord[0] = (float)fbxUV[0]; vertexArray[vertexIndex].texCoord[1] = 1.0f - (float)fbxUV[1]; vertexArray[vertexIndex].normal[0] = (float)fbxNorm[0]; vertexArray[vertexIndex].normal[1] = (float)fbxNorm[1]; vertexArray[vertexIndex].normal[2] = -(float)fbxNorm[2]; indexArray[vertexIndex] = vertexIndex; vertexIndex++; //3rd vertex controlIndex = pMesh->GetPolygonVertex(j, 0); pMesh->GetPolygonVertexUV(j, 0, "map1", fbxUV, isMapped); pMesh->GetPolygonVertexNormal(j, 0, fbxNorm); vertexArray[vertexIndex].point[0] = (float)pVertices[controlIndex].mData[0] - xCenter; vertexArray[vertexIndex].point[1] = (float)pVertices[controlIndex].mData[1] - yCenter; vertexArray[vertexIndex].point[2] = -(float)pVertices[controlIndex].mData[2] - zCenter; vertexArray[vertexIndex].texCoord[0] = (float)fbxUV[0]; vertexArray[vertexIndex].texCoord[1] = 1.0f - (float)fbxUV[1]; vertexArray[vertexIndex].normal[0] = (float)fbxNorm[0]; vertexArray[vertexIndex].normal[1] = (float)fbxNorm[1]; vertexArray[vertexIndex].normal[2] = -(float)fbxNorm[2]; indexArray[vertexIndex] = vertexIndex; vertexIndex++; } // Generate vertex and index buffers from the vertex and index arrays *vBuf = renderer->createVertexBuffer(vertexArray, vertexCount); *iBuf = renderer->createIndexBuffer(indexArray, numIndices); delete[] vertexArray; delete[] indexArray; } } return S_OK; }
void fbxLoader2::processMesh(FbxNode* node) { FbxMesh* mesh = node->GetMesh(); this->readAnimationWeigths(mesh); if(mesh!=NULL && mesh->IsTriangleMesh()) { for (int i = 0; i<mesh->GetControlPointsCount(); i++) { readVertex(mesh, i, &vertex[i]); vertexArray[i].position = D3DXVECTOR3(vertex[i]); } int a = mesh->GetPolygonVertexCount(); for (int i = 0; i<mesh->GetPolygonVertexCount(); i++) { readUV(mesh, i, 0, &uv[i]); readNormal(mesh, i, &normal[i]); indices[i].indice = mesh->GetPolygonVertices()[i]; indices[i].normal1 = normal[i]; indices[i].uv1 = uv[i]; indicesMeshCount++; } } //vertexLists.push_back(vertexArray); indiceLists.push_back(indices); FbxAnimStack* pAnimStack = FbxCast<FbxAnimStack>(scene->GetSrcObject(FBX_TYPE(FbxAnimStack))); int numAnimLayers = pAnimStack->GetMemberCount(FBX_TYPE(FbxAnimLayer)); this->setBindPoseCluster(node); for (int i = 0; i < numAnimLayers; i++) { FbxAnimLayer* pAnimLayer = pAnimStack->GetMember(FBX_TYPE(FbxAnimLayer), i); FbxAnimCurve* animCv = this->findSkeletonRootBone(scene->GetRootNode())->GetChild(0)->LclTranslation.GetCurve(pAnimLayer, FBXSDK_CURVENODE_COMPONENT_X); if (animCv) { FbxTimeSpan animationLength; int p = animCv->KeyGetCount(); animCv->GetTimeInterval(animationLength); for(int j = 0; j<animationStructure->GetFramesNumber();j++) { FbxTime timeKey = animCv->KeyGet(j).mTime; //FbxTime interval = (duration/p)*j + animationLength.GetStart(); //int intervalVal = (duration.GetSecondCount()/p)*j + animationLength.GetStart().GetSecondCount(); const FbxTime pTime = animCv->KeyGet(j).mTime; FbxAMatrix pGlobalPos = GetGlobalPosition(node, pTime, scene->GetPose(j)); ComputeSkinDeformation(pGlobalPos, mesh, timeKey, scene->GetPose(j), j); } } } for(int i = 0; i<node->GetChildCount(); i++) { processMesh(node->GetChild(i)); } }
void importFBXNode( FbxNode *node, vector<Vector3> &vertices, vector<Color> &colors, vector<Vector2> &uvs, vector<Vector3> &normals, vector<uint32> &elements) { FbxNode *childNode = 0; int numKids = node->GetChildCount(); for ( int i=0 ; i<numKids ; i++) { childNode = node->GetChild(i); FbxMesh *mesh = childNode->GetMesh(); if ( mesh != NULL ) { auto offset = node->GetGeometricTranslation(FbxNode::eSourcePivot); //================= Get Vertices ==================================== int baseline = vertices.size(); int numVerts = mesh->GetControlPointsCount(); for ( int j=0; j<numVerts; j++) { FbxVector4 vert = mesh->GetControlPointAt(j); vertices.push_back( Vector3(vert.mData[0], vert.mData[1], vert.mData[2]) /*+ Vector3(offset.mData[0], offset.mData[1], offset.mData[2])*/); colors.push_back(Vector3(1, 1, 1)); uvs.push_back(Vector2(0, 0)); } //================= Get Indices ==================================== int numIndices=mesh->GetPolygonVertexCount(); int *indicesRaw = mesh->GetPolygonVertices(); for (int j = 0; j < numIndices; j++) { elements.push_back(indicesRaw[j] + baseline); } int cnt = 0; int polygonCount = mesh->GetPolygonCount(); for (int j = 0; j < polygonCount; ++j) { FbxLayerElementArrayTemplate<FbxVector2>* uvVertices= 0; mesh->GetTextureUV(&uvVertices, FbxLayerElement::eTextureDiffuse); for (int k = 0; k < mesh->GetPolygonSize(j); ++k) { FbxVector2 uv = (*uvVertices)[mesh->GetTextureUVIndex(j, k)]; uvs[indicesRaw[cnt] + baseline].x = uv[0]; uvs[indicesRaw[cnt] + baseline].y = uv[1]; cnt++; } } } importFBXNode(childNode, vertices, colors, uvs, normals, elements); } }
void FbxLoader::LoadAttribute(FbxNodeAttribute* pAttribute) { if (pAttribute->GetAttributeType() == FbxNodeAttribute::eMesh) { FbxMesh* pMesh = (FbxMesh*)pAttribute; FbxVector4* IControlPoints = pMesh->GetControlPoints(); m_vertexCount = pMesh->GetControlPointsCount(); m_vertexBuffer = new float[m_vertexCount * 4]; for (int i = 0; i < m_vertexCount * 4; i+=4) { m_vertexBuffer[i] = (float)IControlPoints[i / 4].mData[0]; m_vertexBuffer[i + 1] = (float)IControlPoints[i / 4].mData[1]; m_vertexBuffer[i + 2] = (float)IControlPoints[i / 4].mData[2]; m_vertexBuffer[i + 3] = 1.0f;// IControlPoints[i / 4].mData[3]; } int* pIndices = pMesh->GetPolygonVertices(); m_indexCount = pMesh->GetPolygonVertexCount(); m_indexBuffer = new uint32[m_indexCount]; for (int i = 0; i < m_indexCount; ++i) { m_indexBuffer[i] = pIndices[i]; } FbxLayer* pLayer = pMesh->GetLayer(0); if (pLayer != NULL) { FbxLayerElementNormal* pNormal = pLayer->GetNormals(); m_normalCount = pNormal->mDirectArray->GetCount(); m_normalBuffer = new float[m_normalCount * 3]; for (int i = 0; i < m_normalCount * 3; i+=3) { m_normalBuffer[i] = (float)(*pNormal->mDirectArray)[i / 3][0]; m_normalBuffer[i + 1] = (float)(*pNormal->mDirectArray)[i / 3][1]; m_normalBuffer[i + 2] = (float)(*pNormal->mDirectArray)[i / 3][2]; //m_normalBuffer[i + 3] = (*pNormal->mDirectArray)[i / 4][3]; } FbxLayerElementUV* pUV = pLayer->GetUVs(); if (pUV->GetMappingMode() == FbxLayerElement::eByPolygonVertex) { if (pUV->GetReferenceMode() == FbxLayerElement::eIndexToDirect) { m_uvCount = pUV->mIndexArray->GetCount(); m_uvBuffer = new float[m_uvCount * 2]; for (int i = 0; i < m_uvCount * 2; i+=2) { m_uvBuffer[i] = (float)(*pUV->mDirectArray)[(*pUV->mIndexArray)[i / 2]][0]; m_uvBuffer[i + 1] = (float)(*pUV->mDirectArray)[(*pUV->mIndexArray)[i / 2]][1]; } } else { m_uvCount = pUV->mDirectArray->GetCount(); m_uvBuffer = new float[m_uvCount * 2]; for (int i = 0; i < m_uvCount * 2; i += 2) { m_uvBuffer[i] = (float)(*pUV->mDirectArray)[i / 2][0]; m_uvBuffer[i + 1] = (float)(*pUV->mDirectArray)[i / 2][1]; } } } else { if (pUV->GetReferenceMode() == FbxLayerElement::eIndexToDirect) { m_uvCount = pUV->mIndexArray->GetCount(); m_uvBuffer = new float[m_uvCount * 2]; for (int i = 0; i < m_uvCount * 2; i+=2) { m_uvBuffer[i] = (float)(*pUV->mDirectArray)[(*pUV->mIndexArray)[i / 2]][0]; m_uvBuffer[i + 1] = (float)(*pUV->mDirectArray)[(*pUV->mIndexArray)[i / 2]][1]; } } else { m_uvCount = pUV->mDirectArray->GetCount(); m_uvBuffer = new float[m_uvCount * 2]; for (int i = 0; i < m_uvCount * 2; i+=2) { m_uvBuffer[i] = (float)(*pUV->mDirectArray)[i / 2][0]; m_uvBuffer[i + 1] = (float)(*pUV->mDirectArray)[i / 2][1]; } } } } } }