网站建设中的主要功能/电商网站运营
加载stl时可以明显看到下面有一部分模型是错位的。
将stl文件格式转化为glb
使用免费将 STL 转换为 GLB - ImageToStl
模型就没有错位了
代码如下
<template><div ref="threeContainer" class="three-container"></div></template><script>import * as THREE from "three";import { STLLoader } from "three/examples/jsm/loaders/STLLoader.js";import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";import {GLTFLoader} from "three/examples/jsm/loaders/GLTFLoader.js";export default {name: "CastleDemo",mounted() {this.initThree();},methods: {initThree() {const scene = new THREE.Scene();scene.background = new THREE.Color(0xeeeeee);const camera = new THREE.PerspectiveCamera(75,window.innerWidth / window.innerHeight,0.1,1000);camera.position.set(-20, -60, 50); // 调整相机位置camera.lookAt(scene.position);// camera.lookAt(0,0,20);const renderer = new THREE.WebGLRenderer({ antialias: true });renderer.setSize(0.5 * window.innerWidth, 0.7 * window.innerHeight);this.$refs.threeContainer.appendChild(renderer.domElement);const ambientLight = new THREE.AmbientLight(0x404040, 1);const pointLight = new THREE.PointLight(0xffffff, 1, 1000);pointLight.position.set(0, 50, 50);scene.add(ambientLight, pointLight);const loader = new GLTFLoader();const models = this.generateModels(); // 状态变量:控制是否开始旋转let allModelsLoaded = false;// 逐层加载模型let currentModelIndex = 0;const loadNextModel = () => {if (currentModelIndex < models.length) {const model = models[currentModelIndex];loader.load(model.url, (gltf) => {const mesh = gltf.scene.children[0]; // 获取加载的模型mesh.position.set(...model.position);mesh.scale.set(model.scale, model.scale, model.scale);// 修改材质颜色mesh.traverse((child) => {if (child.isMesh) {child.material.color.set(model.color);child.material.transparent = true;child.material.opacity = 0.8;}});scene.add(mesh);// 动态更新进度currentModelIndex++;loadNextModel();});} else {// 所有模型加载完成allModelsLoaded = true;}};loadNextModel(); // 开始加载第一个模型// 添加轨道控制器const controls = new OrbitControls(camera, renderer.domElement);controls.enableDamping = true; // 启用阻尼效果controls.dampingFactor = 0.25; // 阻尼系数controls.enableZoom = true; // 允许缩放controls.enablePan = true; // 允许平移// 添加旋转逻辑let rotationSpeed = 0.01; // 旋转速度function animate() {requestAnimationFrame(animate);// 只有在所有模型加载完成后才开始旋转// if (allModelsLoaded) {// scene.traverse((object) => {// if (object.isMesh) {// object.rotation.y += rotationSpeed; // 绕Y轴旋转// object.rotation.x += rotationSpeed * 0.5; // 绕X轴旋转// }// });// }// controls.update(); // 更新轨道控制器renderer.render(scene, camera);}animate();},// 生成47个模型的配置generateModels() {const models = [];const basePosition = [-10, 0, -15]; // 基础位置,从底部开始const spacing = 0.4; // 模型之间的间距for (let i = 0; i < 72; i++) {const position = [basePosition[0], // X轴位置basePosition[1]+ i * spacing, // Y轴方向排列basePosition[2] ,];const color = this.getColorByIndex(i); // 根据索引计算颜色models.push({url: `/3Dmodels/models(glb)/part_${String(i).padStart(6, "0")}.glb`, position,scale: 0.5,color,});}return models;},// 根据索引计算颜色getColorByIndex(index) {const startColor = 0xffff00; // 起始颜色为黄色const endColor = 0x00ffff; // 结束颜色为青色const colorRange = endColor - startColor;const ratio = index / (47 - 1); // 计算颜色比例const color = startColor + Math.floor(colorRange * ratio);return color;},},
};</script><style scoped>.three-container {background-color: #ffffff;}</style>