展示:

three.js同样的代码展示另外的glb无法成功的原因

原因:

代码:

<template>
  <div>
    <div ref="container" class="glb-viewer"></div>
    <div v-if="loading" class="loading">加载中...</div>
    <div v-if="error" class="error">{{ errorMessage }}</div>
  </div>
</template>

<script setup>
import { ref, onMounted, onUnmounted } from 'vue';
import * as THREE from 'three';
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';

const container = ref(null);
const loading = ref(true);
const error = ref(false);
const errorMessage = ref('');

let scene, camera, renderer, model, controls, targetMarker;

onMounted(() => {
  initScene();
  loadModel();
  animate();

  window.addEventListener('resize', handleResize);
});

onUnmounted(() => {
  if (renderer) {
    renderer.dispose();
  }
  window.removeEventListener('resize', handleResize);
});

function initScene() {
  scene = new THREE.Scene();
  scene.background = new THREE.Color(0xf0f0f0);

  camera = new THREE.PerspectiveCamera(
    75,
    container.value.clientWidth / container.value.clientHeight,
    0.1,
    3000
  );

  renderer = new THREE.WebGLRenderer({ antialias: true });
  renderer.setSize(container.value.clientWidth, container.value.clientHeight);
  container.value.appendChild(renderer.domElement);

  const ambientLight = new THREE.AmbientLight(0x404040);//环境光
  scene.add(ambientLight);

  const directionalLight = new THREE.DirectionalLight(0xffffff, 1);//太阳光
  directionalLight.position.set(1, 1, 1);
  scene.add(directionalLight);

  const GridHelper = new THREE.GridHelper(1000);//网格
  GridHelper.position.y = -130; // 将网格向下移动10个单位
  scene.add(GridHelper);
}

function loadModel() {
  const loader = new GLTFLoader();
  const modelUrl = process.env.BASE_URL + '3d/zong.glb';

  // glb加载器载入glb文件,参数是 文件地址和加载场景
  loader.load(
    modelUrl,
    (gltf) => {
      model = gltf.scene;
      scene.add(model);

      const box = new THREE.Box3().setFromObject(model);//创建一个立方体区域用来装载glb文件
      const center = box.getCenter(new THREE.Vector3());//盒子的中心点
      const size = box.getSize(new THREE.Vector3());//盒子的尺寸

      model.position.x -= center.x;
      model.position.y -= center.y;
      model.position.z -= center.z;

      camera.position.set(center.x, center.y, size.length() * 2);
      camera.lookAt(center);

      // 设置控制器的目标点11111111111
      const targetPosition = new THREE.Vector3(center.x + 25, center.y, center.z - 20);
      
      // 创建红色标记
      createTargetMarker(targetPosition);
      
      controls = new OrbitControls(camera, renderer.domElement);//轨道控制器=相机+渲染器
      controls.target.copy(targetPosition);
      controls.enableDamping = true;
      controls.dampingFactor = 0.25;
      controls.rotateSpeed = 0.5;
      controls.update();

      loading.value = false;
    },
    (xhr) => {
      console.log((xhr.loaded / xhr.total * 100) + '% loaded');
    },
    (error) => {
      console.error('加载GLB文件出错:', error);
      error.value = true;
      errorMessage.value = `加载模型失败: ${error.message}`;
      loading.value = false;
    }
  );
}

// 创建目标点标记
function createTargetMarker(position) {
  const geometry = new THREE.SphereGeometry(2, 32, 32);
  const material = new THREE.MeshBasicMaterial({ color: 0xff0000 });
  targetMarker = new THREE.Mesh(geometry, material);
  targetMarker.position.copy(position);
  scene.add(targetMarker);
}

function animate() {
  if (!renderer || !scene || !camera) {
    console.error('渲染器、场景或相机未初始化');
    return;
  }

  requestAnimationFrame(animate);

  try {
    controls.update();
    renderer.render(scene, camera);
  } catch (error) {
    console.error('渲染出错:', error);
  }
}

function handleResize() {
  camera.aspect = container.value.clientWidth / container.value.clientHeight;
  camera.updateProjectionMatrix();
  renderer.setSize(container.value.clientWidth, container.value.clientHeight);
}
</script>

<style scoped>
.glb-viewer {
  width: 100%;
  height: 600px;
  border: 1px solid #ccc;
}

.loading,
.error {
  text-align: center;
  padding: 20px;
  font-size: 18px;
}

.error {
  color: red;
}
</style>

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