API4.x实现本地gltf模型的导入
环境 ArcGIS API for JS 4.12
深夜唠叨:导入gltf这个功能大概是4.11或4.10开始出现了(记不清了),当时感觉怎么引用自己本地的gltf模型啊,好难!结果就一直搁置了,我们的作品主体功能搭建好,其他零碎功能进入瓶颈期的时候又开始想到了gltf这个小玩意儿,打算花个几天时间去搞定,没想到第二天就搞定了!(其实是在一个学长的远程操作下....)
关于咋样进行glTF模型的处理,请参考https://www.cnblogs.com/jiangyuanjia/p/11218188.html
有了能用的glTF模型了就好办了,直奔主题——API ——Import glTF 3D Models
官网上说,若要调用本地模型,首先要托管服务器balabala的,其实啥都没有,就是把glTF/glb文件和html文件放在同一目录下
此处要格外注意要使用相对路径!!!
看我在代码中的注释
//在ObjectSymbol3DLayer的资源中引用glTF模型的相对路径。 /* html环境下引用相对路径问题。 * ./表示当前目录,可以省略不写 * ../表示上一级目录 * */
够明确了吧?
比如我的html——index.html和glb——car.glb都位于同一目录——假如说D:\3d\Test 下
引用glb模型时只写url:"./car.glb" 就好了,甚至这种情况连“./”都可以省略!如果glb文件不在同一目录下那就另说了
总之要符合HTML关于相对路径的规范!
放上源码以供参考

