From 5769688f2f4a533e6ebc3b4649f67d89880a82b8 Mon Sep 17 00:00:00 2001 From: Jonathan Lurie Date: Mon, 30 Sep 2024 09:02:47 +0200 Subject: [PATCH] adding point cloud examples --- demos/point_cloud_NMH.html | 165 ++++++++++++++++++++++++++++++++++ demos/point_cloud_dundee.html | 165 ++++++++++++++++++++++++++++++++++ demos/point_cloud_shore.html | 163 +++++++++++++++++++++++++++++++++ src/Layer3D.ts | 39 +++++++- 4 files changed, 530 insertions(+), 2 deletions(-) create mode 100644 demos/point_cloud_NMH.html create mode 100644 demos/point_cloud_dundee.html create mode 100644 demos/point_cloud_shore.html diff --git a/demos/point_cloud_NMH.html b/demos/point_cloud_NMH.html new file mode 100644 index 0000000..6b7254b --- /dev/null +++ b/demos/point_cloud_NMH.html @@ -0,0 +1,165 @@ + + + + MapTiler 3D + + + + + + + + + + + + +
+ + + + diff --git a/demos/point_cloud_dundee.html b/demos/point_cloud_dundee.html new file mode 100644 index 0000000..56760e0 --- /dev/null +++ b/demos/point_cloud_dundee.html @@ -0,0 +1,165 @@ + + + + MapTiler 3D + + + + + + + + + + + + +
+ + + + diff --git a/demos/point_cloud_shore.html b/demos/point_cloud_shore.html new file mode 100644 index 0000000..14e14db --- /dev/null +++ b/demos/point_cloud_shore.html @@ -0,0 +1,163 @@ + + + + MapTiler 3D + + + + + + + + + + + + +
+ + + + diff --git a/src/Layer3D.ts b/src/Layer3D.ts index aa3dc30..1a28d66 100644 --- a/src/Layer3D.ts +++ b/src/Layer3D.ts @@ -21,6 +21,8 @@ import { type ColorRepresentation, AmbientLight, Color, + Points, + PointsMaterial, } from "three"; import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader"; @@ -116,6 +118,12 @@ export type MeshOptions = GenericObject3DOptions & { * Opacity of the mesh */ opacity?: number; + + /** + * Point size, applicable only to point clouds. + * Default: 1 + */ + pointSize?: number; }; /** @@ -376,6 +384,7 @@ export class Layer3D implements CustomLayerInterface { const headingQuaternion = headingToQuaternion(heading); const visible = options.visible ?? true; const opacity = options.opacity ?? 1; + const pointSize = options.pointSize ?? 1; if (opacity !== 1) { this.setMeshOpacity(mesh, opacity, false); @@ -385,6 +394,10 @@ export class Layer3D implements CustomLayerInterface { mesh.scale.set(options.scale, options.scale, options.scale); } + if ("pointSize" in options) { + this.setMeshPointSize(mesh, pointSize); + } + mesh.visible = visible; mesh.setRotationFromQuaternion(headingQuaternion.multiply(sourceOrientationQuaternion)); this.scene.add(mesh); @@ -507,6 +520,10 @@ export class Layer3D implements CustomLayerInterface { this.setMeshOpacity(item.mesh, options.opacity, false); } + if (typeof options.pointSize === "number") { + this.setMeshPointSize(item.mesh, options.pointSize); + } + this.map.triggerRepaint(); } @@ -651,9 +668,9 @@ export class Layer3D implements CustomLayerInterface { /** * Traverse a Mesh/Group/Object3D to modify the opacities of the all the materials it finds */ - private setMeshOpacity(obj: Mesh | Group | Object3D, opacity: number, forceRepaint = false) { + private setMeshOpacity(obj: Mesh | Group | Object3D | Points, opacity: number, forceRepaint = false) { obj.traverse((node) => { - if ("isMesh" in node && node.isMesh === true) { + if (("isMesh" in node && node.isMesh === true) || ("isPoints" in node && node.isPoints === true)) { const mesh = node as Mesh; const materials = Array.isArray(mesh.material) ? mesh.material : [mesh.material]; for (const mat of materials) { @@ -666,6 +683,24 @@ export class Layer3D implements CustomLayerInterface { if (forceRepaint) this.map.triggerRepaint(); } + + /** + * If a mesh is a point cloud, it defines the size of the points + */ + private setMeshPointSize(obj: Mesh | Group | Object3D | Points, size: number, forceRepaint = false) { + obj.traverse((node) => { + if ("isPoints" in node && node.isPoints === true) { + const mesh = node as Points; + const materials = Array.isArray(mesh.material) ? mesh.material : [mesh.material]; + for (const mat of materials) { + (mat as PointsMaterial).size = size; + } + } + }); + + if (forceRepaint) this.map.triggerRepaint(); + } + /** * Adding a point light. The default options are mimicking the sun: * lngLat: `[0, 0]` (null island)