import * as THREE from "three"; import { OrbitControls } from "three/examples/jsm/controls/OrbitControls"; import { RGBELoader } from "three/examples/jsm/loaders/RGBELoader"; import { Reflector } from "three/examples/jsm/objects/Reflector"; import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader"; import { DRACOLoader } from "three/examples/jsm/loaders/DRACOLoader"; import { Line2 } from "three/examples/jsm/lines/Line2"; // import gsap from "gsap"; // import * as CANNON from "cannon-es"; import * as echarts from "echarts"; export let openDriveMixin = { data() { return { ModuleOpenDrive: null, OpenDriveMap: null, INTERSECTED_LANE_ID: 0xffffffff, INTERSECTED_ROADMARK_ID: 0xffffffff, refline_material: null, lane_outlines_material: null, roadmark_outlines_material: null, disposable_objs: [], id_material: null, xyz_material: null, st_material: null, roadmarks_material: null, road_objects_material: null, road_network_material: null, lane_picking_scene: null, roadmark_picking_scene: null, xyz_scene: null, st_scene: null, lane_picking_texture: null, roadmark_picking_texture: null, xyz_texture: null, st_texture: null, controls: null, ground_grid: null, road_network_mesh: null, roadmarks_mesh: null, road_objects_mesh: null, refline_lines: null, lane_outline_lines: null, roadmark_outline_lines: null, COLORS: { road: 1.0, roadmark: 1.0, road_object: 0.9, lane_outline: 0x444444, roadmark_outline: 0xffffff, ref_line: 0x444444, background: 0x444444, lane_highlight: 0xff3030, roadmark_highlight: 0x2F4F4F, }, renderer: null, scene: null, camera: null, light: null, 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, ], startAndEndPoints: [], mappingLineId: new Map() } }, created() { }, mounted() { this.init(); // this.loadMap("/map/mine4.xodr"); }, methods: { drawPoint(point) { let arr = this.startAndEndPoints; if (arr.length != 0) { for (let elem of arr) { if (elem.point.type == point.type) { let index = arr.indexOf(elem); if (index !== -1) { arr = [...arr.slice(0, index), ...arr.slice(index + 1)]; } this.scene.remove(elem.target); } } } const group = new THREE.Group(); let cricle = new THREE.CircleBufferGeometry(5, 200); let metrial = new THREE.MeshBasicMaterial({ color: 0xff0000 }) let mesh = new THREE.Mesh(cricle, metrial); group.add(mesh); let texture = new THREE.CanvasTexture(this.getTextCanvas(point.name)); let material = new THREE.SpriteMaterial({ map: texture }); let sprite = new THREE.Sprite(material); sprite.position.set(0, 0, 2); group.add(sprite); group.position.set(point.x - this.OpenDriveMap.x_offs, point.y - this.OpenDriveMap.y_offs, 0.015) this.scene.add(group); this.startAndEndPoints.push({ target: group, point: point }); }, clearPoint() { if (this.startAndEndPoints.length != 0) { for (let elem of this.startAndEndPoints) { this.scene.remove(elem.target); } } }, clearMappingId() { this.mappingLineId = new Map(); }, loadMap(url) { libOpenDrive().then((Module) => { this.ModuleOpenDrive = Module; fetch(url).then( (file_data) => { file_data.text().then((file_text) => { //加载数据文件 this.loadFile(file_text, false); }); } ); }); }, reloadOdrMap() { if (this.OpenDriveMap) this.OpenDriveMap.delete(); this.OpenDriveMap = new this.ModuleOpenDrive.OpenDriveMap( "./data.xodr", PARAMS.lateralProfile, PARAMS.laneHeight, true ); this.loadOdrMap(true, false); }, reloadNewMap(url) { this.clearPoint(); this.clearMappingId(); fetch(url, {}).then(response => response.blob()).then(blob => { const file = new File([blob], "map.xodr", { type: "text/plain", }); this.onFileSelect(file); }) }, onFileSelect(file) { let file_reader = new FileReader(); file_reader.onload = () => { this.loadFile(file_reader.result, true); }; file_reader.readAsText(file); }, loadFile(file_text, clear_map) { //清除文件系统中保存的文件节点 if (clear_map) this.ModuleOpenDrive["FS_unlink"]("./data.xodr"); //将文件数据转为节点保存到文件系统本地指定的文件目录,支持读写 this.ModuleOpenDrive["FS_createDataFile"]( ".", "data.xodr", file_text, true, true ); //OpenDriveMap不为null,则已经打开过,需要删除地图重新尝试打开 if (this.OpenDriveMap) this.OpenDriveMap.delete(); //打开驱动地图 this.OpenDriveMap = new this.ModuleOpenDrive.OpenDriveMap( "./data.xodr", PARAMS.lateralProfile, PARAMS.laneHeight, true ); //this.drawPoint(); this.loadOdrMap(clear_map); }, loadOdrMap(clear_map = true, fit_view = true) { if (clear_map) { this.road_network_mesh.userData.odr_road_network_mesh.delete(); this.scene.remove( this.road_network_mesh, this.roadmarks_mesh, this.road_objects_mesh, this.refline_lines, this.lane_outline_lines, this.roadmark_outline_lines, this.ground_grid ); this.lane_picking_scene.remove(...this.lane_picking_scene.children); this.roadmark_picking_scene.remove(...this.roadmark_picking_scene.children); this.xyz_scene.remove(...this.xyz_scene.children); this.st_scene.remove(...this.st_scene.children); for (let obj of this.disposable_objs) obj.dispose(); } //web浏览器内置api,精度微秒级,performance.now是浏览器(Web API)提供的方法,不同浏览器获取到的精度不同。Date.now是Javascript内置方法,差异主要在于浏览器遵循的ECMAScript规范。 const t0 = performance.now(); //是否清除地图 /** * 道路中间s方向的线 */ //获取参考线矩形几何体 const reflines_geom = new THREE.BufferGeometry(); //获取驱动中参考线数据信息 const odr_refline_segments = this.OpenDriveMap.get_refline_segments( parseFloat(PARAMS.resolution) ); //设置参考线坐标点 reflines_geom.setAttribute( "position", new THREE.Float32BufferAttribute( this.getStdVecEntries(odr_refline_segments.vertices).flat(), 3 ) ); //设置参考线坐标点索引 reflines_geom.setIndex( this.getStdVecEntries(odr_refline_segments.indices, true) ); //创建参考线物体 let refline_lines = new THREE.LineSegments(reflines_geom, this.refline_material); this.refline_lines = refline_lines; refline_lines.renderOrder = 10; //设置是否可见 refline_lines.visible = PARAMS.ref_line; refline_lines.matrixAutoUpdate = false; this.disposable_objs.push(reflines_geom); //将参考线加入场景中 this.scene.add(refline_lines); /* *道路面 */ //根据细节级别获取道路网格物体PARAMS.resolution 默认0.3中等级别 const odr_road_network_mesh = this.OpenDriveMap.get_mesh( parseFloat(PARAMS.resolution) ); //获取所有路段的车道(车道id为 -2, -1, 0, 1, 2) const odr_lanes_mesh = odr_road_network_mesh.lanes_mesh; //收集映射 for (const [vert_start_idx, lineId] of this.getStdMapEntries(odr_lanes_mesh.lane_start_indices)) { const road_id = odr_lanes_mesh.get_road_id(vert_start_idx); this.mappingLineId.set(road_id + ":" + lineId, vert_start_idx); } //获取所有路段车道点集构建道路物体 const road_network_geom = this.get_geometry(odr_lanes_mesh); //设置道路颜色 road_network_geom.attributes.color.array.fill(this.COLORS.road); //获取所有路段的车道的起始位置索引 //将索引作为车道开始和结束信息 for (const [vert_start_idx, _] of this.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 = this.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 ); } this.disposable_objs.push(road_network_geom); let road_network_mesh = new THREE.Mesh( road_network_geom, this.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"); this.scene.add(road_network_mesh); this.road_network_mesh = road_network_mesh; /** * 选中被选中的车道进行离屏渲染 */ const lane_picking_mesh = new THREE.Mesh(road_network_geom, this.id_material); lane_picking_mesh.matrixAutoUpdate = false; this.lane_picking_scene.add(lane_picking_mesh); /* xyz coords road network mesh */ let xyz_mesh = new THREE.Mesh(road_network_geom, this.xyz_material); xyz_mesh.matrixAutoUpdate = false; this.xyz_scene.add(xyz_mesh); /* st coords road network mesh */ const st_mesh = new THREE.Mesh(road_network_geom, this.st_material); st_mesh.matrixAutoUpdate = false; this.st_scene.add(st_mesh); /** * 车道线宽度区域填充,由于车道线有宽度,宽度区域颜色填充 */ const odr_roadmarks_mesh = odr_road_network_mesh.roadmarks_mesh; const roadmarks_geom = this.get_geometry(odr_roadmarks_mesh); roadmarks_geom.attributes.color.array.fill(this.COLORS.roadmark); for (const [vert_start_idx, _] of this.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 = this.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 ); } this.disposable_objs.push(roadmarks_geom); /* roadmarks mesh */ let roadmarks_mesh = new THREE.Mesh(roadmarks_geom, this.roadmarks_material); this.roadmarks_mesh = roadmarks_mesh; roadmarks_mesh.matrixAutoUpdate = false; roadmarks_mesh.visible = !(PARAMS.view_mode == "Outlines") && PARAMS.roadmarks; this.scene.add(roadmarks_mesh); //离屏渲染车道线宽度区域 const roadmark_picking_mesh = new THREE.Mesh(roadmarks_geom, this.id_material); roadmark_picking_mesh.matrixAutoUpdate = false; this.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 = this.get_geometry(odr_road_objects_mesh); road_objects_geom.attributes.color.array.fill(this.COLORS.road_object); for (const [vert_start_idx, _] of this.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 = this.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 ); } this.disposable_objs.push(road_objects_geom); /* road objects mesh */ let road_objects_mesh = new THREE.Mesh( road_objects_geom, this.road_objects_material ); this.road_objects_mesh = road_objects_mesh; road_objects_mesh.matrixAutoUpdate = false; this.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( this.getStdVecEntries(odr_lanes_mesh.get_lane_outline_indices(), true) ); let lane_outline_lines = new THREE.LineSegments( lane_outlines_geom, this.lane_outlines_material ); this.lane_outline_lines = lane_outline_lines; lane_outline_lines.renderOrder = 9; this.disposable_objs.push(lane_outlines_geom); this.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( this.getStdVecEntries( odr_roadmarks_mesh.get_roadmark_outline_indices(), true ) ); let roadmark_outline_lines = new THREE.LineSegments( roadmark_outlines_geom, this.roadmark_outlines_material ); this.roadmark_outline_lines = roadmark_outline_lines; roadmark_outline_lines.renderOrder = 8; roadmark_outline_lines.matrixAutoUpdate = false; this.disposable_objs.push(roadmark_outlines_geom); roadmark_outline_lines.visible = PARAMS.roadmarks; this.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); this.camera.far = max_diag_dist * 1.5; //controls.autoRotate = fit_view; this.camera.position.set(0, 0, max_diag_dist/3); // if (fit_view) { // this.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); let ground_grid = new THREE.GridHelper( max_diag_dist * 6, max_diag_dist / 10, 0x2f4f4f, 0x2f4f4f ); // console.log(THREE.InfiniteGridHelper) // let ground_grid = THREE.InfiniteGridHelper(10, 10, new THREE.Color(0x2f4f4f), 500); this.ground_grid = ground_grid; 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 ); this.disposable_objs.push(ground_grid.geometry); this.scene.add(ground_grid); // const rgbeLoader = new RGBELoader(); // rgbeLoader.loadAsync("hdr/index8.hdr").then((loader) => { // loader.needsUpdate = true; // loader.mapping = THREE.EquirectangularRefractionMapping; // loader.encoding = THREE.RGBEEncoding; //设置编码属性的值 // loader.mapping = THREE.EquirectangularRefractionMapping; // loader.minFilter = THREE.NearestFilter; //当一个纹素覆盖小于一个像素时,贴图将如何采样 // loader.magFilter = THREE.NearestFilter; //当一个纹素覆盖大于一个像素时,贴图将如何采样 // loader.flipY = true; //翻转图像的Y轴以匹配WebGL纹理坐标空间 // // this.scene.background = new THREE.Color(0x2F4F4F); // const sphereGeometry = new THREE.SphereBufferGeometry(max_diag_dist, 100, 100); // 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; // this.scene.add(sphereMesh); // }); // this.scene.environment = new THREE.Color(0x2F4F4F); /** * 灯光 */ this.light.position.set( bbox_reflines.min.x, bbox_reflines.min.y, bbox_reflines.max.z + max_diag_dist ); this.light.target.position.set( bbox_center_pt.x, bbox_center_pt.y, bbox_center_pt.z ); this.light.position.needsUpdate = true; this.light.target.position.needsUpdate = true; this.light.target.updateMatrixWorld(); // const t1 = performance.now(); // console.log( // "Heap size: " + this.ModuleOpenDrive.HEAP8.length / 1024 / 1024 + " mb" // ); //删除数据冗余,避免造成内存泄漏 odr_roadmarks_mesh.delete(); odr_lanes_mesh.delete(); this.animate(); }, initThreeJs() { // THREE.vertexColors = true; //创建渲染器 this.renderer = new THREE.WebGLRenderer({ antialias: true, //抗锯齿,防失真 sortObjects: false, //定义渲染器是否应对对象进行排序 //对数深度缓冲区,防止模型闪烁 logarithmicdepthbuffer: true, }); //开启投影阴影 this.renderer.shadowMap.enabled = true; //设置渲染器渲染区域 this.renderer.setSize(window.innerWidth, window.innerHeight); //渲染 document.getElementById("ThreeJS").appendChild(this.renderer.domElement); //创建场景 this.scene = new THREE.Scene(); //创建透视相机 this.camera = new THREE.PerspectiveCamera( 100, window.innerWidth / window.innerHeight, 0.1, 100000 ); //让Z轴朝上+ this.camera.up.set(0, 0, 1); //创建控制器 this.controls = new OrbitControls(this.camera, this.renderer.domElement); //const controls = new THREE.OrbControls(camera, renderer.domElement); // this.controls.addEventListener("start", () => { // /** // * 拖动开始停止开启聚集光和停止旋转 // */ // spotlight_paused = true; //聚集光暂停 // //controls.autoRotate = false; //是否旋转 // }); // this.controls.addEventListener("end", () => { // //拖动结束聚集光关闭并且开启旋转 // spotlight_paused = false; //聚集光开始 // //将其设为true,以自动围绕目标旋转。请注意,如果它被启用,你必须在你的动画循环里调用 // // controls.autoRotate = true;//开启旋转 // }); // controls.autoRotate = true; //开启旋转 //创建平行光 this.light; for (let index = 0; index < this.lights.length / 2; index++) { this.light = new THREE.DirectionalLight(0xffffff, 0.6); this.light.position.set(this.lights[2 * index], this.lights[2 * index + 1], 5); this.scene.add(this.light); //平行光方向指向原点(0,0,0) this.scene.add(this.light.target); } window.addEventListener("resize", this.onWindowResize, false); }, initOffscreen() { //选择车道线场景 this.lane_picking_scene = new THREE.Scene(); //车道线场景背景颜色 this.lane_picking_scene.background = new THREE.Color(0xffffff); //路标场景 this.roadmark_picking_scene = new THREE.Scene(); //路标场景背景颜色 this.roadmark_picking_scene.background = new THREE.Color(0xffffff); //坐标场景 this.xyz_scene = new THREE.Scene(); //坐标场景背景颜色 this.xyz_scene.background = new THREE.Color(0xffffff); this.st_scene = new THREE.Scene(); this.st_scene.background = new THREE.Color(0xffffff); //创建渲染器 this.lane_picking_texture = new THREE.WebGLRenderTarget(1, 1, { type: THREE.FloatType, }); this.roadmark_picking_texture = new THREE.WebGLRenderTarget(1, 1, { type: THREE.FloatType, }); this.xyz_texture = new THREE.WebGLRenderTarget(1, 1, { type: THREE.FloatType, }); this.st_texture = new THREE.WebGLRenderTarget(1, 1, { type: THREE.FloatType, }); }, initMaterial() { //获取顶点着色器 const idVertexShader = document.getElementById("idVertexShader").textContent; 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; //设置车道中轴线颜色 this.refline_material = new THREE.LineBasicMaterial({ color: this.COLORS.ref_line, //color: 0x0000ff, }); //道路线 this.lane_outlines_material = new THREE.LineBasicMaterial({ color: this.COLORS.lane_outline, }); //外侧线 this.roadmark_outlines_material = new THREE.LineBasicMaterial({ color: this.COLORS.roadmark_outline, }); this.id_material = new THREE.ShaderMaterial({ vertexShader: idVertexShader, fragmentShader: idFragmentShader, }); this.xyz_material = new THREE.ShaderMaterial({ vertexShader: xyzVertexShader, fragmentShader: xyzFragmentShader, }); this.st_material = new THREE.ShaderMaterial({ vertexShader: stVertexShader, fragmentShader: stFragmentShader, }); this.roadmarks_material = new THREE.MeshBasicMaterial({ vertexColors: true, }); this.road_objects_material = new THREE.MeshBasicMaterial({ vertexColors: true, side: THREE.DoubleSide, wireframe: true, }); this.road_network_material = new THREE.MeshPhongMaterial({ vertexColors: THREE.VertexColors, wireframe: PARAMS.wireframe, //显示现况 shininess: 20.0, transparent: true, opacity: 0.4, }); }, animate() { //控制电脑帧频,防止刷屏过快导致的页面刷3D数据刷新过快 控制每秒30次 setTimeout(() => { window.requestAnimationFrame(this.animate); }, 1000 / 30); this.controls.update(); this.camera.setViewOffset( this.renderer.domElement.width, //画布的宽度 this.renderer.domElement.height, //画布的高度 (this.renderer.domElement.width / 2) | 0, //画布坐标系中,相机的x坐标位置 (this.renderer.domElement.height / 2) | 0, //画布坐标系中,相机的y坐标位置 1, //副相机的宽度 1 //副相机的高度 ); //离屏渲染 this.renderer.setRenderTarget(this.lane_picking_texture); this.renderer.render(this.lane_picking_scene, this.camera); this.renderer.setRenderTarget(this.roadmark_picking_texture); this.renderer.render(this.roadmark_picking_scene, this.camera); this.renderer.setRenderTarget(this.xyz_texture); this.renderer.render(this.xyz_scene, this.camera); this.renderer.setRenderTarget(this.st_texture); this.renderer.render(this.st_scene, this.camera); const lane_id_pixel_buffer = new Float32Array(4); this.renderer.readRenderTargetPixels( this.lane_picking_texture, 0, 0, 1, 1, this.lane_id_pixel_buffer ); const roadmark_id_pixel_buffer = new Float32Array(4); this.renderer.readRenderTargetPixels( this.roadmark_picking_texture, 0, 0, 1, 1, this.roadmark_id_pixel_buffer ); const xyz_pixel_buffer = new Float32Array(4); this.renderer.readRenderTargetPixels( this.xyz_texture, 0, 0, 1, 1, this.xyz_pixel_buffer ); xyz_pixel_buffer[0] += this.OpenDriveMap.x_offs; xyz_pixel_buffer[1] += this.OpenDriveMap.y_offs; const st_pixel_buffer = new Float32Array(4); this.renderer.readRenderTargetPixels( this.st_texture, 0, 0, 1, 1, this.st_pixel_buffer ); this.camera.clearViewOffset(); this.renderer.setRenderTarget(null); if (this.isValid(lane_id_pixel_buffer) && false) { const decoded_lane_id = this.decodeUInt32(lane_id_pixel_buffer); const odr_lanes_mesh = this.road_network_mesh.userData.odr_road_network_mesh.lanes_mesh; if (this.INTERSECTED_LANE_ID != decoded_lane_id) { if (this.INTERSECTED_LANE_ID != 0xffffffff) { this.road_network_mesh.geometry.attributes.color.array.fill( this.COLORS.road ); } this.INTERSECTED_LANE_ID = decoded_lane_id; const lane_vert_idx_interval = odr_lanes_mesh.get_idx_interval_lane(this.INTERSECTED_LANE_ID); const vert_count = lane_vert_idx_interval[1] - lane_vert_idx_interval[0]; this.applyVertexColors( this.road_network_mesh.geometry.attributes.color, new THREE.Color(this.COLORS.lane_highlight), lane_vert_idx_interval[0], vert_count ); this.road_network_mesh.geometry.attributes.color.needsUpdate = true; } odr_lanes_mesh.delete(); } else { if (this.INTERSECTED_LANE_ID != 0xffffffff) { const odr_lanes_mesh = this.road_network_mesh.userData.odr_road_network_mesh.lanes_mesh; const lane_vert_idx_interval = odr_lanes_mesh.get_idx_interval_lane(this.INTERSECTED_LANE_ID); this.road_network_mesh.geometry.attributes.color.array.fill(this.COLORS.road); this.road_network_mesh.geometry.attributes.color.needsUpdate = true; odr_lanes_mesh.delete(); this.INTERSECTED_LANE_ID = 0xffffffff; } } if (this.isValid(roadmark_id_pixel_buffer)) { //获取 const decoded_roadmark_id = this.decodeUInt32(roadmark_id_pixel_buffer); const odr_roadmarks_mesh = this.road_network_mesh.userData.odr_road_network_mesh.roadmarks_mesh; if (this.INTERSECTED_ROADMARK_ID != decoded_roadmark_id) { if (this.INTERSECTED_ROADMARK_ID != 0xffffffff) { const prev_roadmark_vert_idx_interval = odr_roadmarks_mesh.get_idx_interval_roadmark( this.INTERSECTED_ROADMARK_ID ); this.roadmarks_mesh.geometry.attributes.color.array.fill( this.COLORS.roadmark, prev_roadmark_vert_idx_interval[0] * 3, prev_roadmark_vert_idx_interval[1] * 3 ); } this.INTERSECTED_ROADMARK_ID = decoded_roadmark_id; const roadmark_vert_idx_interval = odr_roadmarks_mesh.get_idx_interval_roadmark( this.INTERSECTED_ROADMARK_ID ); const vert_count = roadmark_vert_idx_interval[1] - roadmark_vert_idx_interval[0]; this.applyVertexColors( this.roadmarks_mesh.geometry.attributes.color, new THREE.Color(this.COLORS.roadmark_highlight), roadmark_vert_idx_interval[0], vert_count ); this.roadmarks_mesh.geometry.attributes.color.needsUpdate = true; } odr_roadmarks_mesh.delete(); } else { if (this.INTERSECTED_ROADMARK_ID != 0xffffffff) { const odr_roadmarks_mesh = this.road_network_mesh.userData.odr_road_network_mesh.roadmarks_mesh; const roadmark_vert_idx_interval = odr_roadmarks_mesh.get_idx_interval_lane(this.INTERSECTED_ROADMARK_ID); this.roadmarks_mesh.geometry.attributes.color.array.fill( this.COLORS.roadmark, roadmark_vert_idx_interval[0] * 3, roadmark_vert_idx_interval[1] * 3 ); this.roadmarks_mesh.geometry.attributes.color.needsUpdate = true; this.INTERSECTED_ROADMARK_ID = 0xffffffff; odr_roadmarks_mesh.delete(); } } if (this.INTERSECTED_LANE_ID != 0xffffffff) { const odr_lanes_mesh = this.road_network_mesh.userData.odr_road_network_mesh.lanes_mesh; const road_id = odr_lanes_mesh.get_road_id(this.INTERSECTED_LANE_ID); const lanesec_s0 = odr_lanes_mesh.get_lanesec_s0(this.INTERSECTED_LANE_ID); const lane_id = odr_lanes_mesh.get_lane_id(this.INTERSECTED_LANE_ID); const lane_type = this.OpenDriveMap.roads .get(road_id) .s_to_lanesection.get(lanesec_s0) .id_to_lane.get(lane_id).type; odr_lanes_mesh.delete(); } this.renderer.render(this.scene, this.camera); }, fillColorLine(roadId, lineId) { lineId = this.mappingLineId.get(roadId + ":" + lineId); const odr_lanes_mesh = this.road_network_mesh.userData.odr_road_network_mesh.lanes_mesh; const lane_vert_idx_interval = odr_lanes_mesh.get_idx_interval_lane(lineId); const vert_count = (lane_vert_idx_interval[1] - lane_vert_idx_interval[0]); this.applyVertexColors(this.road_network_mesh.geometry.attributes.color, new THREE.Color(this.COLORS .lane_highlight), lane_vert_idx_interval[0], vert_count); this.road_network_mesh.geometry.attributes.color.needsUpdate = true; odr_lanes_mesh.delete(); }, clearColorLine(roadId, lineId) { lineId = this.mappingLineId.get(roadId + ":" + lineId); const odr_lanes_mesh = this.road_network_mesh.userData.odr_road_network_mesh.lanes_mesh; const lane_vert_idx_interval = odr_lanes_mesh.get_idx_interval_lane(lineId); const vert_count = (lane_vert_idx_interval[1] - lane_vert_idx_interval[0]); this.road_network_mesh.geometry.attributes.color.array.fill( this.COLORS.road ); this.road_network_mesh.geometry.attributes.color.needsUpdate = true; odr_lanes_mesh.delete(); }, onWindowResize() { this.camera.aspect = window.innerWidth / window.innerHeight; this.camera.updateProjectionMatrix(); this.renderer.setSize(window.innerWidth, window.innerHeight); this.renderer.setPixelRatio(window.devicePixelRatio); }, init(){ this.initThreeJs(); this.initOffscreen(); this.initMaterial(); } } }