【babylonjs】babylonjs实践(十四)--测试车跑起来

1,450 阅读1分钟

背景

前面我们说了物体的移动、模型和地图,那么这一章节,我们就汇总一下,在地图上换一个会动的测试车。

基本思想:加载一个模型的测试车,画一个简单的地图,然后车移动起来就可以了。

正文

image.png

然后让它在车道线内动起来即可。

image.png

源码:

var myCar

            // createScene function that creates and return the scene
            var createScene = function () {
                // create a basic BJS Scene object
                var scene = new BABYLON.Scene(engine);

                //Create a light
                // var light = new BABYLON.PointLight("Omni", new BABYLON.Vector3(-60, 60, 80), scene);
                // scene.ambientColor = new BABYLON.Color3(1, 1, 1); // 场景环境颜色 
                var light = new BABYLON.HemisphericLight('light1', new BABYLON.Vector3(0, 1, 0), scene);

                //Create an Arc Rotate Camera - aimed negative z this time
                var camera = new BABYLON.ArcRotateCamera("Camera", Math.PI / 2, 1.0, 110, BABYLON.Vector3.Zero(), scene);
                camera.attachControl(canvas, true);

                // 单实线
                const line11 = [
                    new BABYLON.Vector3(0, 0, 0),
                    new BABYLON.Vector3(50, 0, 0)
                ]
                const line12 = [
                    new BABYLON.Vector3(0, 0, 10),
                    new BABYLON.Vector3(50, 0, 10)
                ]
                const line21 = [
                    new BABYLON.Vector3(0, 0, 10),
                    new BABYLON.Vector3(0, 0, 60)
                ]
                const line22 = [
                    new BABYLON.Vector3(-10, 0, 10),
                    new BABYLON.Vector3(-10, 0, 60)
                ]
                var line33 = [];
                for (let i = 180; i <= 270; i++) {
                    line33.push(new BABYLON.Vector3(10 * Math.sin(i / 180 * Math.PI), 0, 10 + 10 * Math.cos(i / 180 * Math.PI)));
                }

                const singleSolidLineOptions = {
                    lines: [line11, line12, line21, line22, line33],
                    useVertexAlpha: false
                }
                BABYLON.MeshBuilder.CreateLineSystem('', singleSolidLineOptions, scene)

                const computeOffsetPoint = (targetPoint, referencePoint, changeSide = false) => {
                    const offsetDirection = referencePoint.subtract(targetPoint).cross(new BABYLON.Vector3(0, 1, 0)).normalize()
                    const offsetDimension = 0.3

                    if (changeSide) {
                        offsetDirection.scaleInPlace(-1.0)
                    }

                    const offsetPoint = targetPoint.add(offsetDirection.scale(offsetDimension))

                    return offsetPoint
                }

                // 双黄线
                const line51 = [
                    computeOffsetPoint(new BABYLON.Vector3(0, 0, 5), new BABYLON.Vector3(50, 0, 5)),
                    computeOffsetPoint(new BABYLON.Vector3(50, 0, 5), new BABYLON.Vector3(100, 0, 5)),
                ]
                const line52 = [
                    computeOffsetPoint(new BABYLON.Vector3(-5, 0, 10), new BABYLON.Vector3(-5, 0, 60)),
                    computeOffsetPoint(new BABYLON.Vector3(-5, 0, 60), new BABYLON.Vector3(-5, 0, 110)),
                ]
                var line53 = [];
                for (let i = 180; i <= 270; i++) {
                    line53.push(new BABYLON.Vector3(5 * Math.sin(i / 180 * Math.PI), 0, 10 + 5 * Math.cos(i / 180 * Math.PI)));
                }
                var line54 = []
                for (let i = 0; i < line53.length - 1; i++) {
                    line54.push(computeOffsetPoint(line53[i], line53[i + 1]))
                }

                const line511 = [
                    computeOffsetPoint(new BABYLON.Vector3(0, 0, 5), new BABYLON.Vector3(50, 0, 5), true),
                    computeOffsetPoint(new BABYLON.Vector3(50, 0, 5), new BABYLON.Vector3(100, 0, 5), true),
                ]
                const line521 = [
                    computeOffsetPoint(new BABYLON.Vector3(-5, 0, 10), new BABYLON.Vector3(-5, 0, 60), true),
                    computeOffsetPoint(new BABYLON.Vector3(-5, 0, 60), new BABYLON.Vector3(-5, 0, 110), true),
                ]
                var line541 = []
                for (let i = 0; i < line53.length - 1; i++) {
                    line541.push(computeOffsetPoint(line53[i], line53[i + 1], true))
                }

                const options22 = {
                    lines: [line51, line52, line54, line511, line521, line541],
                    useVertexAlpha: false
                }
                var line = BABYLON.MeshBuilder.CreateLineSystem('', options22, scene)
                line.color = new BABYLON.Color3(1, 1, 0)

                // 测试车
                BABYLON.SceneLoader.ImportMesh("", "http://10.101.16.90:8890/common/", "testee.stl", scene, function (meshes) {
                    myCar = meshes[0]
                    var mat2 = new BABYLON.StandardMaterial("texture3", scene);

                    myCar.material = mat2
                    myCar.rotation.x = Math.PI / 2
                    myCar.rotation.y = Math.PI
                    myCar.position.y = 0.5
                    myCar.position.x = 45
                    myCar.position.z = 5
                })


                const options = {
                    width: 500,
                    height: 500,
                    subdivisions: 50
                }
                var ground = BABYLON.MeshBuilder.CreateGround('ground', options, scene)

                var groundMaterial = new BABYLON.StandardMaterial('groundMat', scene)
                groundMaterial.emissiveTexture = new BABYLON.Texture("http://10.101.16.90:8890/common/background.png", scene);
                groundMaterial.emissiveTexture.uScale = 100
                groundMaterial.emissiveTexture.vScale = 100
                groundMaterial.disableLighting = true
                ground.material = groundMaterial

                // return the created scene
                return scene;
            }

runRenderLoop

            engine.runRenderLoop(function () {
                if(myCar){
                    if(myCar.position.x > -4){
                        myCar.position.x = myCar.position.x - (Math.random() * 0.2 + 0.05)
                    }else if(myCar.position.x < -4 && myCar.position.x > -5){
                        myCar.rotation.y = - Math.PI / 2 
                        myCar.position.x = -5
                    }else if(myCar.position.z > 50){
                        myCar.position.x = 45
                        myCar.position.z = 5
                        myCar.rotation.y = Math.PI
                    }else {
                        myCar.position.z = myCar.position.z + 0.1
                    }
       
                }
                scene.render();
            });

这边运动坐标是自己算的,以后就直接拿服务端给的xy就行。

整体小demo完成。

源码地址在。

gitee.com/wangsong129…