Custom THREE.BufferGeometry.toIndexed (slow)

by PhilQ

HTML

<script async src="https://unpkg.com/[email protected]/dist/es-module-shims.js"></script>
<script type="importmap">
	{
		"imports": {
			"three": "https://unpkg.com/[email protected]/build/three.module.js",
			"ConvexGeometry": "https://unpkg.com/[email protected]/examples/jsm/geometries/ConvexGeometry.js"
		}
	}
</script>

JavaScript

import * as THREE from 'three';
import { ConvexGeometry } from 'ConvexGeometry';

class LatLng {
	constructor( lat, lng ) {
		// Latitude and longitude in radians
		this.lat = lat ? lat : 0;
		this.lng = lng ? lng : 0;
		this.u = 0;
		this.v = 0;
		this.updateUV();
	}

	// Latitude:
	//  -90 (N) --> 90 (S)
	//     PI/2 --> -PI/2
	// Longitude:
	// -180 (W) --> 180 (E)
	//      -PI --> PI
	updateUV() {
		this.v = (this.lat / (-0.5 * Math.PI)) * 0.5 + 0.5;
		this.u = (this.lng / Math.PI) * 0.5 + 0.5;
	}

	fromUV( u, v ) {
		this.lng = 2 * (u - 0.5) * Math.PI;
		this.lat = 2 * (v - 0.5) * -0.5 * Math.PI;
	}

	fromVector( v ) {
		// From point on unit sphere
		v = v.clone().normalize();
		this.lat = Math.asin( v.y );
		this.lng = Math.atan2( v.x, v.z );
		this.updateUV();
		return this;
	}

	toVector() {
		// To point on unit sphere
		let r = Math.cos( this.lat );
		return new THREE.Vector3(
			Math.sin( this.lng ) * r,
			Math.sin( this.lat ),
			Math.cos( this.lng ) * r
		);
	}
}
THREE.Vector3.prototype.toLatLng = function() {
	return new LatLng().fromVector( this );
};
THREE.Vector3.prototype.fromLatLng = function( latlng ) {
	return this.copy( latlng.toVector() );
};

// Author: Fyrestar https://mevedia.com (https://github.com/Fyrestar/THREE.BufferGeometry-toIndexed)
THREE.BufferGeometry.prototype.toIndexedOrig = function () {

	let list = [], vertices = {};

	let _src, attributesKeys, morphKeys;

	let prec = 0, precHalf = 0, length = 0;


	function floor( array, offset ) {

		if ( array instanceof Float32Array ) {

			return Math.floor( array[ offset ] * prec );

		} else if ( array instanceof Float16Array ) {

			return Math.floor( array[ offset ] * precHalf );

		} else {

			return array[ offset ];

		}

	}

	function createAttribute( src_attribute ) {

		const dst_attribute = new THREE.BufferAttribute( new src_attribute.array.constructor( length * src_attribute.itemSize ), src_attribute.itemSize );

		const dst_array = dst_attribute.array;
		const src_array...