Skip to content

Commit 25f1559

Browse files
committed
fixed fbx not working on web and fixed pcd loader
1 parent 1a95ad8 commit 25f1559

File tree

3 files changed

+106
-80
lines changed

3 files changed

+106
-80
lines changed

examples/lib/loaders/webgl_loader_pcd.dart

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ class _State extends State<WebglLoaderPcd> {
7878
final loader = three.PCDLoader();
7979

8080
Map<String, dynamic> temp = {
81-
'size': 0.001,
81+
'size': 0.005,
8282
'color': 0,
8383
'name': 'binary/Zaghetto.pcd',
8484
'points': null
@@ -103,8 +103,12 @@ class _State extends State<WebglLoaderPcd> {
103103

104104
final gui = wg.addFolder('GUI')..open();
105105

106-
gui.addSlider( temp, 'size', 0.001, 0.01, 0.001 );
107-
gui.addColor( temp, 'color' );
106+
gui.addSlider( temp, 'size', 0.001, 0.011, 0.001 ).onChange((e){
107+
temp['points']?.material!.size = e;
108+
});
109+
gui.addColor( temp, 'color' ).onChange((e){
110+
temp['points']?.material!.color = three.Color.fromHex32(e);
111+
});
108112
gui.addDropDown( temp, 'name', <String>[
109113
'ascii/simple.pcd',
110114
'binary/Zaghetto.pcd',

packages/three_js_advanced_loaders/lib/fbx_loader.dart

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ import 'dart:async';
22
import 'dart:io';
33
import 'dart:typed_data';
44
import 'dart:math' as math;
5-
//import 'package:archive/archive.dart';
6-
5+
import 'package:archive/archive.dart' as arc;
6+
import 'package:flutter/foundation.dart';
77
import 'package:three_js_core/three_js_core.dart';
88
import 'package:three_js_math/three_js_math.dart';
99
import 'package:three_js_animations/three_js_animations.dart';
@@ -3143,12 +3143,19 @@ class _BinaryParser {
31433143
}
31443144

31453145
// https://pub.dev/packages/archive
3146-
// use archive replace fflate.js
3146+
// use archive replace fflate.js'
3147+
final List<int> data;
31473148
// final data = fflate.unzlibSync( Uint8List( reader.getArrayBuffer( compressedLength ) ) ); // eslint-disable-line no-undef
3148-
//final data = const ZLibDecoder().decodeBytes(reader.getArrayBuffer(compressedLength), verify: true);
3149-
final data = ZLibDecoder().convert(reader.getArrayBuffer(compressedLength));
3149+
if(kIsWeb){
3150+
data = const arc.ZLibDecoder().decodeBytes(reader.getArrayBuffer(compressedLength), verify: true);
3151+
}
3152+
else{
3153+
data = ZLibDecoder().convert(reader.getArrayBuffer(compressedLength));
3154+
}
3155+
//final data = utf8.decode(GZipDecoder().decodeBytes(response.bodyBytes));
31503156
final reader2 = _BinaryReader(data);
31513157

3158+
// ... inside your code where you handle the response
31523159
switch (type) {
31533160
case 'b':
31543161
case 'c':

packages/three_js_advanced_loaders/lib/pcd_loader.dart

Lines changed: 87 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -150,31 +150,26 @@ class PCDLoader extends Loader {
150150
if ( size == 8 ) {
151151
return dataview.getFloat64( offset, endian );
152152
}
153-
154153
return dataview.getFloat32( offset, endian );
155154
}
156155

157156
case 'I': {
158157
if ( size == 1 ) {
159158
return dataview.getInt8( offset );
160159
}
161-
162160
if ( size == 2 ) {
163161
return dataview.getInt16( offset, endian );
164162
}
165-
166163
return dataview.getInt32( offset, endian );
167164
}
168165

169166
case 'U': {
170167
if ( size == 1 ) {
171168
return dataview.getUint8( offset );
172169
}
173-
174170
if ( size == 2 ) {
175171
return dataview.getUint16( offset, endian );
176172
}
177-
178173
return dataview.getUint32( offset, endian );
179174
}
180175
}
@@ -187,64 +182,91 @@ class PCDLoader extends Loader {
187182
* @param {ArrayBuffer} data - The raw PCD data as an array buffer.
188183
* @return {Points} The parsed point cloud.
189184
*/
190-
Points _parse(List<int> data ) {
185+
Points _parse(Uint8List data ) {
191186
// from https://gitlab.com/taketwo/three-pcd-loader/blob/master/decompress-lzf.js
192187

193-
decompressLZF(Uint8Array inData, int outLength ) {
194-
final inLength = inData.length;
195-
final outData = new Uint8Array( outLength );
188+
Uint8List decompressLZF(Uint8List inData, int outLength) {
189+
final int inLength = inData.lengthInBytes;
190+
final Uint8List outData = Uint8List(outLength);
196191
int inPtr = 0;
197192
int outPtr = 0;
198-
int ctrl = 0;
193+
int ctrl;
199194
int len;
200195
int ref;
201196

202-
do {
203-
ctrl = inData[ inPtr ++ ];
204-
if ( ctrl < ( 1 << 5 ) ) {
197+
while (inPtr < inLength) {
198+
ctrl = inData[inPtr++];
205199

206-
ctrl ++;
207-
if ( outPtr + ctrl > outLength ) throw ( 'Output buffer is not large enough' );
208-
if ( inPtr + ctrl > inLength ) throw ( 'Invalid compressed data' );
209-
do {
210-
outData[ outPtr ++ ] = inData[ inPtr ++ ];
211-
} while ( -- ctrl >= 0);
212-
213-
}
214-
else {
200+
if (ctrl < (1 << 5)) {
201+
// Literal run
202+
ctrl++;
203+
if (outPtr + ctrl > outLength) {
204+
throw StateError('Output buffer is not large enough');
205+
}
206+
if (inPtr + ctrl > inLength) {
207+
throw StateError('Invalid compressed data');
208+
}
209+
210+
// Copy bytes one by one using a while loop
211+
int count = ctrl;
212+
while (count-- > 0) {
213+
outData[outPtr++] = inData[inPtr++];
214+
}
215+
216+
} else {
217+
// Back reference
215218
len = ctrl >> 5;
216-
ref = outPtr - ( ( ctrl & 0x1f ) << 8 ) - 1;
217-
if ( inPtr >= inLength ) throw ( 'Invalid compressed data' );
218-
if ( len == 7 ) {
219-
len += inData[ inPtr ++ ];
220-
if ( inPtr >= inLength ) throw ( 'Invalid compressed data' );
219+
ref = outPtr - ((ctrl & 0x1f) << 8) - 1;
220+
221+
if (inPtr >= inLength) {
222+
throw StateError('Invalid compressed data');
223+
}
224+
225+
if (len == 7) {
226+
len += inData[inPtr++];
227+
if (inPtr >= inLength) {
228+
throw StateError('Invalid compressed data');
229+
}
230+
}
231+
232+
ref -= inData[inPtr++];
233+
234+
// The length in JS was adjusted inside the do-while condition (len-- + 2)
235+
final int copyLength = len + 2;
236+
237+
if (outPtr + copyLength > outLength) {
238+
throw StateError('Output buffer is not large enough');
239+
}
240+
if (ref < 0) {
241+
throw StateError('Invalid compressed data (reference < 0)');
242+
}
243+
if (ref >= outPtr) {
244+
throw StateError('Invalid compressed data (reference >= outPtr)');
221245
}
222246

223-
ref -= inData[ inPtr ++ ];
224-
if ( outPtr + len + 2 > outLength ) throw ( 'Output buffer is not large enough' );
225-
if ( ref < 0 ) throw ( 'Invalid compressed data' );
226-
if ( ref >= outPtr ) throw ( 'Invalid compressed data' );
227-
do {
228-
outData[ outPtr ++ ] = outData[ ref ++ ];
229-
} while ( (-- len + 2 ) >- 0);
247+
// Copy bytes from the existing output data (back reference)
248+
int count = copyLength;
249+
while (count-- > 0) {
250+
outData[outPtr++] = outData[ref++];
251+
}
230252
}
231-
} while ( inPtr < inLength );
253+
}
254+
232255
return outData;
233256
}
234-
235-
PCDHeader parseHeader( binaryData ) {
257+
PCDHeader parseHeader(Uint8List binaryData ) {
236258
PCDHeader PCDheader = PCDHeader();
237-
final buffer = new Uint8Array.fromList( binaryData );
259+
final buffer = binaryData;
238260

239-
String data = '';
240-
String line = '';
241-
int i = 0;
242-
bool end = false;
261+
String sData = '';
262+
String line = '';
263+
int i = 0;
264+
bool end = false;
243265

244266
final max = buffer.length;
245267

246268
while ( i < max && end == false ) {
247-
final char = String.fromCharCode( buffer[ i ++ ] );
269+
final char = String.fromCharCode( buffer[ i ++ ] );
248270

249271
if ( char == '\n' || char == '\r' ) {
250272
if ( line.trim().toLowerCase().startsWith( 'data' ) ) {
@@ -253,26 +275,24 @@ class PCDLoader extends Loader {
253275

254276
line = '';
255277
}
256-
else {
278+
else {
257279
line += char;
258280
}
259281

260-
data += char;
282+
sData += char;
261283
}
262284

263-
final result1 = data.indexOf(RegExp(r'[\r\n]DATA\s(\S*)\s',caseSensitive: false,));//data.search( /[\r\n]DATA\s(\S*)\s/i );
264-
final result2 = RegExp(r'[\r\n]DATA\s(\S*)\s',caseSensitive: false).firstMatch(data.substring(result1 - 1))?.group(1);///[\r\n]DATA\s(\S*)\s/i.exec( data.slice( result1 - 1 ) );
265-
print(result2);
285+
final result1 = sData.indexOf(RegExp(r'[\r\n]DATA\s(\S*)\s',caseSensitive: false,));//data.search( /[\r\n]DATA\s(\S*)\s/i );
286+
final result = RegExp(r'[\r\n]DATA\s(\S*)\s',caseSensitive: false).firstMatch(sData.substring(result1 - 1));//
287+
final result2 = result?.group(1);///[\r\n]DATA\s(\S*)\s/i.exec( data.slice( result1 - 1 ) );
266288
PCDheader.data = result2!;
267-
PCDheader.headerLen = result2.length + result1;
268-
PCDheader.str = data.substring(0, PCDheader.headerLen);//.slice( 0, PCDheader.headerLen );
289+
PCDheader.headerLen = result!.group(0)!.length + result1;
290+
PCDheader.str = sData.substring(0, PCDheader.headerLen);
269291

270292
// remove comments
271-
272293
PCDheader.str = PCDheader.str?.replaceAll(RegExp(r'#.*', caseSensitive: false), '' );
273294

274295
// parse
275-
276296
final version = RegExp(r'^VERSION (.*)',caseSensitive: false,multiLine: true).firstMatch( PCDheader.str!);//^VERSION (.*)/im.exec( PCDheader.str );
277297
final fields = RegExp(r'^FIELDS (.*)',caseSensitive: false,multiLine: true).firstMatch( PCDheader.str!);//^FIELDS (.*)/im.exec( PCDheader.str );
278298
final size = RegExp(r'^SIZE (.*)',caseSensitive: false,multiLine: true).firstMatch( PCDheader.str!);//^SIZE (.*)/im.exec( PCDheader.str );
@@ -284,7 +304,6 @@ class PCDLoader extends Loader {
284304
final points = RegExp(r'^POINTS (.*)',caseSensitive: false,multiLine: true).firstMatch( PCDheader.str!);//^POINTS (.*)/im.exec( PCDheader.str );
285305

286306
// evaluate
287-
288307
if (version != null )
289308
PCDheader.version = double.tryParse(version.group(1) ?? '' );
290309

@@ -319,7 +338,7 @@ class PCDLoader extends Loader {
319338
return int.parse( x, radix: 10 );
320339
} ).toList() ?? [];
321340
}
322-
else {
341+
else {
323342
PCDheader.count = [];
324343
for (int i = 0, l = PCDheader.fields.length; i < l; i ++ ) {
325344
PCDheader.count.add( 1 );
@@ -331,17 +350,16 @@ class PCDLoader extends Loader {
331350
int sizeSum = 0;
332351

333352
for (int i = 0, l = PCDheader.fields.length; i < l; i ++ ) {
334-
335353
if ( PCDheader.data == 'ascii' ) {
336354
PCDheader.offset![ PCDheader.fields[ i ] ] = i;
337-
} else {
355+
}
356+
else {
338357
PCDheader.offset![ PCDheader.fields[ i ] ] = sizeSum;
339358
sizeSum += PCDheader.size[ i ] * PCDheader.count[ i ];
340359
}
341360
}
342361

343362
// for binary only
344-
345363
PCDheader.rowSize = sizeSum;
346364

347365
print(PCDheader.toString());
@@ -365,13 +383,12 @@ class PCDLoader extends Loader {
365383
// ascii
366384

367385
if ( PCDheader.data == 'ascii' ) {
368-
369386
final offset = PCDheader.offset!;
370-
final textData = utf8.decode(data);//new TextDecoder().decode( data );
371-
final pcdData = textData.substring( PCDheader.headerLen );
387+
final textData = utf8.decode(data);
388+
final pcdData = textData.substring( PCDheader.headerLen);
372389
final lines = pcdData.split( '\n' );
373390

374-
for (int i = 1, l = lines.length; i < l; i ++ ) {
391+
for (int i = 0, l = lines.length; i < l; i ++ ) {
375392
if ( lines[ i ] == '' ) continue;
376393
final line = lines[ i ].split( ' ' );
377394

@@ -406,11 +423,9 @@ class PCDLoader extends Loader {
406423
}
407424

408425
if ( offset['normal_x'] != null ) {
409-
410426
normal.add( double.parse( line[ offset['normal_x'] ] ) );
411427
normal.add( double.parse( line[ offset['normal_y'] ] ) );
412428
normal.add( double.parse( line[ offset['normal_z'] ] ) );
413-
414429
}
415430

416431
if ( offset['intensity'] != null ) {
@@ -430,11 +445,13 @@ class PCDLoader extends Loader {
430445
// that requires a totally different parsing approach compared to non-compressed data
431446

432447
if ( PCDheader.data == 'binary_compressed' ) {
433-
final sizes = new Uint32Array.fromList( data.sublist( PCDheader.headerLen, PCDheader.headerLen + 8 ) );
434-
final compressedSize = sizes[ 0 ];
435-
final decompressedSize = sizes[ 1 ];
436-
final decompressed = decompressLZF( Uint8Array.fromList( data.sublist(PCDheader.headerLen + 8, compressedSize)), decompressedSize );
437-
final dataview = new ByteData.view( decompressed.toDartList().buffer );
448+
final sizes = data.sublist(PCDheader.headerLen, PCDheader.headerLen + 8).buffer.asUint32List();
449+
final compressedSize = sizes[0];
450+
final decompressedSize = sizes[1];
451+
452+
final t = data.sublist(PCDheader.headerLen + 8, compressedSize);
453+
final decompressed = decompressLZF(t, decompressedSize);
454+
final dataview = ByteData.view(decompressed.buffer);
438455

439456
final offset = PCDheader.offset ?? {};
440457

@@ -484,10 +501,10 @@ class PCDLoader extends Loader {
484501
// binary
485502

486503
if ( PCDheader.data == 'binary' ) {
487-
final dataview = new ByteData.view( Uint8List.fromList(data).buffer, PCDheader.headerLen );
504+
final dataview = ByteData.view( Uint8List.fromList(data).buffer, PCDheader.headerLen);
488505
final offset = PCDheader.offset!;
489506

490-
for ( int i = 0, row = 0; i < PCDheader.points; i ++, row += PCDheader.rowSize ) {
507+
for ( int i = 0, row = 0; i < PCDheader.points; i++, row += PCDheader.rowSize ) {
491508
if ( offset['x'] != null ) {
492509
final xIndex = PCDheader.fields.indexOf( 'x' );
493510
final yIndex = PCDheader.fields.indexOf( 'y' );
@@ -540,15 +557,13 @@ class PCDLoader extends Loader {
540557
geometry.computeBoundingSphere();
541558

542559
// build material
543-
544560
final material = new PointsMaterial.fromMap( { 'size': 0.005 } );
545561

546562
if ( color.length > 0 ) {
547563
material.vertexColors = true;
548564
}
549565

550566
// build point cloud
551-
552567
return new Points( geometry, material );
553568
}
554569
}

0 commit comments

Comments
 (0)