Skip to content

案例展示

重力模拟

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

<script setup>
import { onMounted } from 'vue';

onMounted(() => {
    // 模型数据
    const modelList = [
        {
            modelName: '立方体',
            modelType: 'cube',
            scale: { x: 1, y: 1, z: 1 },
            position: { x: 0, y: 20, z: 0 },
            rotation: { x: 0, y: 0, z: 0 },
            base: {
                depth: 5,
                width: 5,
                height: 5,
            },
            material: {
                color: "yellow",
            },
            userData: {
                physics: {
                    restitution: 0,
                    moveData: {
                        x: 10,
                        y: 0,
                        z: 0,
                    },
                    mass: 1,
                    friction: 0,
                    isCopy: true,
                },
            },
        },
        {
            modelName: '平面',
            modelType: 'cube',
            scale: { x: 1, y: 1, z: 1 },
            position: { x: 0, y: 3, z: 0 },
            rotation: { x: 0, y: 0, z: 0 },
            base: {
                depth: 100,
                width: 100,
                height: 5,
            },
            material: {
                color: 0x525252,
            },
            userData: {
                physics: {
                    restitution: 0,
                    mass: 0,
                    friction: 0,
                    isCopy: false,
                },
            },
        },
    ]
    // 场景参数
    const sceneData = {
        camera: {
            position: {
                x: 0,
                y: 40,
                z: 85,
            },
        },
        helper: {
            axes: {
                active: false,
            },
            grid: {
                active: false,
            },
        },
    }
    //初始化场景
    let TO = new ThingOrigin("easyBuild", document.getElementById("TO"), sceneData)
    //初始化物理世界
    let physicsWorld = TO.physics.initWorld();

    //初始化时钟
    let clock = TO.tool.initClock();
    // 启动物理模拟
    const startPhysics = () => {
        let delta = clock.getDelta();
        physicsWorld.step(1 / 60, delta);
        if (physicsModel) {
            //更新
            threeModel.position.copy(physicsModel.position);
            threeModel.quaternion.copy(physicsModel.quaternion);
        }
        requestAnimationFrame(startPhysics);
    };

    let threeModel, physicsModel;
    // 添加模型
    const addModels = () => {
        modelList.forEach(item => {
            // 3D模型
            const threeMesh = TO.model.initCube(item);
            TO.scene.add(threeMesh)
            // 物理模型
            const { position, base } = item;
            const { physics } = item.userData;
            const info = {
                mass: physics.mass, //重力
                friction: physics.friction, //摩擦力
                restitution: physics.restitution, //弹力
                position: { x: position.x, y: position.y, z: position.z }, //位置
                base: base, //基础信息
            };
            Object.assign(item, info)
            //添加物理立方体Body
            const physicsBody = TO.physics.initBoxBody(info);
            physicsWorld.addBody(physicsBody);
            if (physics.isCopy) {
                console.log(TO.scene.children, item);
                threeModel = threeMesh;
                physicsModel = physicsBody
                console.log(threeModel, physicsModel)
            }
        })
        startPhysics()
    }
    addModels()
});
</script>

<style scoped>
#TO {
    width: 100%;
    height: 400px;
    position: relative;
}
</style>