You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将Django模型的3D文件路径传入Three.js加载函数?

实现Django列表项点击加载Three.js 3D模型

我来帮你一步步搞定这个功能,核心就是把Django模板里的模型路径传递给JavaScript,再触发Three.js的加载逻辑,具体步骤如下:

1. 修改Django模板,让列表项可交互并携带路径

首先把原来的<li>改成可点击的元素,用HTML的data-*属性存储模型路径,方便JavaScript获取。修改后的模板代码:

<ul class="3d-model-list">
  {% for 3dobj in 3dobj_list %}
    <li class="3d-model-item" data-model-path="{{ 3dobj.path }}">
      {{ 3dobj.path }}
    </li>
  {% endfor %}
</ul>

可以加一点CSS让列表项看起来更像可点击的按钮,提升用户体验:

.3d-model-item {
  cursor: pointer;
  padding: 8px 12px;
  margin: 6px 0;
  border: 1px solid #e0e0e0;
  border-radius: 4px;
  transition: background-color 0.2s;
}
.3d-model-item:hover {
  background-color: #f8f9fa;
}

2. 编写JavaScript逻辑:监听点击并加载模型

接下来把Three.js的加载逻辑和点击事件绑定,先确保你已经在模板中引入了Three.js核心库以及OBJLoader、MTLLoader(因为你提到了onLoadMtl,应该是用MTL材质配合OBJ模型)。

然后编写如下JS代码:

// 初始化Three.js加载器(假设你已经创建了scene、camera等基础场景元素)
const objLoader = new THREE.OBJLoader();
const mtlLoader = new THREE.MTLLoader();

// 获取所有模型列表项
const modelItems = document.querySelectorAll('.3d-model-item');

// 给每个列表项添加点击监听
modelItems.forEach(item => {
  item.addEventListener('click', function() {
    // 从data属性中取出模型路径
    const objPath = this.getAttribute('data-model-path');
    // 生成MTL材质路径(假设MTL和OBJ同目录,替换扩展名即可,可根据实际情况调整)
    const mtlPath = objPath.replace('.obj', '.mtl');
    
    // 调用加载函数
    load3DModel(mtlPath, objPath);
  });
});

// 封装加载函数,整合你提到的onLoadMtl逻辑
function load3DModel(mtlFilePath, objFilePath) {
  // 先加载材质文件
  mtlLoader.load(
    mtlFilePath,
    function(materials) {
      materials.preload();
      // 给OBJ加载器设置材质
      objLoader.setMaterials(materials);
      
      // 加载OBJ模型
      objLoader.load(
        objFilePath,
        function(object) {
          // 模型加载完成后的处理:先清除旧模型(可选),再添加新模型
          const existingModel = scene.getObjectByName('loaded-3d-model');
          if (existingModel) {
            scene.remove(existingModel);
          }
          
          object.name = 'loaded-3d-model';
          object.scale.set(1, 1, 1); // 根据模型大小调整缩放比例
          scene.add(object);
          
          // 可选:让相机自动对准模型中心
          const box = new THREE.Box3().setFromObject(object);
          const center = box.getCenter(new THREE.Vector3());
          camera.lookAt(center);
        },
        // 加载进度回调(可选)
        function(xhr) {
          console.log(`模型加载进度: ${Math.round(xhr.loaded / xhr.total * 100)}%`);
        },
        // 加载错误回调
        function(error) {
          console.error('模型加载失败:', error);
        }
      );
    },
    // 材质加载进度回调(可选)
    function(xhr) {
      console.log(`材质加载进度: ${Math.round(xhr.loaded / xhr.total * 100)}%`);
    },
    // 材质加载错误回调
    function(error) {
      console.error('材质加载失败:', error);
    }
  );
}

3. 必要的基础配置提醒

  • 确保Django已经正确配置媒体文件服务,让/media/开头的路径能被正常访问。
  • 提前初始化Three.js的基础场景元素(场景、相机、渲染器、光源),否则模型加载后无法显示,示例代码:
    const scene = new THREE.Scene();
    const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
    const renderer = new THREE.WebGLRenderer();
    renderer.setSize(window.innerWidth, window.innerHeight);
    document.body.appendChild(renderer.domElement);
    
    // 添加基础光源(否则模型会看不见)
    const ambientLight = new THREE.AmbientLight(0x404040);
    scene.add(ambientLight);
    const directionalLight = new THREE.DirectionalLight(0xffffff, 0.5);
    scene.add(directionalLight);
    
    // 渲染循环
    function animate() {
      requestAnimationFrame(animate);
      renderer.render(scene, camera);
    }
    animate();
    

这样用户点击列表里的任意3D模型路径,对应的模型就会被加载到Three.js场景中啦!

内容的提问来源于stack exchange,提问作者jul1731

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 09:36:05