load fbx
This commit is contained in:
parent
95d5d00363
commit
a202d3c9ea
|
@ -1 +1,3 @@
|
|||
/target
|
||||
*.o
|
||||
*.exe
|
|
@ -0,0 +1,35 @@
|
|||
{
|
||||
"files.associations": {
|
||||
"*.dbclient-js": "javascript",
|
||||
"bit": "cpp",
|
||||
"compare": "cpp",
|
||||
"concepts": "cpp",
|
||||
"cstddef": "cpp",
|
||||
"cstdint": "cpp",
|
||||
"cstdio": "cpp",
|
||||
"cstdlib": "cpp",
|
||||
"cstring": "cpp",
|
||||
"cwchar": "cpp",
|
||||
"exception": "cpp",
|
||||
"initializer_list": "cpp",
|
||||
"iosfwd": "cpp",
|
||||
"iterator": "cpp",
|
||||
"limits": "cpp",
|
||||
"map": "cpp",
|
||||
"new": "cpp",
|
||||
"stdexcept": "cpp",
|
||||
"tuple": "cpp",
|
||||
"type_traits": "cpp",
|
||||
"utility": "cpp",
|
||||
"vector": "cpp",
|
||||
"xmemory": "cpp",
|
||||
"xstddef": "cpp",
|
||||
"xstring": "cpp",
|
||||
"xtr1common": "cpp",
|
||||
"xtree": "cpp",
|
||||
"xutility": "cpp",
|
||||
"iostream": "cpp",
|
||||
"ostream": "cpp"
|
||||
},
|
||||
"C_Cpp.errorSquiggles": "disabled"
|
||||
}
|
1
build.rs
1
build.rs
|
@ -8,6 +8,7 @@ fn main() {
|
|||
.warnings(false)
|
||||
.include("./cpp_src/include")
|
||||
.file("./cpp_src/fbx_parse.cpp")
|
||||
.file("./cpp_src/fbx_wrap.cpp")
|
||||
.compile("fbx_parse");
|
||||
// -------------
|
||||
println!("cargo:rustc-link-search=native=./cpp_src/lib");
|
||||
|
|
|
@ -1,62 +1,49 @@
|
|||
#include <fbxsdk.h>
|
||||
// external
|
||||
#include <stdio.h>
|
||||
// buz
|
||||
#include <fbx_wrap.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
extern "C" {
|
||||
// 定义给Rust调用的接口函数
|
||||
void fbx_parse(const char* fbx_path) {
|
||||
std::printf("%s\n", fbx_path);
|
||||
void fbx_parse(const char* fbx_path)
|
||||
{
|
||||
printf("%s\n", fbx_path);
|
||||
FbxManager* lSdkManager = FbxManager::Create();
|
||||
if (lSdkManager){
|
||||
std::printf("FbxManager created successfully.\n");
|
||||
printf("FbxManager created\n");
|
||||
} else{
|
||||
std::printf("FbxManager creation failed.\n");
|
||||
printf("FbxManager creation failed.\n");
|
||||
}
|
||||
FbxScene* lScene = FbxScene::Create(lSdkManager, "myScene");
|
||||
if (lScene){
|
||||
std::printf("FbxScene created successfully.\n");
|
||||
printf("FbxScene created\n");
|
||||
} else{
|
||||
std::printf("FbxScene creation failed.\n");
|
||||
printf("FbxScene creation failed.\n");
|
||||
}
|
||||
FbxImporter* lImporter = FbxImporter::Create(lSdkManager, "");
|
||||
bool s = lImporter->Initialize(fbx_path, -1, lSdkManager->GetIOSettings());
|
||||
if (s){
|
||||
std::printf("FbxImporter initialized successfully.\n");
|
||||
printf("FbxImporter initialized\n");
|
||||
} else{
|
||||
std::printf("FbxImporter initialization failed.\n");
|
||||
printf("FbxImporter initialization failed.\n");
|
||||
}
|
||||
lImporter->Import(lScene);
|
||||
lImporter->Destroy();
|
||||
|
||||
FbxNode* lRootNode = lScene->GetRootNode();
|
||||
if (lRootNode) {
|
||||
std::printf("Root node found. Node name: %s\n", lRootNode->GetName());
|
||||
int childCount = lRootNode->GetChildCount();
|
||||
std::printf("Number of child nodes: %d\n", childCount);
|
||||
for (int i = 0; i < childCount; ++i) {
|
||||
FbxNode* childNode = lRootNode->GetChild(i);
|
||||
std::printf("Child node %d name: %s\n", i, childNode->GetName());
|
||||
}
|
||||
each_node(lRootNode, 0);
|
||||
} else {
|
||||
std::printf("No root node found in the scene.\n");
|
||||
}
|
||||
|
||||
|
||||
if (lRootNode && lRootNode->GetNodeAttribute() &&
|
||||
lRootNode->GetNodeAttribute()->GetAttributeType() == FbxNodeAttribute::eMesh) {
|
||||
FbxMesh* lMesh = static_cast<FbxMesh*>(lRootNode->GetNodeAttribute());
|
||||
int materialCount = lMesh->GetElementMaterialCount();
|
||||
std::printf("Number of materials in the mesh: %d\n", materialCount);
|
||||
for (int i = 0; i < materialCount; ++i) {
|
||||
FbxSurfaceMaterial* lMaterial = nullptr;
|
||||
std::printf("Material name: %s\n", lMaterial->GetName());
|
||||
// lMesh->GetElementMaterial(0)->eMaterial(i, lMaterial);
|
||||
// if (lMaterial) {
|
||||
// std::printf("Material %d name: %s\n", i, lMaterial->GetName());
|
||||
// }
|
||||
}
|
||||
int controlPointCount = lMesh->GetControlPointsCount();
|
||||
std::printf("Number of vertices in the mesh: %d\n", controlPointCount);
|
||||
printf("No root node found in the scene.\n");
|
||||
}
|
||||
}
|
||||
|
||||
void load_fbx_mesh_to_db(const char* fbx_path)
|
||||
{
|
||||
FbxNode* root = get_fbx_root_node(fbx_path);
|
||||
|
||||
each_node(root, 0);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,101 @@
|
|||
#include "fbx_wrap.h"
|
||||
#include <stdio.h>
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
int load_triangles(fbxsdk::FbxNodeAttribute* attr, std::vector<Triangle>& triangles) {
|
||||
FbxMesh* mesh = static_cast<FbxMesh*>(attr);
|
||||
// 顶点数据
|
||||
// int ctrlPointCount = mesh->GetControlPointsCount();
|
||||
// vertices.assign(mesh->GetControlPoints(), mesh->GetControlPoints() + ctrlPointCount);
|
||||
|
||||
// 三角化并提取三角形索引
|
||||
FbxGeometryConverter converter(mesh->GetFbxManager());
|
||||
if (!converter.Triangulate(mesh, true)) return false; // 强制三角化
|
||||
|
||||
int polyCount = mesh->GetPolygonCount();
|
||||
triangles.reserve(polyCount);
|
||||
for (int i = 0; i < polyCount; ++i) {
|
||||
if (mesh->GetPolygonSize(i) != 3) continue; // 跳过非三角形(理论上不会存在)
|
||||
int i0 = mesh->GetPolygonVertex(i, 0);
|
||||
int i1 = mesh->GetPolygonVertex(i, 1);
|
||||
int i2 = mesh->GetPolygonVertex(i, 2);
|
||||
triangles.emplace_back(i0, i1, i2);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
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(FbxNode* parent_node, int level)
|
||||
{
|
||||
// info
|
||||
print_node_info(parent_node, level);
|
||||
// data
|
||||
for (int i = 0; i < parent_node->GetNodeAttributeCount(); i++)
|
||||
{
|
||||
FbxNodeAttribute* attr = parent_node->GetNodeAttributeByIndex(i);
|
||||
if (attr && attr->GetAttributeType() == FbxNodeAttribute::eMesh)
|
||||
{
|
||||
std::vector<Triangle> triangles;
|
||||
int count = load_triangles(attr, triangles);
|
||||
printf("triangles: %ld;", triangles.size());
|
||||
std::cout << "("
|
||||
<< get<0>(triangles[0]) << ", "
|
||||
<< get<1>(triangles[0]) << ", "
|
||||
<< get<2>(triangles[0]) << ")"
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// children
|
||||
if (parent_node->GetChildCount())
|
||||
{
|
||||
for (int i = 0; i < parent_node->GetChildCount(); i++)
|
||||
{
|
||||
FbxNode* child = parent_node->GetChild(i);
|
||||
each_node(child, level + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void print_node_info(FbxNode* node, int level)
|
||||
{
|
||||
// 打印一下节点信息
|
||||
printf("|");
|
||||
for (int i = 0; i < level; i++)
|
||||
{
|
||||
printf("-");
|
||||
}
|
||||
printf("> ");
|
||||
printf("[%ld]: %s\n", node->GetUniqueID(), node->GetNameOnly().Buffer());
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
#include <fbxsdk.h>
|
||||
#include <vector>
|
||||
|
||||
using namespace std;
|
||||
|
||||
using Triangle = std::tuple<int, int, int>;
|
||||
|
||||
struct Context {
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* 递归遍历FBX节点树结构
|
||||
* @param parent_node 起始父节点,从此节点开始向下遍历(若为nullptr则函数不执行任何操作)
|
||||
* @param level 当前节点层级(用于缩进或层级标识,建议初始调用时传入0)
|
||||
* @note 函数内部会递归访问parent_node的所有直接子节点和间接子节点
|
||||
* @warning 若输入的parent_node无效(如野指针)可能导致程序崩溃
|
||||
*/
|
||||
void each_node(FbxNode* parent_node, int level);
|
||||
/**
|
||||
* 打印FBX节点的基本信息(含层级缩进)
|
||||
* @param node 待打印信息的节点指针(nullptr时输出警告日志)
|
||||
* @param level 节点层级(用于控制打印缩进,每级建议缩进4空格)
|
||||
* @details 输出内容包含:节点名称、类型、子节点数量、层级深度
|
||||
* @example 层级2的节点打印格式:" |-- NodeName (Type: Mesh, Children: 3)"
|
||||
*/
|
||||
void print_node_info(FbxNode* node, int level);
|
||||
|
||||
FbxNode* get_fbx_root_node(const char* fbx_path);
|
||||
|
||||
int load_triangles(fbxsdk::FbxNodeAttribute* attr, std::vector<Triangle>& triangles);
|
|
@ -5,12 +5,15 @@ fn main() {
|
|||
|
||||
unsafe extern "C" {
|
||||
pub unsafe fn fbx_parse(name_in: *const u8);
|
||||
pub unsafe fn load_fbx_mesh_to_db(path: *const u8);
|
||||
}
|
||||
|
||||
fn convert_fbx_to_3dtiles(fbx_path: &str) {
|
||||
|
||||
unsafe {
|
||||
fbx_parse(fbx_path.as_ptr() as *const u8);
|
||||
// fbx_parse(fbx_path.as_ptr() as *const u8);
|
||||
// 1. load to disk
|
||||
load_fbx_mesh_to_db(fbx_path.as_ptr() as *const u8);
|
||||
}
|
||||
|
||||
// unsafe {
|
||||
|
|
Loading…
Reference in New Issue