使用OpenSceneGraph生成3D數據格式文件

OpenSceneGraph (OSG) 提供了多種方式來生成和導出3D數據格式文件。以下是詳細的生成方法和示例代碼:

一、基本文件生成方法

1. 使用osgDB::writeNodeFile函數

這是最直接的生成方式,支持多種格式:

#include <osgDB/WriteFile>osg::ref_ptr<osg::Node> scene = createScene(); // 創建你的場景圖// 導出為不同格式
bool success;
success = osgDB::writeNodeFile(*scene, "output.osgt");  // OSG文本格式
success = osgDB::writeNodeFile(*scene, "output.osgb");  // OSG二進制格式
success = osgDB::writeNodeFile(*scene, "output.obj");   // Wavefront OBJ
success = osgDB::writeNodeFile(*scene, "output.dae");   // COLLADA
success = osgDB::writeNodeFile(*scene, "output.fbx");   // FBX(需插件支持)

2. 支持的導出格式

格式類型文件擴展名說明
OSG原生.osgt, .osgb, .osgx文本/二進制/XML格式
通用3D.obj, .stl, .ply靜態網格格式
場景格式.dae, .fbx, .3ds支持完整場景
地形數據.ive, .lwo, .txp優化格式

二、編程生成場景并導出

1. 創建簡單幾何體并導出

#include <osg/Geode>
#include <osg/Geometry>
#include <osgDB/WriteFile>osg::Geode* createCube() {osg::ref_ptr<osg::Geode> geode = new osg::Geode;osg::ref_ptr<osg::Geometry> geometry = new osg::Geometry;// 定義8個頂點(立方體)osg::Vec3Array* vertices = new osg::Vec3Array;vertices->push_back(osg::Vec3(-1.0f, -1.0f,  1.0f)); // 前左下vertices->push_back(osg::Vec3( 1.0f, -1.0f,  1.0f)); // 前右下vertices->push_back(osg::Vec3( 1.0f,  1.0f,  1.0f)); // 前右上vertices->push_back(osg::Vec3(-1.0f,  1.0f,  1.0f)); // 前左上vertices->push_back(osg::Vec3(-1.0f, -1.0f, -1.0f)); // 后左下vertices->push_back(osg::Vec3( 1.0f, -1.0f, -1.0f)); // 后右下vertices->push_back(osg::Vec3( 1.0f,  1.0f, -1.0f)); // 后右上vertices->push_back(osg::Vec3(-1.0f,  1.0f, -1.0f)); // 后左上geometry->setVertexArray(vertices);// 定義法線osg::Vec3Array* normals = new osg::Vec3Array;normals->push_back(osg::Vec3( 0.0f,  0.0f,  1.0f)); // 前normals->push_back(osg::Vec3( 0.0f,  0.0f, -1.0f)); // 后normals->push_back(osg::Vec3( 1.0f,  0.0f,  0.0f)); // 右normals->push_back(osg::Vec3(-1.0f,  0.0f,  0.0f)); // 左normals->push_back(osg::Vec3( 0.0f,  1.0f,  0.0f)); // 上normals->push_back(osg::Vec3( 0.0f, -1.0f,  0.0f)); // 下geometry->setNormalArray(normals, osg::Array::BIND_PER_PRIMITIVE);// 定義6個面(12個三角形)osg::DrawElementsUInt* faces = new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLES, 0);// 前面faces->push_back(0); faces->push_back(1); faces->push_back(2);faces->push_back(2); faces->push_back(3); faces->push_back(0);// 后面faces->push_back(5); faces->push_back(4); faces->push_back(7);faces->push_back(7); faces->push_back(6); faces->push_back(5);// 右面faces->push_back(1); faces->push_back(5); faces->push_back(6);faces->push_back(6); faces->push_back(2); faces->push_back(1);// 左面faces->push_back(4); faces->push_back(0); faces->push_back(3);faces->push_back(3); faces->push_back(7); faces->push_back(4);// 上面faces->push_back(3); faces->push_back(2); faces->push_back(6);faces->push_back(6); faces->push_back(7); faces->push_back(3);// 下面faces->push_back(4); faces->push_back(5); faces->push_back(1);faces->push_back(1); faces->push_back(0); faces->push_back(4);geometry->addPrimitiveSet(faces);geode->addDrawable(geometry);return geode.release();
}int main() {osg::ref_ptr<osg::Node> scene = createCube();osgDB::writeNodeFile(*scene, "box.osgb");return 0;
}

