فهرست منبع

JSM: Added module and TS file for PRWMLoader.

Mugen87 6 سال پیش
والد
کامیت
a732e185bc

+ 1 - 0
docs/manual/en/introduction/Import-via-modules.html

@@ -173,6 +173,7 @@
 						<li>PDBLoader</li>
 						<li>PlayCanvasLoader</li>
 						<li>PLYLoader</li>
+						<li>PRWMLoader</li>
 						<li>PVRLoader</li>
 						<li>RGBELoader</li>
 						<li>STLLoader</li>

+ 8 - 12
examples/js/loaders/PRWMLoader.js

@@ -3,9 +3,7 @@
  * See https://github.com/kchapelier/PRWM for more informations about this file format
  */
 
-( function ( THREE ) {
-
-	'use strict';
+THREE.PRWMLoader = ( function () {
 
 	var bigEndianPlatform = null;
 
@@ -224,13 +222,13 @@
 
 	// Define the public interface
 
-	THREE.PRWMLoader = function PRWMLoader( manager ) {
+	function PRWMLoader( manager ) {
 
 		this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager;
 
-	};
+	}
 
-	THREE.PRWMLoader.prototype = {
+	PRWMLoader.prototype = {
 
 		constructor: THREE.PRWMLoader,
 
@@ -261,8 +259,6 @@
 
 		parse: function ( arrayBuffer ) {
 
-			console.time( 'PRWMLoader' );
-
 			var data = decodePrwm( arrayBuffer ),
 				attributesKey = Object.keys( data.attributes ),
 				bufferGeometry = new THREE.BufferGeometry(),
@@ -282,18 +278,18 @@
 
 			}
 
-			console.timeEnd( 'PRWMLoader' );
-
 			return bufferGeometry;
 
 		}
 
 	};
 
-	THREE.PRWMLoader.isBigEndianPlatform = function () {
+	PRWMLoader.isBigEndianPlatform = function () {
 
 		return isBigEndianPlatform();
 
 	};
 
-} )( THREE );
+	return PRWMLoader;
+
+} )();

+ 17 - 0
examples/jsm/loaders/PRWMLoader.d.ts

@@ -0,0 +1,17 @@
+import {
+  BufferGeometry,
+  LoadingManager
+} from '../../../src/Three';
+
+
+export class PRWMLoader {
+  constructor(manager?: LoadingManager);
+  manager: LoadingManager;
+  path: string;
+
+  load(url: string, onLoad: (geometry: BufferGeometry) => void, onProgress?: (event: ProgressEvent) => void, onError?: (event: ErrorEvent) => void) : void;
+  setPath(path: string) : this;
+  parse(data: ArrayBuffer) : BufferGeometry;
+
+  static isBigEndianPlatform(): boolean;
+}

+ 304 - 0
examples/jsm/loaders/PRWMLoader.js

@@ -0,0 +1,304 @@
+/**
+ * @author Kevin Chapelier / https://github.com/kchapelier
+ * See https://github.com/kchapelier/PRWM for more informations about this file format
+ */
+
+import {
+	BufferAttribute,
+	BufferGeometry,
+	DefaultLoadingManager,
+	FileLoader
+} from "../../../build/three.module.js";
+
+var PRWMLoader = ( function () {
+
+	var bigEndianPlatform = null;
+
+	/**
+	 * Check if the endianness of the platform is big-endian (most significant bit first)
+	 * @returns {boolean} True if big-endian, false if little-endian
+	 */
+	function isBigEndianPlatform() {
+
+		if ( bigEndianPlatform === null ) {
+
+			var buffer = new ArrayBuffer( 2 ),
+				uint8Array = new Uint8Array( buffer ),
+				uint16Array = new Uint16Array( buffer );
+
+			uint8Array[ 0 ] = 0xAA; // set first byte
+			uint8Array[ 1 ] = 0xBB; // set second byte
+			bigEndianPlatform = ( uint16Array[ 0 ] === 0xAABB );
+
+		}
+
+		return bigEndianPlatform;
+
+	}
+
+	// match the values defined in the spec to the TypedArray types
+	var InvertedEncodingTypes = [
+		null,
+		Float32Array,
+		null,
+		Int8Array,
+		Int16Array,
+		null,
+		Int32Array,
+		Uint8Array,
+		Uint16Array,
+		null,
+		Uint32Array
+	];
+
+	// define the method to use on a DataView, corresponding the TypedArray type
+	var getMethods = {
+		Uint16Array: 'getUint16',
+		Uint32Array: 'getUint32',
+		Int16Array: 'getInt16',
+		Int32Array: 'getInt32',
+		Float32Array: 'getFloat32',
+		Float64Array: 'getFloat64'
+	};
+
+
+	function copyFromBuffer( sourceArrayBuffer, viewType, position, length, fromBigEndian ) {
+
+		var bytesPerElement = viewType.BYTES_PER_ELEMENT,
+			result;
+
+		if ( fromBigEndian === isBigEndianPlatform() || bytesPerElement === 1 ) {
+
+			result = new viewType( sourceArrayBuffer, position, length );
+
+		} else {
+
+			var readView = new DataView( sourceArrayBuffer, position, length * bytesPerElement ),
+				getMethod = getMethods[ viewType.name ],
+				littleEndian = ! fromBigEndian,
+				i = 0;
+
+			result = new viewType( length );
+
+			for ( ; i < length; i ++ ) {
+
+				result[ i ] = readView[ getMethod ]( i * bytesPerElement, littleEndian );
+
+			}
+
+		}
+
+		return result;
+
+	}
+
+
+	function decodePrwm( buffer ) {
+
+		var array = new Uint8Array( buffer ),
+			version = array[ 0 ],
+			flags = array[ 1 ],
+			indexedGeometry = !! ( flags >> 7 & 0x01 ),
+			indicesType = flags >> 6 & 0x01,
+			bigEndian = ( flags >> 5 & 0x01 ) === 1,
+			attributesNumber = flags & 0x1F,
+			valuesNumber = 0,
+			indicesNumber = 0;
+
+		if ( bigEndian ) {
+
+			valuesNumber = ( array[ 2 ] << 16 ) + ( array[ 3 ] << 8 ) + array[ 4 ];
+			indicesNumber = ( array[ 5 ] << 16 ) + ( array[ 6 ] << 8 ) + array[ 7 ];
+
+		} else {
+
+			valuesNumber = array[ 2 ] + ( array[ 3 ] << 8 ) + ( array[ 4 ] << 16 );
+			indicesNumber = array[ 5 ] + ( array[ 6 ] << 8 ) + ( array[ 7 ] << 16 );
+
+		}
+
+		/** PRELIMINARY CHECKS **/
+
+		if ( version === 0 ) {
+
+			throw new Error( 'PRWM decoder: Invalid format version: 0' );
+
+		} else if ( version !== 1 ) {
+
+			throw new Error( 'PRWM decoder: Unsupported format version: ' + version );
+
+		}
+
+		if ( ! indexedGeometry ) {
+
+			if ( indicesType !== 0 ) {
+
+				throw new Error( 'PRWM decoder: Indices type must be set to 0 for non-indexed geometries' );
+
+			} else if ( indicesNumber !== 0 ) {
+
+				throw new Error( 'PRWM decoder: Number of indices must be set to 0 for non-indexed geometries' );
+
+			}
+
+		}
+
+		/** PARSING **/
+
+		var pos = 8;
+
+		var attributes = {},
+			attributeName,
+			char,
+			attributeType,
+			cardinality,
+			encodingType,
+			arrayType,
+			values,
+			indices,
+			i;
+
+		for ( i = 0; i < attributesNumber; i ++ ) {
+
+			attributeName = '';
+
+			while ( pos < array.length ) {
+
+				char = array[ pos ];
+				pos ++;
+
+				if ( char === 0 ) {
+
+					break;
+
+				} else {
+
+					attributeName += String.fromCharCode( char );
+
+				}
+
+			}
+
+			flags = array[ pos ];
+
+			attributeType = flags >> 7 & 0x01;
+			cardinality = ( flags >> 4 & 0x03 ) + 1;
+			encodingType = flags & 0x0F;
+			arrayType = InvertedEncodingTypes[ encodingType ];
+
+			pos ++;
+
+			// padding to next multiple of 4
+			pos = Math.ceil( pos / 4 ) * 4;
+
+			values = copyFromBuffer( buffer, arrayType, pos, cardinality * valuesNumber, bigEndian );
+
+			pos += arrayType.BYTES_PER_ELEMENT * cardinality * valuesNumber;
+
+			attributes[ attributeName ] = {
+				type: attributeType,
+				cardinality: cardinality,
+				values: values
+			};
+
+		}
+
+		pos = Math.ceil( pos / 4 ) * 4;
+
+		indices = null;
+
+		if ( indexedGeometry ) {
+
+			indices = copyFromBuffer(
+				buffer,
+				indicesType === 1 ? Uint32Array : Uint16Array,
+				pos,
+				indicesNumber,
+				bigEndian
+			);
+
+		}
+
+		return {
+			version: version,
+			attributes: attributes,
+			indices: indices
+		};
+
+	}
+
+	// Define the public interface
+
+	function PRWMLoader( manager ) {
+
+		this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;
+
+	}
+
+	PRWMLoader.prototype = {
+
+		constructor: PRWMLoader,
+
+		load: function ( url, onLoad, onProgress, onError ) {
+
+			var scope = this;
+
+			var loader = new FileLoader( scope.manager );
+			loader.setPath( scope.path );
+			loader.setResponseType( 'arraybuffer' );
+
+			url = url.replace( /\*/g, isBigEndianPlatform() ? 'be' : 'le' );
+
+			loader.load( url, function ( arrayBuffer ) {
+
+				onLoad( scope.parse( arrayBuffer ) );
+
+			}, onProgress, onError );
+
+		},
+
+		setPath: function ( value ) {
+
+			this.path = value;
+			return this;
+
+		},
+
+		parse: function ( arrayBuffer ) {
+
+			var data = decodePrwm( arrayBuffer ),
+				attributesKey = Object.keys( data.attributes ),
+				bufferGeometry = new BufferGeometry(),
+				attribute,
+				i;
+
+			for ( i = 0; i < attributesKey.length; i ++ ) {
+
+				attribute = data.attributes[ attributesKey[ i ] ];
+				bufferGeometry.addAttribute( attributesKey[ i ], new BufferAttribute( attribute.values, attribute.cardinality, attribute.normalized ) );
+
+			}
+
+			if ( data.indices !== null ) {
+
+				bufferGeometry.setIndex( new BufferAttribute( data.indices, 1 ) );
+
+			}
+
+			return bufferGeometry;
+
+		}
+
+	};
+
+	PRWMLoader.isBigEndianPlatform = function () {
+
+		return isBigEndianPlatform();
+
+	};
+
+	return PRWMLoader;
+
+} )();
+
+export { PRWMLoader };

+ 2 - 8
examples/webgl_loader_prwm.html

@@ -6,12 +6,6 @@
 		<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
 		<link type="text/css" rel="stylesheet" href="main.css">
 		<style>
-			.models {
-				position: absolute;
-				top: 10px;
-				left: 12px;
-				font-family: "Arial", "Helvetica Neue", "Helvetica", sans-serif;
-			}
 			.notes {
 				position:absolute;
 				left: 12px;
@@ -22,7 +16,7 @@
 	</head>
 	<body>
 
-		<div class="models">
+		<div id="info">
 			<strong>Models</strong>:
 			<a class="model" href="models/prwm/faceted-nefertiti.*.prwm">Faceted Nefertiti</a>,
 			<a class="model" href="models/prwm/smooth-suzanne.*.prwm">Smooth Suzanne</a>,
@@ -138,7 +132,7 @@
 				//
 
 				renderer = new THREE.WebGLRenderer( { antialias: true } );
-				renderer.setPixelRatio( 1 );
+				renderer.setPixelRatio( window.devicePixelRatio );
 				renderer.setSize( window.innerWidth, window.innerHeight );
 				container.appendChild( renderer.domElement );
 

+ 1 - 0
utils/modularize.js

@@ -80,6 +80,7 @@ var files = [
 	{ path: 'loaders/PDBLoader.js', dependencies: [], ignoreList: [] },
 	{ path: 'loaders/PlayCanvasLoader.js', dependencies: [], ignoreList: [] },
 	{ path: 'loaders/PLYLoader.js', dependencies: [], ignoreList: [ 'Mesh' ] },
+	{ path: 'loaders/PRWMLoader.js', dependencies: [], ignoreList: [] },
 	{ path: 'loaders/PVRLoader.js', dependencies: [], ignoreList: [] },
 	{ path: 'loaders/RGBELoader.js', dependencies: [], ignoreList: [ 'RGBAFormat' ] },
 	{ path: 'loaders/STLLoader.js', dependencies: [], ignoreList: [ 'Mesh', 'MeshPhongMaterial', 'VertexColors' ] },