<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no" /> <title>导入gltf模型 v1.0</title> <link rel="stylesheet" href="http://localhost/arcgis_js_api/library/4.12/esri/css/main.css" /> <script src="http://localhost/arcgis_js_api/library/4.12/init.js"></script> <style> html, body, #viewDiv { padding: 0; margin: 0; height: 100%; width: 100%; } #paneDiv { padding: 10px; max-width: 200px; background-color: rgba(255, 255, 255, 0.8); font-size: 1.1em; } </style> <script> /* * 参与式规划--gltf模型的导入 * 把所有的模型分成三维建筑 景观小品 公共交通和植被等大类。 *在底部做出下拉列表的形式进行展示。 *如果能从sketchfab网站上直接在线调取模型那是最好的了!但是现在还实现不了 * */ require([ "esri/views/SceneView", "esri/WebScene", "esri/Map", "esri/layers/GraphicsLayer", "esri/widgets/Sketch/SketchViewModel", "esri/config" ], function(SceneView, WebScene, Map, GraphicsLayer, SketchViewModel,esriConfig) { // 首先要引入Config esriConfig.portalUrl="https://trail.arcgisonline.cn/portal"; const webScene = new WebScene({ portalItem: { id: "2d7739d823cb4f8b90d77886ce050db3" //引入websceneID } }); const view = new SceneView({ container: "viewDiv", map: webScene }); /*-----------------------------------*/ const graphicsLayer = new GraphicsLayer(); view.map.add(graphicsLayer); //定义添加gltf模型的按钮 const tentBtn = document.getElementById("tent"); const canoeBtn = document.getElementById("canoe"); const stopBtn=document.getElementById("stop"); const busBtn=document.getElementById("bus"); const carBtn=document.getElementById("car"); const lionBtn=document.getElementById("lion"); view .when(function() { //本示例使用SketchViewModel向GraphicsLayer添加点。点以三维glTF模型为符号。 const sketchVM = new SketchViewModel({ layer: graphicsLayer, view: view }); tentBtn.addEventListener("click", function() { //在ObjectSymbol3DLayer的资源中引用glTF模型的相对路径。 /* html环境下引用相对路径问题。 * ./表示当前目录,可以省略不写 * ../表示上一级目录 * */ sketchVM.pointSymbol = { type: "point-3d", symbolLayers: [ { type: "object", resource: { href:"zz.glb" //"chairmanmao.glb" //"./barrel.gltf" //啤酒桶 } } ] }; sketchVM.create("point"); deactivateButtons(); this.classList.add("esri-button--secondary"); }); canoeBtn.addEventListener("click", function() { //要写相对路径 sketchVM.pointSymbol = { type: "point-3d", //类型依旧是点三维 symbolLayers: [ { type: "object", resource: { href: //"DPS.glb" //外部带有铁架楼梯的二层屋 //"busstop1.glb" //公交车站1(绿色) "langan1.glb" //中式栏杆 } } ] }; deactivateButtons(); //点击事件之后触发停用按钮 sketchVM.create("point"); //其实是一个点 this.classList.add("esri-button--secondary"); }); stopBtn.addEventListener("click", function() { // reference the relative path to the glTF model // in the resource of an ObjectSymbol3DLayer //要写相对路径 sketchVM.pointSymbol = { type: "point-3d", //类型依旧是点三维 symbolLayers: [ { type: "object", resource: { href: "DPS.glb" //外部带有铁架楼梯的二层屋 } } ] }; deactivateButtons(); sketchVM.create("point"); this.classList.add("esri-button--secondary"); }); busBtn.addEventListener("click", function() { // reference the relative path to the glTF model // in the resource of an ObjectSymbol3DLayer //要写相对路径 sketchVM.pointSymbol = { type: "point-3d", //类型依旧是点三维 symbolLayers: [ { type: "object", resource: { href:"busstop1.glb" //"DPS.glb" //外部带有铁架楼梯的二层屋 } } ] }; deactivateButtons(); sketchVM.create("point"); this.classList.add("esri-button--secondary"); }); carBtn.addEventListener("click", function() { // reference the relative path to the glTF model // in the resource of an ObjectSymbol3DLayer //要写相对路径 sketchVM.pointSymbol = { type: "point-3d", //类型依旧是点三维 symbolLayers: [ { type: "object", resource: { href: "car0.glb" //"rocklion.glb" //"DPS.glb" //外部带有铁架楼梯的二层屋 } } ] }; deactivateButtons(); sketchVM.create("point"); this.classList.add("esri-button--secondary"); }); lionBtn.addEventListener("click", function() { // reference the relative path to the glTF model // in the resource of an ObjectSymbol3DLayer //要写相对路径 sketchVM.pointSymbol = { type: "point-3d", //类型依旧是点三维 symbolLayers: [ { type: "object", resource: { href: //"car0.glb" "rocklion.glb" //"DPS.glb" //外部带有铁架楼梯的二层屋 } } ] }; deactivateButtons(); sketchVM.create("point"); this.classList.add("esri-button--secondary"); }); /*--------------------*/ sketchVM.on("create", function(event) { //如果事件的状态为完成,则停用按钮。 if (event.state === "complete") { sketchVM.update(event.graphic); deactivateButtons(); } }); }) .catch(console.error); /*------------------------------*/ //停用 function deactivateButtons() { /* * prototype 用来给对象添加属性 * slice 从数组中读取元素 * * */ const elements = Array.prototype.slice.call( document.getElementsByClassName("esri-button") ); elements.forEach(function(element) { element.classList.remove("esri-button--secondary"); }); } //添加面板div 到右上角 view.ui.add("paneDiv", "top-right"); }); </script> </head> <body> <div id="viewDiv"></div> <div id="paneDiv" class="esri-widget"> <p>点击<strong>按钮</strong>选择模型并放置到场景中</p> <button id="tent" class="esri-button">赵总</button><br /> <button id="canoe" class="esri-button">中式木制栏杆</button><br /> <button id="stop" class="esri-button">二层小房屋</button><br /> <button id="bus" class="esri-button">公交站台</button><br /> <button id="car" class="esri-button">小汽车</button><br /> <button id="lion" class="esri-button">石狮子</button> </div> </body> </html>
注意!请将你的代码放在web容器内!否则极有可能遇到跨域问题!
解决跨域问题请参见
本文完
如果我的文章对您有帮助请点赞谢谢