?2. 生成帶紋理的模型

osg::Node* createTexturedQuad() {osg::ref_ptr<osg::Geode> geode = new osg::Geode;osg::ref_ptr<osg::Geometry> geom = new osg::Geometry;// 頂點osg::Vec3Array* vertices = new osg::Vec3Array;vertices->push_back(osg::Vec3(-1,0,-1));vertices->push_back(osg::Vec3(1,0,-1));vertices->push_back(osg::Vec3(1,0,1));vertices->push_back(osg::Vec3(-1,0,1));geom->setVertexArray(vertices);// 紋理坐標osg::Vec2Array* texcoords = new osg::Vec2Array;texcoords->push_back(osg::Vec2(0,0));texcoords->push_back(osg::Vec2(1,0));texcoords->push_back(osg::Vec2(1,1));texcoords->push_back(osg::Vec2(0,1));geom->setTexCoordArray(0, texcoords);// 加載紋理osg::ref_ptr<osg::Texture2D> texture = new osg::Texture2D;texture->setImage(osgDB::readImageFile("texture.jpg"));// 創建狀態集osg::ref_ptr<osg::StateSet> stateset = geom->getOrCreateStateSet();stateset->setTextureAttributeAndModes(0, texture, osg::StateAttribute::ON);geom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS, 0, 4));geode->addDrawable(geom);return geode.release();
}

三、高級導出選項

1. 使用osg::Options控制導出

osg::ref_ptr<osgDB::Options> options = new osgDB::Options;
options->setOptionString("WriteImageHint=IncludeFile");  // 包含紋理引用osgDB::writeNodeFile(*scene, "textured_model.osgt", options.get());

2. 常用導出選項

選項字符串功能描述
"WriteImageHint=IncludeFile"包含紋理文件引用
"Compressor=zlib"使用壓縮格式
"Precision=15"設置浮點精度
"OutputTextureFiles"導出紋理文件

3. 批量導出多個LOD級別

void exportLODs(osg::Node* model, const std::string& basename) {osg::ref_ptr<osg::LOD> lod = new osg::LOD;// 創建不同細節級別的模型osg::Node* highRes = createSimplifiedModel(model, 1.0f);osg::Node* medRes = createSimplifiedModel(model, 0.5f);osg::Node* lowRes = createSimplifiedModel(model, 0.2f);lod->addChild(highRes, 0, 50);lod->addChild(medRes, 50, 200);lod->addChild(lowRes, 200, FLT_MAX);osgDB::writeNodeFile(*lod, basename + "_lod.osgb");
}// 輔助函數:創建簡化模型
osg::Node* createSimplifiedModel(osg::Node* original, float ratio) {osgUtil::Simplifier simplifier(ratio);osg::ref_ptr<osg::Node> copy = dynamic_cast<osg::Node*>(original->clone(osg::CopyOp::DEEP_COPY_ALL));copy->accept(simplifier);return copy.release();
}

四、處理導出問題

1. 檢查插件支持

// 列出所有支持的寫入格式
osgDB::Registry::instance()->getWriterExtensions();// 檢查特定格式是否支持
if (osgDB::Registry::instance()->getReaderWriterForExtension("fbx")) {// FBX導出可用
}

2. 錯誤處理

bool result = osgDB::writeNodeFile(*node, "output.fbx");
if (!result) {OSG_WARN << "Failed to export FBX file. Make sure FBX plugin is installed." << std::endl;// 嘗試回退格式osgDB::writeNodeFile(*node, "output.obj");
}

五、實際應用示例

1. 生成地形并導出

osg::Node* createTerrain() {osg::ref_ptr<osg::HeightField> hf = new osg::HeightField;hf->allocate(64, 64); // 64x64網格// 填充高度數據for (unsigned int r=0; r<hf->getNumRows(); ++r) {for (unsigned int c=0; c<hf->getNumColumns(); ++c) {float height = sin(c/10.0f) * cos(r/10.0f) * 10.0f;hf->setHeight(c, r, height);}}osg::ref_ptr<osg::Geode> geode = new osg::Geode;geode->addDrawable(new osg::ShapeDrawable(hf.get()));return geode.release();
}// 導出為OpenFlight格式
osgDB::writeNodeFile(*createTerrain(), "terrain.flt");

2. 動畫模型導出

