Skip to content

案例展示

摩擦力模拟

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

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

onMounted(() => {
    // 模型数据
    const modelList = [
        {
            modelName: '立方体-1',
            modelType: 'cube',
            scale: { x: 1, y: 1, z: 1 },
            position: { x: -10, y: 5, z: 0 },
            rotation: { x: 0, y: 0, z: 0 },
            base: {
                depth: 5,
                width: 5,
                height: 5,
            },
            material: {
                color: "yellow",
            },
            userData: {
                physics: {
                    restitution: 1,
                    moveData: {
                        x: 10,
                        y: 0,
                        z: 0,
                    },
                    mass: 1,
                    friction: 1,
                    isCopy: true,
                },
            },
        },
        {
            modelName: '立方体-2',
            modelType: 'cube',
            scale: { x: 1, y: 1, z: 1 },
            position: { x: 10, y: 5, z: 0 },
            rotation: { x: 0, y: 0, z: 0 },
            base: {
                depth: 5,
                width: 5,
                height: 5,
            },
            material: {
                color: "yellow",
            },
            userData: {
                physics: {
                    restitution: 1,
                    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: 0, z: 0 },
            rotation: { x: 0, y: 0, z: 0 },
            base: {
                depth: 100,
                width: 100,
                height: 5,
            },
            material: {
                color: 0x525252,
            },
            userData: {
                physics: {
                    restitution: 0.5,
                    mass: 0,
                    friction: 1,
                    isCopy: false,
                },
            },
        },
    ]
    // 场景参数
    const sceneData = {
        scene: {
            ground: {
                active: false
            }
        },
        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 threeModel = []
    let physicsModel = []

    // 初始化时钟
    let clock = TO.tool.initClock();
    // 启动物理世界
    const startPhysics = () => {
        let delta = clock.getDelta();
        physicsWorld.step(1 / 60, delta);
        for (let i = 0; i < physicsModel.length; i++) {
            //更新
            threeModel[i].position.copy(physicsModel[i].position);
            threeModel[i].quaternion.copy(physicsModel[i].quaternion);
        }
        requestAnimationFrame(startPhysics);
    };
    // 添加速度
    const addVelocity = () => {
        for (let i = 0; i < physicsModel.length; i++) {
            physicsModel[i].velocity.set(10, 0, 0);
        }
        startPhysics()
    }

    // 添加模型
    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) {
                threeModel.push(threeMesh);
                physicsModel.push(physicsBody)
            }
        })
        addVelocity()
    }
    addModels()
});
</script>

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