#include #include #include #include #include int load_triangles(fbxsdk::FbxNodeAttribute *attr, std::vector indices, std::vector &vertices) { if (!attr || attr->GetAttributeType() != FbxNodeAttribute::eMesh) return false; FbxMesh *mesh = static_cast(attr); unsigned int index_p = 0; FbxVector4* control_points = mesh->GetControlPoints(); for (int p = 0; p < mesh->GetPolygonCount(); p++) { if (mesh->GetPolygonSize(p) != 3) { // 不是三角形 return index_p; } for (int p_vertex = 0; p_vertex < mesh->GetPolygonSize(p); p_vertex++) { int vertex_indexed = mesh->GetPolygonVertex(p, p_vertex); FbxVector4 control_point = control_points[vertex_indexed]; V3 v = V3(control_point.mData[0], control_point.mData[1], control_point.mData[2]); vertices.push_back(v); indices.push_back(index_p++); } } return index_p; } FbxNode *get_fbx_root_node(const char *fbx_path) { printf("loading fbx file: %s\n", fbx_path); FbxManager *lSdkManager = FbxManager::Create(); if (lSdkManager) { printf("FbxManager created successfully.\n"); } else { printf("FbxManager creation failed.\n"); } FbxScene *lScene = FbxScene::Create(lSdkManager, "myScene"); if (lScene) { printf("FbxScene created successfully.\n"); } else { printf("FbxScene creation failed.\n"); } FbxImporter *lImporter = FbxImporter::Create(lSdkManager, ""); bool s = lImporter->Initialize(fbx_path, -1, lSdkManager->GetIOSettings()); if (s) { printf("FbxImporter initialized successfully.\n"); } else { printf("FbxImporter initialization failed.\n"); } lImporter->Import(lScene); lImporter->Destroy(); return lScene->GetRootNode(); } void each_node(FttContext *ctx, FbxNode *node, int level) { uint id = node->GetUniqueID(); uint pid = node->GetParent() == NULL ? 0 : node->GetParent()->GetUniqueID(); FbxString name = node->GetNameOnly(); print_node_info(node, level); // 变化矩阵信息 FbxDouble3 t = node->LclTranslation.Get(); FbxDouble3 r = node->LclRotation.Get(); FbxDouble3 s = node->LclScaling.Get(); save_nodes(ctx, id, pid, name.Buffer(), t[0], t[1], t[2], r[0], r[1], r[2], s[0], s[1], s[2], "" ); // data for (int i = 0; i < node->GetNodeAttributeCount(); i++) { FbxNodeAttribute *attr = node->GetNodeAttributeByIndex(i); if (attr && attr->GetAttributeType() == FbxNodeAttribute::eMesh) { std::vector indices; std::vector vertices; int count = load_triangles(attr, indices, vertices); printf("[%d]vertices: %ld\n", count); // save data to database sqlite3 *db = ctx->db; // todo save mesh into db save_mesh_to_table(ctx, ctx->db, id, pid, attr->GetName(), vertices.size(), indices.size(), node->GetNameOnly().Buffer()); save_mesh_vertices(ctx, id, vertices); save_mesh_indices(ctx, id, indices); } } // children if (node->GetChildCount()) { for (int i = 0; i < node->GetChildCount(); i++) { FbxNode *child = node->GetChild(i); each_node(ctx, child, level + 1); } } } void print_node_info(FbxNode* node, int level) { // 层级前缀 for (int i = 0; i < level; i++) printf("--"); printf("|"); printf("--> "); // 基础信息:ID/父ID/名称 FbxNode* parent = node->GetParent(); printf("[ID:%lld/PID:%lld] Name: %s\n", node->GetUniqueID(), parent ? parent->GetUniqueID() : 0, node->GetNameOnly().Buffer()); // 变换矩阵:平移/旋转/缩放 FbxDouble3 t = node->LclTranslation.Get(); FbxDouble3 r = node->LclRotation.Get(); FbxDouble3 s = node->LclScaling.Get(); printf(" Transform: T(%.2f,%.2f,%.2f) R(%.2f,%.2f,%.2f) S(%.2f,%.2f,%.2f)\n", t[0], t[1], t[2], r[0], r[1], r[2], s[0], s[1], s[2]); // 属性列表(前5个非默认属性) FbxProperty p = node->GetFirstProperty(); int prop_count = 0; printf(" Properties: "); while (p.IsValid() && prop_count < 5) { printf("%s[%.2f] ", p.GetName().Buffer(), p.Get()); prop_count++; p = node->GetNextProperty(p); } if (prop_count > 0) printf("\n"); }