osg::AnimationPath* createAnimationPath() {osg::ref_ptr<osg::AnimationPath> path = new osg::AnimationPath;path->setLoopMode(osg::AnimationPath::LOOP);float time = 0.0f;float delta = 1.0f/30.0f; // 30fpsfor (unsigned int i=0; i<60; ++i) {osg::Vec3 pos(sin(time), cos(time), 0.0f);path->insert(time, osg::AnimationPath::ControlPoint(pos));time += delta;}return path.release();
}osg::Node* createAnimatedModel() {osg::ref_ptr<osg::MatrixTransform> animNode = new osg::MatrixTransform;animNode->setUpdateCallback(new osg::AnimationPathCallback(createAnimationPath()));// 添加你的模型animNode->addChild(createSimpleBox());return animNode.release();
}// 導出動畫模型
osgDB::writeNodeFile(*createAnimatedModel(), "animated.dae");

?

?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/75815.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/75815.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/75815.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

JMeter接口性能測試從入門到精通

前言&#xff1a; 本文主要介紹了如何利用jmter進行接口的性能測試 1.在測試計劃中添加線程組 1.1.線程組界面中元素含義 如果點擊循環次數為永遠&#xff1a; 2.添加HTTP取樣器 2.1.填寫登錄接口的各個參數 2.2.在線程組下面增加查看結果樹 請求成功的情況&#xff1a; 請求…

C++抽卡模擬器

近日在學校無聊&#xff0c;寫了個抽卡模擬器供大家娛樂。 代碼實現以下功能&#xff1a;抽卡界面&#xff0c;抽卡判定、動畫播放、存檔。 1.抽卡界面及判定 技術有限&#xff0c;不可能做的和原神一樣精致。代碼如下&#xff08;注&#xff1a;這不是完整代碼&#xff0c;…

詳解相機的內參和外參,以及內外參的標定方法

1 四個坐標系 要想深入搞清楚相機的內參和外參含義&#xff0c; 首先得清楚以下4個坐標系的定義&#xff1a; 世界坐標系&#xff1a; 名字看著很唬人&#xff0c; 其實沒什么大不了的&#xff0c; 這個就是你自己定義的某一個坐標系。 比如&#xff0c; 你把房間的某一個點定…

學透Spring Boot — 011. 一篇文章學會Spring Test

系列文章目錄 這是學透Spring Boot的第11篇文章。更多系列文章請關注 CSDN postnull 用戶的專欄 文章目錄 系列文章目錄Spring Test的依賴Spring Test的核心功能SpringBootTest 加載Spring上下文依賴注入有問題時Spring配置有問題時 WebMvcTest 測試Web層&#xff08;Controll…

Mysql 數據庫編程技術01

一、數據庫基礎 1.1 認識數據庫 為什么學習數據庫 瞬時數據&#xff1a;比如內存中的數據&#xff0c;是不能永久保存的。持久化數據&#xff1a;比如持久化至數據庫中或者文檔中&#xff0c;能夠長久保存。 數據庫是“按照數據結構來組織、存儲和管理數據的倉庫”。是一個長…

新一代AI架構實踐:數字大腦AI+智能調度MCP+領域執行APP的黃金金字塔體系

新一代AI架構實踐&#xff1a;數字大腦智能調度領域執行的黃金金字塔體系 一、架構本質的三層穿透性認知 1.1 核心范式轉變&#xff08;CPS理論升級&#xff09; 傳統算法架構&#xff1a;數據驅動 → 特征工程 → 模型訓練 → 業務應用 新一代AI架構&#xff1a;物理規律建…

macOS可視化桌面配置docker加速器

