当前位置: 首页 > news >正文

obj离线加载(vue+threejs)+apk方式浏览

demo需求:移动端,实现obj本地离线浏览
结合需求,利用(vue2+threejs173)进行obj的加载,然后采用apk方式(hbuilderX打包发布)移动端浏览;

https://github.com/bianbian886/LoadLocalObjThreejs-Vue2.githttps://github.com/bianbian886/LoadLocalObjThreejs-Vue2.git

技术要点:

1、threejs的objloader的方法是使用Fetch API进行网络请求,不适用与three原生obj 的加载方式,因此需要改造three的方法;

常规通用写法:

mtlLoader.load(

      "./static/models1/xpj1/A-XPJ.mtl",

      function (materials) {

        materials.preload();

        objLoader

          .setMaterials(materials)

          .load("./static/models1/xpj1/A-XPJ.obj", function (object) {

            object.children[0].geometry.computeBoundingBox(); //

            object.children[0].geometry.center(); //定位到模型中心

            console.log(object.children[0].geometry.center());

            object.rotateZ(Math.PI / 2); //模型倒置

            object.rotateY(Math.PI / 2); //模型倒置

            object.position.y = 10; //模型抬升

            that.scene.add(object);

          }),

          (xhr) => {

            console.log((xhr.loaded / xhr.total) * 100 + "% loaded");

          },

          // called when loading has errors

          (error) => {

            console.log("An error happened " + error);

          };

      }

    );

    }

但是在apk调试会报请求错误,因为是fecth api的方式。

‌解决方式:将threejs的objloader的方法改为XMLHttpRequest进行请求。代码如下:

// 加载 .mtl 文件

  loadMTL(mtlLoader, mtlUrl, callback) {

    const xhr = new XMLHttpRequest();

    xhr.open("GET", mtlUrl, true);

    xhr.onload = function () {

      if (xhr.status === 200) {

        const materials = mtlLoader.parse(xhr.responseText); // 解析 .mtl 文件

        materials.preload(); // 预加载材质

        callback(materials);

      } else {

        console.error("Failed to load MTL file:", xhr.statusText);

      }

    };

    xhr.onerror = function (error) {

      console.error("Error loading MTL file:", error);

    };

    xhr.send();

  }

  // 加载 .obj 文件

  loadOBJ(objLoader, objUrl, materials, callback) {

    const xhr = new XMLHttpRequest();

    xhr.open("GET", objUrl, true);

    xhr.onload = function () {

      if (xhr.status === 200) {

        objLoader.setMaterials(materials); // 设置材质

        const object = objLoader.parse(xhr.responseText); // 解析 .obj 文件

        callback(object);

      } else {

        console.error("Failed to load OBJ file:", xhr.statusText);

      }

    };

    xhr.onerror = function (error) {

      console.error("Error loading OBJ file:", error);

    };

    xhr.send();

  }

var objLoader = new OBJLoader();

var mtlLoader = new MTLLoader();

this.loadMTL(mtlLoader, mtlUrl, function (materials) {

      that.loadOBJ(objLoader, objUrl, materials, function (object) {

        console.log("Model loaded");

        // 对单个模型进行操作

        const model = object.children[0];

       /model.geometry.computeBoundingBox();

       model.geometry.center();//模型定位

       console.log(model.geometry.center());

        //object.rotateZ(Math.PI);

        object.rotateX(Math.PI/2);

        object.scale.setScalar(0.3);

        //添加到场景that.filterEmptyMeshes()

        that.scene.add(object);

        console.log("Model added to scene");

      });

    });

    this.animate();

    window.addEventListener("resize", () => {

      this.onWindowResize();

    });

  }

2、obj 数据,其中mtl文件一定要是相对路径(且mtl 不要带中文),不然在apk 调试也请求不到。

带中文报错截图,忘记截图了,在apk运行到手机模拟器一看就知道了。

3、最后,利用vue 打包好的拷贝到hbuilderX发布apk,示例参考很多,利用5+app发布就可以了(发布前可以自己运行调试下),如图红框即为替换的内容。npm run build 打包出来的内容

利用5+app模版,将相应内容更换后的布局。

注意点是index.html 中的路径要修改,具体,全局搜索/css和/js的将其修改为css和js。修改前

修改后

成果展示:

相关文章:

  • DDNS-GO 动态域名解析
  • 基于YOLO11深度学习的医学X光骨折检测与语音提示系统【python源码+Pyqt5界面+数据集+训练代码】
  • 基于SpringBoot的“洪涝灾害应急信息管理系统”的设计与实现(源码+数据库+文档+PPT)
  • 【Java】I/O 流篇 —— 转换流与序列化流
  • 5分钟学习-什么事前端HTML文件
  • Python 网络爬虫实战全解析:案例驱动的技术探索
  • Linux-IPC-消息队列
  • Java 大视界 -- Java 大数据在智能物流路径规划与车辆调度中的创新应用(102)
  • C# Unity 唐老狮 No.2 模拟面试题
  • 36. Spring Boot 2.1.3.RELEASE 中实现监控信息可视化并添加邮件报警功能
  • 信息系统的安全防护
  • 神经网络 - 激活函数(Sigmoid 型函数)
  • 剑指 Offer II 032. 有效的变位词
  • flask 是如何分发请求的?
  • 机试准备第三天
  • 关于CanvasRenderer.SyncTransform触发调用的机制
  • 04 路由表的IP分组传输过程
  • 【deepseek解决不了的问题】vue2响应式数据在视图改变后被无感置空
  • 【Python LeetCode】面试经典 150 题
  • (九)axios的使用
  • 北京公园使用指南
  • 驻美国使馆发言人就美方希就关税问题与中方对话答记者问
  • 初中女生遭多人侵犯后,家属奔波三年要追责那个“案外”的生物学父亲
  • 印度加大应对力度,吊销所有巴基斯坦公民签证
  • 冲击一英里4分钟大关,基普耶贡挑战女子中长跑极限
  • 嫦娥八号任务合作项目,这十个入选