Skip to content

Commit

Permalink
feat(potree): render all nodes
Browse files Browse the repository at this point in the history
  • Loading branch information
belom88 committed Nov 17, 2024
1 parent f1732de commit 3d967f3
Show file tree
Hide file tree
Showing 13 changed files with 302 additions and 43 deletions.
4 changes: 2 additions & 2 deletions examples-experimental/potree/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@
"@deck.gl/layers": "^9.0.32",
"@deck.gl/mesh-layers": "^9.0.32",
"@deck.gl/react": "^9.0.32",
"@loaders.gl/potree": "4.4.0-alpha.0",
"@loaders.gl/loader-utils": "4.4.0-alpha.0",
"@loaders.gl/potree": "4.4.0-alpha.1",
"@loaders.gl/loader-utils": "4.4.0-alpha.1",
"maplibre-gl": "^4.7.1",
"react": "^18.2.0",
"react-dom": "^18.2.0",
Expand Down
16 changes: 8 additions & 8 deletions examples-experimental/potree/src/app.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import React, {useState, useEffect} from 'react';
import React, {useState} from 'react';
import {createRoot} from 'react-dom/client';

import Map from 'react-map-gl/maplibre';
import {Map} from 'react-map-gl/maplibre';
import maplibregl from 'maplibre-gl';
import 'maplibre-gl/dist/maplibre-gl.css';

import DeckGL from '@deck.gl/react';
import {DeckGL} from '@deck.gl/react';
import {MapViewState} from '@deck.gl/core';
import {PotreeSource} from '@loaders.gl/potree';

Expand All @@ -14,14 +14,14 @@ import {PotreeTile3DLayer} from './potree-tile-3d-layer';
export const TRANSITION_DURAITON = 4000;

const INITIAL_VIEW_STATE = {
longitude: -90,
latitude: 34,
longitude: 5.9822,
latitude: 51.805,
pitch: 0,
maxPitch: 90,
bearing: 0,
minZoom: 2,
maxZoom: 30,
zoom: 3
zoom: 15
};

