<script> // import * as Three from '../../node_modules/three/build/three.module.js'; import "maptalks/dist/maptalks.css"; import * as maptalks from "maptalks"; import * as Three from "three"; import { ThreeLayer } from "maptalks.three"; import { OrbitControls } from "three/examples/jsm/controls/OrbitControls"; import { PointerLockControls } from "three/examples/jsm/controls/PointerLockControls.js"; import { PCDLoader } from "three/examples/jsm/loaders/PCDLoader"; import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";
export default { name: "ThreeTest", data() { return { map: null, threeLayer: null, mapConfig: { center: [568318.74296, 4314626.47854], zoom: 12.364821148501335, pitch: 71.6000000000002, bearing: -52.200000000000045, }, camera: null, scene: null, renderer: null, controls: "", intersections: null, objects: [], clock: "", moveForward: false, moveLeft: false, moveBackward: false, moveRighta: false, //----车辆参数---------- car: null, //汽车对象 speed: 0, rSpeed: 0, run: false, acceleration: 0.005, //car 转弯半径大小,越小越转弯越陡 deceleration: 0.02, //car溜车长短,越小溜车越久 // maxSpeed: 2, // lock: -1, // isBrake: false, realRotation: -1.6, // 车辆自身真实的旋转度 dirRotation: 0, // 方向上的旋转 addRotation: 0, // 累计的旋转角度 //-------------- direction: new Three.Vector3(), velocity: new Three.Vector3(), prevTime: performance.now(), }; }, methods: { init() { var that = this; this.map = new maptalks.Map("map", { center: this.mapConfig.center, zoom: this.mapConfig.zoom, seamlessZoom: false, hitDetect: false, // 是否为此地图上的光标样式启用图层命中检测,请禁用它以提高性能。 zoomControl: false, scaleControl: false, overviewControl: false, attribution: false, pitch: this.mapConfig.pitch, bearing: this.mapConfig.bearing, spatialReference: { projection: "identity", }, }); //3D图层 this.threeLayer = new ThreeLayer("car", { forceRenderOnMoving: true, forceRenderOnRotating: true, animation: true, }); this.threeLayer.setZIndex(10); this.threeLayer.prepareToDraw = function (gl, scene, camera) { // this.camera = camera; that.initScene(); //场景对象 that.initPlane(); //地板 that.initCamera(); //相机 that.initWebGLRenderer(); //渲染器 // this.initAxisHelper(); //辅助坐标 that.render(); // this.createControls(); //控件对象 that.loadPointCloud(); that.Car(); that.initControls(); //相机视角 that.initMobile(); //移动 }; this.threeLayer.addTo(this.map); }, //鼠标控制移动相机视角***** initControls() { let that = this; that.controls = new PointerLockControls(this.camera, document.body); // var container = document.getElementById("container"); // container.addEventListener("click", function () { // that.controls.lock(); // }); this.scene.add(that.controls.getObject()); }, initMobile() { let that = this; // console.log(this.controls); var onKeyDown = function (event) { switch (event.keyCode) { case 38: // up case 87: // w that.run = true; break; case 37: // left case 65: // a that.rSpeed = 0.02; break; case 40: // down case 83: // s that.run = false; break; case 39: // right case 68: // d that.rSpeed = -0.02; break; } };
var onKeyUp = function (event) { switch (event.keyCode) { case 38: // up case 87: // w that.run = false; break; case 37: // left case 65: // a that.rSpeed = 0; break; case 40: // down case 83: // s that.run = false; break; case 39: // right case 68: // d that.rSpeed = 0; break; } };
document.addEventListener("keydown", onKeyDown, false); document.addEventListener("keyup", onKeyUp, false); }, // 创建场景对象Scene initScene() { this.scene = new Three.Scene(); }, // 相机 initCamera() { // let container = document.getElementById("map"); this.camera = new Three.PerspectiveCamera( 90, window.innerWidth / window.innerHeight, 0.1, 10000 ); this.camera.speed = { z: 0, x: 0, }; this.camera.position.set(2, 7, 5); //设置相机位置 // this.camera.lookAt(this.camera.position); //设置相机方向(指向的场景对象) this.camera.add(new Three.PointLight("#fff", 3)); //设置灯光 }, loadPointCloud() { var that = this; // instantiate a loader var loader = new PCDLoader(); // load a resource loader.load( // resource URL "./trunk.pcd", // called when the resource is loaded function (mesh) { console.log(mesh); // scene.add(mesh); mesh.scale.set(1.32, 1.32, 5); // mesh.position.copy( // that.threeLayer.coordinateToVector3([567403.0, 4315210.0]) // ); that.threeLayer.addMesh(mesh); }, // called when loading is in progresses function (xhr) { // console.log((xhr.loaded / xhr.total) * 100 + "% loaded"); }, // called when loading has errors function (error) { console.log("An error happened"); } ); }, Car() { var that = this; var loader = new GLTFLoader(); let url = "./car.glb"; loader.load(url, function (gltf) { console.log(gltf); var model = gltf.scene; model.name = "car"; // model.rotation.x = 0; // model.rotation.z =0; model.rotation.y = -1.5; //car自身旋转度 model.scale.set(0.5, 0.5, 0.5); // 矫正 model.position.z = -15; model.position.y = 0; model.position.x = 0; that.car = model; that.scene.add(that.car); }); }, //地板 initPlane() { var planeGeometry = new Three.PlaneGeometry(1000, 1000); //平面使用颜色为0xcccccc的基本材质 // var planeMaterial = new Three.MeshBasicMaterial({ color: 0xcccccc }); this.scene.add(new Three.AmbientLight(0xffffff)); //添加灯光显示地板图片 // ground 添加地面 const loader = new Three.TextureLoader(); const groundTexture = loader.load(require('../../public/Cad1.png')); //图片 // const groundTexture = loader.load( // require("../assets/grasslight-big.jpeg") // ); //绿色草地 groundTexture.wrapS = groundTexture.wrapT = Three.RepeatWrapping; // groundTexture.repeat.set(100, 100); groundTexture.anisotropy = 16; groundTexture.encoding = Three.sRGBEncoding;
const groundMaterial = new Three.MeshLambertMaterial({ map: groundTexture, }); var plane = new Three.Mesh(planeGeometry, groundMaterial); //设置屏幕的位置和旋转角度 plane.rotation.x = -0.5 * Math.PI; plane.position.x = 0; plane.position.y = 0; plane.position.z = 0; //将平面添加场景中 this.scene.add(plane); }, //创建渲染器对象 initWebGLRenderer() { var container = document.getElementById("map"); this.renderer = new Three.WebGLRenderer({ antialias: true }); this.renderer.setSize(container.clientWidth, container.clientHeight); //设置渲染区域尺寸 this.renderer.setClearColor(0xb9d3ff, 1); //设置背景颜色 container.appendChild(this.renderer.domElement); //body元素中插入canvas对象 }, //辅助三维坐标系AxisHelper initAxisHelper() { this.axisHelper = new Three.AxisHelper(1000); this.scene.add(this.axisHelper); }, //处理车辆方向键逻辑及算法 runCarTick() { if (this.run) { this.speed += this.acceleration; // if (this.speed > this.maxSpeed) { // this.speed = this.maxSpeed; // } } else { this.speed -= this.deceleration; if (this.speed < 0) { this.speed = 0; } } var speed = -this.speed; if (speed === 0) { return; } var time = Date.now();
this.dirRotation += this.rSpeed; this.realRotation += this.rSpeed;
var rotation = this.dirRotation;
var speedX = Math.sin(rotation) * speed; var speedZ = Math.cos(rotation) * speed;
var tempX = this.car.position.x + speedX; var tempZ = this.car.position.z + speedZ;
var tempA = -this.car.rotation.y; this.car.rotation.y = this.realRotation; this.car.position.z += speedZ; this.car.position.x += speedX; this.camera.rotation.y = rotation; this.camera.position.x = this.car.position.x + Math.sin(rotation) * 20; this.camera.position.z = this.car.position.z + Math.cos(rotation) * 20; }, render: function () { this.runCarTick(); requestAnimationFrame(this.render); //请求再次执行渲染函数render this.renderer.render(this.scene, this.camera); //执行渲染操作 }, // 创建控件对象 createControls() { this.controls = new OrbitControls(this.camera, this.renderer.domElement); //是否开启右键拖拽 // this.controls.enablePan = false; //设置自动旋转 // this.controls.autoRotate = true; // 禁止鼠标操作 this.controls.enabled = false; }, }, mounted() { this.init(); }, }; </script> <style scoped> #map { height: 800px; } </style>