super-three 0.136.1 → 0.137.0
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.
- package/README.md +1 -1
- package/build/three.cjs +37132 -0
- package/build/three.js +71 -53
- package/build/three.min.js +2 -2
- package/build/three.module.js +80 -47
- package/examples/js/animation/MMDAnimationHelper.js +3 -1
- package/examples/js/controls/experimental/CameraControls.js +6 -2
- package/examples/js/exporters/GLTFExporter.js +82 -39
- package/examples/js/geometries/TextGeometry.js +12 -10
- package/examples/js/interactive/HTMLMesh.js +14 -2
- package/examples/js/loaders/EXRLoader.js +20 -9
- package/examples/js/loaders/GLTFLoader.js +1 -1
- package/examples/js/loaders/LDrawLoader.js +541 -425
- package/examples/js/loaders/MD2Loader.js +5 -5
- package/examples/js/loaders/MTLLoader.js +10 -3
- package/examples/js/loaders/PCDLoader.js +2 -2
- package/examples/js/loaders/STLLoader.js +1 -1
- package/examples/js/loaders/SVGLoader.js +3 -2
- package/examples/js/modifiers/EdgeSplitModifier.js +0 -6
- package/examples/js/modifiers/SimplifyModifier.js +0 -10
- package/examples/js/objects/Lensflare.js +2 -2
- package/examples/js/postprocessing/OutlinePass.js +1 -5
- package/examples/js/renderers/CSS2DRenderer.js +25 -19
- package/examples/js/renderers/CSS3DRenderer.js +37 -32
- package/examples/js/utils/LDrawUtils.js +182 -0
- package/examples/jsm/exporters/GLTFExporter.js +80 -12
- package/examples/jsm/geometries/TextGeometry.js +13 -13
- package/examples/jsm/interactive/HTMLMesh.js +16 -2
- package/examples/jsm/libs/flow.module.js +930 -169
- package/examples/jsm/loaders/EXRLoader.js +19 -9
- package/examples/jsm/loaders/GLTFLoader.js +1 -1
- package/examples/jsm/loaders/LDrawLoader.js +534 -442
- package/examples/jsm/loaders/MD2Loader.js +5 -5
- package/examples/jsm/loaders/MTLLoader.js +11 -4
- package/examples/jsm/loaders/PCDLoader.js +2 -2
- package/examples/jsm/loaders/STLLoader.js +1 -1
- package/examples/jsm/loaders/SVGLoader.js +3 -1
- package/examples/jsm/loaders/VRMLLoader.js +0 -1
- package/examples/jsm/modifiers/EdgeSplitModifier.js +0 -6
- package/examples/jsm/modifiers/SimplifyModifier.js +0 -10
- package/examples/jsm/node-editor/NodeEditor.js +435 -181
- package/examples/jsm/node-editor/accessors/NormalEditor.js +8 -8
- package/examples/jsm/node-editor/accessors/PositionEditor.js +8 -8
- package/examples/jsm/node-editor/accessors/UVEditor.js +6 -7
- package/examples/jsm/node-editor/core/BaseNode.js +83 -0
- package/examples/jsm/node-editor/display/BlendEditor.js +7 -6
- package/examples/jsm/node-editor/examples/animate-uv.json +1 -1
- package/examples/jsm/node-editor/examples/fake-top-light.json +1 -1
- package/examples/jsm/node-editor/examples/oscillator-color.json +1 -1
- package/examples/jsm/node-editor/examples/rim.json +1 -1
- package/examples/jsm/node-editor/inputs/ColorEditor.js +14 -10
- package/examples/jsm/node-editor/inputs/FloatEditor.js +6 -7
- package/examples/jsm/node-editor/inputs/SliderEditor.js +4 -5
- package/examples/jsm/node-editor/inputs/Vector2Editor.js +6 -7
- package/examples/jsm/node-editor/inputs/Vector3Editor.js +8 -9
- package/examples/jsm/node-editor/inputs/Vector4Editor.js +9 -10
- package/examples/jsm/node-editor/materials/BasicMaterialEditor.js +87 -0
- package/examples/jsm/node-editor/materials/PointsMaterialEditor.js +97 -0
- package/examples/jsm/node-editor/materials/StandardMaterialEditor.js +20 -17
- package/examples/jsm/node-editor/math/AngleEditor.js +39 -0
- package/examples/jsm/node-editor/math/DotEditor.js +6 -7
- package/examples/jsm/node-editor/math/InvertEditor.js +4 -3
- package/examples/jsm/node-editor/math/LimiterEditor.js +11 -10
- package/examples/jsm/node-editor/math/NormalizeEditor.js +6 -5
- package/examples/jsm/node-editor/math/OperatorEditor.js +12 -11
- package/examples/jsm/node-editor/math/PowerEditor.js +6 -5
- package/examples/jsm/node-editor/math/TrigonometryEditor.js +12 -7
- package/examples/jsm/node-editor/procedural/CheckerEditor.js +4 -3
- package/examples/jsm/node-editor/scene/MeshEditor.js +99 -0
- package/examples/jsm/node-editor/scene/Object3DEditor.js +160 -0
- package/examples/jsm/node-editor/scene/PointsEditor.js +99 -0
- package/examples/jsm/node-editor/utils/JoinEditor.js +58 -0
- package/examples/jsm/node-editor/utils/OscillatorEditor.js +7 -6
- package/examples/jsm/node-editor/utils/SplitEditor.js +39 -0
- package/examples/jsm/node-editor/utils/TimerEditor.js +6 -5
- package/examples/jsm/postprocessing/OutlinePass.js +1 -4
- package/examples/jsm/renderers/CSS2DRenderer.js +24 -19
- package/examples/jsm/renderers/CSS3DRenderer.js +36 -30
- package/examples/jsm/renderers/nodes/accessors/UVNode.js +4 -4
- package/examples/jsm/renderers/nodes/core/NodeBuilder.js +2 -1
- package/examples/jsm/renderers/nodes/utils/SplitNode.js +19 -4
- package/examples/jsm/utils/LDrawUtils.js +18 -11
- package/package.json +16 -9
- package/src/constants.js +1 -3
- package/src/core/BufferGeometry.js +2 -2
- package/src/geometries/LatheGeometry.js +1 -1
- package/src/loaders/FileLoader.js +20 -3
- package/src/math/Box3.js +24 -10
- package/src/renderers/WebGLRenderTarget.js +4 -1
- package/src/renderers/WebGLRenderer.js +3 -3
- package/src/renderers/shaders/ShaderChunk/morphnormal_vertex.glsl.js +1 -1
- package/src/renderers/shaders/ShaderChunk/morphtarget_vertex.glsl.js +2 -2
- package/src/renderers/webgl/WebGLBackground.js +2 -2
- package/src/renderers/webgl/WebGLGeometries.js +2 -2
- package/src/renderers/webgl/WebGLPrograms.js +2 -2
- package/src/renderers/webgl/WebGLState.js +2 -2
- package/src/renderers/webgl/WebGLTextures.js +9 -6
- package/src/renderers/webgl/WebGLUtils.js +1 -3
- package/src/renderers/webxr/WebXRManager.js +2 -0
- package/src/utils.js +15 -1
|
@@ -114,7 +114,7 @@
|
|
|
114
114
|
|
|
115
115
|
for ( let j = 0; j < 16; j ++ ) {
|
|
116
116
|
|
|
117
|
-
const character = data.getUint8( offset + j
|
|
117
|
+
const character = data.getUint8( offset + j );
|
|
118
118
|
if ( character === 0 ) break;
|
|
119
119
|
string[ j ] = character;
|
|
120
120
|
|
|
@@ -129,11 +129,11 @@
|
|
|
129
129
|
|
|
130
130
|
for ( let j = 0; j < header.num_vertices; j ++ ) {
|
|
131
131
|
|
|
132
|
-
let x = data.getUint8( offset
|
|
133
|
-
let y = data.getUint8( offset
|
|
134
|
-
let z = data.getUint8( offset
|
|
132
|
+
let x = data.getUint8( offset ++ );
|
|
133
|
+
let y = data.getUint8( offset ++ );
|
|
134
|
+
let z = data.getUint8( offset ++ );
|
|
135
135
|
|
|
136
|
-
const n = _normalData[ data.getUint8( offset
|
|
136
|
+
const n = _normalData[ data.getUint8( offset ++ ) ];
|
|
137
137
|
|
|
138
138
|
x = x * scale.x + translation.x;
|
|
139
139
|
y = y * scale.y + translation.y;
|
|
@@ -327,6 +327,13 @@
|
|
|
327
327
|
map.offset.copy( texParams.offset );
|
|
328
328
|
map.wrapS = scope.wrap;
|
|
329
329
|
map.wrapT = scope.wrap;
|
|
330
|
+
|
|
331
|
+
if ( mapType === 'map' || mapType === 'emissiveMap' ) {
|
|
332
|
+
|
|
333
|
+
map.encoding = THREE.sRGBEncoding;
|
|
334
|
+
|
|
335
|
+
}
|
|
336
|
+
|
|
330
337
|
params[ mapType ] = map;
|
|
331
338
|
|
|
332
339
|
}
|
|
@@ -342,17 +349,17 @@
|
|
|
342
349
|
// Ns is material specular exponent
|
|
343
350
|
case 'kd':
|
|
344
351
|
// Diffuse color (color under white light) using RGB values
|
|
345
|
-
params.color = new THREE.Color().fromArray( value );
|
|
352
|
+
params.color = new THREE.Color().fromArray( value ).convertSRGBToLinear();
|
|
346
353
|
break;
|
|
347
354
|
|
|
348
355
|
case 'ks':
|
|
349
356
|
// Specular color (color when light is reflected from shiny surface) using RGB values
|
|
350
|
-
params.specular = new THREE.Color().fromArray( value );
|
|
357
|
+
params.specular = new THREE.Color().fromArray( value ).convertSRGBToLinear();
|
|
351
358
|
break;
|
|
352
359
|
|
|
353
360
|
case 'ke':
|
|
354
361
|
// Emissive using RGB values
|
|
355
|
-
params.emissive = new THREE.Color().fromArray( value );
|
|
362
|
+
params.emissive = new THREE.Color().fromArray( value ).convertSRGBToLinear();
|
|
356
363
|
break;
|
|
357
364
|
|
|
358
365
|
case 'map_kd':
|
|
@@ -262,9 +262,9 @@
|
|
|
262
262
|
|
|
263
263
|
if ( offset.rgb !== undefined ) {
|
|
264
264
|
|
|
265
|
-
color.push( dataview.getUint8( PCDheader.points * offset.rgb + PCDheader.size[ 3 ] * i + 0 ) / 255.0 );
|
|
266
|
-
color.push( dataview.getUint8( PCDheader.points * offset.rgb + PCDheader.size[ 3 ] * i + 1 ) / 255.0 );
|
|
267
265
|
color.push( dataview.getUint8( PCDheader.points * offset.rgb + PCDheader.size[ 3 ] * i + 2 ) / 255.0 );
|
|
266
|
+
color.push( dataview.getUint8( PCDheader.points * offset.rgb + PCDheader.size[ 3 ] * i + 1 ) / 255.0 );
|
|
267
|
+
color.push( dataview.getUint8( PCDheader.points * offset.rgb + PCDheader.size[ 3 ] * i + 0 ) / 255.0 );
|
|
268
268
|
|
|
269
269
|
}
|
|
270
270
|
|
|
@@ -134,7 +134,7 @@
|
|
|
134
134
|
// Check if each byte in query matches the corresponding byte from the current offset
|
|
135
135
|
for ( let i = 0, il = query.length; i < il; i ++ ) {
|
|
136
136
|
|
|
137
|
-
if ( query[ i ] !== reader.getUint8( offset + i
|
|
137
|
+
if ( query[ i ] !== reader.getUint8( offset + i ) ) return false;
|
|
138
138
|
|
|
139
139
|
}
|
|
140
140
|
|
|
@@ -110,7 +110,8 @@
|
|
|
110
110
|
|
|
111
111
|
case 'use':
|
|
112
112
|
style = parseStyle( node, style );
|
|
113
|
-
const
|
|
113
|
+
const href = node.getAttributeNS( 'http://www.w3.org/1999/xlink', 'href' ) || '';
|
|
114
|
+
const usedNodeId = href.substring( 1 );
|
|
114
115
|
const usedNode = node.viewportElement.getElementById( usedNodeId );
|
|
115
116
|
|
|
116
117
|
if ( usedNode ) {
|
|
@@ -561,7 +562,7 @@
|
|
|
561
562
|
for ( let j = 0; j < selectorList.length; j ++ ) {
|
|
562
563
|
|
|
563
564
|
// Remove empty rules
|
|
564
|
-
const definitions = Object.fromEntries( Object.entries( stylesheet.style ).filter( ( [
|
|
565
|
+
const definitions = Object.fromEntries( Object.entries( stylesheet.style ).filter( ( [ , v ] ) => v !== '' ) );
|
|
565
566
|
stylesheets[ selectorList[ j ] ] = Object.assign( stylesheets[ selectorList[ j ] ] || {}, definitions );
|
|
566
567
|
|
|
567
568
|
}
|
|
@@ -166,12 +166,6 @@
|
|
|
166
166
|
|
|
167
167
|
if ( geometry.index == null ) {
|
|
168
168
|
|
|
169
|
-
if ( THREE.BufferGeometryUtils === undefined ) {
|
|
170
|
-
|
|
171
|
-
throw new Error( 'THREE.EdgeSplitModifier relies on THREE.BufferGeometryUtils' );
|
|
172
|
-
|
|
173
|
-
}
|
|
174
|
-
|
|
175
169
|
geometry = THREE.BufferGeometryUtils.mergeVertices( geometry );
|
|
176
170
|
|
|
177
171
|
}
|
|
@@ -13,16 +13,6 @@
|
|
|
13
13
|
|
|
14
14
|
class SimplifyModifier {
|
|
15
15
|
|
|
16
|
-
constructor() {
|
|
17
|
-
|
|
18
|
-
if ( THREE.BufferGeometryUtils === undefined ) {
|
|
19
|
-
|
|
20
|
-
throw new Error( 'THREE.SimplifyModifier relies on THREE.BufferGeometryUtils' );
|
|
21
|
-
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
}
|
|
25
|
-
|
|
26
16
|
modify( geometry, count ) {
|
|
27
17
|
|
|
28
18
|
if ( geometry.isGeometry === true ) {
|
|
@@ -15,8 +15,8 @@
|
|
|
15
15
|
const positionScreen = new THREE.Vector3();
|
|
16
16
|
const positionView = new THREE.Vector3(); // textures
|
|
17
17
|
|
|
18
|
-
const tempMap = new THREE.FramebufferTexture( 16, 16, THREE.
|
|
19
|
-
const occlusionMap = new THREE.FramebufferTexture( 16, 16, THREE.
|
|
18
|
+
const tempMap = new THREE.FramebufferTexture( 16, 16, THREE.RGBAFormat );
|
|
19
|
+
const occlusionMap = new THREE.FramebufferTexture( 16, 16, THREE.RGBAFormat ); // material
|
|
20
20
|
|
|
21
21
|
const geometry = Lensflare.Geometry;
|
|
22
22
|
const material1a = new THREE.RawShaderMaterial( {
|
|
@@ -25,10 +25,6 @@
|
|
|
25
25
|
};
|
|
26
26
|
const resx = Math.round( this.resolution.x / this.downSampleRatio );
|
|
27
27
|
const resy = Math.round( this.resolution.y / this.downSampleRatio );
|
|
28
|
-
this.maskBufferMaterial = new THREE.MeshBasicMaterial( {
|
|
29
|
-
color: 0xffffff
|
|
30
|
-
} );
|
|
31
|
-
this.maskBufferMaterial.side = THREE.DoubleSide;
|
|
32
28
|
this.renderTargetMaskBuffer = new THREE.WebGLRenderTarget( this.resolution.x, this.resolution.y, pars );
|
|
33
29
|
this.renderTargetMaskBuffer.texture.name = 'OutlinePass.mask';
|
|
34
30
|
this.renderTargetMaskBuffer.texture.generateMipmaps = false;
|
|
@@ -93,7 +89,7 @@
|
|
|
93
89
|
|
|
94
90
|
function replaceDepthToViewZ( string, camera ) {
|
|
95
91
|
|
|
96
|
-
|
|
92
|
+
const type = camera.isPerspectiveCamera ? 'perspective' : 'orthographic';
|
|
97
93
|
return string.replace( /DEPTH_TO_VIEW_Z/g, type + 'DepthToViewZ' );
|
|
98
94
|
|
|
99
95
|
}
|
|
@@ -102,38 +102,44 @@
|
|
|
102
102
|
|
|
103
103
|
if ( object.isCSS2DObject ) {
|
|
104
104
|
|
|
105
|
-
object.
|
|
105
|
+
const visible = object.visible && _vector.z >= - 1 && _vector.z <= 1 && object.layers.test( camera.layers );
|
|
106
|
+
object.element.style.display = visible ? '' : 'none';
|
|
106
107
|
|
|
107
|
-
|
|
108
|
+
if ( visible ) {
|
|
108
109
|
|
|
109
|
-
|
|
110
|
+
object.onBeforeRender( _this, scene, camera );
|
|
110
111
|
|
|
111
|
-
|
|
112
|
+
_vector.setFromMatrixPosition( object.matrixWorld );
|
|
112
113
|
|
|
113
|
-
|
|
114
|
+
_vector.applyMatrix4( _viewProjectionMatrix );
|
|
114
115
|
|
|
115
|
-
|
|
116
|
-
element.style.transform = 'translate(-50%,-50%) translate(' + Math.round( _vector.x * _widthHalf + _widthHalf ) + 'px,' + Math.round( - _vector.y * _heightHalf + _heightHalf ) + 'px)';
|
|
116
|
+
const element = object.element;
|
|
117
117
|
|
|
118
|
-
|
|
118
|
+
if ( /apple/i.test( navigator.vendor ) ) {
|
|
119
119
|
|
|
120
|
-
|
|
120
|
+
// https://github.com/mrdoob/three.js/issues/21415
|
|
121
|
+
element.style.transform = 'translate(-50%,-50%) translate(' + Math.round( _vector.x * _widthHalf + _widthHalf ) + 'px,' + Math.round( - _vector.y * _heightHalf + _heightHalf ) + 'px)';
|
|
121
122
|
|
|
122
|
-
|
|
123
|
+
} else {
|
|
123
124
|
|
|
124
|
-
|
|
125
|
-
const objectData = {
|
|
126
|
-
distanceToCameraSquared: getDistanceToSquared( camera, object )
|
|
127
|
-
};
|
|
128
|
-
cache.objects.set( object, objectData );
|
|
125
|
+
element.style.transform = 'translate(-50%,-50%) translate(' + ( _vector.x * _widthHalf + _widthHalf ) + 'px,' + ( - _vector.y * _heightHalf + _heightHalf ) + 'px)';
|
|
129
126
|
|
|
130
|
-
|
|
127
|
+
}
|
|
131
128
|
|
|
132
|
-
|
|
129
|
+
const objectData = {
|
|
130
|
+
distanceToCameraSquared: getDistanceToSquared( camera, object )
|
|
131
|
+
};
|
|
132
|
+
cache.objects.set( object, objectData );
|
|
133
133
|
|
|
134
|
-
|
|
134
|
+
if ( element.parentNode !== domElement ) {
|
|
135
|
+
|
|
136
|
+
domElement.appendChild( element );
|
|
135
137
|
|
|
136
|
-
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
object.onAfterRender( _this, scene, camera );
|
|
141
|
+
|
|
142
|
+
}
|
|
137
143
|
|
|
138
144
|
}
|
|
139
145
|
|
|
@@ -181,57 +181,62 @@
|
|
|
181
181
|
|
|
182
182
|
if ( object.isCSS3DObject ) {
|
|
183
183
|
|
|
184
|
-
object.
|
|
185
|
-
|
|
184
|
+
const visible = object.visible && object.layers.test( camera.layers );
|
|
185
|
+
object.element.style.display = visible ? '' : 'none'; // only getObjectCSSMatrix when object.visible
|
|
186
186
|
|
|
187
|
-
if (
|
|
187
|
+
if ( visible ) {
|
|
188
188
|
|
|
189
|
-
|
|
190
|
-
|
|
189
|
+
object.onBeforeRender( _this, scene, camera );
|
|
190
|
+
let style;
|
|
191
191
|
|
|
192
|
-
|
|
192
|
+
if ( object.isCSS3DSprite ) {
|
|
193
193
|
|
|
194
|
-
|
|
195
|
-
|
|
194
|
+
// http://swiftcoder.wordpress.com/2008/11/25/constructing-a-billboard-matrix/
|
|
195
|
+
_matrix.copy( camera.matrixWorldInverse );
|
|
196
196
|
|
|
197
|
-
|
|
197
|
+
_matrix.transpose();
|
|
198
198
|
|
|
199
|
-
|
|
199
|
+
if ( object.rotation2D !== 0 ) _matrix.multiply( _matrix2.makeRotationZ( object.rotation2D ) );
|
|
200
|
+
object.matrixWorld.decompose( _position, _quaternion, _scale );
|
|
200
201
|
|
|
201
|
-
|
|
202
|
-
_matrix.elements[ 7 ] = 0;
|
|
203
|
-
_matrix.elements[ 11 ] = 0;
|
|
204
|
-
_matrix.elements[ 15 ] = 1;
|
|
205
|
-
style = getObjectCSSMatrix( _matrix );
|
|
202
|
+
_matrix.setPosition( _position );
|
|
206
203
|
|
|
207
|
-
|
|
204
|
+
_matrix.scale( _scale );
|
|
208
205
|
|
|
209
|
-
|
|
206
|
+
_matrix.elements[ 3 ] = 0;
|
|
207
|
+
_matrix.elements[ 7 ] = 0;
|
|
208
|
+
_matrix.elements[ 11 ] = 0;
|
|
209
|
+
_matrix.elements[ 15 ] = 1;
|
|
210
|
+
style = getObjectCSSMatrix( _matrix );
|
|
210
211
|
|
|
211
|
-
|
|
212
|
+
} else {
|
|
212
213
|
|
|
213
|
-
|
|
214
|
-
const cachedObject = cache.objects.get( object );
|
|
214
|
+
style = getObjectCSSMatrix( object.matrixWorld );
|
|
215
215
|
|
|
216
|
-
|
|
216
|
+
}
|
|
217
217
|
|
|
218
|
-
element
|
|
219
|
-
const
|
|
220
|
-
style: style
|
|
221
|
-
};
|
|
222
|
-
cache.objects.set( object, objectData );
|
|
218
|
+
const element = object.element;
|
|
219
|
+
const cachedObject = cache.objects.get( object );
|
|
223
220
|
|
|
224
|
-
|
|
221
|
+
if ( cachedObject === undefined || cachedObject.style !== style ) {
|
|
225
222
|
|
|
226
|
-
|
|
223
|
+
element.style.transform = style;
|
|
224
|
+
const objectData = {
|
|
225
|
+
style: style
|
|
226
|
+
};
|
|
227
|
+
cache.objects.set( object, objectData );
|
|
227
228
|
|
|
228
|
-
|
|
229
|
+
}
|
|
229
230
|
|
|
230
|
-
|
|
231
|
+
if ( element.parentNode !== cameraElement ) {
|
|
231
232
|
|
|
232
|
-
|
|
233
|
+
cameraElement.appendChild( element );
|
|
233
234
|
|
|
234
|
-
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
object.onAfterRender( _this, scene, camera );
|
|
238
|
+
|
|
239
|
+
}
|
|
235
240
|
|
|
236
241
|
}
|
|
237
242
|
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
( function () {
|
|
2
|
+
|
|
3
|
+
class LDrawUtils {
|
|
4
|
+
|
|
5
|
+
static mergeObject( object ) {
|
|
6
|
+
|
|
7
|
+
// Merges geometries in object by materials and returns new object. Use on not indexed geometries.
|
|
8
|
+
// The object buffers reference the old object ones.
|
|
9
|
+
// Special treatment is done to the conditional lines generated by LDrawLoader.
|
|
10
|
+
function extractGroup( geometry, group, elementSize, isConditionalLine ) {
|
|
11
|
+
|
|
12
|
+
// Extracts a group from a geometry as a new geometry (with attribute buffers referencing original buffers)
|
|
13
|
+
const newGeometry = new THREE.BufferGeometry();
|
|
14
|
+
const originalPositions = geometry.getAttribute( 'position' ).array;
|
|
15
|
+
const originalNormals = elementSize === 3 ? geometry.getAttribute( 'normal' ).array : null;
|
|
16
|
+
const numVertsGroup = Math.min( group.count, Math.floor( originalPositions.length / 3 ) - group.start );
|
|
17
|
+
const vertStart = group.start * 3;
|
|
18
|
+
const vertEnd = ( group.start + numVertsGroup ) * 3;
|
|
19
|
+
const positions = originalPositions.subarray( vertStart, vertEnd );
|
|
20
|
+
const normals = originalNormals !== null ? originalNormals.subarray( vertStart, vertEnd ) : null;
|
|
21
|
+
newGeometry.setAttribute( 'position', new THREE.BufferAttribute( positions, 3 ) );
|
|
22
|
+
if ( normals !== null ) newGeometry.setAttribute( 'normal', new THREE.BufferAttribute( normals, 3 ) );
|
|
23
|
+
|
|
24
|
+
if ( isConditionalLine ) {
|
|
25
|
+
|
|
26
|
+
const controlArray0 = geometry.getAttribute( 'control0' ).array.subarray( vertStart, vertEnd );
|
|
27
|
+
const controlArray1 = geometry.getAttribute( 'control1' ).array.subarray( vertStart, vertEnd );
|
|
28
|
+
const directionArray = geometry.getAttribute( 'direction' ).array.subarray( vertStart, vertEnd );
|
|
29
|
+
newGeometry.setAttribute( 'control0', new THREE.BufferAttribute( controlArray0, 3, false ) );
|
|
30
|
+
newGeometry.setAttribute( 'control1', new THREE.BufferAttribute( controlArray1, 3, false ) );
|
|
31
|
+
newGeometry.setAttribute( 'direction', new THREE.BufferAttribute( directionArray, 3, false ) );
|
|
32
|
+
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return newGeometry;
|
|
36
|
+
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function addGeometry( mat, geometry, geometries ) {
|
|
40
|
+
|
|
41
|
+
const geoms = geometries[ mat.uuid ];
|
|
42
|
+
|
|
43
|
+
if ( ! geoms ) {
|
|
44
|
+
|
|
45
|
+
geometries[ mat.uuid ] = {
|
|
46
|
+
mat: mat,
|
|
47
|
+
arr: [ geometry ]
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
} else {
|
|
51
|
+
|
|
52
|
+
geoms.arr.push( geometry );
|
|
53
|
+
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function permuteAttribute( attribute, elemSize ) {
|
|
59
|
+
|
|
60
|
+
// Permutes first two vertices of each attribute element
|
|
61
|
+
if ( ! attribute ) return;
|
|
62
|
+
const verts = attribute.array;
|
|
63
|
+
const numVerts = Math.floor( verts.length / 3 );
|
|
64
|
+
let offset = 0;
|
|
65
|
+
|
|
66
|
+
for ( let i = 0; i < numVerts; i ++ ) {
|
|
67
|
+
|
|
68
|
+
const x = verts[ offset ];
|
|
69
|
+
const y = verts[ offset + 1 ];
|
|
70
|
+
const z = verts[ offset + 2 ];
|
|
71
|
+
verts[ offset ] = verts[ offset + 3 ];
|
|
72
|
+
verts[ offset + 1 ] = verts[ offset + 4 ];
|
|
73
|
+
verts[ offset + 2 ] = verts[ offset + 5 ];
|
|
74
|
+
verts[ offset + 3 ] = x;
|
|
75
|
+
verts[ offset + 4 ] = y;
|
|
76
|
+
verts[ offset + 5 ] = z;
|
|
77
|
+
offset += elemSize * 3;
|
|
78
|
+
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
} // Traverse the object hierarchy collecting geometries and transforming them to world space
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
const meshGeometries = {};
|
|
85
|
+
const linesGeometries = {};
|
|
86
|
+
const condLinesGeometries = {};
|
|
87
|
+
object.updateMatrixWorld( true );
|
|
88
|
+
const normalMatrix = new THREE.Matrix3();
|
|
89
|
+
object.traverse( c => {
|
|
90
|
+
|
|
91
|
+
if ( c.isMesh | c.isLineSegments ) {
|
|
92
|
+
|
|
93
|
+
const elemSize = c.isMesh ? 3 : 2;
|
|
94
|
+
const geometry = c.geometry.clone();
|
|
95
|
+
const matrixIsInverted = c.matrixWorld.determinant() < 0;
|
|
96
|
+
|
|
97
|
+
if ( matrixIsInverted ) {
|
|
98
|
+
|
|
99
|
+
permuteAttribute( geometry.attributes.position, elemSize );
|
|
100
|
+
permuteAttribute( geometry.attributes.normal, elemSize );
|
|
101
|
+
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
geometry.applyMatrix4( c.matrixWorld );
|
|
105
|
+
|
|
106
|
+
if ( c.isConditionalLine ) {
|
|
107
|
+
|
|
108
|
+
geometry.attributes.control0.applyMatrix4( c.matrixWorld );
|
|
109
|
+
geometry.attributes.control1.applyMatrix4( c.matrixWorld );
|
|
110
|
+
normalMatrix.getNormalMatrix( c.matrixWorld );
|
|
111
|
+
geometry.attributes.direction.applyNormalMatrix( normalMatrix );
|
|
112
|
+
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
const geometries = c.isMesh ? meshGeometries : c.isConditionalLine ? condLinesGeometries : linesGeometries;
|
|
116
|
+
|
|
117
|
+
if ( Array.isArray( c.material ) ) {
|
|
118
|
+
|
|
119
|
+
for ( const groupIndex in geometry.groups ) {
|
|
120
|
+
|
|
121
|
+
const group = geometry.groups[ groupIndex ];
|
|
122
|
+
const mat = c.material[ group.materialIndex ];
|
|
123
|
+
const newGeometry = extractGroup( geometry, group, elemSize, c.isConditionalLine );
|
|
124
|
+
addGeometry( mat, newGeometry, geometries );
|
|
125
|
+
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
} else {
|
|
129
|
+
|
|
130
|
+
addGeometry( c.material, geometry, geometries );
|
|
131
|
+
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
} ); // Create object with merged geometries
|
|
137
|
+
|
|
138
|
+
const mergedObject = new THREE.Group();
|
|
139
|
+
const meshMaterialsIds = Object.keys( meshGeometries );
|
|
140
|
+
|
|
141
|
+
for ( const i in meshMaterialsIds ) {
|
|
142
|
+
|
|
143
|
+
const meshGeometry = meshGeometries[ meshMaterialsIds[ i ] ];
|
|
144
|
+
const mergedGeometry = THREE.mergeBufferGeometries( meshGeometry.arr );
|
|
145
|
+
mergedObject.add( new THREE.Mesh( mergedGeometry, meshGeometry.mat ) );
|
|
146
|
+
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
const linesMaterialsIds = Object.keys( linesGeometries );
|
|
150
|
+
|
|
151
|
+
for ( const i in linesMaterialsIds ) {
|
|
152
|
+
|
|
153
|
+
const lineGeometry = linesGeometries[ linesMaterialsIds[ i ] ];
|
|
154
|
+
const mergedGeometry = THREE.mergeBufferGeometries( lineGeometry.arr );
|
|
155
|
+
mergedObject.add( new THREE.LineSegments( mergedGeometry, lineGeometry.mat ) );
|
|
156
|
+
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
const condLinesMaterialsIds = Object.keys( condLinesGeometries );
|
|
160
|
+
|
|
161
|
+
for ( const i in condLinesMaterialsIds ) {
|
|
162
|
+
|
|
163
|
+
const condLineGeometry = condLinesGeometries[ condLinesMaterialsIds[ i ] ];
|
|
164
|
+
const mergedGeometry = THREE.mergeBufferGeometries( condLineGeometry.arr );
|
|
165
|
+
const condLines = new THREE.LineSegments( mergedGeometry, condLineGeometry.mat );
|
|
166
|
+
condLines.isConditionalLine = true;
|
|
167
|
+
mergedObject.add( condLines );
|
|
168
|
+
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
mergedObject.userData.constructionStep = 0;
|
|
172
|
+
mergedObject.userData.numConstructionSteps = 1;
|
|
173
|
+
return mergedObject;
|
|
174
|
+
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
THREE.LDrawUtils = {};
|
|
180
|
+
THREE.LDrawUtils.LDrawUtils = LDrawUtils;
|
|
181
|
+
|
|
182
|
+
} )();
|
|
@@ -17,6 +17,7 @@ import {
|
|
|
17
17
|
RGBAFormat,
|
|
18
18
|
RepeatWrapping,
|
|
19
19
|
Scene,
|
|
20
|
+
Texture,
|
|
20
21
|
Vector3
|
|
21
22
|
} from 'three';
|
|
22
23
|
|
|
@@ -688,6 +689,79 @@ class GLTFWriter {
|
|
|
688
689
|
|
|
689
690
|
}
|
|
690
691
|
|
|
692
|
+
buildORMTexture( material ) {
|
|
693
|
+
|
|
694
|
+
const occlusion = material.aoMap?.image;
|
|
695
|
+
const roughness = material.roughnessMap?.image;
|
|
696
|
+
const metalness = material.metalnessMap?.image;
|
|
697
|
+
|
|
698
|
+
if ( occlusion === roughness && roughness === metalness ) return occlusion;
|
|
699
|
+
|
|
700
|
+
if ( occlusion || roughness || metalness ) {
|
|
701
|
+
|
|
702
|
+
const width = Math.max( occlusion?.width || 0, roughness?.width || 0, metalness?.width || 0 );
|
|
703
|
+
const height = Math.max( occlusion?.height || 0, roughness?.height || 0, metalness?.height || 0 );
|
|
704
|
+
|
|
705
|
+
const canvas = document.createElement( 'canvas' );
|
|
706
|
+
canvas.width = width;
|
|
707
|
+
canvas.height = height;
|
|
708
|
+
|
|
709
|
+
const context = canvas.getContext( '2d' );
|
|
710
|
+
context.fillStyle = '#ffffff';
|
|
711
|
+
context.fillRect( 0, 0, width, height );
|
|
712
|
+
|
|
713
|
+
const composite = context.getImageData( 0, 0, width, height );
|
|
714
|
+
|
|
715
|
+
if ( occlusion ) {
|
|
716
|
+
|
|
717
|
+
context.drawImage( occlusion, 0, 0, width, height );
|
|
718
|
+
|
|
719
|
+
const data = context.getImageData( 0, 0, width, height ).data;
|
|
720
|
+
|
|
721
|
+
for ( let i = 0; i < data.length; i += 4 ) {
|
|
722
|
+
|
|
723
|
+
composite.data[ i ] = data[ i ];
|
|
724
|
+
|
|
725
|
+
}
|
|
726
|
+
|
|
727
|
+
}
|
|
728
|
+
|
|
729
|
+
if ( roughness ) {
|
|
730
|
+
|
|
731
|
+
context.drawImage( roughness, 0, 0, width, height );
|
|
732
|
+
|
|
733
|
+
const data = context.getImageData( 0, 0, width, height ).data;
|
|
734
|
+
|
|
735
|
+
for ( let i = 1; i < data.length; i += 4 ) {
|
|
736
|
+
|
|
737
|
+
composite.data[ i ] = data[ i ];
|
|
738
|
+
|
|
739
|
+
}
|
|
740
|
+
|
|
741
|
+
}
|
|
742
|
+
|
|
743
|
+
if ( metalness ) {
|
|
744
|
+
|
|
745
|
+
context.drawImage( metalness, 0, 0, width, height );
|
|
746
|
+
|
|
747
|
+
const data = context.getImageData( 0, 0, width, height ).data;
|
|
748
|
+
|
|
749
|
+
for ( let i = 2; i < data.length; i += 4 ) {
|
|
750
|
+
|
|
751
|
+
composite.data[ i ] = data[ i ];
|
|
752
|
+
|
|
753
|
+
}
|
|
754
|
+
|
|
755
|
+
}
|
|
756
|
+
|
|
757
|
+
context.putImageData( composite, 0, 0 );
|
|
758
|
+
|
|
759
|
+
return new Texture( canvas );
|
|
760
|
+
|
|
761
|
+
}
|
|
762
|
+
|
|
763
|
+
}
|
|
764
|
+
|
|
691
765
|
/**
|
|
692
766
|
* Process a buffer to append to the default one.
|
|
693
767
|
* @param {ArrayBuffer} buffer
|
|
@@ -1178,20 +1252,14 @@ class GLTFWriter {
|
|
|
1178
1252
|
|
|
1179
1253
|
}
|
|
1180
1254
|
|
|
1255
|
+
const ormTexture = this.buildORMTexture( material );
|
|
1256
|
+
|
|
1181
1257
|
// pbrMetallicRoughness.metallicRoughnessTexture
|
|
1182
1258
|
if ( material.metalnessMap || material.roughnessMap ) {
|
|
1183
1259
|
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
this.applyTextureTransform( metalRoughMapDef, material.metalnessMap );
|
|
1188
|
-
materialDef.pbrMetallicRoughness.metallicRoughnessTexture = metalRoughMapDef;
|
|
1189
|
-
|
|
1190
|
-
} else {
|
|
1191
|
-
|
|
1192
|
-
console.warn( 'THREE.GLTFExporter: Ignoring metalnessMap and roughnessMap because they are not the same Texture.' );
|
|
1193
|
-
|
|
1194
|
-
}
|
|
1260
|
+
const metalRoughMapDef = { index: this.processTexture( ormTexture ) };
|
|
1261
|
+
this.applyTextureTransform( metalRoughMapDef, material.metalnessMap || material.roughnessMap );
|
|
1262
|
+
materialDef.pbrMetallicRoughness.metallicRoughnessTexture = metalRoughMapDef;
|
|
1195
1263
|
|
|
1196
1264
|
}
|
|
1197
1265
|
|
|
@@ -1257,7 +1325,7 @@ class GLTFWriter {
|
|
|
1257
1325
|
if ( material.aoMap ) {
|
|
1258
1326
|
|
|
1259
1327
|
const occlusionMapDef = {
|
|
1260
|
-
index: this.processTexture(
|
|
1328
|
+
index: this.processTexture( ormTexture ),
|
|
1261
1329
|
texCoord: 1
|
|
1262
1330
|
};
|
|
1263
1331
|
|
|
@@ -16,7 +16,6 @@
|
|
|
16
16
|
*/
|
|
17
17
|
|
|
18
18
|
import {
|
|
19
|
-
BufferGeometry,
|
|
20
19
|
ExtrudeGeometry
|
|
21
20
|
} from 'three';
|
|
22
21
|
|
|
@@ -26,26 +25,27 @@ class TextGeometry extends ExtrudeGeometry {
|
|
|
26
25
|
|
|
27
26
|
const font = parameters.font;
|
|
28
27
|
|
|
29
|
-
if (
|
|
28
|
+
if ( font === undefined ) {
|
|
30
29
|
|
|
31
|
-
|
|
32
|
-
return new BufferGeometry();
|
|
30
|
+
super(); // generate default extrude geometry
|
|
33
31
|
|
|
34
|
-
}
|
|
32
|
+
} else {
|
|
33
|
+
|
|
34
|
+
const shapes = font.generateShapes( text, parameters.size );
|
|
35
35
|
|
|
36
|
-
|
|
36
|
+
// translate parameters to ExtrudeGeometry API
|
|
37
37
|
|
|
38
|
-
|
|
38
|
+
parameters.depth = parameters.height !== undefined ? parameters.height : 50;
|
|
39
39
|
|
|
40
|
-
|
|
40
|
+
// defaults
|
|
41
41
|
|
|
42
|
-
|
|
42
|
+
if ( parameters.bevelThickness === undefined ) parameters.bevelThickness = 10;
|
|
43
|
+
if ( parameters.bevelSize === undefined ) parameters.bevelSize = 8;
|
|
44
|
+
if ( parameters.bevelEnabled === undefined ) parameters.bevelEnabled = false;
|
|
43
45
|
|
|
44
|
-
|
|
45
|
-
if ( parameters.bevelSize === undefined ) parameters.bevelSize = 8;
|
|
46
|
-
if ( parameters.bevelEnabled === undefined ) parameters.bevelEnabled = false;
|
|
46
|
+
super( shapes, parameters );
|
|
47
47
|
|
|
48
|
-
|
|
48
|
+
}
|
|
49
49
|
|
|
50
50
|
this.type = 'TextGeometry';
|
|
51
51
|
|