@damienmortini/three 0.1.171 → 0.1.173
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -73,21 +73,12 @@ class DRACOLoader extends Loader {
|
|
|
73
73
|
|
|
74
74
|
loader.load( url, ( buffer ) => {
|
|
75
75
|
|
|
76
|
-
|
|
77
|
-
attributeIDs: this.defaultAttributeIDs,
|
|
78
|
-
attributeTypes: this.defaultAttributeTypes,
|
|
79
|
-
useUniqueIDs: false
|
|
80
|
-
};
|
|
81
|
-
|
|
82
|
-
this.decodeGeometry( buffer, taskConfig )
|
|
83
|
-
.then( onLoad )
|
|
84
|
-
.catch( onError );
|
|
76
|
+
this.decodeDracoFile( buffer, onLoad ).catch( onError );
|
|
85
77
|
|
|
86
78
|
}, onProgress, onError );
|
|
87
79
|
|
|
88
80
|
}
|
|
89
81
|
|
|
90
|
-
/** @deprecated Kept for backward-compatibility with previous DRACOLoader versions. */
|
|
91
82
|
decodeDracoFile( buffer, callback, attributeIDs, attributeTypes ) {
|
|
92
83
|
|
|
93
84
|
const taskConfig = {
|
|
@@ -96,29 +87,12 @@ class DRACOLoader extends Loader {
|
|
|
96
87
|
useUniqueIDs: !! attributeIDs
|
|
97
88
|
};
|
|
98
89
|
|
|
99
|
-
this.decodeGeometry( buffer, taskConfig ).then( callback );
|
|
90
|
+
return this.decodeGeometry( buffer, taskConfig ).then( callback );
|
|
100
91
|
|
|
101
92
|
}
|
|
102
93
|
|
|
103
94
|
decodeGeometry( buffer, taskConfig ) {
|
|
104
95
|
|
|
105
|
-
// TODO: For backward-compatibility, support 'attributeTypes' objects containing
|
|
106
|
-
// references (rather than names) to typed array constructors. These must be
|
|
107
|
-
// serialized before sending them to the worker.
|
|
108
|
-
for ( const attribute in taskConfig.attributeTypes ) {
|
|
109
|
-
|
|
110
|
-
const type = taskConfig.attributeTypes[ attribute ];
|
|
111
|
-
|
|
112
|
-
if ( type.BYTES_PER_ELEMENT !== undefined ) {
|
|
113
|
-
|
|
114
|
-
taskConfig.attributeTypes[ attribute ] = type.name;
|
|
115
|
-
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
//
|
|
121
|
-
|
|
122
96
|
const taskKey = JSON.stringify( taskConfig );
|
|
123
97
|
|
|
124
98
|
// Check for an existing task using this buffer. A transferred buffer cannot be transferred
|
|
@@ -12,6 +12,7 @@ import {
|
|
|
12
12
|
FrontSide,
|
|
13
13
|
Group,
|
|
14
14
|
ImageBitmapLoader,
|
|
15
|
+
InstancedMesh,
|
|
15
16
|
InterleavedBuffer,
|
|
16
17
|
InterleavedBufferAttribute,
|
|
17
18
|
Interpolant,
|
|
@@ -147,6 +148,12 @@ class GLTFLoader extends Loader {
|
|
|
147
148
|
|
|
148
149
|
} );
|
|
149
150
|
|
|
151
|
+
this.register( function ( parser ) {
|
|
152
|
+
|
|
153
|
+
return new GLTFMeshGpuInstancing( parser );
|
|
154
|
+
|
|
155
|
+
} );
|
|
156
|
+
|
|
150
157
|
}
|
|
151
158
|
|
|
152
159
|
load( url, onLoad, onProgress, onError ) {
|
|
@@ -277,15 +284,15 @@ class GLTFLoader extends Loader {
|
|
|
277
284
|
|
|
278
285
|
parse( data, path, onLoad, onError ) {
|
|
279
286
|
|
|
280
|
-
let
|
|
287
|
+
let json;
|
|
281
288
|
const extensions = {};
|
|
282
289
|
const plugins = {};
|
|
283
290
|
|
|
284
291
|
if ( typeof data === 'string' ) {
|
|
285
292
|
|
|
286
|
-
|
|
293
|
+
json = JSON.parse( data );
|
|
287
294
|
|
|
288
|
-
} else {
|
|
295
|
+
} else if ( data instanceof ArrayBuffer ) {
|
|
289
296
|
|
|
290
297
|
const magic = LoaderUtils.decodeText( new Uint8Array( data, 0, 4 ) );
|
|
291
298
|
|
|
@@ -302,17 +309,19 @@ class GLTFLoader extends Loader {
|
|
|
302
309
|
|
|
303
310
|
}
|
|
304
311
|
|
|
305
|
-
|
|
312
|
+
json = JSON.parse( extensions[ EXTENSIONS.KHR_BINARY_GLTF ].content );
|
|
306
313
|
|
|
307
314
|
} else {
|
|
308
315
|
|
|
309
|
-
|
|
316
|
+
json = JSON.parse( LoaderUtils.decodeText( new Uint8Array( data ) ) );
|
|
310
317
|
|
|
311
318
|
}
|
|
312
319
|
|
|
313
|
-
}
|
|
320
|
+
} else {
|
|
314
321
|
|
|
315
|
-
|
|
322
|
+
json = data;
|
|
323
|
+
|
|
324
|
+
}
|
|
316
325
|
|
|
317
326
|
if ( json.asset === undefined || json.asset.version[ 0 ] < 2 ) {
|
|
318
327
|
|
|
@@ -468,7 +477,8 @@ const EXTENSIONS = {
|
|
|
468
477
|
KHR_MESH_QUANTIZATION: 'KHR_mesh_quantization',
|
|
469
478
|
KHR_MATERIALS_EMISSIVE_STRENGTH: 'KHR_materials_emissive_strength',
|
|
470
479
|
EXT_TEXTURE_WEBP: 'EXT_texture_webp',
|
|
471
|
-
EXT_MESHOPT_COMPRESSION: 'EXT_meshopt_compression'
|
|
480
|
+
EXT_MESHOPT_COMPRESSION: 'EXT_meshopt_compression',
|
|
481
|
+
EXT_MESH_GPU_INSTANCING: 'EXT_mesh_gpu_instancing'
|
|
472
482
|
};
|
|
473
483
|
|
|
474
484
|
/**
|
|
@@ -1044,7 +1054,7 @@ class GLTFMaterialsVolumeExtension {
|
|
|
1044
1054
|
|
|
1045
1055
|
}
|
|
1046
1056
|
|
|
1047
|
-
materialParams.attenuationDistance = extension.attenuationDistance ||
|
|
1057
|
+
materialParams.attenuationDistance = extension.attenuationDistance || Infinity;
|
|
1048
1058
|
|
|
1049
1059
|
const colorArray = extension.attenuationColor || [ 1, 1, 1 ];
|
|
1050
1060
|
materialParams.attenuationColor = new Color( colorArray[ 0 ], colorArray[ 1 ], colorArray[ 2 ] );
|
|
@@ -1341,7 +1351,7 @@ class GLTFMeshoptCompression {
|
|
|
1341
1351
|
|
|
1342
1352
|
}
|
|
1343
1353
|
|
|
1344
|
-
return
|
|
1354
|
+
return buffer.then( function ( res ) {
|
|
1345
1355
|
|
|
1346
1356
|
const byteOffset = extensionDef.byteOffset || 0;
|
|
1347
1357
|
const byteLength = extensionDef.byteLength || 0;
|
|
@@ -1349,11 +1359,28 @@ class GLTFMeshoptCompression {
|
|
|
1349
1359
|
const count = extensionDef.count;
|
|
1350
1360
|
const stride = extensionDef.byteStride;
|
|
1351
1361
|
|
|
1352
|
-
const
|
|
1353
|
-
|
|
1362
|
+
const source = new Uint8Array( res, byteOffset, byteLength );
|
|
1363
|
+
|
|
1364
|
+
if ( decoder.decodeGltfBufferAsync ) {
|
|
1365
|
+
|
|
1366
|
+
return decoder.decodeGltfBufferAsync( count, stride, source, extensionDef.mode, extensionDef.filter ).then( function ( res ) {
|
|
1354
1367
|
|
|
1355
|
-
|
|
1356
|
-
|
|
1368
|
+
return res.buffer;
|
|
1369
|
+
|
|
1370
|
+
} );
|
|
1371
|
+
|
|
1372
|
+
} else {
|
|
1373
|
+
|
|
1374
|
+
// Support for MeshoptDecoder 0.18 or earlier, without decodeGltfBufferAsync
|
|
1375
|
+
return decoder.ready.then( function () {
|
|
1376
|
+
|
|
1377
|
+
const result = new ArrayBuffer( count * stride );
|
|
1378
|
+
decoder.decodeGltfBuffer( new Uint8Array( result ), count, stride, source, extensionDef.mode, extensionDef.filter );
|
|
1379
|
+
return result;
|
|
1380
|
+
|
|
1381
|
+
} );
|
|
1382
|
+
|
|
1383
|
+
}
|
|
1357
1384
|
|
|
1358
1385
|
} );
|
|
1359
1386
|
|
|
@@ -1367,6 +1394,160 @@ class GLTFMeshoptCompression {
|
|
|
1367
1394
|
|
|
1368
1395
|
}
|
|
1369
1396
|
|
|
1397
|
+
/**
|
|
1398
|
+
* GPU Instancing Extension
|
|
1399
|
+
*
|
|
1400
|
+
* Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Vendor/EXT_mesh_gpu_instancing
|
|
1401
|
+
*
|
|
1402
|
+
*/
|
|
1403
|
+
class GLTFMeshGpuInstancing {
|
|
1404
|
+
|
|
1405
|
+
constructor( parser ) {
|
|
1406
|
+
|
|
1407
|
+
this.name = EXTENSIONS.EXT_MESH_GPU_INSTANCING;
|
|
1408
|
+
this.parser = parser;
|
|
1409
|
+
|
|
1410
|
+
}
|
|
1411
|
+
|
|
1412
|
+
createNodeMesh( nodeIndex ) {
|
|
1413
|
+
|
|
1414
|
+
const json = this.parser.json;
|
|
1415
|
+
const nodeDef = json.nodes[ nodeIndex ];
|
|
1416
|
+
|
|
1417
|
+
if ( ! nodeDef.extensions || ! nodeDef.extensions[ this.name ] ||
|
|
1418
|
+
nodeDef.mesh === undefined ) {
|
|
1419
|
+
|
|
1420
|
+
return null;
|
|
1421
|
+
|
|
1422
|
+
}
|
|
1423
|
+
|
|
1424
|
+
const meshDef = json.meshes[ nodeDef.mesh ];
|
|
1425
|
+
|
|
1426
|
+
// No Points or Lines + Instancing support yet
|
|
1427
|
+
|
|
1428
|
+
for ( const primitive of meshDef.primitives ) {
|
|
1429
|
+
|
|
1430
|
+
if ( primitive.mode !== WEBGL_CONSTANTS.TRIANGLES &&
|
|
1431
|
+
primitive.mode !== WEBGL_CONSTANTS.TRIANGLE_STRIP &&
|
|
1432
|
+
primitive.mode !== WEBGL_CONSTANTS.TRIANGLE_FAN &&
|
|
1433
|
+
primitive.mode !== undefined ) {
|
|
1434
|
+
|
|
1435
|
+
return null;
|
|
1436
|
+
|
|
1437
|
+
}
|
|
1438
|
+
|
|
1439
|
+
}
|
|
1440
|
+
|
|
1441
|
+
const extensionDef = nodeDef.extensions[ this.name ];
|
|
1442
|
+
const attributesDef = extensionDef.attributes;
|
|
1443
|
+
|
|
1444
|
+
// @TODO: Can we support InstancedMesh + SkinnedMesh?
|
|
1445
|
+
|
|
1446
|
+
const pending = [];
|
|
1447
|
+
const attributes = {};
|
|
1448
|
+
|
|
1449
|
+
for ( const key in attributesDef ) {
|
|
1450
|
+
|
|
1451
|
+
pending.push( this.parser.getDependency( 'accessor', attributesDef[ key ] ).then( accessor => {
|
|
1452
|
+
|
|
1453
|
+
attributes[ key ] = accessor;
|
|
1454
|
+
return attributes[ key ];
|
|
1455
|
+
|
|
1456
|
+
} ) );
|
|
1457
|
+
|
|
1458
|
+
}
|
|
1459
|
+
|
|
1460
|
+
if ( pending.length < 1 ) {
|
|
1461
|
+
|
|
1462
|
+
return null;
|
|
1463
|
+
|
|
1464
|
+
}
|
|
1465
|
+
|
|
1466
|
+
pending.push( this.parser.createNodeMesh( nodeIndex ) );
|
|
1467
|
+
|
|
1468
|
+
return Promise.all( pending ).then( results => {
|
|
1469
|
+
|
|
1470
|
+
const nodeObject = results.pop();
|
|
1471
|
+
const meshes = nodeObject.isGroup ? nodeObject.children : [ nodeObject ];
|
|
1472
|
+
const count = results[ 0 ].count; // All attribute counts should be same
|
|
1473
|
+
const instancedMeshes = [];
|
|
1474
|
+
|
|
1475
|
+
for ( const mesh of meshes ) {
|
|
1476
|
+
|
|
1477
|
+
// Temporal variables
|
|
1478
|
+
const m = new Matrix4();
|
|
1479
|
+
const p = new Vector3();
|
|
1480
|
+
const q = new Quaternion();
|
|
1481
|
+
const s = new Vector3( 1, 1, 1 );
|
|
1482
|
+
|
|
1483
|
+
const instancedMesh = new InstancedMesh( mesh.geometry, mesh.material, count );
|
|
1484
|
+
|
|
1485
|
+
for ( let i = 0; i < count; i ++ ) {
|
|
1486
|
+
|
|
1487
|
+
if ( attributes.TRANSLATION ) {
|
|
1488
|
+
|
|
1489
|
+
p.fromBufferAttribute( attributes.TRANSLATION, i );
|
|
1490
|
+
|
|
1491
|
+
}
|
|
1492
|
+
|
|
1493
|
+
if ( attributes.ROTATION ) {
|
|
1494
|
+
|
|
1495
|
+
q.fromBufferAttribute( attributes.ROTATION, i );
|
|
1496
|
+
|
|
1497
|
+
}
|
|
1498
|
+
|
|
1499
|
+
if ( attributes.SCALE ) {
|
|
1500
|
+
|
|
1501
|
+
s.fromBufferAttribute( attributes.SCALE, i );
|
|
1502
|
+
|
|
1503
|
+
}
|
|
1504
|
+
|
|
1505
|
+
instancedMesh.setMatrixAt( i, m.compose( p, q, s ) );
|
|
1506
|
+
|
|
1507
|
+
}
|
|
1508
|
+
|
|
1509
|
+
// Add instance attributes to the geometry, excluding TRS.
|
|
1510
|
+
for ( const attributeName in attributes ) {
|
|
1511
|
+
|
|
1512
|
+
if ( attributeName !== 'TRANSLATION' &&
|
|
1513
|
+
attributeName !== 'ROTATION' &&
|
|
1514
|
+
attributeName !== 'SCALE' ) {
|
|
1515
|
+
|
|
1516
|
+
mesh.geometry.setAttribute( attributeName, attributes[ attributeName ] );
|
|
1517
|
+
|
|
1518
|
+
}
|
|
1519
|
+
|
|
1520
|
+
}
|
|
1521
|
+
|
|
1522
|
+
// Just in case
|
|
1523
|
+
Object3D.prototype.copy.call( instancedMesh, mesh );
|
|
1524
|
+
|
|
1525
|
+
// https://github.com/mrdoob/three.js/issues/18334
|
|
1526
|
+
instancedMesh.frustumCulled = false;
|
|
1527
|
+
this.parser.assignFinalMaterial( instancedMesh );
|
|
1528
|
+
|
|
1529
|
+
instancedMeshes.push( instancedMesh );
|
|
1530
|
+
|
|
1531
|
+
}
|
|
1532
|
+
|
|
1533
|
+
if ( nodeObject.isGroup ) {
|
|
1534
|
+
|
|
1535
|
+
nodeObject.clear();
|
|
1536
|
+
|
|
1537
|
+
nodeObject.add( ... instancedMeshes );
|
|
1538
|
+
|
|
1539
|
+
return nodeObject;
|
|
1540
|
+
|
|
1541
|
+
}
|
|
1542
|
+
|
|
1543
|
+
return instancedMeshes[ 0 ];
|
|
1544
|
+
|
|
1545
|
+
} );
|
|
1546
|
+
|
|
1547
|
+
}
|
|
1548
|
+
|
|
1549
|
+
}
|
|
1550
|
+
|
|
1370
1551
|
/* BINARY EXTENSION */
|
|
1371
1552
|
const BINARY_EXTENSION_HEADER_MAGIC = 'glTF';
|
|
1372
1553
|
const BINARY_EXTENSION_HEADER_LENGTH = 12;
|
|
@@ -1487,7 +1668,7 @@ class GLTFDracoMeshCompressionExtension {
|
|
|
1487
1668
|
const accessorDef = json.accessors[ primitive.attributes[ attributeName ] ];
|
|
1488
1669
|
const componentType = WEBGL_COMPONENT_TYPES[ accessorDef.componentType ];
|
|
1489
1670
|
|
|
1490
|
-
attributeTypeMap[ threeAttributeName ] = componentType;
|
|
1671
|
+
attributeTypeMap[ threeAttributeName ] = componentType.name;
|
|
1491
1672
|
attributeNormalizedMap[ threeAttributeName ] = accessorDef.normalized === true;
|
|
1492
1673
|
|
|
1493
1674
|
}
|
|
@@ -3009,7 +3190,7 @@ class GLTFParser {
|
|
|
3009
3190
|
|
|
3010
3191
|
texture.flipY = false;
|
|
3011
3192
|
|
|
3012
|
-
|
|
3193
|
+
texture.name = textureDef.name || sourceDef.name || '';
|
|
3013
3194
|
|
|
3014
3195
|
const samplers = json.samplers || {};
|
|
3015
3196
|
const sampler = samplers[ textureDef.sampler ] || {};
|
|
@@ -3776,7 +3957,7 @@ class GLTFParser {
|
|
|
3776
3957
|
const channel = animationDef.channels[ i ];
|
|
3777
3958
|
const sampler = animationDef.samplers[ channel.sampler ];
|
|
3778
3959
|
const target = channel.target;
|
|
3779
|
-
const name = target.node
|
|
3960
|
+
const name = target.node;
|
|
3780
3961
|
const input = animationDef.parameters !== undefined ? animationDef.parameters[ sampler.input ] : sampler.input;
|
|
3781
3962
|
const output = animationDef.parameters !== undefined ? animationDef.parameters[ sampler.output ] : sampler.output;
|
|
3782
3963
|
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
|
|
14
14
|
import {
|
|
15
15
|
CompressedTexture,
|
|
16
|
+
CompressedArrayTexture,
|
|
16
17
|
Data3DTexture,
|
|
17
18
|
DataTexture,
|
|
18
19
|
FileLoader,
|
|
@@ -35,15 +36,15 @@ import {
|
|
|
35
36
|
RGBAFormat,
|
|
36
37
|
RGFormat,
|
|
37
38
|
sRGBEncoding,
|
|
38
|
-
UnsignedByteType
|
|
39
|
+
UnsignedByteType,
|
|
39
40
|
} from '../../../../three/src/Three.js';
|
|
40
41
|
import { WorkerPool } from '../utils/WorkerPool.js';
|
|
41
|
-
import
|
|
42
|
-
|
|
43
|
-
const {
|
|
42
|
+
import {
|
|
44
43
|
read,
|
|
45
44
|
KHR_DF_FLAG_ALPHA_PREMULTIPLIED,
|
|
46
45
|
KHR_DF_TRANSFER_SRGB,
|
|
46
|
+
KHR_SUPERCOMPRESSION_NONE,
|
|
47
|
+
KHR_SUPERCOMPRESSION_ZSTD,
|
|
47
48
|
VK_FORMAT_UNDEFINED,
|
|
48
49
|
VK_FORMAT_R16_SFLOAT,
|
|
49
50
|
VK_FORMAT_R16G16_SFLOAT,
|
|
@@ -57,12 +58,15 @@ const {
|
|
|
57
58
|
VK_FORMAT_R8G8_UNORM,
|
|
58
59
|
VK_FORMAT_R8G8B8A8_SRGB,
|
|
59
60
|
VK_FORMAT_R8G8B8A8_UNORM,
|
|
60
|
-
}
|
|
61
|
+
} from '../libs/ktx-parse.module.js';
|
|
62
|
+
import { ZSTDDecoder } from '../libs/zstddec.module.js';
|
|
61
63
|
|
|
62
64
|
const _taskCache = new WeakMap();
|
|
63
65
|
|
|
64
66
|
let _activeLoaders = 0;
|
|
65
67
|
|
|
68
|
+
let _zstd;
|
|
69
|
+
|
|
66
70
|
class KTX2Loader extends Loader {
|
|
67
71
|
|
|
68
72
|
constructor( manager ) {
|
|
@@ -233,16 +237,21 @@ class KTX2Loader extends Loader {
|
|
|
233
237
|
|
|
234
238
|
}
|
|
235
239
|
|
|
236
|
-
_createTextureFrom( transcodeResult ) {
|
|
240
|
+
_createTextureFrom( transcodeResult, container ) {
|
|
237
241
|
|
|
238
242
|
const { mipmaps, width, height, format, type, error, dfdTransferFn, dfdFlags } = transcodeResult;
|
|
239
243
|
|
|
240
244
|
if ( type === 'error' ) return Promise.reject( error );
|
|
241
245
|
|
|
242
|
-
const texture =
|
|
246
|
+
const texture = container.layerCount > 1
|
|
247
|
+
? new CompressedArrayTexture( mipmaps, width, height, container.layerCount, format, UnsignedByteType )
|
|
248
|
+
: new CompressedTexture( mipmaps, width, height, format, UnsignedByteType );
|
|
249
|
+
|
|
250
|
+
|
|
243
251
|
texture.minFilter = mipmaps.length === 1 ? LinearFilter : LinearMipmapLinearFilter;
|
|
244
252
|
texture.magFilter = LinearFilter;
|
|
245
253
|
texture.generateMipmaps = false;
|
|
254
|
+
|
|
246
255
|
texture.needsUpdate = true;
|
|
247
256
|
texture.encoding = dfdTransferFn === KHR_DF_TRANSFER_SRGB ? sRGBEncoding : LinearEncoding;
|
|
248
257
|
texture.premultiplyAlpha = !! ( dfdFlags & KHR_DF_FLAG_ALPHA_PREMULTIPLIED );
|
|
@@ -254,9 +263,9 @@ class KTX2Loader extends Loader {
|
|
|
254
263
|
/**
|
|
255
264
|
* @param {ArrayBuffer} buffer
|
|
256
265
|
* @param {object?} config
|
|
257
|
-
* @return {Promise<CompressedTexture|DataTexture|Data3DTexture>}
|
|
266
|
+
* @return {Promise<CompressedTexture|CompressedArrayTexture|DataTexture|Data3DTexture>}
|
|
258
267
|
*/
|
|
259
|
-
_createTexture( buffer, config = {} ) {
|
|
268
|
+
async _createTexture( buffer, config = {} ) {
|
|
260
269
|
|
|
261
270
|
const container = read( new Uint8Array( buffer ) );
|
|
262
271
|
|
|
@@ -267,13 +276,12 @@ class KTX2Loader extends Loader {
|
|
|
267
276
|
}
|
|
268
277
|
|
|
269
278
|
//
|
|
270
|
-
|
|
271
279
|
const taskConfig = config;
|
|
272
280
|
const texturePending = this.init().then( () => {
|
|
273
281
|
|
|
274
282
|
return this.workerPool.postMessage( { type: 'transcode', buffer, taskConfig: taskConfig }, [ buffer ] );
|
|
275
283
|
|
|
276
|
-
} ).then( ( e ) => this._createTextureFrom( e.data ) );
|
|
284
|
+
} ).then( ( e ) => this._createTextureFrom( e.data, container ) );
|
|
277
285
|
|
|
278
286
|
// Cache the task result.
|
|
279
287
|
_taskCache.set( buffer, { promise: texturePending } );
|
|
@@ -434,6 +442,7 @@ KTX2Loader.BasisWorker = function () {
|
|
|
434
442
|
const basisFormat = ktx2File.isUASTC() ? BasisFormat.UASTC_4x4 : BasisFormat.ETC1S;
|
|
435
443
|
const width = ktx2File.getWidth();
|
|
436
444
|
const height = ktx2File.getHeight();
|
|
445
|
+
const layers = ktx2File.getLayers() || 1;
|
|
437
446
|
const levels = ktx2File.getLevels();
|
|
438
447
|
const hasAlpha = ktx2File.getHasAlpha();
|
|
439
448
|
const dfdTransferFn = ktx2File.getDFDTransferFunc();
|
|
@@ -459,30 +468,39 @@ KTX2Loader.BasisWorker = function () {
|
|
|
459
468
|
|
|
460
469
|
for ( let mip = 0; mip < levels; mip ++ ) {
|
|
461
470
|
|
|
462
|
-
const
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
0,
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
471
|
+
const layerMips = [];
|
|
472
|
+
|
|
473
|
+
let mipWidth, mipHeight;
|
|
474
|
+
|
|
475
|
+
for ( let layer = 0; layer < layers; layer ++ ) {
|
|
476
|
+
|
|
477
|
+
const levelInfo = ktx2File.getImageLevelInfo( mip, layer, 0 );
|
|
478
|
+
mipWidth = levelInfo.origWidth;
|
|
479
|
+
mipHeight = levelInfo.origHeight;
|
|
480
|
+
const dst = new Uint8Array( ktx2File.getImageTranscodedSizeInBytes( mip, layer, 0, transcoderFormat ) );
|
|
481
|
+
const status = ktx2File.transcodeImage(
|
|
482
|
+
dst,
|
|
483
|
+
mip,
|
|
484
|
+
layer,
|
|
485
|
+
0,
|
|
486
|
+
transcoderFormat,
|
|
487
|
+
0,
|
|
488
|
+
- 1,
|
|
489
|
+
- 1,
|
|
490
|
+
);
|
|
491
|
+
|
|
492
|
+
if ( ! status ) {
|
|
493
|
+
|
|
494
|
+
cleanup();
|
|
495
|
+
throw new Error( 'THREE.KTX2Loader: .transcodeImage failed.' );
|
|
477
496
|
|
|
478
|
-
|
|
497
|
+
}
|
|
479
498
|
|
|
480
|
-
|
|
481
|
-
throw new Error( 'THREE.KTX2Loader: .transcodeImage failed.' );
|
|
499
|
+
layerMips.push( dst );
|
|
482
500
|
|
|
483
501
|
}
|
|
484
502
|
|
|
485
|
-
mipmaps.push( { data:
|
|
503
|
+
mipmaps.push( { data: concat( layerMips ), width: mipWidth, height: mipHeight } );
|
|
486
504
|
|
|
487
505
|
}
|
|
488
506
|
|
|
@@ -609,6 +627,33 @@ KTX2Loader.BasisWorker = function () {
|
|
|
609
627
|
|
|
610
628
|
}
|
|
611
629
|
|
|
630
|
+
/** Concatenates N byte arrays. */
|
|
631
|
+
function concat( arrays ) {
|
|
632
|
+
|
|
633
|
+
let totalByteLength = 0;
|
|
634
|
+
|
|
635
|
+
for ( const array of arrays ) {
|
|
636
|
+
|
|
637
|
+
totalByteLength += array.byteLength;
|
|
638
|
+
|
|
639
|
+
}
|
|
640
|
+
|
|
641
|
+
const result = new Uint8Array( totalByteLength );
|
|
642
|
+
|
|
643
|
+
let byteOffset = 0;
|
|
644
|
+
|
|
645
|
+
for ( const array of arrays ) {
|
|
646
|
+
|
|
647
|
+
result.set( array, byteOffset );
|
|
648
|
+
|
|
649
|
+
byteOffset += array.byteLength;
|
|
650
|
+
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
return result;
|
|
654
|
+
|
|
655
|
+
}
|
|
656
|
+
|
|
612
657
|
};
|
|
613
658
|
|
|
614
659
|
//
|
|
@@ -660,7 +705,7 @@ const ENCODING_MAP = {
|
|
|
660
705
|
|
|
661
706
|
};
|
|
662
707
|
|
|
663
|
-
function createDataTexture( container ) {
|
|
708
|
+
async function createDataTexture( container ) {
|
|
664
709
|
|
|
665
710
|
const { vkFormat, pixelWidth, pixelHeight, pixelDepth } = container;
|
|
666
711
|
|
|
@@ -670,11 +715,36 @@ function createDataTexture( container ) {
|
|
|
670
715
|
|
|
671
716
|
}
|
|
672
717
|
|
|
673
|
-
|
|
718
|
+
const level = container.levels[ 0 ];
|
|
674
719
|
|
|
720
|
+
let levelData;
|
|
675
721
|
let view;
|
|
676
722
|
|
|
677
|
-
|
|
723
|
+
if ( container.supercompressionScheme === KHR_SUPERCOMPRESSION_NONE ) {
|
|
724
|
+
|
|
725
|
+
levelData = level.levelData;
|
|
726
|
+
|
|
727
|
+
} else if ( container.supercompressionScheme === KHR_SUPERCOMPRESSION_ZSTD ) {
|
|
728
|
+
|
|
729
|
+
if ( ! _zstd ) {
|
|
730
|
+
|
|
731
|
+
_zstd = new Promise( async ( resolve ) => {
|
|
732
|
+
|
|
733
|
+
const zstd = new ZSTDDecoder();
|
|
734
|
+
await zstd.init();
|
|
735
|
+
resolve( zstd );
|
|
736
|
+
|
|
737
|
+
} );
|
|
738
|
+
|
|
739
|
+
}
|
|
740
|
+
|
|
741
|
+
levelData = ( await _zstd ).decode( level.levelData, level.uncompressedByteLength );
|
|
742
|
+
|
|
743
|
+
} else {
|
|
744
|
+
|
|
745
|
+
throw new Error( 'THREE.KTX2Loader: Unsupported supercompressionScheme.' );
|
|
746
|
+
|
|
747
|
+
}
|
|
678
748
|
|
|
679
749
|
if ( TYPE_MAP[ vkFormat ] === FloatType ) {
|
|
680
750
|
|
|
@@ -701,7 +771,6 @@ function createDataTexture( container ) {
|
|
|
701
771
|
view = levelData;
|
|
702
772
|
|
|
703
773
|
}
|
|
704
|
-
|
|
705
774
|
//
|
|
706
775
|
|
|
707
776
|
const texture = pixelDepth === 0
|
|
@@ -5,7 +5,6 @@ import {
|
|
|
5
5
|
InstancedBufferAttribute,
|
|
6
6
|
InterleavedBuffer,
|
|
7
7
|
InterleavedBufferAttribute,
|
|
8
|
-
MathUtils,
|
|
9
8
|
TriangleFanDrawMode,
|
|
10
9
|
TriangleStripDrawMode,
|
|
11
10
|
TrianglesDrawMode,
|
|
@@ -36,17 +35,16 @@ function computeMikkTSpaceTangents( geometry, MikkTSpace, negateSign = true ) {
|
|
|
36
35
|
|
|
37
36
|
if ( attribute.normalized || attribute.isInterleavedBufferAttribute ) {
|
|
38
37
|
|
|
39
|
-
const srcArray = attribute.isInterleavedBufferAttribute ? attribute.data.array : attribute.array;
|
|
40
38
|
const dstArray = new Float32Array( attribute.getCount() * attribute.itemSize );
|
|
41
39
|
|
|
42
40
|
for ( let i = 0, j = 0; i < attribute.getCount(); i ++ ) {
|
|
43
41
|
|
|
44
|
-
dstArray[ j ++ ] =
|
|
45
|
-
dstArray[ j ++ ] =
|
|
42
|
+
dstArray[ j ++ ] = attribute.getX( i );
|
|
43
|
+
dstArray[ j ++ ] = attribute.getY( i );
|
|
46
44
|
|
|
47
45
|
if ( attribute.itemSize > 2 ) {
|
|
48
46
|
|
|
49
|
-
dstArray[ j ++ ] =
|
|
47
|
+
dstArray[ j ++ ] = attribute.getZ( i );
|
|
50
48
|
|
|
51
49
|
}
|
|
52
50
|
|
|
@@ -194,11 +192,6 @@ function mergeBufferGeometries( geometries, useGroups = false ) {
|
|
|
194
192
|
|
|
195
193
|
}
|
|
196
194
|
|
|
197
|
-
// gather .userData
|
|
198
|
-
|
|
199
|
-
mergedGeometry.userData.mergedUserData = mergedGeometry.userData.mergedUserData || [];
|
|
200
|
-
mergedGeometry.userData.mergedUserData.push( geometry.userData );
|
|
201
|
-
|
|
202
195
|
if ( useGroups ) {
|
|
203
196
|
|
|
204
197
|
let count;
|
|
@@ -373,6 +366,28 @@ function mergeBufferAttributes( attributes ) {
|
|
|
373
366
|
|
|
374
367
|
}
|
|
375
368
|
|
|
369
|
+
/**
|
|
370
|
+
* @param {BufferAttribute}
|
|
371
|
+
* @return {BufferAttribute}
|
|
372
|
+
*/
|
|
373
|
+
export function deepCloneAttribute( attribute ) {
|
|
374
|
+
|
|
375
|
+
if ( attribute.isInstancedInterleavedBufferAttribute || attribute.isInterleavedBufferAttribute ) {
|
|
376
|
+
|
|
377
|
+
return deinterleaveAttribute( attribute );
|
|
378
|
+
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
if ( attribute.isInstancedBufferAttribute ) {
|
|
382
|
+
|
|
383
|
+
return new InstancedBufferAttribute().copy( attribute );
|
|
384
|
+
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
return new BufferAttribute().copy( attribute );
|
|
388
|
+
|
|
389
|
+
}
|
|
390
|
+
|
|
376
391
|
/**
|
|
377
392
|
* @param {Array<BufferAttribute>} attributes
|
|
378
393
|
* @return {Array<InterleavedBufferAttribute>}
|
|
@@ -385,7 +400,7 @@ function interleaveAttributes( attributes ) {
|
|
|
385
400
|
let arrayLength = 0;
|
|
386
401
|
let stride = 0;
|
|
387
402
|
|
|
388
|
-
// calculate the
|
|
403
|
+
// calculate the length and type of the interleavedBuffer
|
|
389
404
|
for ( let i = 0, l = attributes.length; i < l; ++ i ) {
|
|
390
405
|
|
|
391
406
|
const attribute = attributes[ i ];
|
|
@@ -555,7 +570,7 @@ function estimateBytesUsed( geometry ) {
|
|
|
555
570
|
/**
|
|
556
571
|
* @param {BufferGeometry} geometry
|
|
557
572
|
* @param {number} tolerance
|
|
558
|
-
* @return {BufferGeometry
|
|
573
|
+
* @return {BufferGeometry}
|
|
559
574
|
*/
|
|
560
575
|
function mergeVertices( geometry, tolerance = 1e-4 ) {
|
|
561
576
|
|
|
@@ -573,22 +588,33 @@ function mergeVertices( geometry, tolerance = 1e-4 ) {
|
|
|
573
588
|
|
|
574
589
|
// attributes and new attribute arrays
|
|
575
590
|
const attributeNames = Object.keys( geometry.attributes );
|
|
576
|
-
const
|
|
577
|
-
const
|
|
591
|
+
const tmpAttributes = {};
|
|
592
|
+
const tmpMorphAttributes = {};
|
|
578
593
|
const newIndices = [];
|
|
579
594
|
const getters = [ 'getX', 'getY', 'getZ', 'getW' ];
|
|
595
|
+
const setters = [ 'setX', 'setY', 'setZ', 'setW' ];
|
|
580
596
|
|
|
581
|
-
//
|
|
597
|
+
// Initialize the arrays, allocating space conservatively. Extra
|
|
598
|
+
// space will be trimmed in the last step.
|
|
582
599
|
for ( let i = 0, l = attributeNames.length; i < l; i ++ ) {
|
|
583
600
|
|
|
584
601
|
const name = attributeNames[ i ];
|
|
602
|
+
const attr = geometry.attributes[ name ];
|
|
585
603
|
|
|
586
|
-
|
|
604
|
+
tmpAttributes[ name ] = new BufferAttribute(
|
|
605
|
+
new attr.array.constructor( attr.count * attr.itemSize ),
|
|
606
|
+
attr.itemSize,
|
|
607
|
+
attr.normalized
|
|
608
|
+
);
|
|
587
609
|
|
|
588
610
|
const morphAttr = geometry.morphAttributes[ name ];
|
|
589
611
|
if ( morphAttr ) {
|
|
590
612
|
|
|
591
|
-
|
|
613
|
+
tmpMorphAttributes[ name ] = new BufferAttribute(
|
|
614
|
+
new morphAttr.array.constructor( morphAttr.count * morphAttr.itemSize ),
|
|
615
|
+
morphAttr.itemSize,
|
|
616
|
+
morphAttr.normalized
|
|
617
|
+
);
|
|
592
618
|
|
|
593
619
|
}
|
|
594
620
|
|
|
@@ -626,26 +652,27 @@ function mergeVertices( geometry, tolerance = 1e-4 ) {
|
|
|
626
652
|
|
|
627
653
|
} else {
|
|
628
654
|
|
|
629
|
-
// copy data to the new index in the
|
|
655
|
+
// copy data to the new index in the temporary attributes
|
|
630
656
|
for ( let j = 0, l = attributeNames.length; j < l; j ++ ) {
|
|
631
657
|
|
|
632
658
|
const name = attributeNames[ j ];
|
|
633
659
|
const attribute = geometry.getAttribute( name );
|
|
634
660
|
const morphAttr = geometry.morphAttributes[ name ];
|
|
635
661
|
const itemSize = attribute.itemSize;
|
|
636
|
-
const newarray =
|
|
637
|
-
const newMorphArrays =
|
|
662
|
+
const newarray = tmpAttributes[ name ];
|
|
663
|
+
const newMorphArrays = tmpMorphAttributes[ name ];
|
|
638
664
|
|
|
639
665
|
for ( let k = 0; k < itemSize; k ++ ) {
|
|
640
666
|
|
|
641
667
|
const getterFunc = getters[ k ];
|
|
642
|
-
|
|
668
|
+
const setterFunc = setters[ k ];
|
|
669
|
+
newarray[ setterFunc ]( nextIndex, attribute[ getterFunc ]( index ) );
|
|
643
670
|
|
|
644
671
|
if ( morphAttr ) {
|
|
645
672
|
|
|
646
673
|
for ( let m = 0, ml = morphAttr.length; m < ml; m ++ ) {
|
|
647
674
|
|
|
648
|
-
newMorphArrays[ m ]
|
|
675
|
+
newMorphArrays[ m ][ setterFunc ]( nextIndex, morphAttr[ m ][ getterFunc ]( index ) );
|
|
649
676
|
|
|
650
677
|
}
|
|
651
678
|
|
|
@@ -663,31 +690,29 @@ function mergeVertices( geometry, tolerance = 1e-4 ) {
|
|
|
663
690
|
|
|
664
691
|
}
|
|
665
692
|
|
|
666
|
-
//
|
|
667
|
-
// the attributeBuffers
|
|
693
|
+
// generate result BufferGeometry
|
|
668
694
|
const result = geometry.clone();
|
|
669
|
-
for (
|
|
670
|
-
|
|
671
|
-
const name = attributeNames[ i ];
|
|
672
|
-
const oldAttribute = geometry.getAttribute( name );
|
|
673
|
-
|
|
674
|
-
const buffer = new oldAttribute.array.constructor( attrArrays[ name ] );
|
|
675
|
-
const attribute = new BufferAttribute( buffer, oldAttribute.itemSize, oldAttribute.normalized );
|
|
695
|
+
for ( const name in geometry.attributes ) {
|
|
676
696
|
|
|
677
|
-
|
|
697
|
+
const tmpAttribute = tmpAttributes[ name ];
|
|
678
698
|
|
|
679
|
-
|
|
680
|
-
|
|
699
|
+
result.setAttribute( name, new BufferAttribute(
|
|
700
|
+
tmpAttribute.array.slice( 0, nextIndex * tmpAttribute.itemSize ),
|
|
701
|
+
tmpAttribute.itemSize,
|
|
702
|
+
tmpAttribute.normalized,
|
|
703
|
+
) );
|
|
681
704
|
|
|
682
|
-
|
|
705
|
+
if ( ! ( name in tmpMorphAttributes ) ) continue;
|
|
683
706
|
|
|
684
|
-
|
|
707
|
+
for ( let j = 0; j < tmpMorphAttributes[ name ].length; j ++ ) {
|
|
685
708
|
|
|
686
|
-
|
|
687
|
-
const morphAttribute = new BufferAttribute( buffer, oldMorphAttribute.itemSize, oldMorphAttribute.normalized );
|
|
688
|
-
result.morphAttributes[ name ][ j ] = morphAttribute;
|
|
709
|
+
const tmpMorphAttribute = tmpMorphAttributes[ name ][ j ];
|
|
689
710
|
|
|
690
|
-
|
|
711
|
+
result.morphAttributes[ name ][ j ] = new BufferAttribute(
|
|
712
|
+
tmpMorphAttribute.array.slice( 0, nextIndex * tmpMorphAttribute.itemSize ),
|
|
713
|
+
tmpMorphAttribute.itemSize,
|
|
714
|
+
tmpMorphAttribute.normalized,
|
|
715
|
+
);
|
|
691
716
|
|
|
692
717
|
}
|
|
693
718
|
|
|
@@ -704,7 +729,7 @@ function mergeVertices( geometry, tolerance = 1e-4 ) {
|
|
|
704
729
|
/**
|
|
705
730
|
* @param {BufferGeometry} geometry
|
|
706
731
|
* @param {number} drawMode
|
|
707
|
-
* @return {BufferGeometry
|
|
732
|
+
* @return {BufferGeometry}
|
|
708
733
|
*/
|
|
709
734
|
function toTrianglesDrawMode( geometry, drawMode ) {
|
|
710
735
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@damienmortini/three",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.173",
|
|
4
4
|
"description": "Three.js helpers",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"install": "npm run copyexamples",
|
|
@@ -25,9 +25,9 @@
|
|
|
25
25
|
"bugs": "https://github.com/damienmortini/lib/issues",
|
|
26
26
|
"homepage": "https://github.com/damienmortini/lib/tree/main/packages/three",
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@damienmortini/core": "^0.2.
|
|
28
|
+
"@damienmortini/core": "^0.2.135",
|
|
29
29
|
"fs-extra": "^10.1.0",
|
|
30
|
-
"three": "0.
|
|
30
|
+
"three": "0.146.0"
|
|
31
31
|
},
|
|
32
|
-
"gitHead": "
|
|
32
|
+
"gitHead": "2eeafcaa9fe81bdec2dc81d847962be4a821f5eb"
|
|
33
33
|
}
|