xzw 2 hónapja
szülő
commit
b2413982a8
2 módosított fájl, 377 hozzáadás és 13 törlés
  1. 1 1
      src/custom/viewer/ViewerNew.js
  2. 376 12
      src/workers/BinaryDecoderWorker.js

+ 1 - 1
src/custom/viewer/ViewerNew.js

@@ -6025,7 +6025,7 @@ export class Viewer extends ViewerBase{
                 //dropInMode: true,
                 logLevel:10, //console info
                 antialiased: fileInfo.antialiased,
-                sharedMemoryForWorkers: true, //有的 报错 SharedArrayBuffer transfer requires self.crossOriginIsolated.  本地已经配置所以不会,但我手机自带浏览器必须false
+                sharedMemoryForWorkers: true, //有的 报错 SharedArrayBuffer transfer requires self.crossOriginIsolated.  本地已经配置所以不会,ip的话要https,但我手机自带浏览器必须false
                 sphericalHarmonicsDegree:  2   //最大支持的sh Level
             });
             //let path = Potree.resourcePath+'/models/gaussian/bonsai.ksplat';

+ 376 - 12
src/workers/BinaryDecoderWorker.js

@@ -1,10 +1,8 @@
 
-import * as THREE from "../../libs/three.js/build/three.module.js";
+//import * as THREE from "../../libs/three.js/build/three.module.js";
 import {Version} from "../Version.js";
 import {PointAttributes, PointAttribute, PointAttributeTypes} from "../loader/PointAttributes.js";
