安装依赖
yarn add three three-orbit-controls
把fbx文件放在pubilc文件下面
下面是相关代码
<template>
<div id="my-three"></div>
</template>
<script setup>
import { ref, onMounted, getCurrentInstance } from "vue";
import * as THREE from "three";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls"
import { FBXLoader } from "three/examples/jsm/loaders/FBXLoader";
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader"; //gltf
let height =0,width
const { proxy } = getCurrentInstance();
const scene = new THREE.Scene();
const renderer = new THREE.WebGLRenderer();
const loader = new FBXLoader();
var clock = new THREE.Clock();
var mixer=null;
let camera,controls;
onMounted(() => {
document.getElementById("my-three")?.appendChild(renderer.domElement);
height = document.getElementById("three").offsetHeight;
width = document.getElementById("three").offsetWidth;
console.log(height);
camera = new THREE.PerspectiveCamera(45, width / height, 1, 1000);
controls = new OrbitControls(camera, renderer.domElement);
if(height>0){
console.log(11);
init();
renderModel();
gltfModel1();
render();
}
});
function init() {
//光源
const ambient = new THREE.AmbientLight(0xffffff, 0.4);
scene.add(ambient);
const pointLight = new THREE.PointLight(0xffffff, 0.6);
pointLight.position.set(100, 50, 400);
scene.add(pointLight);
const directionalLight = new THREE.DirectionalLight(0xffffff, 0.6); //光源,color:灯光颜色,intensity:光照强度
directionalLight.position.set(400, 200, 400);
scene.add(directionalLight);
// const pointLightHelper = new THREE.PointLightHelper(directionalLight,10);
// scene.add(pointLightHelper);
//设置相机位置
camera.position.set(400, 400, 400);
//设置相机方向
camera.lookAt(0, 400, 0);
//辅助坐标轴
// const axesHelper = new THREE.AxesHelper(200); //参数200标示坐标系大小,可以根据场景大小去设置
// scene.add(axesHelper);
scene.background = new THREE.Color(0xeaeaea);
renderer.setPixelRatio(window.devicePixelRatio);
renderer.antialias = true;
}
function gltfModel1() {
/* // glb
loader.load(
"/kai.glb",
function(gltf) {
// console.log(gltf,'loaded');
const model = gltf.scene;
model.scale.set(200, 180, 180); // 将模型放大两倍
model.position.set(0, -90, 0); // 将模型位置设置为长方形模型的中心点
model.rotation.set(0, 0, 0); // 可以根据需要调整模型的旋转
scene.add(gltf.scene);
},
function(xhr) {
const percent = Math.floor((xhr.loaded / xhr.total) * 100); // 计算加载进度百分比
// console.log(`模型加载进度:${percent}%`);
}
);*/
// var mixer=null;//声明一个混合器变量
// var loader = new THREE.FBXLoader();//创建一个FBX加载器
loader.load("/kai2.fbx", function(obj) {
console.log(obj,'`11111111111111111')
obj.scale.set(2.3, 2.3, 2.3); // 将模型放大两倍
obj.position.set(0, 0, 0); // 将模型位置设置为长方形模型的中心点
obj.rotation.set(0, 0, 0); // 可以根据需要调整模型的旋转
obj.rotation.y += 0.8; // 旋转
scene.add(obj)
obj.translateY(-80);
// obj作为参数创建一个混合器,解析播放obj及其子对象包含的动画数据
mixer = new THREE.AnimationMixer(obj);
// 查看动画数据
console.log(obj.animations)
// obj.animations[0]:获得剪辑对象clip
var AnimationAction=mixer.clipAction(obj.animations[0]);
// AnimationAction.timeScale = 1; //默认1,可以调节播放速度
// AnimationAction.loop = THREE.LoopOnce; //不循环播放
// AnimationAction.clampWhenFinished=true;//暂停在最后一帧播放的状态
AnimationAction.play();//播放动画
})
}
function renderModel() {
//渲染
renderer.setSize(width, height); //设置渲染区尺寸
renderer.render(scene, camera); //执行渲染操作、指定场景、相机作为参数
// renderer.setClearColor(0x00ff00); // 设置背景颜色为绿色
renderer.toneMapping = THREE.ACESFilmicToneMapping;
// 设置曝光度
renderer.toneMappingExposure = 1.5; // 适当调整曝光度
controls.minPolarAngle = Math.PI / 4; // 最小极角为 45 度
controls.maxPolarAngle = Math.PI / 2; // 最大极角为 90 度
}
function render() {
renderer.render(scene, camera);
controls.update();
requestAnimationFrame(render);
if (mixer !== null) {
//clock.getDelta()方法获得两帧的时间间隔
// 更新混合器相关的时间
mixer.update(clock.getDelta());
}
}
// 画布跟随窗口变化
window.onresize = function() {
renderer.setSize(width, height);
camera.aspect = width / height;
camera.updateProjectionMatrix();
};
// 交互事件
addEventListener("dblclick", onMouseDblclick, false);
function onMouseDblclick(event) {
let intersects = getIntersects(event);
if (intersects.length !== 0 && intersects[0].object instanceof THREE.Mesh) {
const selectedObject = intersects[0].object;
let selectedObjects = [];
selectedObjects.push(selectedObject);
console.log(selectedObjects);
// outlinePass.selectedObjects = selectedObjects;
}
}
//获取与射线相交的对象数组
function getIntersects(event) {
let rayCaster = new THREE.Raycaster();
let mouse = new THREE.Vector2();
//通过鼠标点击位置,计算出raycaster所需点的位置,以屏幕为中心点,范围-1到1
mouse.x = (event.clientX / width) * 2 - 1;
mouse.y = -(event.clientY / height) * 2 + 1; //这里为什么是-号,没有就无法点中
//通过鼠标点击的位置(二维坐标)和当前相机的矩阵计算出射线位置
rayCaster.setFromCamera(mouse, camera);
return rayCaster.intersectObjects(scene.children);
}
</script>
<style scoped lang="scss"></style>