Three.js中的四元数旋转(Vue3+Vite+TypeScript)

506 阅读2分钟

在Vue3+ts中使用threejs,首先需要安装依赖

npm install three @types/three

用四元数旋转物体,首先需要声明一个新的四元数

const quaternion = new THREE.Quaternion();

然后从给定的旋转轴和旋转角度生成旋转四元数,注意这里的旋转轴必须是归一化的,旋转角度使用弧度制

quaternion.setFromAxisAngle(new THREE.Vector3(0, 0, 1).normalize(), Math.PI / 2);

获取物体自身的四元数,然后乘以上面得出的旋转四元数,就能将物体旋转

model.quaternion.multiply(quaternion);

完整代码

<template>
    <div id="container"></div>
</template>

<script setup lang="ts">
import * as THREE from "three";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js";
import { onMounted } from "vue";

//获取id为container的标签
var container: HTMLElement | null = null;
onMounted(() => {
    container = document.getElementById("container");
    container!.appendChild(renderer.domElement);
});

//新建一个渲染器并设置相应参数
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);

//新建一个场景并设置场景颜色
const scene = new THREE.Scene();
scene.background = new THREE.Color(0xbfe3dd);

//新建一个全局光照并添加到场景中
const ambientLight = new THREE.AmbientLight(0xffffff);
scene.add(ambientLight);

//新建一个坐标轴并添加到场景中
const axesHelper = new THREE.AxesHelper(20);
scene.add(axesHelper);

//新建一个摄像机并添加设置摄像机位置
const camera = new THREE.PerspectiveCamera(40, window.innerWidth / window.innerHeight, 1, 100);
camera.position.set(10, 10, 10);

//新建一个轨道控制器并设置目标点,禁用平移,启用阻尼
const controls = new OrbitControls(camera, renderer.domElement);
controls.target.set(0, 0, 0);
controls.update();
controls.enablePan = false;
controls.enableDamping = true;

//声明一个新的四元数
const quaternion = new THREE.Quaternion();
//从给定的旋转轴和角度生成一个旋转四元数,第一个参数是旋转轴,第二个参数是旋转角度(弧度制)
quaternion.setFromAxisAngle(new THREE.Vector3(0, 0, 1).normalize(), Math.PI / 2);//将物体绕z轴旋转90度

//新建一个gltf加载器并向场景中添加三维模型
const loader = new GLTFLoader();
loader.load(
    "models/wuti.glb",//模型加载路径
    function (gltf) {
        const model = gltf.scene;
        model.quaternion.multiply(quaternion);//将物体绕z轴旋转90度
        scene.add(model);
        animate();
    },
    function (xhr) {
        console.log(xhr);
    },
    function (e) {
        console.error(e);
    }
);

//循环调用
var animate = () => {
    requestAnimationFrame(animate);
    controls.update();
    renderer.render(scene, camera);
};
</script>

<style scoped></style>