|
@@ -1,7 +1,6 @@
|
|
<template>
|
|
<template>
|
|
- <div id="ThreeJS" class="three_div"></div>
|
|
|
|
|
|
+ <div id="ThreeJS" class="three_div"></div>
|
|
</template>
|
|
</template>
|
|
-
|
|
|
|
<script>
|
|
<script>
|
|
import * as THREE from "three";
|
|
import * as THREE from "three";
|
|
import {
|
|
import {
|
|
@@ -26,1162 +25,26 @@
|
|
// import * as CANNON from "cannon-es";
|
|
// import * as CANNON from "cannon-es";
|
|
|
|
|
|
import * as echarts from "echarts";
|
|
import * as echarts from "echarts";
|
|
-
|
|
|
|
|
|
+ import {getStdMapMixin} from "@/mixin/workManagement/getStdMapMixin.js"
|
|
|
|
+ import {openDriveMixin} from "@/mixin/workManagement/openDriveMixin.js"
|
|
export default {
|
|
export default {
|
|
name: "OpenDrive",
|
|
name: "OpenDrive",
|
|
|
|
+ mixins: [getStdMapMixin, openDriveMixin],
|
|
components: {
|
|
components: {
|
|
// vueQr,
|
|
// vueQr,
|
|
// glHome,
|
|
// glHome,
|
|
},
|
|
},
|
|
data() {
|
|
data() {
|
|
return {
|
|
return {
|
|
- position: [
|
|
|
|
- 119.11, 12.65, 0, 107.94, 5.02, 0, 58.54, -6.55, 0, 2.96, -18.14, 0,
|
|
|
|
- -5.68, -15.92, 0, -15.26, -17.45, 0, -17.59, -16.22, 0, -19.98, -14.53,
|
|
|
|
- 0, -22.03, -12.75, 0, -23.79, -8.2, 0, -26.57, 0.89, 0, -52.05, 100.97,
|
|
|
|
- 0, -47.34, 115.73, 0, -40.4, 122.3, 0, -36.06, 123.67, 0, 23.43, 141.03,
|
|
|
|
- 0, 235.4, 186.38, 0, 247.38, 188.33, 0, 255.22, 187.49, 0, 261.95,
|
|
|
|
- 177.78, 0, 284, 89, 0, 293, 56, 0, 119.11, 12.65, 0,
|
|
|
|
- ],
|
|
|
|
- lights: [
|
|
|
|
- -295.65, 117.04, -408.97, -114.11, -272.34, -220.81, 250.93, 194.26,
|
|
|
|
- 338.92, 65.23, -3.58, -16.76,
|
|
|
|
- ],
|
|
|
|
- start: function() {},
|
|
|
|
- startPoint: false,
|
|
|
|
- carStart: false,
|
|
|
|
- carmeDownW: 300,
|
|
|
|
- carmeDownH: 280,
|
|
|
|
- count: 1,
|
|
|
|
- isMove: false,
|
|
|
|
};
|
|
};
|
|
},
|
|
},
|
|
methods: {
|
|
methods: {
|
|
- cleanPoint() {
|
|
|
|
- //清除打点
|
|
|
|
- this.startPoint = true;
|
|
|
|
- this.position = [];
|
|
|
|
- console.log(this.position);
|
|
|
|
- },
|
|
|
|
- pointEnabled() {
|
|
|
|
- // this.allowAllow = true;
|
|
|
|
- this.cleanPoint();
|
|
|
|
- },
|
|
|
|
|
|
+ changeMap(fileUrl){
|
|
|
|
+ this.onFileSelect(fileUrl);
|
|
|
|
+ this.reloadOdrMap();
|
|
|
|
+ }
|
|
},
|
|
},
|
|
mounted() {
|
|
mounted() {
|
|
- let that = this;
|
|
|
|
- let carmeDownW = this.carmeDownW;
|
|
|
|
- let carmeDownH = this.carmeDownH;
|
|
|
|
- /* globals */
|
|
|
|
- //版本问题,打印THREE,发现并没有VertexColors,于是查找资料中才发现把vertexColors: THREE.VertexColors设置为vertexColors: true即可
|
|
|
|
- THREE.vertexColors = true;
|
|
|
|
- console.log(1)
|
|
|
|
- let curvePath = null;
|
|
|
|
- var ModuleOpenDrive = null;
|
|
|
|
- var OpenDriveMap = null;
|
|
|
|
- var refline_lines = null;
|
|
|
|
- var road_network_mesh = null;
|
|
|
|
- var roadmarks_mesh = null;
|
|
|
|
- var lane_outline_lines = null;
|
|
|
|
- var roadmark_outline_lines = null;
|
|
|
|
- var ground_grid = null;
|
|
|
|
- var disposable_objs = [];
|
|
|
|
- var mouse = new THREE.Vector2();
|
|
|
|
- var spotlight_info = document.getElementById("spotlight_info");
|
|
|
|
- //相交车道ID
|
|
|
|
- var INTERSECTED_LANE_ID = 0xffffffff;
|
|
|
|
- var INTERSECTED_ROADMARK_ID = 0xffffffff;
|
|
|
|
- //聚集光是否暂停
|
|
|
|
- var spotlight_paused = false;
|
|
|
|
- //鼠标点击的三位坐标
|
|
|
|
- var mouse3D = [];
|
|
|
|
- var car3D = null;
|
|
|
|
- var lights = this.lights;
|
|
|
|
- var isMove = this.isMove;
|
|
|
|
- var carStart = this.carStart;
|
|
|
|
- var wheels = [];
|
|
|
|
- var line = null;
|
|
|
|
- const COLORS = {
|
|
|
|
- road: 1.0,
|
|
|
|
- roadmark: 1.0,
|
|
|
|
- road_object: 0.9,
|
|
|
|
- lane_outline: 0xae52d4,
|
|
|
|
- roadmark_outline: 0xffffff,
|
|
|
|
- ref_line: 0x69f0ae,
|
|
|
|
- background: 0x444444,
|
|
|
|
- lane_highlight: 0xff3030,
|
|
|
|
- roadmark_highlight: 0xff0000,
|
|
|
|
- };
|
|
|
|
-
|
|
|
|
- //自适应大小
|
|
|
|
- window.addEventListener("resize", onWindowResize, false);
|
|
|
|
-
|
|
|
|
- //监听鼠标位置改变
|
|
|
|
- window.addEventListener("mousemove", onDocumentMouseMove, false);
|
|
|
|
- window.addEventListener("dblclick", onDocumentMouseDbClick, false);
|
|
|
|
- window.addEventListener("click", recordPathPoint, false);
|
|
|
|
- /* notifactions */
|
|
|
|
- const notyf = new Notyf({
|
|
|
|
- duration: 3000,
|
|
|
|
- position: {
|
|
|
|
- x: "left",
|
|
|
|
- y: "bottom"
|
|
|
|
- },
|
|
|
|
- types: [{
|
|
|
|
- type: "info",
|
|
|
|
- background: "#607d8b",
|
|
|
|
- icon: false
|
|
|
|
- }],
|
|
|
|
- });
|
|
|
|
-
|
|
|
|
- //创建渲染器
|
|
|
|
- const renderer = new THREE.WebGLRenderer({
|
|
|
|
- antialias: true, //抗锯齿,防失真
|
|
|
|
- sortObjects: false, //定义渲染器是否应对对象进行排序
|
|
|
|
- //对数深度缓冲区,防止模型闪烁
|
|
|
|
- logarithmicdepthbuffer: true,
|
|
|
|
- });
|
|
|
|
- //开启投影阴影
|
|
|
|
- renderer.shadowMap.enabled = true;
|
|
|
|
- //设置渲染器渲染区域
|
|
|
|
- renderer.setSize(window.innerWidth, window.innerHeight);
|
|
|
|
- //渲染
|
|
|
|
- document.getElementById("ThreeJS").appendChild(renderer.domElement);
|
|
|
|
-
|
|
|
|
- //创建场景
|
|
|
|
- const scene = new THREE.Scene();
|
|
|
|
- //创建透视相机
|
|
|
|
- const camera = new THREE.PerspectiveCamera(
|
|
|
|
- 75,
|
|
|
|
- window.innerWidth / window.innerHeight,
|
|
|
|
- 0.1,
|
|
|
|
- 100000
|
|
|
|
- );
|
|
|
|
- //让Z轴朝上+
|
|
|
|
- camera.up.set(0, 0, 1); /* Coordinate system with Z pointing up */
|
|
|
|
- //创建控制器
|
|
|
|
- const controls = new OrbitControls(camera, renderer.domElement);
|
|
|
|
- //const controls = new THREE.OrbControls(camera, renderer.domElement);
|
|
|
|
- controls.addEventListener("start", () => {
|
|
|
|
- /**
|
|
|
|
- * 拖动开始停止开启聚集光和停止旋转
|
|
|
|
- */
|
|
|
|
- spotlight_paused = true; //聚集光暂停
|
|
|
|
- //controls.autoRotate = false; //是否旋转
|
|
|
|
- isMove = true;
|
|
|
|
- });
|
|
|
|
- controls.addEventListener("end", () => {
|
|
|
|
- //拖动结束聚集光关闭并且开启旋转
|
|
|
|
- spotlight_paused = false; //聚集光开始
|
|
|
|
- //将其设为true,以自动围绕目标旋转。请注意,如果它被启用,你必须在你的动画循环里调用
|
|
|
|
- // controls.autoRotate = true;//开启旋转
|
|
|
|
- isMove = false;
|
|
|
|
- });
|
|
|
|
- //controls.autoRotate = true; //开启旋转
|
|
|
|
- //创建平行光
|
|
|
|
- let light;
|
|
|
|
- for (let index = 0; index < lights.length / 2; index++) {
|
|
|
|
- light = new THREE.DirectionalLight(0xffffff, 0.6);
|
|
|
|
- light.position.set(lights[2 * index], lights[2 * index + 1], 5);
|
|
|
|
- scene.add(light);
|
|
|
|
- //平行光方向指向原点(0,0,0)
|
|
|
|
- scene.add(light.target);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- //添加坐标轴辅助器
|
|
|
|
- const axesHepler = new THREE.AxesHelper(5);
|
|
|
|
- scene.add(axesHepler);
|
|
|
|
-
|
|
|
|
- const rgbeLoader = new RGBELoader();
|
|
|
|
- //加载模型车
|
|
|
|
- let wheelPhysicalMaterial = new THREE.MeshPhysicalMaterial({
|
|
|
|
- color: 0xff0000,
|
|
|
|
- metalness: 1,
|
|
|
|
- roughness: 0.5,
|
|
|
|
- transmission: 1,
|
|
|
|
- transparent: true,
|
|
|
|
- clearcoatRoughness: 0,
|
|
|
|
- });
|
|
|
|
-
|
|
|
|
- let carBodyPhysicalMaterial = new THREE.MeshPhysicalMaterial({
|
|
|
|
- color: 0xff0000,
|
|
|
|
- metalness: 1,
|
|
|
|
- roughness: 0.5,
|
|
|
|
- clearcoat: 1,
|
|
|
|
- clearcoatRoughness: 0,
|
|
|
|
- });
|
|
|
|
-
|
|
|
|
- let carFrontPhysicalMaterial = new THREE.MeshPhysicalMaterial({
|
|
|
|
- color: 0xff0000,
|
|
|
|
- metalness: 1,
|
|
|
|
- roughness: 0.5,
|
|
|
|
- clearcoat: 1,
|
|
|
|
- clearcoatRoughness: 0,
|
|
|
|
- });
|
|
|
|
-
|
|
|
|
- let carHoodPhysicalMaterial = new THREE.MeshPhysicalMaterial({
|
|
|
|
- color: 0xff0000,
|
|
|
|
- metalness: 1,
|
|
|
|
- roughness: 0.5,
|
|
|
|
- clearcoat: 1,
|
|
|
|
- clearcoatRoughness: 0,
|
|
|
|
- }),
|
|
|
|
- carGlassPhysicalMaterial = new THREE.MeshPhysicalMaterial({
|
|
|
|
- color: 0xffffff,
|
|
|
|
- metalness: 0,
|
|
|
|
- roughness: 0,
|
|
|
|
- transmission: 1,
|
|
|
|
- transparent: true,
|
|
|
|
- });
|
|
|
|
- const gltfLoader = new GLTFLoader().setPath(
|
|
|
|
- "/"
|
|
|
|
- );
|
|
|
|
- // const gltfLoader = new GLTFLoader().setPath(
|
|
|
|
- // "@static/"
|
|
|
|
- // );
|
|
|
|
- const dracoLoader = new DRACOLoader();
|
|
|
|
- dracoLoader.setDecoderPath("/gltf/");
|
|
|
|
- gltfLoader.setDRACOLoader(dracoLoader);
|
|
|
|
- const wheelNames = ["柱体001", "柱体002", "柱体003", "柱体007"];
|
|
|
|
- gltfLoader.loadAsync("glb/car.glb").then((gltf) => {
|
|
|
|
- //映射-折射映射,不设置将不会透明
|
|
|
|
- car3D = gltf.scene;
|
|
|
|
- let index = 0;
|
|
|
|
- gltf.scene.traverse((child) => {
|
|
|
|
- if (child.isMesh) {
|
|
|
|
- const wheelNames = ["左后轮毂", "右后轮毂", "前轮毂"];
|
|
|
|
- // if(!wheelNames.includes(child.name)){
|
|
|
|
- // child.visible = false;
|
|
|
|
- // }
|
|
|
|
- if (wheelNames.includes(child.name)) {
|
|
|
|
- child.material = wheelPhysicalMaterial;
|
|
|
|
- wheels.push(child);
|
|
|
|
- }
|
|
|
|
- if (child.name.includes("Mesh002")) {
|
|
|
|
- child.material = carBodyPhysicalMaterial;
|
|
|
|
- }
|
|
|
|
- if (child.name.includes("前脸")) {
|
|
|
|
- child.material = carFrontPhysicalMaterial;
|
|
|
|
- }
|
|
|
|
- if (child.name.includes("引擎盖_1")) {
|
|
|
|
- child.material = carHoodPhysicalMaterial;
|
|
|
|
- }
|
|
|
|
- if (child.name.includes("挡风玻璃")) {
|
|
|
|
- child.material = carGlassPhysicalMaterial;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- index++;
|
|
|
|
- });
|
|
|
|
- gltf.scene.rotation.z = Math.PI;
|
|
|
|
- gltf.scene.rotation.x = -Math.PI / 2;
|
|
|
|
- gltf.scene.position.z += 0.05;
|
|
|
|
- scene.add(gltf.scene);
|
|
|
|
- });
|
|
|
|
-
|
|
|
|
- //选择车道线场景
|
|
|
|
- const lane_picking_scene = new THREE.Scene();
|
|
|
|
- //车道线场景背景颜色
|
|
|
|
- lane_picking_scene.background = new THREE.Color(0xffffff);
|
|
|
|
- //路标场景
|
|
|
|
- const roadmark_picking_scene = new THREE.Scene();
|
|
|
|
- //路标场景背景颜色
|
|
|
|
- roadmark_picking_scene.background = new THREE.Color(0xffffff);
|
|
|
|
- //坐标场景
|
|
|
|
- const xyz_scene = new THREE.Scene();
|
|
|
|
- //坐标场景背景颜色
|
|
|
|
- xyz_scene.background = new THREE.Color(0xffffff);
|
|
|
|
- const st_scene = new THREE.Scene();
|
|
|
|
- st_scene.background = new THREE.Color(0xffffff);
|
|
|
|
-
|
|
|
|
- //创建渲染器
|
|
|
|
- const lane_picking_texture = new THREE.WebGLRenderTarget(1, 1, {
|
|
|
|
- type: THREE.FloatType,
|
|
|
|
- });
|
|
|
|
- const roadmark_picking_texture = new THREE.WebGLRenderTarget(1, 1, {
|
|
|
|
- type: THREE.FloatType,
|
|
|
|
- });
|
|
|
|
- const xyz_texture = new THREE.WebGLRenderTarget(1, 1, {
|
|
|
|
- type: THREE.FloatType,
|
|
|
|
- });
|
|
|
|
- const st_texture = new THREE.WebGLRenderTarget(1, 1, {
|
|
|
|
- type: THREE.FloatType,
|
|
|
|
- });
|
|
|
|
- //获取顶点着色器
|
|
|
|
- const idVertexShader =
|
|
|
|
- document.getElementById("idVertexShader").textContent;
|
|
|
|
- console.log(idVertexShader)
|
|
|
|
- const idFragmentShader =
|
|
|
|
- document.getElementById("idFragmentShader").textContent;
|
|
|
|
- const xyzVertexShader =
|
|
|
|
- document.getElementById("xyzVertexShader").textContent;
|
|
|
|
- const xyzFragmentShader =
|
|
|
|
- document.getElementById("xyzFragmentShader").textContent;
|
|
|
|
- const stVertexShader =
|
|
|
|
- document.getElementById("stVertexShader").textContent;
|
|
|
|
- const stFragmentShader =
|
|
|
|
- document.getElementById("stFragmentShader").textContent;
|
|
|
|
- //设置车道中轴线颜色
|
|
|
|
- const refline_material = new THREE.LineBasicMaterial({
|
|
|
|
- color: COLORS.ref_line,
|
|
|
|
- //color: 0x0000ff,
|
|
|
|
- });
|
|
|
|
-
|
|
|
|
- const road_network_material = new THREE.MeshPhongMaterial({
|
|
|
|
- //vertexColors: THREE.VertexColors,
|
|
|
|
- //版本问题,打印THREE,发现并没有VertexColors,于是查找资料中才发现把vertexColors: THREE.VertexColors设置为vertexColors: true即可
|
|
|
|
- vertexColors: THREE.VertexColors,
|
|
|
|
- wireframe: PARAMS.wireframe, //显示现况
|
|
|
|
- shininess: 20.0,
|
|
|
|
- transparent: true,
|
|
|
|
- opacity: 0.4,
|
|
|
|
- });
|
|
|
|
-
|
|
|
|
- //道路线
|
|
|
|
- const lane_outlines_material = new THREE.LineBasicMaterial({
|
|
|
|
- color: COLORS.lane_outline,
|
|
|
|
- });
|
|
|
|
-
|
|
|
|
- //外侧线
|
|
|
|
- const roadmark_outlines_material = new THREE.LineBasicMaterial({
|
|
|
|
- color: COLORS.roadmark_outline,
|
|
|
|
- });
|
|
|
|
- const id_material = new THREE.ShaderMaterial({
|
|
|
|
- vertexShader: idVertexShader,
|
|
|
|
- fragmentShader: idFragmentShader,
|
|
|
|
- });
|
|
|
|
- const xyz_material = new THREE.ShaderMaterial({
|
|
|
|
- vertexShader: xyzVertexShader,
|
|
|
|
- fragmentShader: xyzFragmentShader,
|
|
|
|
- });
|
|
|
|
- const st_material = new THREE.ShaderMaterial({
|
|
|
|
- vertexShader: stVertexShader,
|
|
|
|
- fragmentShader: stFragmentShader,
|
|
|
|
- });
|
|
|
|
- const roadmarks_material = new THREE.MeshBasicMaterial({
|
|
|
|
- vertexColors: THREE.VertexColors,
|
|
|
|
- });
|
|
|
|
- const road_objects_material = new THREE.MeshBasicMaterial({
|
|
|
|
- vertexColors: THREE.VertexColors,
|
|
|
|
- side: THREE.DoubleSide,
|
|
|
|
- wireframe: true,
|
|
|
|
- });
|
|
|
|
-
|
|
|
|
- /* load WASM + odr map */
|
|
|
|
- libOpenDrive().then((Module) => {
|
|
|
|
- ModuleOpenDrive = Module;
|
|
|
|
- fetch("/map/mine3.xodr").then(
|
|
|
|
- (file_data) => {
|
|
|
|
- file_data.text().then((file_text) => {
|
|
|
|
- //加载数据文件
|
|
|
|
- loadFile(file_text, false);
|
|
|
|
- });
|
|
|
|
- }
|
|
|
|
- );
|
|
|
|
- });
|
|
|
|
-
|
|
|
|
- function onFileSelect(file) {
|
|
|
|
- let file_reader = new FileReader();
|
|
|
|
- file_reader.onload = () => {
|
|
|
|
- loadFile(file_reader.result, true);
|
|
|
|
- };
|
|
|
|
- file_reader.readAsText(file);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- function loadFile(file_text, clear_map) {
|
|
|
|
- //清除文件系统中保存的文件节点
|
|
|
|
- if (clear_map) ModuleOpenDrive["FS_unlink"]("./data.xodr");
|
|
|
|
- //将文件数据转为节点保存到文件系统本地指定的文件目录,支持读写
|
|
|
|
- ModuleOpenDrive["FS_createDataFile"](
|
|
|
|
- ".",
|
|
|
|
- "data.xodr",
|
|
|
|
- file_text,
|
|
|
|
- true,
|
|
|
|
- true
|
|
|
|
- );
|
|
|
|
- //OpenDriveMap不为null,则已经打开过,需要删除地图重新尝试打开
|
|
|
|
- if (OpenDriveMap) OpenDriveMap.delete();
|
|
|
|
-
|
|
|
|
- //打开驱动地图
|
|
|
|
- OpenDriveMap = new ModuleOpenDrive.OpenDriveMap(
|
|
|
|
- "./data.xodr",
|
|
|
|
- PARAMS.lateralProfile,
|
|
|
|
- PARAMS.laneHeight,
|
|
|
|
- true
|
|
|
|
- );
|
|
|
|
- loadOdrMap(clear_map);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- function reloadOdrMap() {
|
|
|
|
- if (OpenDriveMap) OpenDriveMap.delete();
|
|
|
|
- OpenDriveMap = new ModuleOpenDrive.OpenDriveMap(
|
|
|
|
- "./data.xodr",
|
|
|
|
- PARAMS.lateralProfile,
|
|
|
|
- PARAMS.laneHeight,
|
|
|
|
- true
|
|
|
|
- );
|
|
|
|
- loadOdrMap(true, false);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- function loadOdrMap(clear_map = true, fit_view = true) {
|
|
|
|
- //web浏览器内置api,精度微秒级,performance.now是浏览器(Web API)提供的方法,不同浏览器获取到的精度不同。Date.now是Javascript内置方法,差异主要在于浏览器遵循的ECMAScript规范。
|
|
|
|
- const t0 = performance.now();
|
|
|
|
- //是否清除地图
|
|
|
|
- if (clear_map) {
|
|
|
|
- road_network_mesh.userData.odr_road_network_mesh.delete();
|
|
|
|
- scene.remove(
|
|
|
|
- road_network_mesh,
|
|
|
|
- roadmarks_mesh,
|
|
|
|
- road_objects_mesh,
|
|
|
|
- refline_lines,
|
|
|
|
- lane_outline_lines,
|
|
|
|
- roadmark_outline_lines,
|
|
|
|
- ground_grid
|
|
|
|
- );
|
|
|
|
- lane_picking_scene.remove(...lane_picking_scene.children);
|
|
|
|
- roadmark_picking_scene.remove(...roadmark_picking_scene.children);
|
|
|
|
- xyz_scene.remove(...xyz_scene.children);
|
|
|
|
- st_scene.remove(...st_scene.children);
|
|
|
|
- for (let obj of disposable_objs) obj.dispose();
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * 道路中间s方向的线
|
|
|
|
- */
|
|
|
|
- //获取参考线矩形几何体
|
|
|
|
- const reflines_geom = new THREE.BufferGeometry();
|
|
|
|
- //获取驱动中参考线数据信息
|
|
|
|
- const odr_refline_segments = OpenDriveMap.get_refline_segments(
|
|
|
|
- parseFloat(PARAMS.resolution)
|
|
|
|
- );
|
|
|
|
- //设置参考线坐标点
|
|
|
|
- reflines_geom.setAttribute(
|
|
|
|
- "position",
|
|
|
|
- new THREE.Float32BufferAttribute(
|
|
|
|
- getStdVecEntries(odr_refline_segments.vertices).flat(),
|
|
|
|
- 3
|
|
|
|
- )
|
|
|
|
- );
|
|
|
|
- //设置参考线坐标点索引
|
|
|
|
- reflines_geom.setIndex(
|
|
|
|
- getStdVecEntries(odr_refline_segments.indices, true)
|
|
|
|
- );
|
|
|
|
- //创建参考线物体
|
|
|
|
- refline_lines = new THREE.LineSegments(reflines_geom, refline_material);
|
|
|
|
- refline_lines.renderOrder = 10;
|
|
|
|
- //设置是否可见
|
|
|
|
- refline_lines.visible = PARAMS.ref_line;
|
|
|
|
- refline_lines.matrixAutoUpdate = false;
|
|
|
|
- disposable_objs.push(reflines_geom);
|
|
|
|
- //将参考线加入场景中
|
|
|
|
- scene.add(refline_lines);
|
|
|
|
-
|
|
|
|
- /*
|
|
|
|
- *道路面
|
|
|
|
- */
|
|
|
|
- //根据细节级别获取道路网格物体PARAMS.resolution 默认0.3中等级别
|
|
|
|
- const odr_road_network_mesh = OpenDriveMap.get_mesh(
|
|
|
|
- parseFloat(PARAMS.resolution)
|
|
|
|
- );
|
|
|
|
- //获取所有路段的车道(车道id为 -2, -1, 0, 1, 2)
|
|
|
|
- const odr_lanes_mesh = odr_road_network_mesh.lanes_mesh;
|
|
|
|
- //获取所有路段车道点集构建道路物体
|
|
|
|
- const road_network_geom = get_geometry(odr_lanes_mesh);
|
|
|
|
- //设置道路颜色
|
|
|
|
- road_network_geom.attributes.color.array.fill(COLORS.road);
|
|
|
|
- //获取所有路段的车道的起始位置索引
|
|
|
|
- //将索引作为车道开始和结束信息
|
|
|
|
- for (const [vert_start_idx, _] of getStdMapEntries(
|
|
|
|
- odr_lanes_mesh.lane_start_indices
|
|
|
|
- )) {
|
|
|
|
- //根据起始位置索引获取车道信息
|
|
|
|
- const vert_idx_interval =
|
|
|
|
- odr_lanes_mesh.get_idx_interval_lane(vert_start_idx);
|
|
|
|
- //结束索引减去起始索引的长度就是该路段该车道的长度
|
|
|
|
- const vert_count = vert_idx_interval[1] - vert_idx_interval[0];
|
|
|
|
- //索引数据压缩
|
|
|
|
- const vert_start_idx_encoded = encodeUInt32(vert_start_idx);
|
|
|
|
- const attr_arr = new Float32Array(vert_count * 4);
|
|
|
|
- for (let i = 0; i < vert_count; i++)
|
|
|
|
- attr_arr.set(
|
|
|
|
- vert_start_idx_encoded, //存入的数据集合,批量存入,底层会打散
|
|
|
|
- i * 4 //数组起始索引位置
|
|
|
|
- );
|
|
|
|
-
|
|
|
|
- road_network_geom.attributes.id.array.set(
|
|
|
|
- attr_arr,
|
|
|
|
- vert_idx_interval[0] * 4
|
|
|
|
- );
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- disposable_objs.push(road_network_geom);
|
|
|
|
- road_network_mesh = new THREE.Mesh(
|
|
|
|
- road_network_geom,
|
|
|
|
- road_network_material
|
|
|
|
- );
|
|
|
|
- road_network_mesh.renderOrder = 0;
|
|
|
|
- road_network_mesh.userData = {
|
|
|
|
- odr_road_network_mesh
|
|
|
|
- };
|
|
|
|
- road_network_mesh.matrixAutoUpdate = false;
|
|
|
|
- road_network_mesh.visible = !(PARAMS.view_mode == "Outlines");
|
|
|
|
- scene.add(road_network_mesh);
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * 选中被选中的车道进行离屏渲染
|
|
|
|
- */
|
|
|
|
- const lane_picking_mesh = new THREE.Mesh(road_network_geom, id_material);
|
|
|
|
- lane_picking_mesh.matrixAutoUpdate = false;
|
|
|
|
- lane_picking_scene.add(lane_picking_mesh);
|
|
|
|
-
|
|
|
|
- /* xyz coords road network mesh */
|
|
|
|
- const xyz_mesh = new THREE.Mesh(road_network_geom, xyz_material);
|
|
|
|
- xyz_mesh.matrixAutoUpdate = false;
|
|
|
|
- xyz_scene.add(xyz_mesh);
|
|
|
|
-
|
|
|
|
- /* st coords road network mesh */
|
|
|
|
- const st_mesh = new THREE.Mesh(road_network_geom, st_material);
|
|
|
|
- st_mesh.matrixAutoUpdate = false;
|
|
|
|
- st_scene.add(st_mesh);
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * 车道线宽度区域填充,由于车道线有宽度,宽度区域颜色填充
|
|
|
|
- */
|
|
|
|
- const odr_roadmarks_mesh = odr_road_network_mesh.roadmarks_mesh;
|
|
|
|
- const roadmarks_geom = get_geometry(odr_roadmarks_mesh);
|
|
|
|
- roadmarks_geom.attributes.color.array.fill(COLORS.roadmark);
|
|
|
|
- for (const [vert_start_idx, _] of getStdMapEntries(
|
|
|
|
- odr_roadmarks_mesh.roadmark_type_start_indices
|
|
|
|
- )) {
|
|
|
|
- const vert_idx_interval =
|
|
|
|
- odr_roadmarks_mesh.get_idx_interval_roadmark(vert_start_idx);
|
|
|
|
- const vert_count = vert_idx_interval[1] - vert_idx_interval[0];
|
|
|
|
- const vert_start_idx_encoded = encodeUInt32(vert_start_idx);
|
|
|
|
- const attr_arr = new Float32Array(vert_count * 4);
|
|
|
|
- for (let i = 0; i < vert_count; i++)
|
|
|
|
- attr_arr.set(
|
|
|
|
- vert_start_idx_encoded, //数组
|
|
|
|
- i * 4 //偏移量,每次偏移step:数组大小
|
|
|
|
- );
|
|
|
|
- roadmarks_geom.attributes.id.array.set(
|
|
|
|
- attr_arr,
|
|
|
|
- vert_idx_interval[0] * 4
|
|
|
|
- );
|
|
|
|
- }
|
|
|
|
- disposable_objs.push(roadmarks_geom);
|
|
|
|
-
|
|
|
|
- /* roadmarks mesh */
|
|
|
|
- roadmarks_mesh = new THREE.Mesh(roadmarks_geom, roadmarks_material);
|
|
|
|
- roadmarks_mesh.matrixAutoUpdate = false;
|
|
|
|
- roadmarks_mesh.visible = !(PARAMS.view_mode == "Outlines") && PARAMS.roadmarks;
|
|
|
|
- scene.add(roadmarks_mesh);
|
|
|
|
-
|
|
|
|
- //离屏渲染车道线宽度区域
|
|
|
|
- const roadmark_picking_mesh = new THREE.Mesh(roadmarks_geom, id_material);
|
|
|
|
- roadmark_picking_mesh.matrixAutoUpdate = false;
|
|
|
|
- roadmark_picking_scene.add(roadmark_picking_mesh);
|
|
|
|
-
|
|
|
|
- /* road objects geometry */
|
|
|
|
- const odr_road_objects_mesh = odr_road_network_mesh.road_objects_mesh;
|
|
|
|
- const road_objects_geom = get_geometry(odr_road_objects_mesh);
|
|
|
|
- road_objects_geom.attributes.color.array.fill(COLORS.road_object);
|
|
|
|
- for (const [vert_start_idx, _] of getStdMapEntries(
|
|
|
|
- odr_road_objects_mesh.road_object_start_indices
|
|
|
|
- )) {
|
|
|
|
- const vert_idx_interval =
|
|
|
|
- odr_roadmarks_mesh.get_idx_interval_roadmark(vert_start_idx);
|
|
|
|
- const vert_count = vert_idx_interval[1] - vert_idx_interval[0];
|
|
|
|
- const vert_start_idx_encoded = encodeUInt32(vert_start_idx);
|
|
|
|
- const attr_arr = new Float32Array(vert_count * 4);
|
|
|
|
- for (let i = 0; i < vert_count; i++)
|
|
|
|
- attr_arr.set(vert_start_idx_encoded, i * 4);
|
|
|
|
- roadmarks_geom.attributes.id.array.set(
|
|
|
|
- attr_arr,
|
|
|
|
- vert_idx_interval[0] * 4
|
|
|
|
- );
|
|
|
|
- }
|
|
|
|
- disposable_objs.push(road_objects_geom);
|
|
|
|
-
|
|
|
|
- /* road objects mesh */
|
|
|
|
- let road_objects_mesh = new THREE.Mesh(
|
|
|
|
- road_objects_geom,
|
|
|
|
- road_objects_material
|
|
|
|
- );
|
|
|
|
- road_objects_mesh.matrixAutoUpdate = false;
|
|
|
|
- scene.add(road_objects_mesh);
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * 车道轮廓线
|
|
|
|
- * 道路轮廓线包含车道线,由于每条车道线有宽度,车道轮廓线即为车道线的中心线
|
|
|
|
- * id为0的车道轮廓线和参考线s重合
|
|
|
|
- */
|
|
|
|
- const lane_outlines_geom = new THREE.BufferGeometry();
|
|
|
|
- lane_outlines_geom.setAttribute(
|
|
|
|
- "position",
|
|
|
|
- road_network_geom.attributes.position
|
|
|
|
- );
|
|
|
|
- lane_outlines_geom.setIndex(
|
|
|
|
- getStdVecEntries(odr_lanes_mesh.get_lane_outline_indices(), true)
|
|
|
|
- );
|
|
|
|
- lane_outline_lines = new THREE.LineSegments(
|
|
|
|
- lane_outlines_geom,
|
|
|
|
- lane_outlines_material
|
|
|
|
- );
|
|
|
|
- lane_outline_lines.renderOrder = 9;
|
|
|
|
- disposable_objs.push(lane_outlines_geom);
|
|
|
|
- //scene.add(lane_outline_lines);
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * 道路轮廓线
|
|
|
|
- */
|
|
|
|
- const roadmark_outlines_geom = new THREE.BufferGeometry();
|
|
|
|
- roadmark_outlines_geom.setAttribute(
|
|
|
|
- "position",
|
|
|
|
- roadmarks_geom.attributes.position
|
|
|
|
- );
|
|
|
|
- roadmark_outlines_geom.setIndex(
|
|
|
|
- getStdVecEntries(
|
|
|
|
- odr_roadmarks_mesh.get_roadmark_outline_indices(),
|
|
|
|
- true
|
|
|
|
- )
|
|
|
|
- );
|
|
|
|
- roadmark_outline_lines = new THREE.LineSegments(
|
|
|
|
- roadmark_outlines_geom,
|
|
|
|
- roadmark_outlines_material
|
|
|
|
- );
|
|
|
|
- roadmark_outline_lines.renderOrder = 8;
|
|
|
|
- roadmark_outline_lines.matrixAutoUpdate = false;
|
|
|
|
- disposable_objs.push(roadmark_outlines_geom);
|
|
|
|
- roadmark_outline_lines.visible = PARAMS.roadmarks;
|
|
|
|
- scene.add(roadmark_outline_lines);
|
|
|
|
-
|
|
|
|
- /* fit view and camera */
|
|
|
|
- const bbox_reflines = new THREE.Box3().setFromObject(refline_lines);
|
|
|
|
- const max_diag_dist = bbox_reflines.min.distanceTo(bbox_reflines.max);
|
|
|
|
- camera.far = max_diag_dist * 1.5;
|
|
|
|
- //controls.autoRotate = fit_view;
|
|
|
|
-
|
|
|
|
- if (fit_view) {
|
|
|
|
- camera.position.set(0, 0, 50);
|
|
|
|
- // fitViewToBbox(bbox_reflines);
|
|
|
|
- //fitViewToBbox(bbox_reflines);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * 网格
|
|
|
|
- */
|
|
|
|
- let bbox_center_pt = new THREE.Vector3();
|
|
|
|
- bbox_reflines.getCenter(bbox_center_pt);
|
|
|
|
- ground_grid = new THREE.GridHelper(
|
|
|
|
- max_diag_dist,
|
|
|
|
- max_diag_dist / 10,
|
|
|
|
- 0x2f2f2f,
|
|
|
|
- 0x2f2f2f
|
|
|
|
- );
|
|
|
|
- ground_grid.geometry.rotateX(Math.PI / 2);
|
|
|
|
- ground_grid.position.set(
|
|
|
|
- bbox_center_pt.x,
|
|
|
|
- bbox_center_pt.y,
|
|
|
|
- bbox_reflines.min.z - 0.1
|
|
|
|
- );
|
|
|
|
- disposable_objs.push(ground_grid.geometry);
|
|
|
|
- scene.add(ground_grid);
|
|
|
|
-
|
|
|
|
- const rgbeLoader = new RGBELoader();
|
|
|
|
- rgbeLoader.loadAsync("hdr/christmas-sky.hdr").then((loader) => {
|
|
|
|
- loader.mapping = THREE.EquirectangularRefractionMapping;
|
|
|
|
- const sphereGeometry = new THREE.SphereBufferGeometry(1000);
|
|
|
|
- const sphereMetrial = new THREE.MeshBasicMaterial({
|
|
|
|
- color: 0xffffff,
|
|
|
|
- map: loader,
|
|
|
|
- });
|
|
|
|
- const sphereMesh = new THREE.Mesh(sphereGeometry, sphereMetrial);
|
|
|
|
- sphereMesh.geometry.scale(1, 1, -1);
|
|
|
|
- sphereMesh.rotation.x = Math.PI / 2;
|
|
|
|
- scene.add(sphereMesh);
|
|
|
|
- });
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * 灯光
|
|
|
|
- */
|
|
|
|
- light.position.set(
|
|
|
|
- bbox_reflines.min.x,
|
|
|
|
- bbox_reflines.min.y,
|
|
|
|
- bbox_reflines.max.z + max_diag_dist
|
|
|
|
- );
|
|
|
|
- light.target.position.set(
|
|
|
|
- bbox_center_pt.x,
|
|
|
|
- bbox_center_pt.y,
|
|
|
|
- bbox_center_pt.z
|
|
|
|
- );
|
|
|
|
- light.position.needsUpdate = true;
|
|
|
|
- light.target.position.needsUpdate = true;
|
|
|
|
- light.target.updateMatrixWorld();
|
|
|
|
-
|
|
|
|
- const t1 = performance.now();
|
|
|
|
- console.log(
|
|
|
|
- "Heap size: " + ModuleOpenDrive.HEAP8.length / 1024 / 1024 + " mb"
|
|
|
|
- );
|
|
|
|
-
|
|
|
|
-
|
|
|
|
- //删除数据冗余,避免造成内存泄漏
|
|
|
|
- odr_roadmarks_mesh.delete();
|
|
|
|
- odr_lanes_mesh.delete();
|
|
|
|
- animate();
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- // 创建clock
|
|
|
|
- const clock = new THREE.Clock();
|
|
|
|
- const positionMap = new Map();
|
|
|
|
-
|
|
|
|
- function animate() {
|
|
|
|
- //控制电脑帧频,防止刷屏过快导致的页面刷3D数据刷新过快 控制每秒30次
|
|
|
|
- setTimeout(function() {
|
|
|
|
- requestAnimationFrame(animate);
|
|
|
|
- }, 1000 / 30);
|
|
|
|
- // 获取总共耗时
|
|
|
|
- const time = clock.getElapsedTime();
|
|
|
|
- let t = time % 80;
|
|
|
|
- t /= 80;
|
|
|
|
- if (that.startPoint == false && that.carStart == true) {
|
|
|
|
- //轮毂旋转
|
|
|
|
- if (wheels.length > 0) {
|
|
|
|
- let wheel;
|
|
|
|
- for (let index = 0; index < wheels.length; index++) {
|
|
|
|
- wheel = wheels[index];
|
|
|
|
- let position = positionMap.get(index);
|
|
|
|
- if (position == null) {
|
|
|
|
- //先记录车轮的原始位置
|
|
|
|
- position = wheel.position;
|
|
|
|
- positionMap.set(index, wheel.position);
|
|
|
|
- }
|
|
|
|
- //将车轮放置原点
|
|
|
|
- wheel.geometry.center();
|
|
|
|
- //让车在原点进行旋转
|
|
|
|
- wheel.rotateZ((60 / 360) * Math.PI);
|
|
|
|
- //根据车子的初始位置进行复位
|
|
|
|
- wheel.position.set(position.x, position.y, position.z);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- // 通过point设置模型dd位置
|
|
|
|
- const point = curvePath.getPointAt(t);
|
|
|
|
- // 获取点的切线
|
|
|
|
- const tangent = curvePath.getTangentAt(t);
|
|
|
|
- const lookAt = tangent.add(point);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- controls.update();
|
|
|
|
-
|
|
|
|
- camera.setViewOffset(
|
|
|
|
- renderer.domElement.width, //画布的宽度
|
|
|
|
- renderer.domElement.height, //画布的高度
|
|
|
|
- (renderer.domElement.width / 2) | 0, //画布坐标系中,相机的x坐标位置
|
|
|
|
- (renderer.domElement.height / 2) | 0, //画布坐标系中,相机的y坐标位置
|
|
|
|
- 1, //副相机的宽度
|
|
|
|
- 1 //副相机的高度
|
|
|
|
- );
|
|
|
|
- //离屏渲染
|
|
|
|
- renderer.setRenderTarget(lane_picking_texture);
|
|
|
|
- renderer.render(lane_picking_scene, camera);
|
|
|
|
-
|
|
|
|
- renderer.setRenderTarget(roadmark_picking_texture);
|
|
|
|
- renderer.render(roadmark_picking_scene, camera);
|
|
|
|
-
|
|
|
|
- renderer.setRenderTarget(xyz_texture);
|
|
|
|
- renderer.render(xyz_scene, camera);
|
|
|
|
-
|
|
|
|
- renderer.setRenderTarget(st_texture);
|
|
|
|
- renderer.render(st_scene, camera);
|
|
|
|
-
|
|
|
|
- const lane_id_pixel_buffer = new Float32Array(4);
|
|
|
|
- //拾取颜色
|
|
|
|
- //console.log(mouse.x, window.innerHeight - mouse.y)
|
|
|
|
- renderer.readRenderTargetPixels(
|
|
|
|
- lane_picking_texture,
|
|
|
|
- 0, //相机截图左上角为坐标原点,相对于截图左上角而言的渲染起始点x坐标
|
|
|
|
- 0, //相机截图左上角为坐标原点,相对于截图左上角而言的渲染起始点y坐标
|
|
|
|
- 1, //渲染宽度范围
|
|
|
|
- 1, //渲染高度范围
|
|
|
|
- lane_id_pixel_buffer
|
|
|
|
- );
|
|
|
|
- const roadmark_id_pixel_buffer = new Float32Array(4);
|
|
|
|
- renderer.readRenderTargetPixels(
|
|
|
|
- roadmark_picking_texture,
|
|
|
|
- 0,
|
|
|
|
- 0,
|
|
|
|
- 1,
|
|
|
|
- 1,
|
|
|
|
- roadmark_id_pixel_buffer
|
|
|
|
- );
|
|
|
|
- const xyz_pixel_buffer = new Float32Array(4);
|
|
|
|
- renderer.readRenderTargetPixels(
|
|
|
|
- xyz_texture,
|
|
|
|
- 0,
|
|
|
|
- 0,
|
|
|
|
- 1,
|
|
|
|
- 1,
|
|
|
|
- xyz_pixel_buffer
|
|
|
|
- );
|
|
|
|
- //记录webgl坐标
|
|
|
|
- mouse3D[0] = xyz_pixel_buffer[0];
|
|
|
|
- mouse3D[1] = xyz_pixel_buffer[1];
|
|
|
|
- mouse3D[2] = xyz_pixel_buffer[2];
|
|
|
|
- xyz_pixel_buffer[0] += OpenDriveMap.x_offs;
|
|
|
|
- xyz_pixel_buffer[1] += OpenDriveMap.y_offs;
|
|
|
|
- const st_pixel_buffer = new Float32Array(4);
|
|
|
|
- renderer.readRenderTargetPixels(
|
|
|
|
- st_texture,
|
|
|
|
- 0,
|
|
|
|
- 0,
|
|
|
|
- 1,
|
|
|
|
- 1,
|
|
|
|
- st_pixel_buffer
|
|
|
|
- );
|
|
|
|
-
|
|
|
|
- camera.clearViewOffset();
|
|
|
|
- renderer.setRenderTarget(null);
|
|
|
|
- /**
|
|
|
|
- * 选中车道离屏渲染
|
|
|
|
- */
|
|
|
|
-
|
|
|
|
- if (isValid(lane_id_pixel_buffer)) {
|
|
|
|
- //根据颜色值解码成车道ID
|
|
|
|
- const decoded_lane_id = decodeUInt32(lane_id_pixel_buffer);
|
|
|
|
- //自定义数据中获取所有车段中的所有车道数据
|
|
|
|
- const odr_lanes_mesh =
|
|
|
|
- road_network_mesh.userData.odr_road_network_mesh.lanes_mesh;
|
|
|
|
- //本次选中的区域车道ID是否和上次一样
|
|
|
|
- if (INTERSECTED_LANE_ID != decoded_lane_id) {
|
|
|
|
- //当前是否是初始化状态,如果不是则进行初始化,防止重复初始化
|
|
|
|
- if (INTERSECTED_LANE_ID != 0xffffffff) {
|
|
|
|
- //根据车道ID索引获取车道信息
|
|
|
|
- road_network_mesh.geometry.attributes.color.array.fill(
|
|
|
|
- COLORS.road
|
|
|
|
- );
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- //保存选中车道ID
|
|
|
|
- INTERSECTED_LANE_ID = decoded_lane_id;
|
|
|
|
- //根据车道ID获取车道信息
|
|
|
|
- const lane_vert_idx_interval =
|
|
|
|
- odr_lanes_mesh.get_idx_interval_lane(INTERSECTED_LANE_ID);
|
|
|
|
- //获取该车道长度
|
|
|
|
- const vert_count =
|
|
|
|
- lane_vert_idx_interval[1] - lane_vert_idx_interval[0];
|
|
|
|
- //修改离屏渲染场景中该车道的背景颜色
|
|
|
|
- applyVertexColors(
|
|
|
|
- road_network_mesh.geometry.attributes.color,
|
|
|
|
- new THREE.Color(COLORS.lane_highlight),
|
|
|
|
- lane_vert_idx_interval[0],
|
|
|
|
- vert_count
|
|
|
|
- );
|
|
|
|
- //手动更新颜色值
|
|
|
|
- road_network_mesh.geometry.attributes.color.needsUpdate = true;
|
|
|
|
- }
|
|
|
|
- //使用过后删除数据冗余,避免造成内存泄漏
|
|
|
|
- odr_lanes_mesh.delete();
|
|
|
|
- } else {
|
|
|
|
- if (INTERSECTED_LANE_ID != 0xffffffff) {
|
|
|
|
- const odr_lanes_mesh =
|
|
|
|
- road_network_mesh.userData.odr_road_network_mesh.lanes_mesh;
|
|
|
|
- const lane_vert_idx_interval =
|
|
|
|
- odr_lanes_mesh.get_idx_interval_lane(INTERSECTED_LANE_ID);
|
|
|
|
- road_network_mesh.geometry.attributes.color.array.fill(COLORS.road);
|
|
|
|
- road_network_mesh.geometry.attributes.color.needsUpdate = true;
|
|
|
|
- odr_lanes_mesh.delete();
|
|
|
|
- INTERSECTED_LANE_ID = 0xffffffff;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (isValid(roadmark_id_pixel_buffer)) {
|
|
|
|
- //获取
|
|
|
|
- const decoded_roadmark_id = decodeUInt32(roadmark_id_pixel_buffer);
|
|
|
|
- const odr_roadmarks_mesh =
|
|
|
|
- road_network_mesh.userData.odr_road_network_mesh.roadmarks_mesh;
|
|
|
|
- if (INTERSECTED_ROADMARK_ID != decoded_roadmark_id) {
|
|
|
|
- if (INTERSECTED_ROADMARK_ID != 0xffffffff) {
|
|
|
|
- const prev_roadmark_vert_idx_interval =
|
|
|
|
- odr_roadmarks_mesh.get_idx_interval_roadmark(
|
|
|
|
- INTERSECTED_ROADMARK_ID
|
|
|
|
- );
|
|
|
|
- roadmarks_mesh.geometry.attributes.color.array.fill(
|
|
|
|
- COLORS.roadmark,
|
|
|
|
- prev_roadmark_vert_idx_interval[0] * 3,
|
|
|
|
- prev_roadmark_vert_idx_interval[1] * 3
|
|
|
|
- );
|
|
|
|
- }
|
|
|
|
- INTERSECTED_ROADMARK_ID = decoded_roadmark_id;
|
|
|
|
- const roadmark_vert_idx_interval =
|
|
|
|
- odr_roadmarks_mesh.get_idx_interval_roadmark(
|
|
|
|
- INTERSECTED_ROADMARK_ID
|
|
|
|
- );
|
|
|
|
- const vert_count =
|
|
|
|
- roadmark_vert_idx_interval[1] - roadmark_vert_idx_interval[0];
|
|
|
|
- applyVertexColors(
|
|
|
|
- roadmarks_mesh.geometry.attributes.color,
|
|
|
|
- new THREE.Color(COLORS.roadmark_highlight),
|
|
|
|
- roadmark_vert_idx_interval[0],
|
|
|
|
- vert_count
|
|
|
|
- );
|
|
|
|
- roadmarks_mesh.geometry.attributes.color.needsUpdate = true;
|
|
|
|
- }
|
|
|
|
- odr_roadmarks_mesh.delete();
|
|
|
|
- } else {
|
|
|
|
- if (INTERSECTED_ROADMARK_ID != 0xffffffff) {
|
|
|
|
- const odr_roadmarks_mesh =
|
|
|
|
- road_network_mesh.userData.odr_road_network_mesh.roadmarks_mesh;
|
|
|
|
- const roadmark_vert_idx_interval =
|
|
|
|
- odr_roadmarks_mesh.get_idx_interval_lane(INTERSECTED_ROADMARK_ID);
|
|
|
|
- roadmarks_mesh.geometry.attributes.color.array.fill(
|
|
|
|
- COLORS.roadmark,
|
|
|
|
- roadmark_vert_idx_interval[0] * 3,
|
|
|
|
- roadmark_vert_idx_interval[1] * 3
|
|
|
|
- );
|
|
|
|
- roadmarks_mesh.geometry.attributes.color.needsUpdate = true;
|
|
|
|
- INTERSECTED_ROADMARK_ID = 0xffffffff;
|
|
|
|
- odr_roadmarks_mesh.delete();
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (INTERSECTED_LANE_ID != 0xffffffff) {
|
|
|
|
- const odr_lanes_mesh =
|
|
|
|
- road_network_mesh.userData.odr_road_network_mesh.lanes_mesh;
|
|
|
|
- const road_id = odr_lanes_mesh.get_road_id(INTERSECTED_LANE_ID);
|
|
|
|
- const lanesec_s0 = odr_lanes_mesh.get_lanesec_s0(INTERSECTED_LANE_ID);
|
|
|
|
- const lane_id = odr_lanes_mesh.get_lane_id(INTERSECTED_LANE_ID);
|
|
|
|
- const lane_type = OpenDriveMap.roads
|
|
|
|
- .get(road_id)
|
|
|
|
- .s_to_lanesection.get(lanesec_s0)
|
|
|
|
- .id_to_lane.get(lane_id).type;
|
|
|
|
- odr_lanes_mesh.delete();
|
|
|
|
- }
|
|
|
|
- renderer.render(scene, camera);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- //集合体
|
|
|
|
- function get_geometry(odr_meshunion) {
|
|
|
|
- const geom = new THREE.BufferGeometry();
|
|
|
|
- geom.setAttribute(
|
|
|
|
- "position",
|
|
|
|
- new THREE.Float32BufferAttribute(
|
|
|
|
- getStdVecEntries(odr_meshunion.vertices, true).flat(),
|
|
|
|
- 3
|
|
|
|
- )
|
|
|
|
- );
|
|
|
|
- //获取uv坐标
|
|
|
|
- geom.setAttribute(
|
|
|
|
- "st",
|
|
|
|
- new THREE.Float32BufferAttribute(
|
|
|
|
- getStdVecEntries(odr_meshunion.st_coordinates, true).flat(),
|
|
|
|
- 2
|
|
|
|
- )
|
|
|
|
- );
|
|
|
|
- //设置点颜色
|
|
|
|
- geom.setAttribute(
|
|
|
|
- "color",
|
|
|
|
- new THREE.Float32BufferAttribute(
|
|
|
|
- new Float32Array(geom.attributes.position.count * 3),
|
|
|
|
- 3
|
|
|
|
- )
|
|
|
|
- );
|
|
|
|
- //设置几何体唯一编号
|
|
|
|
- geom.setAttribute(
|
|
|
|
- "id",
|
|
|
|
- new THREE.Float32BufferAttribute(
|
|
|
|
- new Float32Array(geom.attributes.position.count * 4),
|
|
|
|
- 4
|
|
|
|
- )
|
|
|
|
- );
|
|
|
|
- // geom.setAttribute('ids', new THREE.Float32BufferAttribute(new Float32Array(geom.attributes.position.count * 4), 4));
|
|
|
|
- //设置几何体索引数据
|
|
|
|
- geom.setIndex(getStdVecEntries(odr_meshunion.indices, true));
|
|
|
|
- geom.computeVertexNormals();
|
|
|
|
- return geom;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- //切换照相机视角
|
|
|
|
- function fitViewToBbox(bbox, restrict_zoom = true) {
|
|
|
|
- let center_pt = new THREE.Vector3();
|
|
|
|
- //返回盒子的中心点
|
|
|
|
- bbox.getCenter(center_pt);
|
|
|
|
-
|
|
|
|
- const l2xy =
|
|
|
|
- 0.5 *
|
|
|
|
- Math.sqrt(
|
|
|
|
- Math.pow(bbox.max.x - bbox.min.x, 2.0) +
|
|
|
|
- Math.pow(bbox.max.y - bbox.min.y, 2)
|
|
|
|
- );
|
|
|
|
- const fov2r = camera.fov * 0.5 * (Math.PI / 180.0);
|
|
|
|
- const dz = l2xy / Math.tan(fov2r);
|
|
|
|
-
|
|
|
|
- camera.position.set(bbox.min.x, center_pt.y, bbox.max.z + dz);
|
|
|
|
- controls.target.set(center_pt.x, center_pt.y, center_pt.z);
|
|
|
|
- if (restrict_zoom)
|
|
|
|
- controls.maxDistance = center_pt.distanceTo(bbox.max) * 1.2;
|
|
|
|
- controls.update();
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- function fitViewToObj(obj) {
|
|
|
|
- const bbox = new THREE.Box3().setFromObject(obj);
|
|
|
|
- fitViewToBbox(bbox);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- //改变颜色
|
|
|
|
- function applyVertexColors(buffer_attribute, color, offset, count) {
|
|
|
|
- //buffer_attribute.itemSize颜色宽度
|
|
|
|
- const colors = new Float32Array(count * buffer_attribute.itemSize);
|
|
|
|
- for (
|
|
|
|
- let i = 0; i < count * buffer_attribute.itemSize; i += buffer_attribute.itemSize
|
|
|
|
- ) {
|
|
|
|
- colors[i] = color.r;
|
|
|
|
- colors[i + 1] = color.g;
|
|
|
|
- colors[i + 2] = color.b;
|
|
|
|
- // colors[i] =0;
|
|
|
|
- // colors[i + 1] = 0;
|
|
|
|
- // colors[i + 2] = 255;
|
|
|
|
- }
|
|
|
|
- //根据颜色偏移设置改变颜色值
|
|
|
|
- buffer_attribute.array.set(colors, offset * buffer_attribute.itemSize);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- function getStdMapKeys(std_map, delete_map = false) {
|
|
|
|
- let map_keys = [];
|
|
|
|
- const map_keys_vec = std_map.keys();
|
|
|
|
- for (let idx = 0; idx < map_keys_vec.size(); idx++)
|
|
|
|
- map_keys.push(map_keys_vec.get(idx));
|
|
|
|
- map_keys_vec.delete();
|
|
|
|
- if (delete_map) std_map.delete();
|
|
|
|
- return map_keys;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- function getStdMapEntries(std_map) {
|
|
|
|
- let map_entries = [];
|
|
|
|
- //key路段索引 , std_map.get(key)车道编号
|
|
|
|
- for (let key of getStdMapKeys(std_map)) {
|
|
|
|
- map_entries.push([key, std_map.get(key)]);
|
|
|
|
- }
|
|
|
|
- return map_entries;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- function getStdVecEntries(std_vec, delete_vec = false, ArrayType = null) {
|
|
|
|
- //获取道路网格三位坐标点数据
|
|
|
|
- let entries = ArrayType ?
|
|
|
|
- new ArrayType(std_vec.size()) :
|
|
|
|
- new Array(std_vec.size());
|
|
|
|
- for (let idx = 0; idx < std_vec.size(); idx++) {
|
|
|
|
- entries[idx] = std_vec.get(idx);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (delete_vec) std_vec.delete();
|
|
|
|
- return entries;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- //判断当前拾取颜色是否是道路范围的颜色,否则视为无效拾取
|
|
|
|
- function isValid(rgba) {
|
|
|
|
- return !(rgba[0] == 1 && rgba[1] == 1 && rgba[2] == 1 && rgba[3] == 1);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- //数据压缩
|
|
|
|
- function encodeUInt32(ui32) {
|
|
|
|
- let rgba = new Float32Array(4);
|
|
|
|
- rgba[0] = (Math.trunc(ui32) % 256) / 255;
|
|
|
|
- rgba[1] = (Math.trunc(ui32 / 256) % 256) / 255;
|
|
|
|
- rgba[2] = (Math.trunc(ui32 / 256 / 256) % 256) / 255;
|
|
|
|
- rgba[3] = (Math.trunc(ui32 / 256 / 256 / 256) % 256) / 255;
|
|
|
|
- return rgba;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- //数据还原
|
|
|
|
- function decodeUInt32(rgba) {
|
|
|
|
- return (
|
|
|
|
- Math.round(rgba[0] * 255) +
|
|
|
|
- Math.round(rgba[1] * 255) * 256 +
|
|
|
|
- Math.round(rgba[2] * 255) * 256 * 256 +
|
|
|
|
- Math.round(rgba[3] * 255) * 256 * 256 * 256
|
|
|
|
- );
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- //监听画面变化,更新渲染画面,(自适应的大小)
|
|
|
|
- function onWindowResize() {
|
|
|
|
- camera.aspect = window.innerWidth / window.innerHeight;
|
|
|
|
- camera.updateProjectionMatrix();
|
|
|
|
- renderer.setSize(window.innerWidth, window.innerHeight);
|
|
|
|
- renderer.setPixelRatio(window.devicePixelRatio);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- //记录鼠标位置
|
|
|
|
- function onDocumentMouseMove(event) {
|
|
|
|
- event.preventDefault();
|
|
|
|
- mouse.x = event.clientX;
|
|
|
|
- mouse.y = event.clientY;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- //双击切换选中视角
|
|
|
|
- function onDocumentMouseDbClick(e) {
|
|
|
|
- //判断是否是初始换状态
|
|
|
|
- if (INTERSECTED_LANE_ID != 0xffffffff) {
|
|
|
|
- //获取车道线
|
|
|
|
- const odr_lanes_mesh =
|
|
|
|
- road_network_mesh.userData.odr_road_network_mesh.lanes_mesh;
|
|
|
|
- const lane_vert_idx_interval =
|
|
|
|
- odr_lanes_mesh.get_idx_interval_lane(INTERSECTED_LANE_ID);
|
|
|
|
- //根据索引获取坐标
|
|
|
|
- const vertA = odr_lanes_mesh.vertices.get(lane_vert_idx_interval[0]);
|
|
|
|
- const vertB = odr_lanes_mesh.vertices.get(
|
|
|
|
- lane_vert_idx_interval[1] - 1
|
|
|
|
- );
|
|
|
|
- odr_lanes_mesh.delete();
|
|
|
|
- const bbox = new THREE.Box3();
|
|
|
|
- //flat, 将数组所有元素都降维(一维)
|
|
|
|
- bbox.setFromArray([vertA, vertB].flat());
|
|
|
|
- fitViewToBbox(bbox, false);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- function recordPathPoint(e) {
|
|
|
|
- if (that.startPoint == true) {
|
|
|
|
- if (that.count > 1) {
|
|
|
|
- camera.setViewOffset(
|
|
|
|
- renderer.domElement.width, //画布的宽度
|
|
|
|
- renderer.domElement.height, //画布的高度
|
|
|
|
- mouse.x | 0, //画布坐标系中,相机的x坐标位置
|
|
|
|
- mouse.y | 0, //画布坐标系中,相机的y坐标位置
|
|
|
|
- 1, //副相机的宽度
|
|
|
|
- 1 //副相机的高度
|
|
|
|
- );
|
|
|
|
- renderer.setRenderTarget(xyz_texture);
|
|
|
|
- renderer.render(xyz_scene, camera);
|
|
|
|
- const xyz_pixel_buffer = new Float32Array(4);
|
|
|
|
- renderer.readRenderTargetPixels(
|
|
|
|
- xyz_texture,
|
|
|
|
- 0,
|
|
|
|
- 0,
|
|
|
|
- 1,
|
|
|
|
- 1,
|
|
|
|
- xyz_pixel_buffer
|
|
|
|
- );
|
|
|
|
- //记录webgl坐标
|
|
|
|
- mouse3D[0] = xyz_pixel_buffer[0];
|
|
|
|
- mouse3D[1] = xyz_pixel_buffer[1];
|
|
|
|
- mouse3D[2] = xyz_pixel_buffer[2];
|
|
|
|
- camera.clearViewOffset();
|
|
|
|
- renderer.setRenderTarget(null);
|
|
|
|
- renderer.render(scene, camera);
|
|
|
|
- that.position.push(mouse3D[0], mouse3D[1], mouse3D[2]);
|
|
|
|
- console.log(mouse3D);
|
|
|
|
- let cricle = new THREE.CircleBufferGeometry(0.5, 200);
|
|
|
|
- let metrial = new THREE.MeshBasicMaterial({
|
|
|
|
- color: 0xff0000
|
|
|
|
- })
|
|
|
|
- let mesh = new THREE.Mesh(cricle, metrial);
|
|
|
|
- mesh.position.set(mouse3D[0], mouse3D[1], mouse3D[2] + 0.011)
|
|
|
|
- scene.add(mesh);
|
|
|
|
- } else {
|
|
|
|
- that.count++;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
},
|
|
},
|
|
};
|
|
};
|
|
</script>
|
|
</script>
|