From 318ec91a236d16b9ed2905508ded4d1ca0f58424 Mon Sep 17 00:00:00 2001 From: Yugam Dhuriya Date: Thu, 28 Sep 2023 02:33:30 +0530 Subject: [PATCH] Added remaining color types for PNTS (#391) * Added rgb565torgb function in utils * Added rgba, rgb565 and constant_rgba support * Added a check for opacity if it is less than one * Updated rgb565torgb to a simpler unpacking * Added info for rgb565 unpacking * Disable depth write when setting transparency * Small style changes --------- Co-authored-by: Garrett Johnson --- src/three/PNTSLoader.js | 47 +++++++++++++++++++++++++++++++++--- src/utilities/rgb565torgb.js | 22 +++++++++++++++++ 2 files changed, 65 insertions(+), 4 deletions(-) create mode 100644 src/utilities/rgb565torgb.js diff --git a/src/three/PNTSLoader.js b/src/three/PNTSLoader.js index 058155c5f..eb3632dec 100644 --- a/src/three/PNTSLoader.js +++ b/src/three/PNTSLoader.js @@ -6,7 +6,9 @@ import { BufferAttribute, DefaultLoadingManager, Vector3, + Color, } from 'three'; +import { rgb565torgb } from '../utilities/rgb565torgb.js'; const DRACO_ATTRIBUTE_MAP = { RGB: 'color', @@ -81,6 +83,9 @@ export class PNTSLoader extends PNTSLoaderBase { const POINTS_LENGTH = featureTable.getData( 'POINTS_LENGTH' ); const POSITION = featureTable.getData( 'POSITION', POINTS_LENGTH, 'FLOAT', 'VEC3' ); const RGB = featureTable.getData( 'RGB', POINTS_LENGTH, 'UNSIGNED_BYTE', 'VEC3' ); + const RGBA = featureTable.getData( 'RGBA', POINTS_LENGTH, 'UNSIGNED_BYTE', 'VEC4' ); + const RGB565 = featureTable.getData( 'RGB565', POINTS_LENGTH, 'UNSIGNED_SHORT', 'SCALAR' ); + const CONSTANT_RGBA = featureTable.getData( 'CONSTANT_RGBA', POINTS_LENGTH, 'UNSIGNED_BYTE', 'VEC4' ); const POSITION_QUANTIZED = featureTable.getData( 'POSITION_QUANTIZED', POINTS_LENGTH, 'UNSIGNED_SHORT', 'VEC3' ); const QUANTIZED_VOLUME_SCALE = featureTable.getData( 'QUANTIZED_VOLUME_SCALE', POINTS_LENGTH, 'FLOAT', 'VEC3' ); const QUANTIZED_VOLUME_OFFSET = featureTable.getData( 'QUANTIZED_VOLUME_OFFSET', POINTS_LENGTH, 'FLOAT', 'VEC3' ); @@ -111,20 +116,54 @@ export class PNTSLoader extends PNTSLoaderBase { } - if ( RGB !== null ) { + if ( RGBA !== null ) { + + geometry.setAttribute( 'color', new BufferAttribute( RGBA, 4, true ) ); + material.vertexColors = true; + material.transparent = true; + material.depthWrite = false; + + } else if ( RGB !== null ) { geometry.setAttribute( 'color', new BufferAttribute( RGB, 3, true ) ); material.vertexColors = true; + } else if ( RGB565 !== null ) { + + const color = new Uint8Array( POINTS_LENGTH * 3 ); + for ( let i = 0; i < POINTS_LENGTH; i ++ ) { + + const rgbColor = rgb565torgb( RGB565[ i ] ); + for ( let j = 0; j < 3; j ++ ) { + + const index = 3 * i + j; + color[ index ] = rgbColor[ j ]; + + } + + } + geometry.setAttribute( 'color', new BufferAttribute( color, 3, true ) ); + material.vertexColors = true; + + } else if ( CONSTANT_RGBA !== null ) { + + const color = new Color( CONSTANT_RGBA[ 0 ], CONSTANT_RGBA[ 1 ], CONSTANT_RGBA[ 2 ] ); + material.color = color; + const opacity = CONSTANT_RGBA[ 3 ] / 255; + if ( opacity < 1 ) { + + material.opacity = opacity; + material.transparent = true; + material.depthWrite = false; + + } + } } [ - 'CONSTANT_RGBA', 'BATCH_LENGTH', - 'RGBA', - 'RGB565', 'NORMAL', 'NORMAL_OCT16P', ].forEach( ( feature ) => { diff --git a/src/utilities/rgb565torgb.js b/src/utilities/rgb565torgb.js new file mode 100644 index 000000000..461656c3e --- /dev/null +++ b/src/utilities/rgb565torgb.js @@ -0,0 +1,22 @@ +// The implementation of rgb565 to rgb888 is from +// https://rgbcolorpicker.com/565 + +export function rgb565torgb( rgb565 ) { + + // Shift the red value to the right by 11 bits. + const red5 = rgb565 >> 11; + // Shift the green value to the right by 5 bits and extract the lower 6 bits. + const green6 = ( rgb565 >> 5 ) & 0b111111; + // Extract the lower 5 bits. + const blue5 = rgb565 & 0b11111; + + // Convert 5-bit red to 8-bit red. + const red8 = Math.round( ( red5 / 31 ) * 255 ); + // Convert 6-bit green to 8-bit green. + const green8 = Math.round( ( green6 / 63 ) * 255 ); + // Convert 5-bit blue to 8-bit blue. + const blue8 = Math.round( ( blue5 / 31 ) * 255 ); + + return [ red8, green8, blue8 ]; + +}