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

Three.js中移除/隐藏已加载STL模型及条件加载实现方法

Three.js 模型操作:移除/隐藏、条件切换及反向逻辑实现

一、移除或隐藏已加载的STL模型

先给你区分两种场景的处理方式,按需选择:

临时隐藏模型(可快速恢复)

如果只是暂时不想显示模型,后续还要复用,直接修改模型的visible属性是最高效的方式:

// 假设mesh是你加载的STL模型实例
mesh.visible = false;
// 需要恢复显示时再设为true
// mesh.visible = true;

这种方式不会从场景中移除模型,只是停止渲染,适合频繁切换显示状态的场景。

彻底移除模型(清理资源)

如果确定不再需要该模型,为了避免内存泄漏,要完整清理资源:

// 假设mesh是目标模型,scene是你的Three.js场景实例
scene.remove(mesh);
// 清理几何体资源
mesh.geometry.dispose();
// 清理材质资源
mesh.material.dispose();
// 最后将模型实例置为null,帮助JS垃圾回收
mesh = null;

*注意:*如果模型包含多个子对象,需要递归遍历所有子节点执行移除和清理操作,比如通过循环处理mesh.children数组。

二、根据条件实现模型的加载与切换

针对你提到的“门状态为0时加载flame.stl”的需求,我们可以封装一个通用的切换函数,同时做好缓存避免重复加载,提升性能:

示例实现

// 缓存已加载的模型,避免重复发起网络请求
const modelCache = {};
// 存储当前显示的模型实例,方便后续移除
let activeModel = null;

function switchModelByDoorStatus(doorStatus) {
  // 先移除当前显示的模型(如果存在)
  if (activeModel) {
    scene.remove(activeModel);
    activeModel.geometry.dispose();
    activeModel.material.dispose();
    activeModel = null;
  }

  // 根据门状态确定要加载的模型路径
  let targetModelPath;
  if (doorStatus === 0) {
    targetModelPath = 'model/flame.stl';
  } else if (doorStatus === 1) {
    targetModelPath = 'model/panic.stl';
  } else {
    // 其他状态可选择不加载模型或加载默认模型
    return;
  }

  // 优先从缓存中复用模型
  if (modelCache[targetModelPath]) {
    activeModel = modelCache[targetModelPath].clone();
    scene.add(activeModel);
    // 设置模型位置(补全你需要的Z轴参数)
    activeModel.position.set(0.145, -0.3, -0.2);
    return;
  }

  // 缓存中没有则发起加载请求
  const loader = new THREE.STLLoader();
  loader.load(
    targetModelPath,
    (geometry) => {
      // 根据模型类型设置合适的材质
      const material = new THREE.MeshPhongMaterial({
        color: targetModelPath.includes('flame') ? 0xffff00 : 0xa80306,
        specular: 0x111111,
        shininess: 200
      });
      const mesh = new THREE.Mesh(geometry, material);
      mesh.position.set(0.145, -0.3, -0.2);
      scene.add(mesh);
      activeModel = mesh;
      // 将模型存入缓存
      modelCache[targetModelPath] = mesh;
    },
    undefined,
    (error) => {
      console.error('模型加载失败:', error);
    }
  );
}

// 使用示例:门状态变化时调用
// switchModelByDoorStatus(0); // 加载flame.stl
// switchModelByDoorStatus(1); // 加载panic.stl

三、为checkDoorStatus实现反向逻辑

你原函数是当isDoorOpen == 1时加载panic.stl,反向逻辑就是当门关闭(isDoorOpen == 0)时加载flame.stl,同时要对比前后状态,避免重复执行操作:

反向逻辑实现

// 全局变量存储已加载的模型实例,方便后续移除
let panicMesh = null;
let flameMesh = null;

function checkDoorStatus(isDoorOpen, prevIsDoorOpen) {
  // 反向逻辑:门从打开变为关闭时,加载flame并移除panic
  if (isDoorOpen === 0 && isDoorOpen !== prevIsDoorOpen) {
    // 移除panic模型(如果存在)
    if (panicMesh) {
      scene.remove(panicMesh);
      panicMesh.geometry.dispose();
      panicMesh.material.dispose();
      panicMesh = null;
    }

    // 加载flame.stl
    const loader = new THREE.STLLoader();
    loader.load('model/flame.stl', (geometry) => {
      const material = new THREE.MeshPhongMaterial({
        color: 0xffff00,
        specular: 0x111111,
        shininess: 200
      });
      flameMesh = new THREE.Mesh(geometry, material);
      flameMesh.position.set(0.145, -0.3, -0.2);
      scene.add(flameMesh);
    });
  } 
  // 保留原逻辑:门从关闭变为打开时,加载panic并移除flame
  else if (isDoorOpen === 1 && isDoorOpen !== prevIsDoorOpen) {
    if (flameMesh) {
      scene.remove(flameMesh);
      flameMesh.geometry.dispose();
      flameMesh.material.dispose();
      flameMesh = null;
    }

    const loader = new THREE.STLLoader();
    loader.load('model/panic.stl', (geometry) => {
      const material = new THREE.MeshPhongMaterial({
        color: 0xa80306,
        specular: 0x111111,
        shininess: 200
      });
      panicMesh = new THREE.Mesh(geometry, material);
      panicMesh.position.set(0.145, -0.3, -0.2);
      scene.add(panicMesh);
    });
  }
}

*核心要点:*通过对比isDoorOpen和prevIsDoorOpen,只在状态发生变化时执行操作,避免重复加载;每次加载新模型前先清理旧模型,防止场景中多个模型共存。


内容的提问来源于stack exchange,提问作者RUHAIZAN FAZREEN ASHRAFF MOHD

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 07:02:48