macOS可視化桌面配置docker加速器 在鏡像settings->docker Engine改為國內鏡像修改為國內鏡像重啟docker(可視化界面啟動或者使用命令行)使用命令重啟可視化界面重啟 在鏡像settings->docker Engine改為國內鏡像 修改為國內鏡像 {"registry-mirrors": ["…

Nginx 基礎使用(2025)

一、Nginx目錄結構 [rootlocalhost ~]# tree /usr/local/nginx /usr/local/nginx ├── client_body_temp # POST 大文件暫存目錄 ├── conf # Nginx所有配置文件的目錄 │ ├── fastcgi.conf # fastcgi相…

用spring-webmvc包實現AI(Deepseek)事件流(SSE)推送

前后端&#xff1a; Spring Boot Angular spring-webmvc-5.2.2包 代碼片段如下&#xff1a; 控制層&#xff1a; GetMapping(value "/realtime/page/ai/sse", produces MediaType.TEXT_EVENT_STREAM_VALUE)ApiOperation(value "獲取告警記錄進行AI分析…

基于Python的招聘推薦數據可視化分析系統

【Python】基于Python的招聘推薦數據可視化分析系統&#xff08;完整系統源碼開發筆記詳細部署教程&#xff09;? 目錄 一、項目簡介二、項目界面展示三、項目視頻展示 一、項目簡介 &#x1f680;&#x1f31f; 基于Python的招聘推薦數據可視化分析系統&#xff01;&#x1…

使用注解開發springMVC

引言 在學習過第一個springMVC項目建造過后&#xff0c;讓我們直接進入真實開發中所必需的注解開發&#xff0c; 是何等的簡潔高效&#xff01;&#xff01; 注&#xff1a;由于Maven可能存在資源過濾的問題&#xff0c;在maven依賴中加入 <build><resources>&l…

linux專題3-----禁止SSH的密碼登錄

要在linux系統中禁止密碼登錄&#xff0c;您可以通過修改 SSH 配置來實現。請按照以下步驟操作(此處以 Ubuntu為例)&#xff1a; 1、SSH 登錄到您的服務器&#xff08;或直接在命令行模式下&#xff09;。 2、備份 SSH 配置文件&#xff1a; 在終端中運行以下命令以備份現有的…

基于LangChain和通義(Tongyi)實現NL2SQL的智能檢索(無需訓練)

在數據驅動的時代,如何高效地從數據庫中獲取信息成為了一個重要的挑戰。自然語言到SQL(NL2SQL)技術提供了一種便捷的解決方案,使用戶能夠用自然語言查詢數據庫,而無需深入了解SQL語法。本文將探討如何利用LangChain和通義(Tongyi)實現NL2SQL的智能檢索,具體步驟如下: …

深度學習處理文本(10)

保存自定義層 在編寫自定義層時&#xff0c;一定要實現get_config()方法&#xff1a;這樣我們可以利用config字典將該層重新實例化&#xff0c;這對保存和加載模型很有用。該方法返回一個Python字典&#xff0c;其中包含用于創建該層的構造函數的參數值。所有Keras層都可以被序…

機器視覺3D中激光偏鏡的優點

機器視覺的3D應用中,激光偏鏡(如偏振片、波片、偏振分束器等)通過其獨特的偏振控制能力,顯著提升了系統的測量精度、抗干擾能力和適應性。以下是其核心優點: 1. 提升3D成像精度 抑制環境光干擾:偏振片可濾除非偏振的環境雜光(如日光、室內照明),僅保留激光偏振信號,大…

線程同步的學習與應用

1.多線程并發 1).多線程并發引例 #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <assert.h> #include <pthread.h>int wg0; void *fun(void *arg) {for(int i0;i<1000;i){wg;printf("wg%d\n",wg);} } i…

寫.NET可以指定運行SUB MAIN嗎?調用任意一個里面的類時,如何先執行某段初始化代碼?

VB.NET 寫.NET可以指定運行SUB MAIN嗎?調用任意一個里面的類時,如何先執行某段初始化代碼? 分享 1. 在 VB.NET 中指定運行 Sub Main 在 VB.NET 里&#xff0c;你能夠指定 Sub Main 作為程序的入口點。下面為你介紹兩種實現方式&#xff1a; 方式一&#xff1a;在項目屬性…

【AI插件開發】Notepad++ AI插件開發實踐(代碼篇):從Dock窗口集成到功能菜單實現

一、引言 上篇文章已經在Notepad的插件開發中集成了選中即問AI的功能&#xff0c;這一篇文章將在此基礎上進一步集成&#xff0c;支持AI對話窗口以及常見的代碼功能菜單&#xff1a; 顯示AI的Dock窗口&#xff0c;可以用自然語言向 AI 提問或要求執行任務選中代碼后使用&…

關聯容器-模板類pair數對

關聯容器 關聯容器和順序容器有著根本的不同:關聯容器中的元素是按關鍵字來保存和訪問的,而順序容器中的元素是按它們在容器中的位置來順序保存和訪問的。 關聯容器支持高效的關鍵字查找和訪問。 兩個主要的關聯容器(associative-container),set和map。 set 中每個元素只包…

京東運維面試題及參考答案

目錄 OSPF 實現原理是什么? 請描述 TCP 三次握手的過程。 LVS 的原理是什么? 闡述 Nginx 七層負載均衡的原理。 Nginx 與 Apache 有什么區別? 如何查看監聽在 8080 端口的是哪個進程(可舉例:netstat -tnlp | grep 8080)? OSI 七層模型是什么,請寫出各層的協議。 …