Skip to content

Commit 3ea9856

Browse files
authored
USDZLoader: Support quads as triangles. (#28648)
1 parent 6c8ff24 commit 3ea9856

File tree

1 file changed

+70
-2
lines changed

1 file changed

+70
-2
lines changed

examples/jsm/loaders/USDZLoader.js

Lines changed: 70 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -340,8 +340,11 @@ class USDZLoader extends Loader {
340340

341341
const geometry = new BufferGeometry();
342342
let indices = null;
343+
let counts = null;
343344
let uvs = null;
344345

346+
let positionsLength = - 1;
347+
345348
// index
346349

347350
if ( 'int[] faceVertexIndices' in data ) {
@@ -350,11 +353,21 @@ class USDZLoader extends Loader {
350353

351354
}
352355

356+
// face count
357+
358+
if ( 'int[] faceVertexCounts' in data ) {
359+
360+
counts = JSON.parse( data[ 'int[] faceVertexCounts' ] );
361+
indices = toTriangleIndices( indices, counts );
362+
363+
}
364+
353365
// position
354366

355367
if ( 'point3f[] points' in data ) {
356368

357369
const positions = JSON.parse( data[ 'point3f[] points' ].replace( /[()]*/g, '' ) );
370+
positionsLength = positions.length;
358371
let attribute = new BufferAttribute( new Float32Array( positions ), 3 );
359372

360373
if ( indices !== null ) attribute = toFlatBufferAttribute( attribute, indices );
@@ -387,7 +400,8 @@ class USDZLoader extends Loader {
387400
// custom uv index, overwrite uvs with new data
388401

389402
const attribute = new BufferAttribute( new Float32Array( uvs ), 2 );
390-
const indices = JSON.parse( data[ 'int[] primvars:st:indices' ] );
403+
let indices = JSON.parse( data[ 'int[] primvars:st:indices' ] );
404+
indices = toTriangleIndices( indices, counts );
391405
geometry.setAttribute( 'uv', toFlatBufferAttribute( attribute, indices ) );
392406

393407
}
@@ -399,8 +413,20 @@ class USDZLoader extends Loader {
399413
const normals = JSON.parse( data[ 'normal3f[] normals' ].replace( /[()]*/g, '' ) );
400414
let attribute = new BufferAttribute( new Float32Array( normals ), 3 );
401415

402-
if ( attribute.count !== geometry.attributes.position.count && indices !== null ) {
416+
// normals require a special treatment in USD
417+
418+
if ( normals.length === positionsLength ) {
419+
420+
// raw normal and position data have equal length (like produced by USDZExporter)
421+
422+
if ( indices !== null ) attribute = toFlatBufferAttribute( attribute, indices );
403423

424+
} else {
425+
426+
// unequal length, normals are independent of faceVertexIndices
427+
428+
let indices = Array.from( Array( normals.length / 3 ).keys() ); // [ 0, 1, 2, 3 ... ]
429+
indices = toTriangleIndices( indices, counts );
404430
attribute = toFlatBufferAttribute( attribute, indices );
405431

406432
}
@@ -409,6 +435,8 @@ class USDZLoader extends Loader {
409435

410436
} else {
411437

438+
// compute flat vertex normals
439+
412440
geometry.computeVertexNormals();
413441

414442
}
@@ -417,6 +445,46 @@ class USDZLoader extends Loader {
417445

418446
}
419447

448+
function toTriangleIndices( rawIndices, counts ) {
449+
450+
const indices = [];
451+
452+
for ( let i = 0; i < counts.length; i ++ ) {
453+
454+
const count = counts[ i ];
455+
456+
const stride = i * count;
457+
458+
if ( count === 3 ) {
459+
460+
const a = rawIndices[ stride + 0 ];
461+
const b = rawIndices[ stride + 1 ];
462+
const c = rawIndices[ stride + 2 ];
463+
464+
indices.push( a, b, c );
465+
466+
} else if ( count === 4 ) {
467+
468+
const a = rawIndices[ stride + 0 ];
469+
const b = rawIndices[ stride + 1 ];
470+
const c = rawIndices[ stride + 2 ];
471+
const d = rawIndices[ stride + 3 ];
472+
473+
indices.push( a, b, c );
474+
indices.push( a, c, d );
475+
476+
} else {
477+
478+
console.warn( 'THREE.USDZLoader: Face vertex count of %s unsupported.', count );
479+
480+
}
481+
482+
}
483+
484+
return indices;
485+
486+
}
487+
420488
function toFlatBufferAttribute( attribute, indices ) {
421489

422490
const array = attribute.array;

0 commit comments

Comments
 (0)