export default function App() {
Expand All @@ -30,6 +30,7 @@ export default function App() {
function renderLayers() {
const layers = new PotreeTile3DLayer({
data: 'https://raw.githubusercontent.com/visgl/deck.gl-data/refs/heads/master/formats/potree/1.8/3dm_32_291_5744_1_nw-converted',
pointSize: 5,
source: PotreeSource
});
return [layers];
Expand All @@ -41,8 +42,7 @@ export default function App() {
<Map
reuseMaps
mapLib={maplibregl}
mapStyle={'https://basemaps.cartocdn.com/gl/dark-matter-nolabels-gl-style/style.json'}
preventStyleDiffing
mapStyle={'https://basemaps.cartocdn.com/gl/voyager-gl-style/style.json'}
preserveDrawingBuffer
/>
</DeckGL>
Expand Down
67 changes: 55 additions & 12 deletions examples-experimental/potree/src/pointcloud-tileset.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import {Vector3} from '@math.gl/core';
import {DataSource} from '@loaders.gl/loader-utils';
import {POTreeNode} from '@loaders.gl/potree';
import {PotreeTraverser} from './potree-traverser';

/** Deck.gl Viewport instance type.
* We can't import it from Deck.gl to avoid circular reference */
Expand All @@ -19,24 +21,35 @@ export type Viewport = {
};

type PointcloudTilesetProps = {
/** Delay time before the tileset traversal. It prevents traversal requests spam.*/
debounceTime: number;
};

const DEFAULT_PROPS: PointcloudTilesetProps = {
debounceTime: 0,
};
/** Delay time before the tileset traversal. It prevents traversal requests spam.*/
debounceTime: number;

onTileLoaded?: (node: POTreeNode) => void;
};

const DEFAULT_PROPS: PointcloudTilesetProps = {
debounceTime: 0
};

export class PointcloudTileset {
private frameNumber: number = 0;
private lastUpdatedVieports: Viewport[] | Viewport | null = null;
private updatePromise: Promise<number> | null = null;
private _selectedNodes: POTreeNode[] = [];
private traverser: PotreeTraverser;

public options: PointcloudTilesetProps;

constructor(public dataSource: DataSource, options?: Partial<PointcloudTilesetProps>) {
// PUBLIC MEMBERS
constructor(
public dataSource: DataSource,
options?: Partial<PointcloudTilesetProps>
) {
this.options = {...DEFAULT_PROPS, ...options};
this.traverser = new PotreeTraverser();

this.dataSource.init().then(() => {
this.traverser.root = this.dataSource.root;
});
}

get isReady() {
Expand All @@ -45,7 +58,7 @@ export class PointcloudTileset {
}

get tiles() {
return [];
return this._selectedNodes;
}

get isLoaded() {
Expand All @@ -61,12 +74,42 @@ export class PointcloudTileset {
if (!this.updatePromise) {
this.updatePromise = new Promise<number>((resolve) => {
setTimeout(() => {
console.log("update viewport");
resolve(this.frameNumber++);
if (this.lastUpdatedVieports) {
this.doUpdate(this.lastUpdatedVieports);
}

resolve(this.frameNumber);
this.updatePromise = null;
}, this.options.debounceTime);
});
}
return this.updatePromise;
}

doUpdate(viewports: Viewport[] | Viewport): void {
const preparedViewports = viewports instanceof Array ? viewports : [viewports];

this.frameNumber++;
this._selectedNodes = this.traverser.traverse(preparedViewports);
this.loadNodesContent(this.traverser.nodesToLoad);
}

loadNodesContent(nodes: POTreeNode[]) {
for (const node of nodes) {
this.loadNodeContent(node);
}
}

async loadNodeContent(node: POTreeNode) {
node.isContentLoading = true;
node.content = await this.dataSource.loadNodeContent(node.name);
this.onTileLoaded(node);
node.isContentLoading = false;
}

onTileLoaded(node: POTreeNode) {
if (this.options.onTileLoaded) {
this.options.onTileLoaded(node);
}
}
}
54 changes: 52 additions & 2 deletions examples-experimental/potree/src/potree-tile-3d-layer.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import {Tile3DLayer, Tile3DLayerProps} from '@deck.gl/geo-layers';
import {UpdateParameters} from '@deck.gl/core/typed';
import {Viewport} from '@deck.gl/core';
import {Viewport, UpdateParameters, COORDINATE_SYSTEM} from '@deck.gl/core';
import {Source} from '@loaders.gl/loader-utils';
import {PointcloudTileset} from './pointcloud-tileset';
import { PointCloudLayer } from '@deck.gl/layers';

export type PotreeTile3DLayerProps = {
source: Source;
Expand Down Expand Up @@ -76,4 +76,54 @@ export class PotreeTile3DLayer<
}
});
}

private _makePointCloudLayer(
tileHeader: Tile3D,
oldLayer?: PointCloudLayer<DataT>
): PointCloudLayer<DataT> | null {
const {
attributes,
pointCount,
constantRGBA,
cartographicOrigin,
modelMatrix,
coordinateSystem = COORDINATE_SYSTEM.METER_OFFSETS
} = tileHeader.content;
const {positions, normals, colors} = attributes;

if (!positions) {
return null;
}
const data = (oldLayer && oldLayer.props.data) || {
header: {
vertexCount: pointCount
},
attributes: {
POSITION: positions,
NORMAL: normals,
COLOR_0: colors
}
};

const {pointSize, getPointColor} = this.props;
const SubLayerClass = this.getSubLayerClass('pointcloud', PointCloudLayer);
return new SubLayerClass(
{
pointSize
},
this.getSubLayerProps({
id: 'pointcloud'
}),
{
id: `${this.id}-pointcloud-${tileHeader.id}`,
tile: tileHeader,
data,
coordinateSystem,
coordinateOrigin: cartographicOrigin,
modelMatrix,
getColor: constantRGBA || getPointColor,
_offset: 0
}
);
}
}
37 changes: 37 additions & 0 deletions examples-experimental/potree/src/potree-traverser.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import {POTreeNode} from "@loaders.gl/potree";

export class PotreeTraverser {
root?: POTreeNode;
nodesToLoad: POTreeNode[] = [];

traverse(viewports: {id: string}[]) {
if (!this.root) {
return [];
}
const viewportIds = viewports.map(item => item.id);

this.nodesToLoad = [];
const result: POTreeNode[] = [];
const stack: POTreeNode[] = [this.root];

while (stack.length > 0) {
const node = stack.pop();

if (!node) {
// eslint-disable-next-line no-continue
continue;
}

for (const child of node?.children ?? []) {
stack.push(child);
}
node.selected = true;
node.viewportIds = viewportIds;
result.push(node);
if (!node.content && !node.isContentLoading) {
this.nodesToLoad.push(node);
}
}
return result;
}
}
6 changes: 5 additions & 1 deletion examples-experimental/potree/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,9 @@
"compilerOptions": {
"jsx": "react-jsx"
},
"include": ["./app.js"]
"include": ["./app.js"],
"baseUrl": "../..",
"paths": {
"@loaders.gl/potree": ["modules/potree/src"]
}
}
2 changes: 1 addition & 1 deletion examples-experimental/potree/vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,6 @@ const getAliases = async (frameworkName, frameworkRootDir) => {

// https://vitejs.dev/config/
export default defineConfig(async () => ({
resolve: {alias: await getAliases('@loaders.gl', `${__dirname}/../../..`)},
resolve: {alias: await getAliases('@loaders.gl', `${__dirname}/../..`)},
server: {open: true}
}));
3 changes: 2 additions & 1 deletion modules/potree/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@
"@loaders.gl/las": "4.4.0-alpha.1",
"@loaders.gl/math": "4.4.0-alpha.1",
"@loaders.gl/schema": "4.4.0-alpha.1",
"@math.gl/core": "^4.1.0"
"@math.gl/core": "^4.1.0",
"@math.gl/proj4": "^4.1.0"
},
"peerDependencies": {
"@loaders.gl/core": "4.4.0-alpha.0"
Expand Down
2 changes: 2 additions & 0 deletions modules/potree/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,5 @@ export {PotreeLoader} from './potree-loader';
export {PotreeHierarchyChunkLoader} from './potree-hierarchy-chunk-loader';
export {PotreeBinLoader} from './potree-bin-loader';
export {PotreeSource} from './potree-source';

export {type POTreeNode} from './parsers/parse-potree-hierarchy-chunk';
Loading

0 comments on commit 3d967f3

Please sign in to comment.