Skip to content

Commit

Permalink
feat(points): Add sizeMode parameter & 3dTiles now also use adaptive …
Browse files Browse the repository at this point in the history
…parameters
  • Loading branch information
Kevin ETOURNEAU committed Aug 25, 2023
1 parent 92d5aaf commit d7fdc3d
Show file tree
Hide file tree
Showing 7 changed files with 94 additions and 12 deletions.
15 changes: 13 additions & 2 deletions src/Layer/C3DTilesLayer.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import GeometryLayer from 'Layer/GeometryLayer';
import { init3dTilesLayer, pre3dTilesUpdate, process3dTilesNode } from 'Process/3dTilesProcessing';
import C3DTileset from 'Core/3DTiles/C3DTileset';
import C3DTExtensions from 'Core/3DTiles/C3DTExtensions';
import { PNTS_MODE } from 'Renderer/PointsMaterial';
import { PNTS_MODE, PNTS_SIZE } from 'Renderer/PointsMaterial';
// eslint-disable-next-line no-unused-vars
import Style from 'Core/Style';
import C3DTFeature from 'Core/3DTiles/C3DTFeature';
Expand Down Expand Up @@ -70,6 +70,10 @@ class C3DTilesLayer extends GeometryLayer {
* removed from the scene.
* @param {C3DTExtensions} [config.registeredExtensions] 3D Tiles extensions managers registered for this tileset.
* @param {String} [config.pntsMode= PNTS_MODE.COLOR] {@link PointsMaterials} Point cloud coloring mode. Only 'COLOR' or 'CLASSIFICATION' are possible. COLOR uses RGB colors of the points, CLASSIFICATION uses a classification property of the batch table to color points.
* @param {String} [config.pntsSize= PNTS_SIZE.VALUE] {@link PointsMaterials} Point cloud size mode. Only 'VALUE' or 'ADAPTIVE' are possible. VALUE use constant size, ADAPTIVE compute size depending on distance from point to camera.
* @param {Number} [config.pntsAdaptiveScale=1] Scale factor used by 'ADAPTIVE' size mode
* @param {Number} [config.pntsMinAdaptiveSize=3] Minimum scale used by 'ADAPTIVE' size mode
* @param {Number} [config.pntsMaxAdaptiveSize=10] Maximum scale used by 'ADAPTIVE' size mode
* @param {Style} [config.style=null] - style used for this layer
* @param {View} view The view
*/
Expand All @@ -84,13 +88,20 @@ class C3DTilesLayer extends GeometryLayer {

this.pntsMode = PNTS_MODE.COLOR;
this.classification = config.classification;

this.pntsSize = PNTS_SIZE.VALUE;
this.pntsAdaptiveScale = config.pntsAdaptiveScale || 1;
this.pntsMinAdaptiveSize = config.pntsMinAdaptiveSize || 3;
this.pntsMaxAdaptiveSize = config.pntsMaxAdaptiveSize || 10;

if (config.pntsMode) {
const exists = Object.values(PNTS_MODE).includes(config.pntsMode);
if (!exists) { console.warn("The points cloud mode doesn't exist. Use 'COLOR' or 'CLASSIFICATION' instead."); } else { this.pntsMode = config.pntsMode; }
}

if (config.pntsSize) {
const exists = Object.values(PNTS_SIZE).includes(config.pntsSize);
if (!exists) { console.warn("The points cloud size doesn't exist. Use 'VALUE' or 'ADAPTIVE' instead."); } else { this.pntsSize = config.pntsSize; }
}

/** @type {Style} */
this._style = config.style || null;
Expand Down
20 changes: 20 additions & 0 deletions src/Layer/ReferencingLayerProperties.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,26 @@ function ReferLayerProperties(material, layer) {
get: () => material.layer.pntsMode,
});
}
if (material.uniforms && material.uniforms.sizeMode != undefined) {
Object.defineProperty(material.uniforms.sizeMode, 'value', {
get: () => material.layer.pntsSize,
});
}
if (material.uniforms && material.uniforms.minAdaptiveSize != undefined) {
Object.defineProperty(material.uniforms.minAdaptiveSize, 'value', {
get: () => material.layer.pntsMinAdaptiveSize,
});
}
if (material.uniforms && material.uniforms.maxAdaptiveSize != undefined) {
Object.defineProperty(material.uniforms.maxAdaptiveSize, 'value', {
get: () => material.layer.pntsMaxAdaptiveSize,
});
}
if (material.uniforms && material.uniforms.adaptiveScale != undefined) {
Object.defineProperty(material.uniforms.adaptiveScale, 'value', {
get: () => material.layer.pntsAdaptiveScale,
});
}