-
-import {Splat} from '../custom/objects/3dgs/Splat.js'
-
+ 
 const typedArrayMapping = {
 	"int8":   Int8Array,
 	"int16":  Int16Array,
@@ -18,9 +16,6 @@ const typedArrayMapping = {
 	"double": Float64Array,
 };
 
-
-
-
 const gs3dProplist = [
 'f_dc_0',  //color
 'f_dc_1',
@@ -80,10 +75,379 @@ const gs3dProplist = [
 'rot_3'
 ]
 
+let clamp = function ( value, min, max ) {
+
+    return Math.max( min, Math.min( max, value ) );
+
+} 
+
+class Vector3 {
+
+	constructor( x = 0, y = 0, z = 0 ) {
+
+		Object.defineProperty( this, 'isVector3', { value: true } );
+
+		this.x = x;
+		this.y = y;
+		this.z = z;
+
+	}
+
+	set( x, y, z ) {
+
+		if ( z === undefined ) z = this.z; // sprite.scale.set(x,y)
+
+		this.x = x;
+		this.y = y;
+		this.z = z;
+
+		return this;
+
+	}
+}
+class Quaternion {
+
+    constructor( x = 0, y = 0, z = 0, w = 1 ) {
+
+        Object.defineProperty( this, 'isQuaternion', { value: true } );
+
+        this._x = x;
+        this._y = y;
+        this._z = z;
+        this._w = w;
+        
+    }
+    
+    set( x, y, z, w ) {
+
+		this._x = x;
+		this._y = y;
+		this._z = z;
+		this._w = w;
+
+		//this._onChangeCallback();
+
+		return this;
+
+	}
+    
+}
+const _zero = new Vector3( 0, 0, 0 );
+const _one = new Vector3( 1, 1, 1 );
+class Matrix4 {
+
+	constructor() {
+
+		Object.defineProperty( this, 'isMatrix4', { value: true } );
+
+		this.elements = [
+
+			1, 0, 0, 0,
+			0, 1, 0, 0,
+			0, 0, 1, 0,
+			0, 0, 0, 1
+
+		];
+
+		if ( arguments.length > 0 ) {
+
+			console.error( 'THREE.Matrix4: the constructor no longer reads arguments. use .set() instead.' );
+
+		}
+
+	}
+     
+    makeRotationFromQuaternion( q ) {
+
+		return this.compose( _zero, q, _one );
+
+	}
+    compose( position, quaternion, scale ) {
+
+		const te = this.elements;
+
+		const x = quaternion._x, y = quaternion._y, z = quaternion._z, w = quaternion._w;
+		const x2 = x + x,	y2 = y + y, z2 = z + z;
+		const xx = x * x2, xy = x * y2, xz = x * z2;
+		const yy = y * y2, yz = y * z2, zz = z * z2;
+		const wx = w * x2, wy = w * y2, wz = w * z2;
+
+		const sx = scale.x, sy = scale.y, sz = scale.z;
+
+		te[ 0 ] = ( 1 - ( yy + zz ) ) * sx;
+		te[ 1 ] = ( xy + wz ) * sx;
+		te[ 2 ] = ( xz - wy ) * sx;
+		te[ 3 ] = 0;
+
+		te[ 4 ] = ( xy - wz ) * sy;
+		te[ 5 ] = ( 1 - ( xx + zz ) ) * sy;
+		te[ 6 ] = ( yz + wx ) * sy;
+		te[ 7 ] = 0;
+
+		te[ 8 ] = ( xz + wy ) * sz;
+		te[ 9 ] = ( yz - wx ) * sz;
+		te[ 10 ] = ( 1 - ( xx + yy ) ) * sz;
+		te[ 11 ] = 0;
+
+		te[ 12 ] = position.x;
+		te[ 13 ] = position.y;
+		te[ 14 ] = position.z;
+		te[ 15 ] = 1;
+
+		return this;
+
+	}
+    makeScale( x, y, z ) {
+
+		this.set(
+
+			x, 0, 0, 0,
+			0, y, 0, 0,
+			0, 0, z, 0,
+			0, 0, 0, 1
+
+		);
+
+		return this;
+
+	}
+    set( n11, n12, n13, n14, n21, n22, n23, n24, n31, n32, n33, n34, n41, n42, n43, n44 ) {
+
+		const te = this.elements;
+
+		te[ 0 ] = n11; te[ 4 ] = n12; te[ 8 ] = n13; te[ 12 ] = n14;
+		te[ 1 ] = n21; te[ 5 ] = n22; te[ 9 ] = n23; te[ 13 ] = n24;
+		te[ 2 ] = n31; te[ 6 ] = n32; te[ 10 ] = n33; te[ 14 ] = n34;
+		te[ 3 ] = n41; te[ 7 ] = n42; te[ 11 ] = n43; te[ 15 ] = n44;
+
+		return this;
+
+	}
+}
+
+class Matrix3 {
+
+	constructor() {
+
+		Object.defineProperty( this, 'isMatrix3', { value: true } );
+
+		this.elements = [
+
+			1, 0, 0,
+			0, 1, 0,
+			0, 0, 1
+
+		];
+
+		if ( arguments.length > 0 ) {
+
+			console.error( 'THREE.Matrix3: the constructor no longer reads arguments. use .set() instead.' );
+
+		}
+
+	}
+    copy( m ) {
+
+		const te = this.elements;
+		const me = m.elements;
+
+		te[ 0 ] = me[ 0 ]; te[ 1 ] = me[ 1 ]; te[ 2 ] = me[ 2 ];
+		te[ 3 ] = me[ 3 ]; te[ 4 ] = me[ 4 ]; te[ 5 ] = me[ 5 ];
+		te[ 6 ] = me[ 6 ]; te[ 7 ] = me[ 7 ]; te[ 8 ] = me[ 8 ];
+
+		return this;
+
+	}
+    multiply( m ) {
+
+		return this.multiplyMatrices( this, m );
+
+	}
+    premultiply( m ) {
+
+		return this.multiplyMatrices( m, this );
+
+	}
+
+	multiplyMatrices( a, b ) {
+
+		const ae = a.elements;
+		const be = b.elements;
+		const te = this.elements;
+
+		const a11 = ae[ 0 ], a12 = ae[ 3 ], a13 = ae[ 6 ];
+		const a21 = ae[ 1 ], a22 = ae[ 4 ], a23 = ae[ 7 ];
+		const a31 = ae[ 2 ], a32 = ae[ 5 ], a33 = ae[ 8 ];
+
+		const b11 = be[ 0 ], b12 = be[ 3 ], b13 = be[ 6 ];
+		const b21 = be[ 1 ], b22 = be[ 4 ], b23 = be[ 7 ];
+		const b31 = be[ 2 ], b32 = be[ 5 ], b33 = be[ 8 ];
+
+		te[ 0 ] = a11 * b11 + a12 * b21 + a13 * b31;
+		te[ 3 ] = a11 * b12 + a12 * b22 + a13 * b32;
+		te[ 6 ] = a11 * b13 + a12 * b23 + a13 * b33;
+
+		te[ 1 ] = a21 * b11 + a22 * b21 + a23 * b31;
+		te[ 4 ] = a21 * b12 + a22 * b22 + a23 * b32;
+		te[ 7 ] = a21 * b13 + a22 * b23 + a23 * b33;
+
+		te[ 2 ] = a31 * b11 + a32 * b21 + a33 * b31;
+		te[ 5 ] = a31 * b12 + a32 * b22 + a33 * b32;
+		te[ 8 ] = a31 * b13 + a32 * b23 + a33 * b33;
+
+		return this;
+
+	}
+    setFromMatrix4( m ) {
+
+		const me = m.elements;
+
+		this.set(
+
+			me[ 0 ], me[ 4 ], me[ 8 ],
+			me[ 1 ], me[ 5 ], me[ 9 ],
+			me[ 2 ], me[ 6 ], me[ 10 ]
+
+		);
+
+		return this;
+
+	}
+    set( n11, n12, n13, n21, n22, n23, n31, n32, n33 ) {
+
+		const te = this.elements;
+
+		te[ 0 ] = n11; te[ 1 ] = n21; te[ 2 ] = n31;
+		te[ 3 ] = n12; te[ 4 ] = n22; te[ 5 ] = n32;
+		te[ 6 ] = n13; te[ 7 ] = n23; te[ 8 ] = n33;
+
+		return this;
+
+	}
+    transpose() {
+
+		let tmp;
+		const m = this.elements;
+
+		tmp = m[ 1 ]; m[ 1 ] = m[ 3 ]; m[ 3 ] = tmp;
+		tmp = m[ 2 ]; m[ 2 ] = m[ 6 ]; m[ 6 ] = tmp;
+		tmp = m[ 5 ]; m[ 5 ] = m[ 7 ]; m[ 7 ] = tmp;
+
+		return this;
+
+	}
+
+}
+
+let toHalfFloat = function ( val ) {
+
+    // Source: http://gamedev.stackexchange.com/questions/17326/conversion-of-a-number-from-single-precision-floating-point-representation-to-a/17410#17410
+
+    /* This method is faster than the OpenEXR implementation (very often
+    * used, eg. in Ogre), with the additional benefit of rounding, inspired
+    * by James Tursa?s half-precision code. */
+
+    _floatView[ 0 ] = val;
+    const x = _int32View[ 0 ];
+
+    let bits = ( x >> 16 ) & 0x8000; /* Get the sign */
+    let m = ( x >> 12 ) & 0x07ff; /* Keep one extra bit for rounding */
+    const e = ( x >> 23 ) & 0xff; /* Using int is faster here */
+
+    /* If zero, or denormal, or exponent underflows too much for a denormal
+        * half, return signed zero. */
+    if ( e < 103 ) return bits;
+
+    /* If NaN, return NaN. If Inf or exponent overflow, return Inf. */
+    if ( e > 142 ) {
+
+        bits |= 0x7c00;
+        /* If exponent was 0xff and one mantissa bit was set, it means NaN,
+                    * not Inf, so make sure we set one mantissa bit too. */
+        bits |= ( ( e == 255 ) ? 0 : 1 ) && ( x & 0x007fffff );
+        return bits;
+
+    }
+
+    /* If exponent underflows but not too much, return a denorma l */
+    if ( e < 113 ) {
+
+        m |= 0x0800;
+        /* Extra rounding may overflow and set mantissa to 0 and exponent
+            * to 1, which is OK. */
+        bits |= ( m >> ( 114 - e ) ) + ( ( m >> ( 113 - e ) ) & 1 );
+        return bits;
+
+    }
+
+    bits |= ( ( e - 112 ) << 10 ) | ( m >> 1 );
+    /* Extra rounding. An overflow will set mantissa to 0 and increment
+        * the exponent, which is OK. */
+    bits += m & 1;
+    return bits;
+
+}
+
+
+
+
+let computeCovariance = function() {//通过旋转和缩放计算协方差(决定姿态)得到6个数  
+
+    const tempMatrix4 = new Matrix4();
+    const scaleMatrix = new Matrix3();
+    const rotationMatrix = new Matrix3();
+    const covarianceMatrix = new Matrix3();
+    const transformedCovariance = new Matrix3();
+    const transform3x3 = new Matrix3();
+    const transform3x3Transpose = new Matrix3();
+    const thf = toHalfFloat  //THREE.DataUtils.toHalfFloat.bind(THREE.DataUtils);
+
+    return function(scale, rotation, transform, outCovariance, outOffset = 0, desiredOutputCompressionLevel) {
+
+        tempMatrix4.makeScale(scale.x, scale.y, scale.z);
+        scaleMatrix.setFromMatrix4(tempMatrix4);
 
+        tempMatrix4.makeRotationFromQuaternion(rotation);
+        rotationMatrix.setFromMatrix4(tempMatrix4);
 
+        covarianceMatrix.copy(rotationMatrix).multiply(scaleMatrix);
+        transformedCovariance.copy(covarianceMatrix).transpose().premultiply(covarianceMatrix); //为什么要乘以自己的转置呀?
 
+        if (transform) {//场景的整体transform   如果可能移动就不传,在sort时直接乘
+            transform3x3.setFromMatrix4(transform);
+            transform3x3Transpose.copy(transform3x3).transpose();
+            transformedCovariance.multiply(transform3x3Transpose);
+            transformedCovariance.premultiply(transform3x3);
+        }
 
+        if (desiredOutputCompressionLevel === 1) {//压缩
+            outCovariance[outOffset] = thf(transformedCovariance.elements[0]);
+            outCovariance[outOffset + 1] = thf(transformedCovariance.elements[3]);
+            outCovariance[outOffset + 2] = thf(transformedCovariance.elements[6]);
+            outCovariance[outOffset + 3] = thf(transformedCovariance.elements[4]);
+            outCovariance[outOffset + 4] = thf(transformedCovariance.elements[7]);
+            outCovariance[outOffset + 5] = thf(transformedCovariance.elements[8]);
+        } else {
+            outCovariance[outOffset] = transformedCovariance.elements[0];
+            outCovariance[outOffset + 1] = transformedCovariance.elements[3];
+            outCovariance[outOffset + 2] = transformedCovariance.elements[6];
+            outCovariance[outOffset + 3] = transformedCovariance.elements[4];
+            outCovariance[outOffset + 4] = transformedCovariance.elements[7];
+            outCovariance[outOffset + 5] = transformedCovariance.elements[8];
+        }
+        
+        
+        /* 
+        Vrk 中的元素分别是transformedCovariance的 [
+            0,3,6,
+            3,4,7,
+            6,7,8 
+        ]
+        
+        */
+    };
+
+}();
 
 
 Potree = {};
@@ -321,11 +685,11 @@ onmessage = function (event) {
             const offset_col = gs3dProplist.indexOf('f_dc_0')   
             let getColor = (index)=>{
                 let value = (0.5 + SH_C0 * f32[index+offset_col]) * 255;  
-                return THREE.Math.clamp(Math.floor(value), 0, 255);
+                return clamp(Math.floor(value), 0, 255);
             }
             let getOpacity = (index)=>{
                 let value = (1 / (1 + Math.exp(-f32[index+offset_opa]))) * 255;   
-                return THREE.Math.clamp(Math.floor(value), 0, 255);
+                return clamp(Math.floor(value), 0, 255);
             }
 			for (let j = 0; j < numPoints; j++) {
 				colors[4 * j + 0] = getColor(j * pointAttribute.numElements + 0)   
@@ -342,8 +706,8 @@ onmessage = function (event) {
             let covs = new Float32Array(buff3);
             const offset_scale = gs3dProplist.indexOf('scale_0') //第49个数开始是      
             const offset_rot = gs3dProplist.indexOf('rot_0')    
-            let scale = new THREE.Vector3()
-            let quaternion = new THREE.Quaternion()
+            let scale = new  Vector3()
+            let quaternion = new Quaternion()
             
             let getScale = (index)=>{ 
                 let get = (offset)=>{
@@ -364,7 +728,7 @@ onmessage = function (event) {
             for (let j = 0; j < numPoints; j++) {
                 getScale(j); 
                 getQuatenion(j);  
-                Splat.computeCovariance(scale, quaternion, null, covs, 6 * j ); 
+                computeCovariance(scale, quaternion, null, covs, 6 * j ); 
             }
             
             attributeBuffers['covs'] = { buffer: buff3, attribute: pointAttribute };