原模型为rvt模型
<template>
<div ref="threeJsContainer"
class="three-js-container"></div>
</template>
<script>
import { defineComponent } from "vue";
import * as THREE from "three";
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
import { DragControls } from "three/examples/jsm/controls/DragControls";
import { onMounted, ref, onUnmounted } from "vue";
import { DRACOLoader } from "three/examples/jsm/loaders/DRACOLoader.js";
export default {
name: 'ThreeJsScene',
mounted () {
this.initThreeJS();
},
methods: {
initThreeJS () {
// 创建场景
const scene = new THREE.Scene();
const url = "/glb/1.glb";
// 创建相机
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.z = 5;
// 创建渲染器
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
// 将渲染器的DOM元素添加到Vue组件的容器中
this.$refs.threeJsContainer.appendChild(renderer.domElement);
// 创建几何体
// const geometry = new THREE.BoxGeometry(1, 1, 1);
// const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
// const cube = new THREE.Mesh(geometry, material);
// scene.add(cube);
// 添加环境光
const ambientLight = new THREE.AmbientLight(0xffffff, 0.5);
scene.add(ambientLight);
//添加坐标轴
// const axesHelper = new THREE.AxesHelper(5)
// scene.add(axesHelper)
//添加轨道控制器
const controls = new OrbitControls(camera, renderer.domElement);
// 加载 glb 格式的 3D 模型
const loader = new GLTFLoader();
const dracoLoader = new DRACOLoader();
dracoLoader.setDecoderPath("/gltf/");
dracoLoader.preload();
loader.setDRACOLoader(dracoLoader);
loader.load(
url,
(gltf) => {
console.log('------------')
console.log(gltf)
// 加载成功后的回调函数
const model = gltf.scene;
model.scale.set(0.8, 0.8, 0.8); // 缩小模型
const box = new THREE.Box3().setFromObject(model);
const center = box.getCenter(new THREE.Vector3());
model.position.sub(center); // 将模型位置移到原点处
scene.add(model);
// 创建DragControls实例 拖动模型
// const controls = new DragControls([model], camera, renderer.domElement);
//controls.addEventListener('dragstart', (event) => {
// 拖动开始时的事件处理
//console.log('Drag started:', event.object);
// 可以从 event 对象中获取有关拖动开始的信息
//});
},
(xhr) => {
// 加载过程中的回调函数
console.log((xhr.loaded / xhr.total) * 100 + "% loaded");
},
(error) => {
// 加载失败的回调函数
console.error("Failed to load model", error);
}
);
// 渲染循环
const animate = () => {
requestAnimationFrame(animate);
// 更新物体或相机位置
// cube.rotation.x += 0.01;
// cube.rotation.y += 0.01;
// 渲染场景
renderer.render(scene, camera);
};
animate();
// 窗口大小变化时调整相机和渲染器大小
window.addEventListener('resize', onWindowResize, false);
window.addEventListener('click', onMouseClick, false);
function onWindowResize () {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
function onMouseClick (event) {
event.preventDefault();
const mouseX = (event.clientX / window.innerWidth) * 2 - 1;
const mouseY = -(event.clientY / window.innerHeight) * 2 + 1;
const vector = new THREE.Vector2(mouseX, mouseY);
// vector.unproject(camera);
const raycaster = new THREE.Raycaster();
raycaster.setFromCamera(vector, camera);
const intersects = raycaster.intersectObjects(scene.children, true);
// 如果有交点
if (intersects.length > 0) {
// 获取最近的交点
const intersect = intersects[0];
// 获取相交的物体
const object = intersect.object;
// 改变物体的材质以实现高亮效果
// 可以改变颜色或透明度
object.material.color.set(0xff0000); // 设置为红色以高亮
object.material.needsUpdate = true; // 更新材质
}
}
},
},
};
</script>
<style scoped>
.three-js-container {
width: 100%;
height: 100%;
}
</style>
配置文件