Object.defineProperty(material, 'wireframe', {
get: () => material.layer.wireframe,
Expand Down
10 changes: 9 additions & 1 deletion src/Provider/3dTilesProvider.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,15 @@ function pntsParse(data, layer) {
return PntsParser.parse(data, layer.registeredExtensions).then((result) => {
const material = layer.material ?
layer.material.clone() :
new PointsMaterial({ size: 0.05, mode: layer.pntsMode, classification: layer.classification });
new PointsMaterial({
size: 0.05,
mode: layer.pntsMode,
classification: layer.classification,
sizeMode: layer.pntsSize,
minAdaptiveSize: layer.pntsMinAdaptiveSize,
maxAdaptiveSize: layer.pntsMaxAdaptiveSize,
adaptiveScale: layer.adaptiveScale,
});

// refer material properties in the layer so when layers opacity and visibility is updated, the material is
// automatically updated
Expand Down
27 changes: 22 additions & 5 deletions src/Renderer/PointsMaterial.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@ export const PNTS_MODE = {
NORMAL: 3,
};

export const PNTS_SIZE = {
VALUE: 0,
ADAPTIVE: 1,
};

const white = new THREE.Color(1.0, 1.0, 1.0);

/**
Expand Down Expand Up @@ -53,15 +58,16 @@ class PointsMaterial extends THREE.RawShaderMaterial {
/**
* @class PointsMaterial
* @param {object} [options={}] The options
* @param {number} [options.size=0] size point (adaptive size mode when size is 0)
* @param {number} [options.size=0] size point
* @param {number} [options.mode=PNTS_MODE.COLOR] display mode.
* @param {THREE.Vector4} [options.overlayColor=new THREE.Vector4(0, 0, 0, 0)] overlay color.
* @param {THREE.Vector2} [options.intensityRange=new THREE.Vector2(0, 1)] intensity range.
* @param {boolean} [options.applyOpacityClassication=false] apply opacity classification on all display mode.
* @param {Classification} [options.classification] - define points classification.
* @param {number} [options.minAdaptiveSize=3] min adaptive size point (used only when size is 0)
* @param {number} [options.maxAdaptiveSize=10] max adaptive size point (used only when size is 0)
* @param {number} [options.adaptiveScale=1] adaptive scale factor (used only when size is 0)
* @param {number} [options.sizeMode=SIZE_MODE.VALUE] point cloud size mode. Only 'VALUE' or 'ADAPTIVE' are possible. VALUE use constant size, ADAPTIVE compute size depending on distance from point to camera.
* @param {number} [options.adaptiveScale=1] scale factor used by 'ADAPTIVE' size mode
* @param {number} [options.minAdaptiveSize=3] minimum scale used by 'ADAPTIVE' size mode
* @param {number} [options.maxAdaptiveSize=10] maximum scale used by 'ADAPTIVE' size mode
* @property {Classification} classification - points classification.
*
* @example
Expand All @@ -75,8 +81,12 @@ class PointsMaterial extends THREE.RawShaderMaterial {
const oiMaterial = options.orientedImageMaterial;
const classification = options.classification || ClassificationScheme.DEFAULT;
const applyOpacityClassication = options.applyOpacityClassication == undefined ? false : options.applyOpacityClassication;
const size = options.size || 0;
let size = options.size || 0;
const mode = options.mode || PNTS_MODE.COLOR;
const sizeMode = size === 0 ? PNTS_SIZE.ADAPTIVE : (options.sizeMode || PNTS_SIZE.VALUE);
if ((sizeMode === PNTS_SIZE.ADAPTIVE) && (size !== 0)) {
size = 0;
}
const minAdaptiveSize = options.minAdaptiveSize || 3;
const maxAdaptiveSize = options.maxAdaptiveSize || 10;
const adaptiveScale = options.adaptiveScale || 1;
Expand All @@ -87,6 +97,7 @@ class PointsMaterial extends THREE.RawShaderMaterial {
delete options.applyOpacityClassication;
delete options.size;
delete options.mode;
delete options.sizeMode;
delete options.minAdaptiveSize;
delete options.maxAdaptiveSize;
delete options.adaptiveScale;
Expand All @@ -98,6 +109,7 @@ class PointsMaterial extends THREE.RawShaderMaterial {
this.scale = options.scale || 0.05 * 0.5 / Math.tan(1.0 / 2.0); // autosizing scale

CommonMaterial.setDefineMapping(this, 'PNTS_MODE', PNTS_MODE);
CommonMaterial.setDefineMapping(this, 'PNTS_SIZE', PNTS_SIZE);

CommonMaterial.setUniformProperty(this, 'size', size);
CommonMaterial.setUniformProperty(this, 'mode', mode);
Expand All @@ -106,6 +118,7 @@ class PointsMaterial extends THREE.RawShaderMaterial {
CommonMaterial.setUniformProperty(this, 'overlayColor', options.overlayColor || new THREE.Vector4(0, 0, 0, 0));
CommonMaterial.setUniformProperty(this, 'intensityRange', intensityRange);
CommonMaterial.setUniformProperty(this, 'applyOpacityClassication', applyOpacityClassication);
CommonMaterial.setUniformProperty(this, 'sizeMode', sizeMode);
CommonMaterial.setUniformProperty(this, 'minAdaptiveSize', minAdaptiveSize);
CommonMaterial.setUniformProperty(this, 'maxAdaptiveSize', maxAdaptiveSize);
CommonMaterial.setUniformProperty(this, 'adaptiveScale', adaptiveScale);
Expand Down Expand Up @@ -226,6 +239,10 @@ class PointsMaterial extends THREE.RawShaderMaterial {
this.transparent = source.transparent;
this.size = source.size;
this.mode = source.mode;
this.sizeMode = source.sizeMode;
this.adaptiveScale = source.adaptiveScale;
this.minAdaptiveSize = source.minAdaptiveSize;
this.maxAdaptiveSize = source.maxAdaptiveSize;
this.picking = source.picking;
this.scale = source.scale;
this.overlayColor.copy(source.overlayColor);
Expand Down
7 changes: 4 additions & 3 deletions src/Renderer/Shader/PointsVS.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ attribute vec4 unique_id;
attribute float intensity;
attribute float classification;
uniform sampler2D classificationLUT;
uniform int sizeMode;
uniform float minAdaptiveSize;
uniform float maxAdaptiveSize;
uniform float adaptiveScale;
Expand Down Expand Up @@ -93,7 +94,7 @@ void main() {
vColor.rgb = vec3(i, i, i);
} else if (mode == PNTS_MODE_NORMAL) {
vColor.rgb = abs(normal);
} else if (mode ==PNTS_MODE_COLOR) {
} else if (mode == PNTS_MODE_COLOR) {
// default to color mode
vColor.rgb = mix(color, overlayColor.rgb, overlayColor.a);
}
Expand All @@ -102,9 +103,9 @@ void main() {
#include <begin_vertex>
#include <project_vertex>

if (size > 0.) {
if (sizeMode == PNTS_SIZE_VALUE) {
gl_PointSize = size;
} else {
} else if (sizeMode == PNTS_SIZE_ADAPTIVE) {
gl_PointSize = clamp(-size / gl_Position.w, minAdaptiveSize, maxAdaptiveSize) * adaptiveScale;
}

Expand Down
17 changes: 17 additions & 0 deletions utils/debug/3dTilesDebug.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import * as THREE from 'three';
import View from 'Core/View';
import GeometryLayer from 'Layer/GeometryLayer';
import { PNTS_SIZE } from 'Renderer/PointsMaterial';
import GeometryDebug from './GeometryDebug';
import OBBHelper from './OBBHelper';

Expand Down Expand Up @@ -112,4 +113,20 @@ export default function create3dTilesDebugUI(datDebugTool, view, _3dTileslayer)
gui.add(_3dTileslayer, 'sseThreshold', 0, 100).name('sseThreshold').onChange(() => {
view.notifyChange(view.camera.camera3D);
});

gui.add(_3dTileslayer, 'pntsSize', PNTS_SIZE).name('Pnts size mode').onChange(() => {
view.notifyChange(view.camera.camera3D);
});

gui.add(_3dTileslayer, 'pntsAdaptiveScale', 0, 15).name('Adptive scale').onChange(() => {
view.notifyChange(view.camera.camera3D);
});

gui.add(_3dTileslayer, 'pntsMinAdaptiveSize', 0, 15).name('Min adptive size').onChange(() => {
view.notifyChange(view.camera.camera3D);
});

gui.add(_3dTileslayer, 'pntsMaxAdaptiveSize', 0, 15).name('Max adptive size').onChange(() => {
view.notifyChange(view.camera.camera3D);
});
}
10 changes: 9 additions & 1 deletion utils/debug/PotreeDebug.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { PNTS_MODE } from 'Renderer/PointsMaterial';
import { PNTS_MODE, PNTS_SIZE } from 'Renderer/PointsMaterial';

export default {
initTools(view, layer, datUi) {
Expand Down Expand Up @@ -26,6 +26,14 @@ export default {
}
styleUI.add(layer, 'opacity', 0, 1).name('Layer Opacity').onChange(update);
styleUI.add(layer, 'pointSize', 0, 15).name('Point Size').onChange(update);
if (layer.material.sizeMode != undefined) {
styleUI.add(layer.material, 'sizeMode', PNTS_SIZE).name('Point size mode').onChange(() => {
if (layer.material.sizeMode == PNTS_SIZE.ADAPTIVE) {
layer.pointSize = 0;
}
update();
});
}
styleUI.add(layer.material, 'adaptiveScale', 0, 15).name('Adaptive scale').onChange(update);
styleUI.add(layer.material, 'minAdaptiveSize', 0, 15).name('Min adaptive size').onChange(update);
styleUI.add(layer.material, 'maxAdaptiveSize', 0, 15).name('Max adaptive size').onChange(update);
Expand Down

0 comments on commit d7fdc3d

Please sign in to comment.