std::shared_ptr<Scene> FBXConverter::LoadScene(FbxScene* fbxScene, FbxManager* fbxManager) { // convert a coordinate system FbxAxisSystem axis(FbxAxisSystem::eOpenGL); axis.ConvertScene(fbxScene); auto scene = std::make_shared<Scene>(); // import nodes auto root = fbxScene->GetRootNode(); scene->Root = LoadHierarchy(nullptr, root, fbxManager); // import animations auto animStackCount = fbxScene->GetSrcObjectCount<FbxAnimStack>(); for (auto animStackIndex = 0; animStackIndex < animStackCount; animStackIndex++) { auto animStack = fbxScene->GetSrcObject<FbxAnimStack>(animStackIndex); fbxScene->SetCurrentAnimationStack(animStack); auto animClip = LoadAnimation(animStack, root); if(animClip.get() == nullptr) continue; scene->AnimationClips.push_back(animClip); } return scene; }
void LoadStrategy_PlacedHierarchy(SAVE_BLOCK_STRATEGY_HEADER* header) { int i; STRATEGYBLOCK* sbPtr; PLACED_HIERARCHY_BEHAV_BLOCK *ph_bhv; char * buffer =(char*) header; buffer+=sizeof(*header); //find the existing strategy block sbPtr = FindSBWithName(header->SBname); if(!sbPtr) return; //make sure the strategy found is of the right type if(sbPtr->I_SBtype != I_BehaviourPlacedHierarchy) return; ph_bhv = (PLACED_HIERARCHY_BEHAV_BLOCK*)sbPtr->SBdataptr; { int sequence_index; sequence_index = *(int*) buffer; buffer+=sizeof(int); if(sequence_index>=0 && sequence_index<ph_bhv->num_sequences) { ph_bhv->current_seq = &ph_bhv->sequences[sequence_index]; } } { int loaded_num_sounds; loaded_num_sounds = *(int*) buffer; buffer +=sizeof(int); for(i=0;i<loaded_num_sounds && i<ph_bhv->num_sounds;i++) { int playing; playing = *(int*)buffer; buffer += sizeof(int); ph_bhv->sounds[i].playing = playing; } } //load the hierarchy { SAVE_BLOCK_HEADER* hier_header = GetNextBlockIfOfType(SaveBlock_Hierarchy); if(hier_header) { LoadHierarchy(hier_header,&ph_bhv->HModelController); } } for(i=0;i<ph_bhv->num_sounds;i++) { Load_SoundState(&ph_bhv->sounds[i].activ_no); } }
bool CRasterTerrainModel::LoadHierarchy(Patch* node, bool compress, FILE* fp) { static const char LOADING_CHARS[] = {'|', '/', '-', '\\' }; static int CUR_CHAR = 0; static std::vector<glm::half> readbuf; glm::vec3 extent; glm::uint count, cmask; //read label fread(&node->label, sizeof(glm::uint), 1, fp); //read bounds fread(&node->bbmin.x, sizeof(glm::vec3), 1, fp); node->bbmin = vec3(node->bbmin.x, node->bbmin.y, node->bbmin.z); UpdateBoundingBox(node->bbmin); fread(&node->bbmax.x, sizeof(glm::vec3), 1, fp); node->bbmax = vec3(node->bbmax.x, node->bbmax.y, node->bbmax.z); UpdateBoundingBox(node->bbmax); fread(&node->error, sizeof(float), 1, fp); //read vertex data if (compress) { fread(&count, sizeof(glm::uint), 1, fp); readbuf.resize(count); fread(readbuf.data(), sizeof(glm::half), count, fp); //decompress extent = node->bbmax - node->bbmin; node->vbuf.reserve(count/6); for (uint i=0; i < readbuf.size(); i+=6) { Vertex v; v.p.x = node->bbmin.x + extent.x*static_cast<float>(readbuf[i]); v.p.y = (node->bbmin.y + extent.y*static_cast<float>(readbuf[i + 1])); v.p.z = (node->bbmin.z + extent.z* static_cast<float>(readbuf[i + 2])); v.n.x = (2.f*static_cast<float>(readbuf[i + 3]) - 1.f); v.n.y = (2.f*static_cast<float>(readbuf[i + 4]) - 1.f); v.n.z = (2.f*static_cast<float>(readbuf[i + 5]) - 1.f); node->vbuf.push_back(v); } } else { fread(&count, sizeof(glm::uint), 1, fp); node->vbuf.resize(count); fread(node->vbuf.data(), sizeof(Vertex), count, fp); for (auto iter = node->vbuf.begin(); iter != node->vbuf.end(); ++iter) { Vertex vertex = *iter; iter->p.y = vertex.p.y; iter->p.z = vertex.p.z; iter->n.y = vertex.n.y; iter->n.z = vertex.n.z; } } //read child mask fread(&cmask, sizeof(glm::uint), 1, fp); node->child_mask = cmask; //read childs for (glm::uint i=0; i < 4; ++i) { Patch* p = nullptr; if (cmask & (1 << i)) { p = new Patch(node); if (!LoadHierarchy(p, compress, fp)) return false; } node->childs[i] = p; } //detect read errors if (ferror(fp) != 0) { std::cerr << "failed to read patch hierchary!" << std::endl; return false; } CUR_CHAR = (CUR_CHAR+1) % 4; //std::cout << "\r\treading patch hierarchy " << LOADING_CHARS[CUR_CHAR]; return true; }
bool CRasterTerrainModel::Init(const char* hfcfile) { mModelPath = std::string(hfcfile); FILE* fp = nullptr; errno_t error = fopen_s(&fp, hfcfile, "rb"); if (fp == nullptr || error != 0) { std::cerr << "failed to open terrain file " << hfcfile << "!" << std::endl; return false; } //read magic char sig[4]; fread(sig, 1, 4, fp); if (memcmp(sig, MAGIC, 4) != 0) { fclose(fp); std::cerr << "terrain file is not a raster-lod!" << std::endl; return false; } //read compress flag uint compressFlag; fread(&compressFlag, sizeof(glm::uint), 1, fp); //read extent float extent[4]; fread(extent, sizeof(float), 4, fp); std::cout << "terrain has an extent of: " << extent[0] << ", " <<extent[2] << "; " << extent[1] << ", " <<extent[3] << "!" << std::endl; mTerrainMin.x = extent[0]; mTerrainMax.x = extent[1]; mTerrainMin.z = extent[2]; mTerrainMax.z = extent[3]; //read patch size fread(&mPatchSize, sizeof(glm::uint), 1, fp); std::cout << "terrain has patchsize of: " << mPatchSize << "!" << std::endl; //read tess levels fread(&mTessLevels, sizeof(glm::uint), 1, fp); mTessellationIBufs.resize(mTessLevels*mTessLevels*4); ///mTessLevels*mTessLevels configs for the 4 childs std::cout << "terrain has a total count of tessellation buffers: " << mTessellationIBufs.size() << "!" << std::endl; glm::uint tessBufferSize = 0; for (glm::uint i=0; i < mTessellationIBufs.size(); ++i) { glm::uint count; fread(&count, sizeof(glm::uint), 1, fp); mTessellationIBufs[i].resize(count); fread(mTessellationIBufs[i].data(), sizeof(glm::uint), count, fp); tessBufferSize += count * sizeof(uint); } std::cout << "tessellation buffers consumes approx: " << tessBufferSize << "bytes!" << std::endl; std::cout << "\treading patch hierarchy |"; mRoot = new Patch(0); if (!LoadHierarchy(mRoot, compressFlag == 1, fp)) { Clear(); return false; } std::cout << "\r\treading patch hierarchy [done]" << std::endl; //assign neighbors AssignChildNeighbors(mRoot); return true; }
std::shared_ptr<Node> FBXConverter::LoadHierarchy(std::shared_ptr<Node> parent, FbxNode* fbxNode, FbxManager* fbxManager) { FbxMesh* mesh = nullptr; std::shared_ptr<Node> node = std::make_shared<Node>(); node->Name = fbxNode->GetName(); auto attribute_ = fbxNode->GetNodeAttribute(); if (attribute_ != nullptr) { auto attributeType = attribute_->GetAttributeType(); switch (attributeType) { case FbxNodeAttribute::eMesh: mesh = fbxNode->GetMesh(); if (!mesh->IsTriangleMesh()) { FbxGeometryConverter converter(fbxManager); auto mesh_tri = (FbxMesh*) converter.Triangulate(mesh, false); if (mesh_tri != nullptr) { mesh = mesh_tri; } } node->MeshData = LoadMesh(mesh); break; case FbxNodeAttribute::eSkeleton: break; default: break; } } else { // This is root. } // load transforms EFbxRotationOrder fbxRotationOrder; fbxNode->GetRotationOrder(FbxNode::eDestinationPivot, fbxRotationOrder); node->RotationOrder = fbxRotationOrder; // default transform auto lclT = fbxNode->LclTranslation.Get(); auto lclR = fbxNode->LclRotation.Get(); auto lclS = fbxNode->LclScaling.Get(); node->Translation[0] = lclT[0]; node->Translation[1] = lclT[1]; node->Translation[2] = lclT[2]; node->Rotation[0] = lclR[0]; node->Rotation[1] = lclR[1]; node->Rotation[2] = lclR[2]; node->Scaling[0] = lclS[0]; node->Scaling[1] = lclS[1]; node->Scaling[2] = lclS[2]; for (auto i = 0; i < fbxNode->GetChildCount(); i++) { auto childNode = LoadHierarchy(node, fbxNode->GetChild(i), fbxManager); if (childNode != nullptr) { node->Children.push_back(childNode); } } return node; }