minerender 2.1.0-alpha.49 → 2.1.0-alpha.50
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/dist/browser/index.d.mts +35 -2
- package/dist/browser/index.d.ts +35 -2
- package/dist/browser/index.js +2712 -152
- package/dist/browser/index.js.map +1 -1
- package/dist/browser/index.mjs +2722 -117
- package/dist/browser/index.mjs.map +1 -1
- package/dist/bundle.js +2615 -22
- package/dist/bundle.js.map +1 -1
- package/dist/node/index.d.mts +35 -2
- package/dist/node/index.d.ts +35 -2
- package/dist/node/index.js +2715 -153
- package/dist/node/index.js.map +1 -1
- package/dist/node/index.mjs +2722 -117
- package/dist/node/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/bundle.js
CHANGED
|
@@ -8271,7 +8271,7 @@ var MineRender = (() => {
|
|
|
8271
8271
|
dispose
|
|
8272
8272
|
};
|
|
8273
8273
|
}
|
|
8274
|
-
function WebGLShadowMap(
|
|
8274
|
+
function WebGLShadowMap(_renderer2, _objects, _capabilities) {
|
|
8275
8275
|
let _frustum = new Frustum();
|
|
8276
8276
|
const _shadowMapSize = new Vector2(), _viewportSize = new Vector2(), _viewport = new Vector4(), _depthMaterial = new MeshDepthMaterial({ depthPacking: RGBADepthPacking }), _distanceMaterial = new MeshDistanceMaterial(), _materialCache = {}, _maxTextureSize = _capabilities.maxTextureSize;
|
|
8277
8277
|
const shadowSide = { [FrontSide]: BackSide, [BackSide]: FrontSide, [DoubleSide]: DoubleSide };
|
|
@@ -8308,10 +8308,10 @@ var MineRender = (() => {
|
|
|
8308
8308
|
if (scope.enabled === false) return;
|
|
8309
8309
|
if (scope.autoUpdate === false && scope.needsUpdate === false) return;
|
|
8310
8310
|
if (lights.length === 0) return;
|
|
8311
|
-
const currentRenderTarget =
|
|
8312
|
-
const activeCubeFace =
|
|
8313
|
-
const activeMipmapLevel =
|
|
8314
|
-
const _state =
|
|
8311
|
+
const currentRenderTarget = _renderer2.getRenderTarget();
|
|
8312
|
+
const activeCubeFace = _renderer2.getActiveCubeFace();
|
|
8313
|
+
const activeMipmapLevel = _renderer2.getActiveMipmapLevel();
|
|
8314
|
+
const _state = _renderer2.state;
|
|
8315
8315
|
_state.setBlending(NoBlending);
|
|
8316
8316
|
_state.buffers.color.setClear(1, 1, 1, 1);
|
|
8317
8317
|
_state.buffers.depth.setTest(true);
|
|
@@ -8351,8 +8351,8 @@ var MineRender = (() => {
|
|
|
8351
8351
|
shadow.map.texture.name = light.name + ".shadowMap";
|
|
8352
8352
|
shadow.camera.updateProjectionMatrix();
|
|
8353
8353
|
}
|
|
8354
|
-
|
|
8355
|
-
|
|
8354
|
+
_renderer2.setRenderTarget(shadow.map);
|
|
8355
|
+
_renderer2.clear();
|
|
8356
8356
|
const viewportCount = shadow.getViewportCount();
|
|
8357
8357
|
for (let vp = 0; vp < viewportCount; vp++) {
|
|
8358
8358
|
const viewport = shadow.getViewport(vp);
|
|
@@ -8374,7 +8374,7 @@ var MineRender = (() => {
|
|
|
8374
8374
|
}
|
|
8375
8375
|
_previousType = this.type;
|
|
8376
8376
|
scope.needsUpdate = false;
|
|
8377
|
-
|
|
8377
|
+
_renderer2.setRenderTarget(currentRenderTarget, activeCubeFace, activeMipmapLevel);
|
|
8378
8378
|
};
|
|
8379
8379
|
function VSMPass(shadow, camera) {
|
|
8380
8380
|
const geometry = _objects.update(fullScreenMesh);
|
|
@@ -8390,15 +8390,15 @@ var MineRender = (() => {
|
|
|
8390
8390
|
shadowMaterialVertical.uniforms.shadow_pass.value = shadow.map.texture;
|
|
8391
8391
|
shadowMaterialVertical.uniforms.resolution.value = shadow.mapSize;
|
|
8392
8392
|
shadowMaterialVertical.uniforms.radius.value = shadow.radius;
|
|
8393
|
-
|
|
8394
|
-
|
|
8395
|
-
|
|
8393
|
+
_renderer2.setRenderTarget(shadow.mapPass);
|
|
8394
|
+
_renderer2.clear();
|
|
8395
|
+
_renderer2.renderBufferDirect(camera, null, geometry, shadowMaterialVertical, fullScreenMesh, null);
|
|
8396
8396
|
shadowMaterialHorizontal.uniforms.shadow_pass.value = shadow.mapPass.texture;
|
|
8397
8397
|
shadowMaterialHorizontal.uniforms.resolution.value = shadow.mapSize;
|
|
8398
8398
|
shadowMaterialHorizontal.uniforms.radius.value = shadow.radius;
|
|
8399
|
-
|
|
8400
|
-
|
|
8401
|
-
|
|
8399
|
+
_renderer2.setRenderTarget(shadow.map);
|
|
8400
|
+
_renderer2.clear();
|
|
8401
|
+
_renderer2.renderBufferDirect(camera, null, geometry, shadowMaterialHorizontal, fullScreenMesh, null);
|
|
8402
8402
|
}
|
|
8403
8403
|
function getDepthMaterial(object, material, light, type) {
|
|
8404
8404
|
let result = null;
|
|
@@ -8407,7 +8407,7 @@ var MineRender = (() => {
|
|
|
8407
8407
|
result = customMaterial;
|
|
8408
8408
|
} else {
|
|
8409
8409
|
result = light.isPointLight === true ? _distanceMaterial : _depthMaterial;
|
|
8410
|
-
if (
|
|
8410
|
+
if (_renderer2.localClippingEnabled && material.clipShadows === true && Array.isArray(material.clippingPlanes) && material.clippingPlanes.length !== 0 || material.displacementMap && material.displacementScale !== 0 || material.alphaMap && material.alphaTest > 0 || material.map && material.alphaTest > 0) {
|
|
8411
8411
|
const keyA = result.uuid, keyB = material.uuid;
|
|
8412
8412
|
let materialsForVariant = _materialCache[keyA];
|
|
8413
8413
|
if (materialsForVariant === void 0) {
|
|
@@ -8441,7 +8441,7 @@ var MineRender = (() => {
|
|
|
8441
8441
|
result.wireframeLinewidth = material.wireframeLinewidth;
|
|
8442
8442
|
result.linewidth = material.linewidth;
|
|
8443
8443
|
if (light.isPointLight === true && result.isMeshDistanceMaterial === true) {
|
|
8444
|
-
const materialProperties =
|
|
8444
|
+
const materialProperties = _renderer2.properties.get(result);
|
|
8445
8445
|
materialProperties.light = light;
|
|
8446
8446
|
}
|
|
8447
8447
|
return result;
|
|
@@ -8461,12 +8461,12 @@ var MineRender = (() => {
|
|
|
8461
8461
|
const groupMaterial = material[group.materialIndex];
|
|
8462
8462
|
if (groupMaterial && groupMaterial.visible) {
|
|
8463
8463
|
const depthMaterial = getDepthMaterial(object, groupMaterial, light, type);
|
|
8464
|
-
|
|
8464
|
+
_renderer2.renderBufferDirect(shadowCamera, null, geometry, depthMaterial, object, group);
|
|
8465
8465
|
}
|
|
8466
8466
|
}
|
|
8467
8467
|
} else if (material.visible) {
|
|
8468
8468
|
const depthMaterial = getDepthMaterial(object, material, light, type);
|
|
8469
|
-
|
|
8469
|
+
_renderer2.renderBufferDirect(shadowCamera, null, geometry, depthMaterial, object, null);
|
|
8470
8470
|
}
|
|
8471
8471
|
}
|
|
8472
8472
|
}
|
|
@@ -10988,7 +10988,7 @@ var MineRender = (() => {
|
|
|
10988
10988
|
}
|
|
10989
10989
|
}
|
|
10990
10990
|
}
|
|
10991
|
-
var REVISION, MOUSE, TOUCH, CullFaceNone, CullFaceBack, CullFaceFront, PCFShadowMap, PCFSoftShadowMap, VSMShadowMap, FrontSide, BackSide, DoubleSide, NoBlending, NormalBlending, AdditiveBlending, SubtractiveBlending, MultiplyBlending, CustomBlending, AddEquation, SubtractEquation, ReverseSubtractEquation, MinEquation, MaxEquation, ZeroFactor, OneFactor, SrcColorFactor, OneMinusSrcColorFactor, SrcAlphaFactor, OneMinusSrcAlphaFactor, DstAlphaFactor, OneMinusDstAlphaFactor, DstColorFactor, OneMinusDstColorFactor, SrcAlphaSaturateFactor, ConstantColorFactor, OneMinusConstantColorFactor, ConstantAlphaFactor, OneMinusConstantAlphaFactor, NeverDepth, AlwaysDepth, LessDepth, LessEqualDepth, EqualDepth, GreaterEqualDepth, GreaterDepth, NotEqualDepth, MultiplyOperation, MixOperation, AddOperation, NoToneMapping, LinearToneMapping, ReinhardToneMapping, CineonToneMapping, ACESFilmicToneMapping, CustomToneMapping, UVMapping, CubeReflectionMapping, CubeRefractionMapping, EquirectangularReflectionMapping, EquirectangularRefractionMapping, CubeUVReflectionMapping, RepeatWrapping, ClampToEdgeWrapping, MirroredRepeatWrapping, NearestFilter, NearestMipmapNearestFilter, NearestMipmapLinearFilter, LinearFilter, LinearMipmapNearestFilter, LinearMipmapLinearFilter, UnsignedByteType, ByteType, ShortType, UnsignedShortType, IntType, UnsignedIntType, FloatType, HalfFloatType, UnsignedShort4444Type, UnsignedShort5551Type, UnsignedInt248Type, AlphaFormat, RGBAFormat, LuminanceFormat, LuminanceAlphaFormat, DepthFormat, DepthStencilFormat, RedFormat, RedIntegerFormat, RGFormat, RGIntegerFormat, RGBAIntegerFormat, RGB_S3TC_DXT1_Format, RGBA_S3TC_DXT1_Format, RGBA_S3TC_DXT3_Format, RGBA_S3TC_DXT5_Format, RGB_PVRTC_4BPPV1_Format, RGB_PVRTC_2BPPV1_Format, RGBA_PVRTC_4BPPV1_Format, RGBA_PVRTC_2BPPV1_Format, RGB_ETC1_Format, RGB_ETC2_Format, RGBA_ETC2_EAC_Format, RGBA_ASTC_4x4_Format, RGBA_ASTC_5x4_Format, RGBA_ASTC_5x5_Format, RGBA_ASTC_6x5_Format, RGBA_ASTC_6x6_Format, RGBA_ASTC_8x5_Format, RGBA_ASTC_8x6_Format, RGBA_ASTC_8x8_Format, RGBA_ASTC_10x5_Format, RGBA_ASTC_10x6_Format, RGBA_ASTC_10x8_Format, RGBA_ASTC_10x10_Format, RGBA_ASTC_12x10_Format, RGBA_ASTC_12x12_Format, RGBA_BPTC_Format, RGB_BPTC_SIGNED_Format, RGB_BPTC_UNSIGNED_Format, RED_RGTC1_Format, SIGNED_RED_RGTC1_Format, RED_GREEN_RGTC2_Format, SIGNED_RED_GREEN_RGTC2_Format, InterpolateDiscrete, InterpolateLinear, InterpolateSmooth, ZeroCurvatureEnding, ZeroSlopeEnding, WrapAroundEnding, TrianglesDrawMode, TriangleStripDrawMode, TriangleFanDrawMode, LinearEncoding, sRGBEncoding, BasicDepthPacking, RGBADepthPacking, TangentSpaceNormalMap, ObjectSpaceNormalMap, NoColorSpace, SRGBColorSpace, LinearSRGBColorSpace, DisplayP3ColorSpace, LinearDisplayP3ColorSpace, LinearTransfer, SRGBTransfer, Rec709Primaries, P3Primaries, KeepStencilOp, AlwaysStencilFunc, NeverCompare, LessCompare, EqualCompare, LessEqualCompare, GreaterCompare, NotEqualCompare, GreaterEqualCompare, AlwaysCompare, StaticDrawUsage, GLSL3, _SRGBAFormat, WebGLCoordinateSystem, WebGPUCoordinateSystem, EventDispatcher, _lut, _seed, DEG2RAD, RAD2DEG, MathUtils, Vector2, Matrix3, _m3, _cache, LINEAR_SRGB_TO_LINEAR_DISPLAY_P3, LINEAR_DISPLAY_P3_TO_LINEAR_SRGB, COLOR_SPACES, SUPPORTED_WORKING_COLOR_SPACES, ColorManagement, _canvas, ImageUtils, _sourceId, Source, _textureId, Texture, Vector4, RenderTarget, WebGLRenderTarget, DataArrayTexture, Data3DTexture, Quaternion, Vector3, _vector$b, _quaternion$4, Box3, _points, _vector$a, _box$3, _v0$2, _v1$7, _v2$4, _f0, _f1, _f2, _center, _extents, _triangleNormal, _testAxis, _box$2, _v1$6, _v2$3, Sphere, _vector$9, _segCenter, _segDir, _diff, _edge1, _edge2, _normal$1, Ray, Matrix4, _v1$5, _m1$2, _zero, _one, _x, _y, _z, _matrix, _quaternion$3, Euler, Layers, _object3DId, _v1$4, _q1, _m1$1, _target, _position$3, _scale$2, _quaternion$2, _xAxis, _yAxis, _zAxis, _addedEvent, _removedEvent, Object3D, _v0$1, _v1$3, _v2$2, _v3$1, _vab, _vac, _vbc, _vap, _vbp, _vcp, warnedGetUV, Triangle, _colorKeywords, _hslA, _hslB, Color, _color, _materialId, Material, MeshBasicMaterial, _vector$8, _vector2$1, BufferAttribute, Uint16BufferAttribute, Uint32BufferAttribute, Float32BufferAttribute, _id$2, _m1, _obj, _offset, _box$1, _boxMorphTargets, _vector$7, BufferGeometry, _inverseMatrix$3, _ray$3, _sphere$5, _sphereHitAt, _vA$1, _vB$1, _vC$1, _tempA, _morphA, _uvA$1, _uvB$1, _uvC$1, _normalA, _normalB, _normalC, _intersectionPoint, _intersectionPointWorld, Mesh, BoxGeometry, UniformsUtils, default_vertex, default_fragment, ShaderMaterial, Camera, PerspectiveCamera, fov, aspect, CubeCamera, CubeTexture, WebGLCubeRenderTarget, _vector1, _vector2, _normalMatrix, Plane, _sphere$4, _vector$6, Frustum, PlaneGeometry, alphahash_fragment, alphahash_pars_fragment, alphamap_fragment, alphamap_pars_fragment, alphatest_fragment, alphatest_pars_fragment, aomap_fragment, aomap_pars_fragment, begin_vertex, beginnormal_vertex, bsdfs, iridescence_fragment, bumpmap_pars_fragment, clipping_planes_fragment, clipping_planes_pars_fragment, clipping_planes_pars_vertex, clipping_planes_vertex, color_fragment, color_pars_fragment, color_pars_vertex, color_vertex, common, cube_uv_reflection_fragment, defaultnormal_vertex, displacementmap_pars_vertex, displacementmap_vertex, emissivemap_fragment, emissivemap_pars_fragment, colorspace_fragment, colorspace_pars_fragment, envmap_fragment, envmap_common_pars_fragment, envmap_pars_fragment, envmap_pars_vertex, envmap_vertex, fog_vertex, fog_pars_vertex, fog_fragment, fog_pars_fragment, gradientmap_pars_fragment, lightmap_fragment, lightmap_pars_fragment, lights_lambert_fragment, lights_lambert_pars_fragment, lights_pars_begin, envmap_physical_pars_fragment, lights_toon_fragment, lights_toon_pars_fragment, lights_phong_fragment, lights_phong_pars_fragment, lights_physical_fragment, lights_physical_pars_fragment, lights_fragment_begin, lights_fragment_maps, lights_fragment_end, logdepthbuf_fragment, logdepthbuf_pars_fragment, logdepthbuf_pars_vertex, logdepthbuf_vertex, map_fragment, map_pars_fragment, map_particle_fragment, map_particle_pars_fragment, metalnessmap_fragment, metalnessmap_pars_fragment, morphcolor_vertex, morphnormal_vertex, morphtarget_pars_vertex, morphtarget_vertex, normal_fragment_begin, normal_fragment_maps, normal_pars_fragment, normal_pars_vertex, normal_vertex, normalmap_pars_fragment, clearcoat_normal_fragment_begin, clearcoat_normal_fragment_maps, clearcoat_pars_fragment, iridescence_pars_fragment, opaque_fragment, packing, premultiplied_alpha_fragment, project_vertex, dithering_fragment, dithering_pars_fragment, roughnessmap_fragment, roughnessmap_pars_fragment, shadowmap_pars_fragment, shadowmap_pars_vertex, shadowmap_vertex, shadowmask_pars_fragment, skinbase_vertex, skinning_pars_vertex, skinning_vertex, skinnormal_vertex, specularmap_fragment, specularmap_pars_fragment, tonemapping_fragment, tonemapping_pars_fragment, transmission_fragment, transmission_pars_fragment, uv_pars_fragment, uv_pars_vertex, uv_vertex, worldpos_vertex, vertex$h, fragment$h, vertex$g, fragment$g, vertex$f, fragment$f, vertex$e, fragment$e, vertex$d, fragment$d, vertex$c, fragment$c, vertex$b, fragment$b, vertex$a, fragment$a, vertex$9, fragment$9, vertex$8, fragment$8, vertex$7, fragment$7, vertex$6, fragment$6, vertex$5, fragment$5, vertex$4, fragment$4, vertex$3, fragment$3, vertex$2, fragment$2, vertex$1, fragment$1, ShaderChunk, UniformsLib, ShaderLib, _rgb, OrthographicCamera, LOD_MIN, EXTRA_LOD_SIGMA, MAX_SAMPLES, _flatCamera, _clearColor, _oldTarget, _oldActiveCubeFace, _oldActiveMipmapLevel, PHI, INV_PHI, _axisDirections, PMREMGenerator, emptyTexture, emptyArrayTexture, empty3dTexture, emptyCubeTexture, arrayCacheF32, arrayCacheI32, mat4array, mat3array, mat2array, SingleUniform, PureArrayUniform, StructuredUniform, RePathPart, WebGLUniforms, COMPLETION_STATUS_KHR, programIdCount, includePattern, shaderChunkMap, unrollLoopPattern, _id$1, WebGLShaderCache, WebGLShaderStage, nextVersion, MeshDepthMaterial, MeshDistanceMaterial, vertex, fragment, ArrayCamera, Group, _moveEvent, WebXRController, DepthTexture, WebXRManager, WebGLRenderer, WebGL1Renderer, Scene, InterleavedBuffer, _vector$5, InterleavedBufferAttribute, DataTexture, InstancedBufferAttribute, _instanceLocalMatrix, _instanceWorldMatrix, _instanceIntersects, _box3, _identity, _mesh, _sphere$2, InstancedMesh, LineBasicMaterial, _start$1, _end$1, _inverseMatrix$1, _ray$1, _sphere$1, Line, _start, _end, LineSegments, CanvasTexture, _v0, _v1$1, _normal, _triangle, EdgesGeometry, MeshStandardMaterial, Interpolant, CubicInterpolant, LinearInterpolant, DiscreteInterpolant, KeyframeTrack, BooleanKeyframeTrack, ColorKeyframeTrack, NumberKeyframeTrack, QuaternionLinearInterpolant, QuaternionKeyframeTrack, StringKeyframeTrack, VectorKeyframeTrack, LoadingManager, DefaultLoadingManager, Loader, _RESERVED_CHARS_RE, _reservedRe, _wordChar, _wordCharOrDot, _directoryRe, _nodeRe, _objectRe, _propertyRe, _trackRe, _supportedObjectNames, Composite, PropertyBinding, _controlInterpolantsResultBuffer, Uniform, Raycaster, Spherical, _vector$4, Box2, GridHelper, AxesHelper;
|
|
10991
|
+
var REVISION, MOUSE, TOUCH, CullFaceNone, CullFaceBack, CullFaceFront, PCFShadowMap, PCFSoftShadowMap, VSMShadowMap, FrontSide, BackSide, DoubleSide, NoBlending, NormalBlending, AdditiveBlending, SubtractiveBlending, MultiplyBlending, CustomBlending, AddEquation, SubtractEquation, ReverseSubtractEquation, MinEquation, MaxEquation, ZeroFactor, OneFactor, SrcColorFactor, OneMinusSrcColorFactor, SrcAlphaFactor, OneMinusSrcAlphaFactor, DstAlphaFactor, OneMinusDstAlphaFactor, DstColorFactor, OneMinusDstColorFactor, SrcAlphaSaturateFactor, ConstantColorFactor, OneMinusConstantColorFactor, ConstantAlphaFactor, OneMinusConstantAlphaFactor, NeverDepth, AlwaysDepth, LessDepth, LessEqualDepth, EqualDepth, GreaterEqualDepth, GreaterDepth, NotEqualDepth, MultiplyOperation, MixOperation, AddOperation, NoToneMapping, LinearToneMapping, ReinhardToneMapping, CineonToneMapping, ACESFilmicToneMapping, CustomToneMapping, UVMapping, CubeReflectionMapping, CubeRefractionMapping, EquirectangularReflectionMapping, EquirectangularRefractionMapping, CubeUVReflectionMapping, RepeatWrapping, ClampToEdgeWrapping, MirroredRepeatWrapping, NearestFilter, NearestMipmapNearestFilter, NearestMipmapLinearFilter, LinearFilter, LinearMipmapNearestFilter, LinearMipmapLinearFilter, UnsignedByteType, ByteType, ShortType, UnsignedShortType, IntType, UnsignedIntType, FloatType, HalfFloatType, UnsignedShort4444Type, UnsignedShort5551Type, UnsignedInt248Type, AlphaFormat, RGBAFormat, LuminanceFormat, LuminanceAlphaFormat, DepthFormat, DepthStencilFormat, RedFormat, RedIntegerFormat, RGFormat, RGIntegerFormat, RGBAIntegerFormat, RGB_S3TC_DXT1_Format, RGBA_S3TC_DXT1_Format, RGBA_S3TC_DXT3_Format, RGBA_S3TC_DXT5_Format, RGB_PVRTC_4BPPV1_Format, RGB_PVRTC_2BPPV1_Format, RGBA_PVRTC_4BPPV1_Format, RGBA_PVRTC_2BPPV1_Format, RGB_ETC1_Format, RGB_ETC2_Format, RGBA_ETC2_EAC_Format, RGBA_ASTC_4x4_Format, RGBA_ASTC_5x4_Format, RGBA_ASTC_5x5_Format, RGBA_ASTC_6x5_Format, RGBA_ASTC_6x6_Format, RGBA_ASTC_8x5_Format, RGBA_ASTC_8x6_Format, RGBA_ASTC_8x8_Format, RGBA_ASTC_10x5_Format, RGBA_ASTC_10x6_Format, RGBA_ASTC_10x8_Format, RGBA_ASTC_10x10_Format, RGBA_ASTC_12x10_Format, RGBA_ASTC_12x12_Format, RGBA_BPTC_Format, RGB_BPTC_SIGNED_Format, RGB_BPTC_UNSIGNED_Format, RED_RGTC1_Format, SIGNED_RED_RGTC1_Format, RED_GREEN_RGTC2_Format, SIGNED_RED_GREEN_RGTC2_Format, InterpolateDiscrete, InterpolateLinear, InterpolateSmooth, ZeroCurvatureEnding, ZeroSlopeEnding, WrapAroundEnding, TrianglesDrawMode, TriangleStripDrawMode, TriangleFanDrawMode, LinearEncoding, sRGBEncoding, BasicDepthPacking, RGBADepthPacking, TangentSpaceNormalMap, ObjectSpaceNormalMap, NoColorSpace, SRGBColorSpace, LinearSRGBColorSpace, DisplayP3ColorSpace, LinearDisplayP3ColorSpace, LinearTransfer, SRGBTransfer, Rec709Primaries, P3Primaries, KeepStencilOp, AlwaysStencilFunc, NeverCompare, LessCompare, EqualCompare, LessEqualCompare, GreaterCompare, NotEqualCompare, GreaterEqualCompare, AlwaysCompare, StaticDrawUsage, GLSL3, _SRGBAFormat, WebGLCoordinateSystem, WebGPUCoordinateSystem, EventDispatcher, _lut, _seed, DEG2RAD, RAD2DEG, MathUtils, Vector2, Matrix3, _m3, _cache, LINEAR_SRGB_TO_LINEAR_DISPLAY_P3, LINEAR_DISPLAY_P3_TO_LINEAR_SRGB, COLOR_SPACES, SUPPORTED_WORKING_COLOR_SPACES, ColorManagement, _canvas, ImageUtils, _sourceId, Source, _textureId, Texture, Vector4, RenderTarget, WebGLRenderTarget, DataArrayTexture, Data3DTexture, Quaternion, Vector3, _vector$b, _quaternion$4, Box3, _points, _vector$a, _box$3, _v0$2, _v1$7, _v2$4, _f0, _f1, _f2, _center, _extents, _triangleNormal, _testAxis, _box$2, _v1$6, _v2$3, Sphere, _vector$9, _segCenter, _segDir, _diff, _edge1, _edge2, _normal$1, Ray, Matrix4, _v1$5, _m1$2, _zero, _one, _x, _y, _z, _matrix, _quaternion$3, Euler, Layers, _object3DId, _v1$4, _q1, _m1$1, _target, _position$3, _scale$2, _quaternion$2, _xAxis, _yAxis, _zAxis, _addedEvent, _removedEvent, Object3D, _v0$1, _v1$3, _v2$2, _v3$1, _vab, _vac, _vbc, _vap, _vbp, _vcp, warnedGetUV, Triangle, _colorKeywords, _hslA, _hslB, Color, _color, _materialId, Material, MeshBasicMaterial, _vector$8, _vector2$1, BufferAttribute, Uint16BufferAttribute, Uint32BufferAttribute, Float32BufferAttribute, _id$2, _m1, _obj, _offset, _box$1, _boxMorphTargets, _vector$7, BufferGeometry, _inverseMatrix$3, _ray$3, _sphere$5, _sphereHitAt, _vA$1, _vB$1, _vC$1, _tempA, _morphA, _uvA$1, _uvB$1, _uvC$1, _normalA, _normalB, _normalC, _intersectionPoint, _intersectionPointWorld, Mesh, BoxGeometry, UniformsUtils, default_vertex, default_fragment, ShaderMaterial, Camera, PerspectiveCamera, fov, aspect, CubeCamera, CubeTexture, WebGLCubeRenderTarget, _vector1, _vector2, _normalMatrix, Plane, _sphere$4, _vector$6, Frustum, PlaneGeometry, alphahash_fragment, alphahash_pars_fragment, alphamap_fragment, alphamap_pars_fragment, alphatest_fragment, alphatest_pars_fragment, aomap_fragment, aomap_pars_fragment, begin_vertex, beginnormal_vertex, bsdfs, iridescence_fragment, bumpmap_pars_fragment, clipping_planes_fragment, clipping_planes_pars_fragment, clipping_planes_pars_vertex, clipping_planes_vertex, color_fragment, color_pars_fragment, color_pars_vertex, color_vertex, common, cube_uv_reflection_fragment, defaultnormal_vertex, displacementmap_pars_vertex, displacementmap_vertex, emissivemap_fragment, emissivemap_pars_fragment, colorspace_fragment, colorspace_pars_fragment, envmap_fragment, envmap_common_pars_fragment, envmap_pars_fragment, envmap_pars_vertex, envmap_vertex, fog_vertex, fog_pars_vertex, fog_fragment, fog_pars_fragment, gradientmap_pars_fragment, lightmap_fragment, lightmap_pars_fragment, lights_lambert_fragment, lights_lambert_pars_fragment, lights_pars_begin, envmap_physical_pars_fragment, lights_toon_fragment, lights_toon_pars_fragment, lights_phong_fragment, lights_phong_pars_fragment, lights_physical_fragment, lights_physical_pars_fragment, lights_fragment_begin, lights_fragment_maps, lights_fragment_end, logdepthbuf_fragment, logdepthbuf_pars_fragment, logdepthbuf_pars_vertex, logdepthbuf_vertex, map_fragment, map_pars_fragment, map_particle_fragment, map_particle_pars_fragment, metalnessmap_fragment, metalnessmap_pars_fragment, morphcolor_vertex, morphnormal_vertex, morphtarget_pars_vertex, morphtarget_vertex, normal_fragment_begin, normal_fragment_maps, normal_pars_fragment, normal_pars_vertex, normal_vertex, normalmap_pars_fragment, clearcoat_normal_fragment_begin, clearcoat_normal_fragment_maps, clearcoat_pars_fragment, iridescence_pars_fragment, opaque_fragment, packing, premultiplied_alpha_fragment, project_vertex, dithering_fragment, dithering_pars_fragment, roughnessmap_fragment, roughnessmap_pars_fragment, shadowmap_pars_fragment, shadowmap_pars_vertex, shadowmap_vertex, shadowmask_pars_fragment, skinbase_vertex, skinning_pars_vertex, skinning_vertex, skinnormal_vertex, specularmap_fragment, specularmap_pars_fragment, tonemapping_fragment, tonemapping_pars_fragment, transmission_fragment, transmission_pars_fragment, uv_pars_fragment, uv_pars_vertex, uv_vertex, worldpos_vertex, vertex$h, fragment$h, vertex$g, fragment$g, vertex$f, fragment$f, vertex$e, fragment$e, vertex$d, fragment$d, vertex$c, fragment$c, vertex$b, fragment$b, vertex$a, fragment$a, vertex$9, fragment$9, vertex$8, fragment$8, vertex$7, fragment$7, vertex$6, fragment$6, vertex$5, fragment$5, vertex$4, fragment$4, vertex$3, fragment$3, vertex$2, fragment$2, vertex$1, fragment$1, ShaderChunk, UniformsLib, ShaderLib, _rgb, OrthographicCamera, LOD_MIN, EXTRA_LOD_SIGMA, MAX_SAMPLES, _flatCamera, _clearColor, _oldTarget, _oldActiveCubeFace, _oldActiveMipmapLevel, PHI, INV_PHI, _axisDirections, PMREMGenerator, emptyTexture, emptyArrayTexture, empty3dTexture, emptyCubeTexture, arrayCacheF32, arrayCacheI32, mat4array, mat3array, mat2array, SingleUniform, PureArrayUniform, StructuredUniform, RePathPart, WebGLUniforms, COMPLETION_STATUS_KHR, programIdCount, includePattern, shaderChunkMap, unrollLoopPattern, _id$1, WebGLShaderCache, WebGLShaderStage, nextVersion, MeshDepthMaterial, MeshDistanceMaterial, vertex, fragment, ArrayCamera, Group, _moveEvent, WebXRController, DepthTexture, WebXRManager, WebGLRenderer, WebGL1Renderer, Scene, InterleavedBuffer, _vector$5, InterleavedBufferAttribute, DataTexture, InstancedBufferAttribute, _instanceLocalMatrix, _instanceWorldMatrix, _instanceIntersects, _box3, _identity, _mesh, _sphere$2, InstancedMesh, LineBasicMaterial, _start$1, _end$1, _inverseMatrix$1, _ray$1, _sphere$1, Line, _start, _end, LineSegments, CompressedTexture, CanvasTexture, _v0, _v1$1, _normal, _triangle, EdgesGeometry, MeshStandardMaterial, Interpolant, CubicInterpolant, LinearInterpolant, DiscreteInterpolant, KeyframeTrack, BooleanKeyframeTrack, ColorKeyframeTrack, NumberKeyframeTrack, QuaternionLinearInterpolant, QuaternionKeyframeTrack, StringKeyframeTrack, VectorKeyframeTrack, LoadingManager, DefaultLoadingManager, Loader, _RESERVED_CHARS_RE, _reservedRe, _wordChar, _wordCharOrDot, _directoryRe, _nodeRe, _objectRe, _propertyRe, _trackRe, _supportedObjectNames, Composite, PropertyBinding, _controlInterpolantsResultBuffer, Uniform, Raycaster, Spherical, _vector$4, Box2, GridHelper, AxesHelper;
|
|
10992
10992
|
var init_three_module = __esm({
|
|
10993
10993
|
"../../node_modules/three/build/three.module.js"() {
|
|
10994
10994
|
init_dirname();
|
|
@@ -22340,6 +22340,16 @@ var MineRender = (() => {
|
|
|
22340
22340
|
return this;
|
|
22341
22341
|
}
|
|
22342
22342
|
};
|
|
22343
|
+
CompressedTexture = class extends Texture {
|
|
22344
|
+
constructor(mipmaps, width, height, format2, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy, colorSpace) {
|
|
22345
|
+
super(null, mapping, wrapS, wrapT, magFilter, minFilter, format2, type, anisotropy, colorSpace);
|
|
22346
|
+
this.isCompressedTexture = true;
|
|
22347
|
+
this.image = { width, height };
|
|
22348
|
+
this.mipmaps = mipmaps;
|
|
22349
|
+
this.flipY = false;
|
|
22350
|
+
this.generateMipmaps = false;
|
|
22351
|
+
}
|
|
22352
|
+
};
|
|
22343
22353
|
CanvasTexture = class extends Texture {
|
|
22344
22354
|
constructor(canvas, mapping, wrapS, wrapT, magFilter, minFilter, format2, type, anisotropy) {
|
|
22345
22355
|
super(canvas, mapping, wrapS, wrapT, magFilter, minFilter, format2, type, anisotropy);
|
|
@@ -82978,6 +82988,7 @@ ${key}` : key;
|
|
|
82978
82988
|
RequestError: () => RequestError,
|
|
82979
82989
|
Requests: () => Requests,
|
|
82980
82990
|
SKIN_PARTS: () => SKIN_PARTS,
|
|
82991
|
+
SceneExporter: () => SceneExporter,
|
|
82981
82992
|
SceneInspector: () => SceneInspector,
|
|
82982
82993
|
SceneObject: () => SceneObject,
|
|
82983
82994
|
SceneStats: () => SceneStats,
|
|
@@ -83067,7 +83078,8 @@ ${key}` : key;
|
|
|
83067
83078
|
timingStart: () => timingStart,
|
|
83068
83079
|
toDegrees: () => toDegrees,
|
|
83069
83080
|
toRadians: () => toRadians,
|
|
83070
|
-
toTrianglesDrawMode: () => toTrianglesDrawMode
|
|
83081
|
+
toTrianglesDrawMode: () => toTrianglesDrawMode,
|
|
83082
|
+
trimCanvas: () => trimCanvas
|
|
83071
83083
|
});
|
|
83072
83084
|
init_dirname();
|
|
83073
83085
|
init_buffer2();
|
|
@@ -83557,6 +83569,40 @@ ${key}` : key;
|
|
|
83557
83569
|
init_CanvasCompat();
|
|
83558
83570
|
init_CanvasImage();
|
|
83559
83571
|
|
|
83572
|
+
// src/canvas/trimCanvas.ts
|
|
83573
|
+
init_dirname();
|
|
83574
|
+
init_buffer2();
|
|
83575
|
+
init_process2();
|
|
83576
|
+
init_CanvasCompat();
|
|
83577
|
+
function trimCanvas(source) {
|
|
83578
|
+
if (source.width === 0 || source.height === 0) return createCanvas(1, 1);
|
|
83579
|
+
const canvas = createCanvas(source.width, source.height);
|
|
83580
|
+
const context = canvas.getContext("2d");
|
|
83581
|
+
if (!context) throw new Error("Image export requires a 2D canvas context");
|
|
83582
|
+
context.drawImage(source, 0, 0);
|
|
83583
|
+
const pixels = context.getImageData(0, 0, canvas.width, canvas.height).data;
|
|
83584
|
+
let left = canvas.width, top = canvas.height, right = -1, bottom = -1;
|
|
83585
|
+
for (let y5 = 0; y5 < canvas.height; y5++) {
|
|
83586
|
+
for (let x4 = 0; x4 < canvas.width; x4++) {
|
|
83587
|
+
if (pixels[(y5 * canvas.width + x4) * 4 + 3] === 0) continue;
|
|
83588
|
+
left = Math.min(left, x4);
|
|
83589
|
+
top = Math.min(top, y5);
|
|
83590
|
+
right = Math.max(right, x4);
|
|
83591
|
+
bottom = Math.max(bottom, y5);
|
|
83592
|
+
}
|
|
83593
|
+
}
|
|
83594
|
+
if (right < left) {
|
|
83595
|
+
canvas.width = canvas.height = 1;
|
|
83596
|
+
return canvas;
|
|
83597
|
+
}
|
|
83598
|
+
const width = right - left + 1, height = bottom - top + 1;
|
|
83599
|
+
const cropped = context.getImageData(left, top, width, height);
|
|
83600
|
+
canvas.width = width;
|
|
83601
|
+
canvas.height = height;
|
|
83602
|
+
context.putImageData(cropped, 0, 0);
|
|
83603
|
+
return canvas;
|
|
83604
|
+
}
|
|
83605
|
+
|
|
83560
83606
|
// src/entity/index.ts
|
|
83561
83607
|
init_dirname();
|
|
83562
83608
|
init_buffer2();
|
|
@@ -83699,6 +83745,2530 @@ ${key}` : key;
|
|
|
83699
83745
|
init_process2();
|
|
83700
83746
|
init_MineRenderError();
|
|
83701
83747
|
|
|
83748
|
+
// src/export/index.ts
|
|
83749
|
+
init_dirname();
|
|
83750
|
+
init_buffer2();
|
|
83751
|
+
init_process2();
|
|
83752
|
+
|
|
83753
|
+
// src/export/SceneExporter.ts
|
|
83754
|
+
init_dirname();
|
|
83755
|
+
init_buffer2();
|
|
83756
|
+
init_process2();
|
|
83757
|
+
init_three_module();
|
|
83758
|
+
|
|
83759
|
+
// ../../node_modules/three/examples/jsm/exporters/OBJExporter.js
|
|
83760
|
+
init_dirname();
|
|
83761
|
+
init_buffer2();
|
|
83762
|
+
init_process2();
|
|
83763
|
+
init_three_module();
|
|
83764
|
+
var OBJExporter = class {
|
|
83765
|
+
parse(object) {
|
|
83766
|
+
let output = "";
|
|
83767
|
+
let indexVertex = 0;
|
|
83768
|
+
let indexVertexUvs = 0;
|
|
83769
|
+
let indexNormals = 0;
|
|
83770
|
+
const vertex2 = new Vector3();
|
|
83771
|
+
const color2 = new Color();
|
|
83772
|
+
const normal = new Vector3();
|
|
83773
|
+
const uv = new Vector2();
|
|
83774
|
+
const face = [];
|
|
83775
|
+
function parseMesh(mesh) {
|
|
83776
|
+
let nbVertex = 0;
|
|
83777
|
+
let nbNormals = 0;
|
|
83778
|
+
let nbVertexUvs = 0;
|
|
83779
|
+
const geometry = mesh.geometry;
|
|
83780
|
+
const normalMatrixWorld = new Matrix3();
|
|
83781
|
+
const vertices = geometry.getAttribute("position");
|
|
83782
|
+
const normals = geometry.getAttribute("normal");
|
|
83783
|
+
const uvs = geometry.getAttribute("uv");
|
|
83784
|
+
const indices = geometry.getIndex();
|
|
83785
|
+
output += "o " + mesh.name + "\n";
|
|
83786
|
+
if (mesh.material && mesh.material.name) {
|
|
83787
|
+
output += "usemtl " + mesh.material.name + "\n";
|
|
83788
|
+
}
|
|
83789
|
+
if (vertices !== void 0) {
|
|
83790
|
+
for (let i4 = 0, l4 = vertices.count; i4 < l4; i4++, nbVertex++) {
|
|
83791
|
+
vertex2.fromBufferAttribute(vertices, i4);
|
|
83792
|
+
vertex2.applyMatrix4(mesh.matrixWorld);
|
|
83793
|
+
output += "v " + vertex2.x + " " + vertex2.y + " " + vertex2.z + "\n";
|
|
83794
|
+
}
|
|
83795
|
+
}
|
|
83796
|
+
if (uvs !== void 0) {
|
|
83797
|
+
for (let i4 = 0, l4 = uvs.count; i4 < l4; i4++, nbVertexUvs++) {
|
|
83798
|
+
uv.fromBufferAttribute(uvs, i4);
|
|
83799
|
+
output += "vt " + uv.x + " " + uv.y + "\n";
|
|
83800
|
+
}
|
|
83801
|
+
}
|
|
83802
|
+
if (normals !== void 0) {
|
|
83803
|
+
normalMatrixWorld.getNormalMatrix(mesh.matrixWorld);
|
|
83804
|
+
for (let i4 = 0, l4 = normals.count; i4 < l4; i4++, nbNormals++) {
|
|
83805
|
+
normal.fromBufferAttribute(normals, i4);
|
|
83806
|
+
normal.applyMatrix3(normalMatrixWorld).normalize();
|
|
83807
|
+
output += "vn " + normal.x + " " + normal.y + " " + normal.z + "\n";
|
|
83808
|
+
}
|
|
83809
|
+
}
|
|
83810
|
+
if (indices !== null) {
|
|
83811
|
+
for (let i4 = 0, l4 = indices.count; i4 < l4; i4 += 3) {
|
|
83812
|
+
for (let m4 = 0; m4 < 3; m4++) {
|
|
83813
|
+
const j4 = indices.getX(i4 + m4) + 1;
|
|
83814
|
+
face[m4] = indexVertex + j4 + (normals || uvs ? "/" + (uvs ? indexVertexUvs + j4 : "") + (normals ? "/" + (indexNormals + j4) : "") : "");
|
|
83815
|
+
}
|
|
83816
|
+
output += "f " + face.join(" ") + "\n";
|
|
83817
|
+
}
|
|
83818
|
+
} else {
|
|
83819
|
+
for (let i4 = 0, l4 = vertices.count; i4 < l4; i4 += 3) {
|
|
83820
|
+
for (let m4 = 0; m4 < 3; m4++) {
|
|
83821
|
+
const j4 = i4 + m4 + 1;
|
|
83822
|
+
face[m4] = indexVertex + j4 + (normals || uvs ? "/" + (uvs ? indexVertexUvs + j4 : "") + (normals ? "/" + (indexNormals + j4) : "") : "");
|
|
83823
|
+
}
|
|
83824
|
+
output += "f " + face.join(" ") + "\n";
|
|
83825
|
+
}
|
|
83826
|
+
}
|
|
83827
|
+
indexVertex += nbVertex;
|
|
83828
|
+
indexVertexUvs += nbVertexUvs;
|
|
83829
|
+
indexNormals += nbNormals;
|
|
83830
|
+
}
|
|
83831
|
+
function parseLine(line) {
|
|
83832
|
+
let nbVertex = 0;
|
|
83833
|
+
const geometry = line.geometry;
|
|
83834
|
+
const type = line.type;
|
|
83835
|
+
const vertices = geometry.getAttribute("position");
|
|
83836
|
+
output += "o " + line.name + "\n";
|
|
83837
|
+
if (vertices !== void 0) {
|
|
83838
|
+
for (let i4 = 0, l4 = vertices.count; i4 < l4; i4++, nbVertex++) {
|
|
83839
|
+
vertex2.fromBufferAttribute(vertices, i4);
|
|
83840
|
+
vertex2.applyMatrix4(line.matrixWorld);
|
|
83841
|
+
output += "v " + vertex2.x + " " + vertex2.y + " " + vertex2.z + "\n";
|
|
83842
|
+
}
|
|
83843
|
+
}
|
|
83844
|
+
if (type === "Line") {
|
|
83845
|
+
output += "l ";
|
|
83846
|
+
for (let j4 = 1, l4 = vertices.count; j4 <= l4; j4++) {
|
|
83847
|
+
output += indexVertex + j4 + " ";
|
|
83848
|
+
}
|
|
83849
|
+
output += "\n";
|
|
83850
|
+
}
|
|
83851
|
+
if (type === "LineSegments") {
|
|
83852
|
+
for (let j4 = 1, k4 = j4 + 1, l4 = vertices.count; j4 < l4; j4 += 2, k4 = j4 + 1) {
|
|
83853
|
+
output += "l " + (indexVertex + j4) + " " + (indexVertex + k4) + "\n";
|
|
83854
|
+
}
|
|
83855
|
+
}
|
|
83856
|
+
indexVertex += nbVertex;
|
|
83857
|
+
}
|
|
83858
|
+
function parsePoints(points) {
|
|
83859
|
+
let nbVertex = 0;
|
|
83860
|
+
const geometry = points.geometry;
|
|
83861
|
+
const vertices = geometry.getAttribute("position");
|
|
83862
|
+
const colors = geometry.getAttribute("color");
|
|
83863
|
+
output += "o " + points.name + "\n";
|
|
83864
|
+
if (vertices !== void 0) {
|
|
83865
|
+
for (let i4 = 0, l4 = vertices.count; i4 < l4; i4++, nbVertex++) {
|
|
83866
|
+
vertex2.fromBufferAttribute(vertices, i4);
|
|
83867
|
+
vertex2.applyMatrix4(points.matrixWorld);
|
|
83868
|
+
output += "v " + vertex2.x + " " + vertex2.y + " " + vertex2.z;
|
|
83869
|
+
if (colors !== void 0) {
|
|
83870
|
+
color2.fromBufferAttribute(colors, i4).convertLinearToSRGB();
|
|
83871
|
+
output += " " + color2.r + " " + color2.g + " " + color2.b;
|
|
83872
|
+
}
|
|
83873
|
+
output += "\n";
|
|
83874
|
+
}
|
|
83875
|
+
output += "p ";
|
|
83876
|
+
for (let j4 = 1, l4 = vertices.count; j4 <= l4; j4++) {
|
|
83877
|
+
output += indexVertex + j4 + " ";
|
|
83878
|
+
}
|
|
83879
|
+
output += "\n";
|
|
83880
|
+
}
|
|
83881
|
+
indexVertex += nbVertex;
|
|
83882
|
+
}
|
|
83883
|
+
object.traverse(function(child) {
|
|
83884
|
+
if (child.isMesh === true) {
|
|
83885
|
+
parseMesh(child);
|
|
83886
|
+
}
|
|
83887
|
+
if (child.isLine === true) {
|
|
83888
|
+
parseLine(child);
|
|
83889
|
+
}
|
|
83890
|
+
if (child.isPoints === true) {
|
|
83891
|
+
parsePoints(child);
|
|
83892
|
+
}
|
|
83893
|
+
});
|
|
83894
|
+
return output;
|
|
83895
|
+
}
|
|
83896
|
+
};
|
|
83897
|
+
|
|
83898
|
+
// ../../node_modules/three/examples/jsm/exporters/PLYExporter.js
|
|
83899
|
+
init_dirname();
|
|
83900
|
+
init_buffer2();
|
|
83901
|
+
init_process2();
|
|
83902
|
+
init_three_module();
|
|
83903
|
+
var PLYExporter = class {
|
|
83904
|
+
parse(object, onDone, options = {}) {
|
|
83905
|
+
function traverseMeshes(cb) {
|
|
83906
|
+
object.traverse(function(child) {
|
|
83907
|
+
if (child.isMesh === true || child.isPoints) {
|
|
83908
|
+
const mesh = child;
|
|
83909
|
+
const geometry = mesh.geometry;
|
|
83910
|
+
if (geometry.hasAttribute("position") === true) {
|
|
83911
|
+
cb(mesh, geometry);
|
|
83912
|
+
}
|
|
83913
|
+
}
|
|
83914
|
+
});
|
|
83915
|
+
}
|
|
83916
|
+
const defaultOptions = {
|
|
83917
|
+
binary: false,
|
|
83918
|
+
excludeAttributes: [],
|
|
83919
|
+
// normal, uv, color, index
|
|
83920
|
+
littleEndian: false
|
|
83921
|
+
};
|
|
83922
|
+
options = Object.assign(defaultOptions, options);
|
|
83923
|
+
const excludeAttributes = options.excludeAttributes;
|
|
83924
|
+
let includeIndices = true;
|
|
83925
|
+
let includeNormals = false;
|
|
83926
|
+
let includeColors = false;
|
|
83927
|
+
let includeUVs = false;
|
|
83928
|
+
let vertexCount = 0;
|
|
83929
|
+
let faceCount = 0;
|
|
83930
|
+
object.traverse(function(child) {
|
|
83931
|
+
if (child.isMesh === true) {
|
|
83932
|
+
const mesh = child;
|
|
83933
|
+
const geometry = mesh.geometry;
|
|
83934
|
+
const vertices = geometry.getAttribute("position");
|
|
83935
|
+
const normals = geometry.getAttribute("normal");
|
|
83936
|
+
const uvs = geometry.getAttribute("uv");
|
|
83937
|
+
const colors = geometry.getAttribute("color");
|
|
83938
|
+
const indices = geometry.getIndex();
|
|
83939
|
+
if (vertices === void 0) {
|
|
83940
|
+
return;
|
|
83941
|
+
}
|
|
83942
|
+
vertexCount += vertices.count;
|
|
83943
|
+
faceCount += indices ? indices.count / 3 : vertices.count / 3;
|
|
83944
|
+
if (normals !== void 0) includeNormals = true;
|
|
83945
|
+
if (uvs !== void 0) includeUVs = true;
|
|
83946
|
+
if (colors !== void 0) includeColors = true;
|
|
83947
|
+
} else if (child.isPoints) {
|
|
83948
|
+
const mesh = child;
|
|
83949
|
+
const geometry = mesh.geometry;
|
|
83950
|
+
const vertices = geometry.getAttribute("position");
|
|
83951
|
+
const normals = geometry.getAttribute("normal");
|
|
83952
|
+
const colors = geometry.getAttribute("color");
|
|
83953
|
+
vertexCount += vertices.count;
|
|
83954
|
+
if (normals !== void 0) includeNormals = true;
|
|
83955
|
+
if (colors !== void 0) includeColors = true;
|
|
83956
|
+
includeIndices = false;
|
|
83957
|
+
}
|
|
83958
|
+
});
|
|
83959
|
+
const tempColor = new Color();
|
|
83960
|
+
includeIndices = includeIndices && excludeAttributes.indexOf("index") === -1;
|
|
83961
|
+
includeNormals = includeNormals && excludeAttributes.indexOf("normal") === -1;
|
|
83962
|
+
includeColors = includeColors && excludeAttributes.indexOf("color") === -1;
|
|
83963
|
+
includeUVs = includeUVs && excludeAttributes.indexOf("uv") === -1;
|
|
83964
|
+
if (includeIndices && faceCount !== Math.floor(faceCount)) {
|
|
83965
|
+
console.error(
|
|
83966
|
+
"PLYExporter: Failed to generate a valid PLY file with triangle indices because the number of indices is not divisible by 3."
|
|
83967
|
+
);
|
|
83968
|
+
return null;
|
|
83969
|
+
}
|
|
83970
|
+
const indexByteCount = 4;
|
|
83971
|
+
let header = `ply
|
|
83972
|
+
format ${options.binary ? options.littleEndian ? "binary_little_endian" : "binary_big_endian" : "ascii"} 1.0
|
|
83973
|
+
element vertex ${vertexCount}
|
|
83974
|
+
property float x
|
|
83975
|
+
property float y
|
|
83976
|
+
property float z
|
|
83977
|
+
`;
|
|
83978
|
+
if (includeNormals === true) {
|
|
83979
|
+
header += "property float nx\nproperty float ny\nproperty float nz\n";
|
|
83980
|
+
}
|
|
83981
|
+
if (includeUVs === true) {
|
|
83982
|
+
header += "property float s\nproperty float t\n";
|
|
83983
|
+
}
|
|
83984
|
+
if (includeColors === true) {
|
|
83985
|
+
header += "property uchar red\nproperty uchar green\nproperty uchar blue\n";
|
|
83986
|
+
}
|
|
83987
|
+
if (includeIndices === true) {
|
|
83988
|
+
header += `element face ${faceCount}
|
|
83989
|
+
property list uchar int vertex_index
|
|
83990
|
+
`;
|
|
83991
|
+
}
|
|
83992
|
+
header += "end_header\n";
|
|
83993
|
+
const vertex2 = new Vector3();
|
|
83994
|
+
const normalMatrixWorld = new Matrix3();
|
|
83995
|
+
let result = null;
|
|
83996
|
+
if (options.binary === true) {
|
|
83997
|
+
const headerBin = new TextEncoder().encode(header);
|
|
83998
|
+
const vertexListLength = vertexCount * (4 * 3 + (includeNormals ? 4 * 3 : 0) + (includeColors ? 3 : 0) + (includeUVs ? 4 * 2 : 0));
|
|
83999
|
+
const faceListLength = includeIndices ? faceCount * (indexByteCount * 3 + 1) : 0;
|
|
84000
|
+
const output = new DataView(new ArrayBuffer(headerBin.length + vertexListLength + faceListLength));
|
|
84001
|
+
new Uint8Array(output.buffer).set(headerBin, 0);
|
|
84002
|
+
let vOffset = headerBin.length;
|
|
84003
|
+
let fOffset = headerBin.length + vertexListLength;
|
|
84004
|
+
let writtenVertices = 0;
|
|
84005
|
+
traverseMeshes(function(mesh, geometry) {
|
|
84006
|
+
const vertices = geometry.getAttribute("position");
|
|
84007
|
+
const normals = geometry.getAttribute("normal");
|
|
84008
|
+
const uvs = geometry.getAttribute("uv");
|
|
84009
|
+
const colors = geometry.getAttribute("color");
|
|
84010
|
+
const indices = geometry.getIndex();
|
|
84011
|
+
normalMatrixWorld.getNormalMatrix(mesh.matrixWorld);
|
|
84012
|
+
for (let i4 = 0, l4 = vertices.count; i4 < l4; i4++) {
|
|
84013
|
+
vertex2.fromBufferAttribute(vertices, i4);
|
|
84014
|
+
vertex2.applyMatrix4(mesh.matrixWorld);
|
|
84015
|
+
output.setFloat32(vOffset, vertex2.x, options.littleEndian);
|
|
84016
|
+
vOffset += 4;
|
|
84017
|
+
output.setFloat32(vOffset, vertex2.y, options.littleEndian);
|
|
84018
|
+
vOffset += 4;
|
|
84019
|
+
output.setFloat32(vOffset, vertex2.z, options.littleEndian);
|
|
84020
|
+
vOffset += 4;
|
|
84021
|
+
if (includeNormals === true) {
|
|
84022
|
+
if (normals != null) {
|
|
84023
|
+
vertex2.fromBufferAttribute(normals, i4);
|
|
84024
|
+
vertex2.applyMatrix3(normalMatrixWorld).normalize();
|
|
84025
|
+
output.setFloat32(vOffset, vertex2.x, options.littleEndian);
|
|
84026
|
+
vOffset += 4;
|
|
84027
|
+
output.setFloat32(vOffset, vertex2.y, options.littleEndian);
|
|
84028
|
+
vOffset += 4;
|
|
84029
|
+
output.setFloat32(vOffset, vertex2.z, options.littleEndian);
|
|
84030
|
+
vOffset += 4;
|
|
84031
|
+
} else {
|
|
84032
|
+
output.setFloat32(vOffset, 0, options.littleEndian);
|
|
84033
|
+
vOffset += 4;
|
|
84034
|
+
output.setFloat32(vOffset, 0, options.littleEndian);
|
|
84035
|
+
vOffset += 4;
|
|
84036
|
+
output.setFloat32(vOffset, 0, options.littleEndian);
|
|
84037
|
+
vOffset += 4;
|
|
84038
|
+
}
|
|
84039
|
+
}
|
|
84040
|
+
if (includeUVs === true) {
|
|
84041
|
+
if (uvs != null) {
|
|
84042
|
+
output.setFloat32(vOffset, uvs.getX(i4), options.littleEndian);
|
|
84043
|
+
vOffset += 4;
|
|
84044
|
+
output.setFloat32(vOffset, uvs.getY(i4), options.littleEndian);
|
|
84045
|
+
vOffset += 4;
|
|
84046
|
+
} else {
|
|
84047
|
+
output.setFloat32(vOffset, 0, options.littleEndian);
|
|
84048
|
+
vOffset += 4;
|
|
84049
|
+
output.setFloat32(vOffset, 0, options.littleEndian);
|
|
84050
|
+
vOffset += 4;
|
|
84051
|
+
}
|
|
84052
|
+
}
|
|
84053
|
+
if (includeColors === true) {
|
|
84054
|
+
if (colors != null) {
|
|
84055
|
+
tempColor.fromBufferAttribute(colors, i4).convertLinearToSRGB();
|
|
84056
|
+
output.setUint8(vOffset, Math.floor(tempColor.r * 255));
|
|
84057
|
+
vOffset += 1;
|
|
84058
|
+
output.setUint8(vOffset, Math.floor(tempColor.g * 255));
|
|
84059
|
+
vOffset += 1;
|
|
84060
|
+
output.setUint8(vOffset, Math.floor(tempColor.b * 255));
|
|
84061
|
+
vOffset += 1;
|
|
84062
|
+
} else {
|
|
84063
|
+
output.setUint8(vOffset, 255);
|
|
84064
|
+
vOffset += 1;
|
|
84065
|
+
output.setUint8(vOffset, 255);
|
|
84066
|
+
vOffset += 1;
|
|
84067
|
+
output.setUint8(vOffset, 255);
|
|
84068
|
+
vOffset += 1;
|
|
84069
|
+
}
|
|
84070
|
+
}
|
|
84071
|
+
}
|
|
84072
|
+
if (includeIndices === true) {
|
|
84073
|
+
if (indices !== null) {
|
|
84074
|
+
for (let i4 = 0, l4 = indices.count; i4 < l4; i4 += 3) {
|
|
84075
|
+
output.setUint8(fOffset, 3);
|
|
84076
|
+
fOffset += 1;
|
|
84077
|
+
output.setUint32(fOffset, indices.getX(i4 + 0) + writtenVertices, options.littleEndian);
|
|
84078
|
+
fOffset += indexByteCount;
|
|
84079
|
+
output.setUint32(fOffset, indices.getX(i4 + 1) + writtenVertices, options.littleEndian);
|
|
84080
|
+
fOffset += indexByteCount;
|
|
84081
|
+
output.setUint32(fOffset, indices.getX(i4 + 2) + writtenVertices, options.littleEndian);
|
|
84082
|
+
fOffset += indexByteCount;
|
|
84083
|
+
}
|
|
84084
|
+
} else {
|
|
84085
|
+
for (let i4 = 0, l4 = vertices.count; i4 < l4; i4 += 3) {
|
|
84086
|
+
output.setUint8(fOffset, 3);
|
|
84087
|
+
fOffset += 1;
|
|
84088
|
+
output.setUint32(fOffset, writtenVertices + i4, options.littleEndian);
|
|
84089
|
+
fOffset += indexByteCount;
|
|
84090
|
+
output.setUint32(fOffset, writtenVertices + i4 + 1, options.littleEndian);
|
|
84091
|
+
fOffset += indexByteCount;
|
|
84092
|
+
output.setUint32(fOffset, writtenVertices + i4 + 2, options.littleEndian);
|
|
84093
|
+
fOffset += indexByteCount;
|
|
84094
|
+
}
|
|
84095
|
+
}
|
|
84096
|
+
}
|
|
84097
|
+
writtenVertices += vertices.count;
|
|
84098
|
+
});
|
|
84099
|
+
result = output.buffer;
|
|
84100
|
+
} else {
|
|
84101
|
+
let writtenVertices = 0;
|
|
84102
|
+
let vertexList = "";
|
|
84103
|
+
let faceList = "";
|
|
84104
|
+
traverseMeshes(function(mesh, geometry) {
|
|
84105
|
+
const vertices = geometry.getAttribute("position");
|
|
84106
|
+
const normals = geometry.getAttribute("normal");
|
|
84107
|
+
const uvs = geometry.getAttribute("uv");
|
|
84108
|
+
const colors = geometry.getAttribute("color");
|
|
84109
|
+
const indices = geometry.getIndex();
|
|
84110
|
+
normalMatrixWorld.getNormalMatrix(mesh.matrixWorld);
|
|
84111
|
+
for (let i4 = 0, l4 = vertices.count; i4 < l4; i4++) {
|
|
84112
|
+
vertex2.fromBufferAttribute(vertices, i4);
|
|
84113
|
+
vertex2.applyMatrix4(mesh.matrixWorld);
|
|
84114
|
+
let line = vertex2.x + " " + vertex2.y + " " + vertex2.z;
|
|
84115
|
+
if (includeNormals === true) {
|
|
84116
|
+
if (normals != null) {
|
|
84117
|
+
vertex2.fromBufferAttribute(normals, i4);
|
|
84118
|
+
vertex2.applyMatrix3(normalMatrixWorld).normalize();
|
|
84119
|
+
line += " " + vertex2.x + " " + vertex2.y + " " + vertex2.z;
|
|
84120
|
+
} else {
|
|
84121
|
+
line += " 0 0 0";
|
|
84122
|
+
}
|
|
84123
|
+
}
|
|
84124
|
+
if (includeUVs === true) {
|
|
84125
|
+
if (uvs != null) {
|
|
84126
|
+
line += " " + uvs.getX(i4) + " " + uvs.getY(i4);
|
|
84127
|
+
} else {
|
|
84128
|
+
line += " 0 0";
|
|
84129
|
+
}
|
|
84130
|
+
}
|
|
84131
|
+
if (includeColors === true) {
|
|
84132
|
+
if (colors != null) {
|
|
84133
|
+
tempColor.fromBufferAttribute(colors, i4).convertLinearToSRGB();
|
|
84134
|
+
line += " " + Math.floor(tempColor.r * 255) + " " + Math.floor(tempColor.g * 255) + " " + Math.floor(tempColor.b * 255);
|
|
84135
|
+
} else {
|
|
84136
|
+
line += " 255 255 255";
|
|
84137
|
+
}
|
|
84138
|
+
}
|
|
84139
|
+
vertexList += line + "\n";
|
|
84140
|
+
}
|
|
84141
|
+
if (includeIndices === true) {
|
|
84142
|
+
if (indices !== null) {
|
|
84143
|
+
for (let i4 = 0, l4 = indices.count; i4 < l4; i4 += 3) {
|
|
84144
|
+
faceList += `3 ${indices.getX(i4 + 0) + writtenVertices}`;
|
|
84145
|
+
faceList += ` ${indices.getX(i4 + 1) + writtenVertices}`;
|
|
84146
|
+
faceList += ` ${indices.getX(i4 + 2) + writtenVertices}
|
|
84147
|
+
`;
|
|
84148
|
+
}
|
|
84149
|
+
} else {
|
|
84150
|
+
for (let i4 = 0, l4 = vertices.count; i4 < l4; i4 += 3) {
|
|
84151
|
+
faceList += `3 ${writtenVertices + i4} ${writtenVertices + i4 + 1} ${writtenVertices + i4 + 2}
|
|
84152
|
+
`;
|
|
84153
|
+
}
|
|
84154
|
+
}
|
|
84155
|
+
faceCount += indices ? indices.count / 3 : vertices.count / 3;
|
|
84156
|
+
}
|
|
84157
|
+
writtenVertices += vertices.count;
|
|
84158
|
+
});
|
|
84159
|
+
result = `${header}${vertexList}${includeIndices ? `${faceList}
|
|
84160
|
+
` : "\n"}`;
|
|
84161
|
+
}
|
|
84162
|
+
if (typeof onDone === "function") requestAnimationFrame(() => onDone(result));
|
|
84163
|
+
return result;
|
|
84164
|
+
}
|
|
84165
|
+
};
|
|
84166
|
+
|
|
84167
|
+
// ../../node_modules/three/examples/jsm/exporters/GLTFExporter.js
|
|
84168
|
+
init_dirname();
|
|
84169
|
+
init_buffer2();
|
|
84170
|
+
init_process2();
|
|
84171
|
+
init_three_module();
|
|
84172
|
+
|
|
84173
|
+
// ../../node_modules/three/examples/jsm/utils/TextureUtils.js
|
|
84174
|
+
init_dirname();
|
|
84175
|
+
init_buffer2();
|
|
84176
|
+
init_process2();
|
|
84177
|
+
init_three_module();
|
|
84178
|
+
var _renderer;
|
|
84179
|
+
var fullscreenQuadGeometry;
|
|
84180
|
+
var fullscreenQuadMaterial;
|
|
84181
|
+
var fullscreenQuad;
|
|
84182
|
+
function decompress(texture, maxTextureSize = Infinity, renderer = null) {
|
|
84183
|
+
if (!fullscreenQuadGeometry) fullscreenQuadGeometry = new PlaneGeometry(2, 2, 1, 1);
|
|
84184
|
+
if (!fullscreenQuadMaterial) fullscreenQuadMaterial = new ShaderMaterial({
|
|
84185
|
+
uniforms: { blitTexture: new Uniform(texture) },
|
|
84186
|
+
vertexShader: `
|
|
84187
|
+
varying vec2 vUv;
|
|
84188
|
+
void main(){
|
|
84189
|
+
vUv = uv;
|
|
84190
|
+
gl_Position = vec4(position.xy * 1.0,0.,.999999);
|
|
84191
|
+
}`,
|
|
84192
|
+
fragmentShader: `
|
|
84193
|
+
uniform sampler2D blitTexture;
|
|
84194
|
+
varying vec2 vUv;
|
|
84195
|
+
|
|
84196
|
+
void main(){
|
|
84197
|
+
gl_FragColor = vec4(vUv.xy, 0, 1);
|
|
84198
|
+
|
|
84199
|
+
#ifdef IS_SRGB
|
|
84200
|
+
gl_FragColor = LinearTosRGB( texture2D( blitTexture, vUv) );
|
|
84201
|
+
#else
|
|
84202
|
+
gl_FragColor = texture2D( blitTexture, vUv);
|
|
84203
|
+
#endif
|
|
84204
|
+
}`
|
|
84205
|
+
});
|
|
84206
|
+
fullscreenQuadMaterial.uniforms.blitTexture.value = texture;
|
|
84207
|
+
fullscreenQuadMaterial.defines.IS_SRGB = texture.colorSpace == SRGBColorSpace;
|
|
84208
|
+
fullscreenQuadMaterial.needsUpdate = true;
|
|
84209
|
+
if (!fullscreenQuad) {
|
|
84210
|
+
fullscreenQuad = new Mesh(fullscreenQuadGeometry, fullscreenQuadMaterial);
|
|
84211
|
+
fullscreenQuad.frustrumCulled = false;
|
|
84212
|
+
}
|
|
84213
|
+
const _camera = new PerspectiveCamera();
|
|
84214
|
+
const _scene = new Scene();
|
|
84215
|
+
_scene.add(fullscreenQuad);
|
|
84216
|
+
if (!renderer) {
|
|
84217
|
+
renderer = _renderer = new WebGLRenderer({ antialias: false });
|
|
84218
|
+
}
|
|
84219
|
+
renderer.setSize(Math.min(texture.image.width, maxTextureSize), Math.min(texture.image.height, maxTextureSize));
|
|
84220
|
+
renderer.clear();
|
|
84221
|
+
renderer.render(_scene, _camera);
|
|
84222
|
+
const readableTexture = new Texture(renderer.domElement);
|
|
84223
|
+
readableTexture.minFilter = texture.minFilter;
|
|
84224
|
+
readableTexture.magFilter = texture.magFilter;
|
|
84225
|
+
readableTexture.wrapS = texture.wrapS;
|
|
84226
|
+
readableTexture.wrapT = texture.wrapT;
|
|
84227
|
+
readableTexture.name = texture.name;
|
|
84228
|
+
if (_renderer) {
|
|
84229
|
+
_renderer.dispose();
|
|
84230
|
+
_renderer = null;
|
|
84231
|
+
}
|
|
84232
|
+
return readableTexture;
|
|
84233
|
+
}
|
|
84234
|
+
|
|
84235
|
+
// ../../node_modules/three/examples/jsm/exporters/GLTFExporter.js
|
|
84236
|
+
var KHR_mesh_quantization_ExtraAttrTypes = {
|
|
84237
|
+
POSITION: [
|
|
84238
|
+
"byte",
|
|
84239
|
+
"byte normalized",
|
|
84240
|
+
"unsigned byte",
|
|
84241
|
+
"unsigned byte normalized",
|
|
84242
|
+
"short",
|
|
84243
|
+
"short normalized",
|
|
84244
|
+
"unsigned short",
|
|
84245
|
+
"unsigned short normalized"
|
|
84246
|
+
],
|
|
84247
|
+
NORMAL: [
|
|
84248
|
+
"byte normalized",
|
|
84249
|
+
"short normalized"
|
|
84250
|
+
],
|
|
84251
|
+
TANGENT: [
|
|
84252
|
+
"byte normalized",
|
|
84253
|
+
"short normalized"
|
|
84254
|
+
],
|
|
84255
|
+
TEXCOORD: [
|
|
84256
|
+
"byte",
|
|
84257
|
+
"byte normalized",
|
|
84258
|
+
"unsigned byte",
|
|
84259
|
+
"short",
|
|
84260
|
+
"short normalized",
|
|
84261
|
+
"unsigned short"
|
|
84262
|
+
]
|
|
84263
|
+
};
|
|
84264
|
+
var GLTFExporter = class {
|
|
84265
|
+
constructor() {
|
|
84266
|
+
this.pluginCallbacks = [];
|
|
84267
|
+
this.register(function(writer) {
|
|
84268
|
+
return new GLTFLightExtension(writer);
|
|
84269
|
+
});
|
|
84270
|
+
this.register(function(writer) {
|
|
84271
|
+
return new GLTFMaterialsUnlitExtension(writer);
|
|
84272
|
+
});
|
|
84273
|
+
this.register(function(writer) {
|
|
84274
|
+
return new GLTFMaterialsTransmissionExtension(writer);
|
|
84275
|
+
});
|
|
84276
|
+
this.register(function(writer) {
|
|
84277
|
+
return new GLTFMaterialsVolumeExtension(writer);
|
|
84278
|
+
});
|
|
84279
|
+
this.register(function(writer) {
|
|
84280
|
+
return new GLTFMaterialsIorExtension(writer);
|
|
84281
|
+
});
|
|
84282
|
+
this.register(function(writer) {
|
|
84283
|
+
return new GLTFMaterialsSpecularExtension(writer);
|
|
84284
|
+
});
|
|
84285
|
+
this.register(function(writer) {
|
|
84286
|
+
return new GLTFMaterialsClearcoatExtension(writer);
|
|
84287
|
+
});
|
|
84288
|
+
this.register(function(writer) {
|
|
84289
|
+
return new GLTFMaterialsIridescenceExtension(writer);
|
|
84290
|
+
});
|
|
84291
|
+
this.register(function(writer) {
|
|
84292
|
+
return new GLTFMaterialsSheenExtension(writer);
|
|
84293
|
+
});
|
|
84294
|
+
this.register(function(writer) {
|
|
84295
|
+
return new GLTFMaterialsAnisotropyExtension(writer);
|
|
84296
|
+
});
|
|
84297
|
+
this.register(function(writer) {
|
|
84298
|
+
return new GLTFMaterialsEmissiveStrengthExtension(writer);
|
|
84299
|
+
});
|
|
84300
|
+
this.register(function(writer) {
|
|
84301
|
+
return new GLTFMeshGpuInstancing(writer);
|
|
84302
|
+
});
|
|
84303
|
+
}
|
|
84304
|
+
register(callback) {
|
|
84305
|
+
if (this.pluginCallbacks.indexOf(callback) === -1) {
|
|
84306
|
+
this.pluginCallbacks.push(callback);
|
|
84307
|
+
}
|
|
84308
|
+
return this;
|
|
84309
|
+
}
|
|
84310
|
+
unregister(callback) {
|
|
84311
|
+
if (this.pluginCallbacks.indexOf(callback) !== -1) {
|
|
84312
|
+
this.pluginCallbacks.splice(this.pluginCallbacks.indexOf(callback), 1);
|
|
84313
|
+
}
|
|
84314
|
+
return this;
|
|
84315
|
+
}
|
|
84316
|
+
/**
|
|
84317
|
+
* Parse scenes and generate GLTF output
|
|
84318
|
+
* @param {Scene or [THREE.Scenes]} input Scene or Array of THREE.Scenes
|
|
84319
|
+
* @param {Function} onDone Callback on completed
|
|
84320
|
+
* @param {Function} onError Callback on errors
|
|
84321
|
+
* @param {Object} options options
|
|
84322
|
+
*/
|
|
84323
|
+
parse(input, onDone, onError, options) {
|
|
84324
|
+
const writer = new GLTFWriter();
|
|
84325
|
+
const plugins = [];
|
|
84326
|
+
for (let i4 = 0, il = this.pluginCallbacks.length; i4 < il; i4++) {
|
|
84327
|
+
plugins.push(this.pluginCallbacks[i4](writer));
|
|
84328
|
+
}
|
|
84329
|
+
writer.setPlugins(plugins);
|
|
84330
|
+
writer.write(input, onDone, options).catch(onError);
|
|
84331
|
+
}
|
|
84332
|
+
parseAsync(input, options) {
|
|
84333
|
+
const scope = this;
|
|
84334
|
+
return new Promise(function(resolve, reject) {
|
|
84335
|
+
scope.parse(input, resolve, reject, options);
|
|
84336
|
+
});
|
|
84337
|
+
}
|
|
84338
|
+
};
|
|
84339
|
+
var WEBGL_CONSTANTS = {
|
|
84340
|
+
POINTS: 0,
|
|
84341
|
+
LINES: 1,
|
|
84342
|
+
LINE_LOOP: 2,
|
|
84343
|
+
LINE_STRIP: 3,
|
|
84344
|
+
TRIANGLES: 4,
|
|
84345
|
+
TRIANGLE_STRIP: 5,
|
|
84346
|
+
TRIANGLE_FAN: 6,
|
|
84347
|
+
BYTE: 5120,
|
|
84348
|
+
UNSIGNED_BYTE: 5121,
|
|
84349
|
+
SHORT: 5122,
|
|
84350
|
+
UNSIGNED_SHORT: 5123,
|
|
84351
|
+
INT: 5124,
|
|
84352
|
+
UNSIGNED_INT: 5125,
|
|
84353
|
+
FLOAT: 5126,
|
|
84354
|
+
ARRAY_BUFFER: 34962,
|
|
84355
|
+
ELEMENT_ARRAY_BUFFER: 34963,
|
|
84356
|
+
NEAREST: 9728,
|
|
84357
|
+
LINEAR: 9729,
|
|
84358
|
+
NEAREST_MIPMAP_NEAREST: 9984,
|
|
84359
|
+
LINEAR_MIPMAP_NEAREST: 9985,
|
|
84360
|
+
NEAREST_MIPMAP_LINEAR: 9986,
|
|
84361
|
+
LINEAR_MIPMAP_LINEAR: 9987,
|
|
84362
|
+
CLAMP_TO_EDGE: 33071,
|
|
84363
|
+
MIRRORED_REPEAT: 33648,
|
|
84364
|
+
REPEAT: 10497
|
|
84365
|
+
};
|
|
84366
|
+
var KHR_MESH_QUANTIZATION = "KHR_mesh_quantization";
|
|
84367
|
+
var THREE_TO_WEBGL = {};
|
|
84368
|
+
THREE_TO_WEBGL[NearestFilter] = WEBGL_CONSTANTS.NEAREST;
|
|
84369
|
+
THREE_TO_WEBGL[NearestMipmapNearestFilter] = WEBGL_CONSTANTS.NEAREST_MIPMAP_NEAREST;
|
|
84370
|
+
THREE_TO_WEBGL[NearestMipmapLinearFilter] = WEBGL_CONSTANTS.NEAREST_MIPMAP_LINEAR;
|
|
84371
|
+
THREE_TO_WEBGL[LinearFilter] = WEBGL_CONSTANTS.LINEAR;
|
|
84372
|
+
THREE_TO_WEBGL[LinearMipmapNearestFilter] = WEBGL_CONSTANTS.LINEAR_MIPMAP_NEAREST;
|
|
84373
|
+
THREE_TO_WEBGL[LinearMipmapLinearFilter] = WEBGL_CONSTANTS.LINEAR_MIPMAP_LINEAR;
|
|
84374
|
+
THREE_TO_WEBGL[ClampToEdgeWrapping] = WEBGL_CONSTANTS.CLAMP_TO_EDGE;
|
|
84375
|
+
THREE_TO_WEBGL[RepeatWrapping] = WEBGL_CONSTANTS.REPEAT;
|
|
84376
|
+
THREE_TO_WEBGL[MirroredRepeatWrapping] = WEBGL_CONSTANTS.MIRRORED_REPEAT;
|
|
84377
|
+
var PATH_PROPERTIES = {
|
|
84378
|
+
scale: "scale",
|
|
84379
|
+
position: "translation",
|
|
84380
|
+
quaternion: "rotation",
|
|
84381
|
+
morphTargetInfluences: "weights"
|
|
84382
|
+
};
|
|
84383
|
+
var DEFAULT_SPECULAR_COLOR = new Color();
|
|
84384
|
+
var GLB_HEADER_BYTES = 12;
|
|
84385
|
+
var GLB_HEADER_MAGIC = 1179937895;
|
|
84386
|
+
var GLB_VERSION = 2;
|
|
84387
|
+
var GLB_CHUNK_PREFIX_BYTES = 8;
|
|
84388
|
+
var GLB_CHUNK_TYPE_JSON = 1313821514;
|
|
84389
|
+
var GLB_CHUNK_TYPE_BIN = 5130562;
|
|
84390
|
+
function equalArray(array1, array2) {
|
|
84391
|
+
return array1.length === array2.length && array1.every(function(element, index) {
|
|
84392
|
+
return element === array2[index];
|
|
84393
|
+
});
|
|
84394
|
+
}
|
|
84395
|
+
function stringToArrayBuffer(text) {
|
|
84396
|
+
return new TextEncoder().encode(text).buffer;
|
|
84397
|
+
}
|
|
84398
|
+
function isIdentityMatrix(matrix) {
|
|
84399
|
+
return equalArray(matrix.elements, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]);
|
|
84400
|
+
}
|
|
84401
|
+
function getMinMax(attribute, start, count) {
|
|
84402
|
+
const output = {
|
|
84403
|
+
min: new Array(attribute.itemSize).fill(Number.POSITIVE_INFINITY),
|
|
84404
|
+
max: new Array(attribute.itemSize).fill(Number.NEGATIVE_INFINITY)
|
|
84405
|
+
};
|
|
84406
|
+
for (let i4 = start; i4 < start + count; i4++) {
|
|
84407
|
+
for (let a4 = 0; a4 < attribute.itemSize; a4++) {
|
|
84408
|
+
let value;
|
|
84409
|
+
if (attribute.itemSize > 4) {
|
|
84410
|
+
value = attribute.array[i4 * attribute.itemSize + a4];
|
|
84411
|
+
} else {
|
|
84412
|
+
if (a4 === 0) value = attribute.getX(i4);
|
|
84413
|
+
else if (a4 === 1) value = attribute.getY(i4);
|
|
84414
|
+
else if (a4 === 2) value = attribute.getZ(i4);
|
|
84415
|
+
else if (a4 === 3) value = attribute.getW(i4);
|
|
84416
|
+
if (attribute.normalized === true) {
|
|
84417
|
+
value = MathUtils.normalize(value, attribute.array);
|
|
84418
|
+
}
|
|
84419
|
+
}
|
|
84420
|
+
output.min[a4] = Math.min(output.min[a4], value);
|
|
84421
|
+
output.max[a4] = Math.max(output.max[a4], value);
|
|
84422
|
+
}
|
|
84423
|
+
}
|
|
84424
|
+
return output;
|
|
84425
|
+
}
|
|
84426
|
+
function getPaddedBufferSize(bufferSize) {
|
|
84427
|
+
return Math.ceil(bufferSize / 4) * 4;
|
|
84428
|
+
}
|
|
84429
|
+
function getPaddedArrayBuffer(arrayBuffer, paddingByte = 0) {
|
|
84430
|
+
const paddedLength = getPaddedBufferSize(arrayBuffer.byteLength);
|
|
84431
|
+
if (paddedLength !== arrayBuffer.byteLength) {
|
|
84432
|
+
const array = new Uint8Array(paddedLength);
|
|
84433
|
+
array.set(new Uint8Array(arrayBuffer));
|
|
84434
|
+
if (paddingByte !== 0) {
|
|
84435
|
+
for (let i4 = arrayBuffer.byteLength; i4 < paddedLength; i4++) {
|
|
84436
|
+
array[i4] = paddingByte;
|
|
84437
|
+
}
|
|
84438
|
+
}
|
|
84439
|
+
return array.buffer;
|
|
84440
|
+
}
|
|
84441
|
+
return arrayBuffer;
|
|
84442
|
+
}
|
|
84443
|
+
function getCanvas() {
|
|
84444
|
+
if (typeof document === "undefined" && typeof OffscreenCanvas !== "undefined") {
|
|
84445
|
+
return new OffscreenCanvas(1, 1);
|
|
84446
|
+
}
|
|
84447
|
+
return document.createElement("canvas");
|
|
84448
|
+
}
|
|
84449
|
+
function getToBlobPromise(canvas, mimeType) {
|
|
84450
|
+
if (canvas.toBlob !== void 0) {
|
|
84451
|
+
return new Promise((resolve) => canvas.toBlob(resolve, mimeType));
|
|
84452
|
+
}
|
|
84453
|
+
let quality;
|
|
84454
|
+
if (mimeType === "image/jpeg") {
|
|
84455
|
+
quality = 0.92;
|
|
84456
|
+
} else if (mimeType === "image/webp") {
|
|
84457
|
+
quality = 0.8;
|
|
84458
|
+
}
|
|
84459
|
+
return canvas.convertToBlob({
|
|
84460
|
+
type: mimeType,
|
|
84461
|
+
quality
|
|
84462
|
+
});
|
|
84463
|
+
}
|
|
84464
|
+
var GLTFWriter = class {
|
|
84465
|
+
constructor() {
|
|
84466
|
+
this.plugins = [];
|
|
84467
|
+
this.options = {};
|
|
84468
|
+
this.pending = [];
|
|
84469
|
+
this.buffers = [];
|
|
84470
|
+
this.byteOffset = 0;
|
|
84471
|
+
this.buffers = [];
|
|
84472
|
+
this.nodeMap = /* @__PURE__ */ new Map();
|
|
84473
|
+
this.skins = [];
|
|
84474
|
+
this.extensionsUsed = {};
|
|
84475
|
+
this.extensionsRequired = {};
|
|
84476
|
+
this.uids = /* @__PURE__ */ new Map();
|
|
84477
|
+
this.uid = 0;
|
|
84478
|
+
this.json = {
|
|
84479
|
+
asset: {
|
|
84480
|
+
version: "2.0",
|
|
84481
|
+
generator: "THREE.GLTFExporter"
|
|
84482
|
+
}
|
|
84483
|
+
};
|
|
84484
|
+
this.cache = {
|
|
84485
|
+
meshes: /* @__PURE__ */ new Map(),
|
|
84486
|
+
attributes: /* @__PURE__ */ new Map(),
|
|
84487
|
+
attributesNormalized: /* @__PURE__ */ new Map(),
|
|
84488
|
+
materials: /* @__PURE__ */ new Map(),
|
|
84489
|
+
textures: /* @__PURE__ */ new Map(),
|
|
84490
|
+
images: /* @__PURE__ */ new Map()
|
|
84491
|
+
};
|
|
84492
|
+
}
|
|
84493
|
+
setPlugins(plugins) {
|
|
84494
|
+
this.plugins = plugins;
|
|
84495
|
+
}
|
|
84496
|
+
/**
|
|
84497
|
+
* Parse scenes and generate GLTF output
|
|
84498
|
+
* @param {Scene or [THREE.Scenes]} input Scene or Array of THREE.Scenes
|
|
84499
|
+
* @param {Function} onDone Callback on completed
|
|
84500
|
+
* @param {Object} options options
|
|
84501
|
+
*/
|
|
84502
|
+
async write(input, onDone, options = {}) {
|
|
84503
|
+
this.options = Object.assign({
|
|
84504
|
+
// default options
|
|
84505
|
+
binary: false,
|
|
84506
|
+
trs: false,
|
|
84507
|
+
onlyVisible: true,
|
|
84508
|
+
maxTextureSize: Infinity,
|
|
84509
|
+
animations: [],
|
|
84510
|
+
includeCustomExtensions: false
|
|
84511
|
+
}, options);
|
|
84512
|
+
if (this.options.animations.length > 0) {
|
|
84513
|
+
this.options.trs = true;
|
|
84514
|
+
}
|
|
84515
|
+
this.processInput(input);
|
|
84516
|
+
await Promise.all(this.pending);
|
|
84517
|
+
const writer = this;
|
|
84518
|
+
const buffers = writer.buffers;
|
|
84519
|
+
const json = writer.json;
|
|
84520
|
+
options = writer.options;
|
|
84521
|
+
const extensionsUsed = writer.extensionsUsed;
|
|
84522
|
+
const extensionsRequired = writer.extensionsRequired;
|
|
84523
|
+
const blob = new Blob(buffers, { type: "application/octet-stream" });
|
|
84524
|
+
const extensionsUsedList = Object.keys(extensionsUsed);
|
|
84525
|
+
const extensionsRequiredList = Object.keys(extensionsRequired);
|
|
84526
|
+
if (extensionsUsedList.length > 0) json.extensionsUsed = extensionsUsedList;
|
|
84527
|
+
if (extensionsRequiredList.length > 0) json.extensionsRequired = extensionsRequiredList;
|
|
84528
|
+
if (json.buffers && json.buffers.length > 0) json.buffers[0].byteLength = blob.size;
|
|
84529
|
+
if (options.binary === true) {
|
|
84530
|
+
const reader = new FileReader();
|
|
84531
|
+
reader.readAsArrayBuffer(blob);
|
|
84532
|
+
reader.onloadend = function() {
|
|
84533
|
+
const binaryChunk = getPaddedArrayBuffer(reader.result);
|
|
84534
|
+
const binaryChunkPrefix = new DataView(new ArrayBuffer(GLB_CHUNK_PREFIX_BYTES));
|
|
84535
|
+
binaryChunkPrefix.setUint32(0, binaryChunk.byteLength, true);
|
|
84536
|
+
binaryChunkPrefix.setUint32(4, GLB_CHUNK_TYPE_BIN, true);
|
|
84537
|
+
const jsonChunk = getPaddedArrayBuffer(stringToArrayBuffer(JSON.stringify(json)), 32);
|
|
84538
|
+
const jsonChunkPrefix = new DataView(new ArrayBuffer(GLB_CHUNK_PREFIX_BYTES));
|
|
84539
|
+
jsonChunkPrefix.setUint32(0, jsonChunk.byteLength, true);
|
|
84540
|
+
jsonChunkPrefix.setUint32(4, GLB_CHUNK_TYPE_JSON, true);
|
|
84541
|
+
const header = new ArrayBuffer(GLB_HEADER_BYTES);
|
|
84542
|
+
const headerView = new DataView(header);
|
|
84543
|
+
headerView.setUint32(0, GLB_HEADER_MAGIC, true);
|
|
84544
|
+
headerView.setUint32(4, GLB_VERSION, true);
|
|
84545
|
+
const totalByteLength = GLB_HEADER_BYTES + jsonChunkPrefix.byteLength + jsonChunk.byteLength + binaryChunkPrefix.byteLength + binaryChunk.byteLength;
|
|
84546
|
+
headerView.setUint32(8, totalByteLength, true);
|
|
84547
|
+
const glbBlob = new Blob([
|
|
84548
|
+
header,
|
|
84549
|
+
jsonChunkPrefix,
|
|
84550
|
+
jsonChunk,
|
|
84551
|
+
binaryChunkPrefix,
|
|
84552
|
+
binaryChunk
|
|
84553
|
+
], { type: "application/octet-stream" });
|
|
84554
|
+
const glbReader = new FileReader();
|
|
84555
|
+
glbReader.readAsArrayBuffer(glbBlob);
|
|
84556
|
+
glbReader.onloadend = function() {
|
|
84557
|
+
onDone(glbReader.result);
|
|
84558
|
+
};
|
|
84559
|
+
};
|
|
84560
|
+
} else {
|
|
84561
|
+
if (json.buffers && json.buffers.length > 0) {
|
|
84562
|
+
const reader = new FileReader();
|
|
84563
|
+
reader.readAsDataURL(blob);
|
|
84564
|
+
reader.onloadend = function() {
|
|
84565
|
+
const base64data = reader.result;
|
|
84566
|
+
json.buffers[0].uri = base64data;
|
|
84567
|
+
onDone(json);
|
|
84568
|
+
};
|
|
84569
|
+
} else {
|
|
84570
|
+
onDone(json);
|
|
84571
|
+
}
|
|
84572
|
+
}
|
|
84573
|
+
}
|
|
84574
|
+
/**
|
|
84575
|
+
* Serializes a userData.
|
|
84576
|
+
*
|
|
84577
|
+
* @param {THREE.Object3D|THREE.Material} object
|
|
84578
|
+
* @param {Object} objectDef
|
|
84579
|
+
*/
|
|
84580
|
+
serializeUserData(object, objectDef) {
|
|
84581
|
+
if (Object.keys(object.userData).length === 0) return;
|
|
84582
|
+
const options = this.options;
|
|
84583
|
+
const extensionsUsed = this.extensionsUsed;
|
|
84584
|
+
try {
|
|
84585
|
+
const json = JSON.parse(JSON.stringify(object.userData));
|
|
84586
|
+
if (options.includeCustomExtensions && json.gltfExtensions) {
|
|
84587
|
+
if (objectDef.extensions === void 0) objectDef.extensions = {};
|
|
84588
|
+
for (const extensionName in json.gltfExtensions) {
|
|
84589
|
+
objectDef.extensions[extensionName] = json.gltfExtensions[extensionName];
|
|
84590
|
+
extensionsUsed[extensionName] = true;
|
|
84591
|
+
}
|
|
84592
|
+
delete json.gltfExtensions;
|
|
84593
|
+
}
|
|
84594
|
+
if (Object.keys(json).length > 0) objectDef.extras = json;
|
|
84595
|
+
} catch (error) {
|
|
84596
|
+
console.warn("THREE.GLTFExporter: userData of '" + object.name + "' won't be serialized because of JSON.stringify error - " + error.message);
|
|
84597
|
+
}
|
|
84598
|
+
}
|
|
84599
|
+
/**
|
|
84600
|
+
* Returns ids for buffer attributes.
|
|
84601
|
+
* @param {Object} object
|
|
84602
|
+
* @return {Integer}
|
|
84603
|
+
*/
|
|
84604
|
+
getUID(attribute, isRelativeCopy = false) {
|
|
84605
|
+
if (this.uids.has(attribute) === false) {
|
|
84606
|
+
const uids2 = /* @__PURE__ */ new Map();
|
|
84607
|
+
uids2.set(true, this.uid++);
|
|
84608
|
+
uids2.set(false, this.uid++);
|
|
84609
|
+
this.uids.set(attribute, uids2);
|
|
84610
|
+
}
|
|
84611
|
+
const uids = this.uids.get(attribute);
|
|
84612
|
+
return uids.get(isRelativeCopy);
|
|
84613
|
+
}
|
|
84614
|
+
/**
|
|
84615
|
+
* Checks if normal attribute values are normalized.
|
|
84616
|
+
*
|
|
84617
|
+
* @param {BufferAttribute} normal
|
|
84618
|
+
* @returns {Boolean}
|
|
84619
|
+
*/
|
|
84620
|
+
isNormalizedNormalAttribute(normal) {
|
|
84621
|
+
const cache = this.cache;
|
|
84622
|
+
if (cache.attributesNormalized.has(normal)) return false;
|
|
84623
|
+
const v5 = new Vector3();
|
|
84624
|
+
for (let i4 = 0, il = normal.count; i4 < il; i4++) {
|
|
84625
|
+
if (Math.abs(v5.fromBufferAttribute(normal, i4).length() - 1) > 5e-4) return false;
|
|
84626
|
+
}
|
|
84627
|
+
return true;
|
|
84628
|
+
}
|
|
84629
|
+
/**
|
|
84630
|
+
* Creates normalized normal buffer attribute.
|
|
84631
|
+
*
|
|
84632
|
+
* @param {BufferAttribute} normal
|
|
84633
|
+
* @returns {BufferAttribute}
|
|
84634
|
+
*
|
|
84635
|
+
*/
|
|
84636
|
+
createNormalizedNormalAttribute(normal) {
|
|
84637
|
+
const cache = this.cache;
|
|
84638
|
+
if (cache.attributesNormalized.has(normal)) return cache.attributesNormalized.get(normal);
|
|
84639
|
+
const attribute = normal.clone();
|
|
84640
|
+
const v5 = new Vector3();
|
|
84641
|
+
for (let i4 = 0, il = attribute.count; i4 < il; i4++) {
|
|
84642
|
+
v5.fromBufferAttribute(attribute, i4);
|
|
84643
|
+
if (v5.x === 0 && v5.y === 0 && v5.z === 0) {
|
|
84644
|
+
v5.setX(1);
|
|
84645
|
+
} else {
|
|
84646
|
+
v5.normalize();
|
|
84647
|
+
}
|
|
84648
|
+
attribute.setXYZ(i4, v5.x, v5.y, v5.z);
|
|
84649
|
+
}
|
|
84650
|
+
cache.attributesNormalized.set(normal, attribute);
|
|
84651
|
+
return attribute;
|
|
84652
|
+
}
|
|
84653
|
+
/**
|
|
84654
|
+
* Applies a texture transform, if present, to the map definition. Requires
|
|
84655
|
+
* the KHR_texture_transform extension.
|
|
84656
|
+
*
|
|
84657
|
+
* @param {Object} mapDef
|
|
84658
|
+
* @param {THREE.Texture} texture
|
|
84659
|
+
*/
|
|
84660
|
+
applyTextureTransform(mapDef, texture) {
|
|
84661
|
+
let didTransform = false;
|
|
84662
|
+
const transformDef = {};
|
|
84663
|
+
if (texture.offset.x !== 0 || texture.offset.y !== 0) {
|
|
84664
|
+
transformDef.offset = texture.offset.toArray();
|
|
84665
|
+
didTransform = true;
|
|
84666
|
+
}
|
|
84667
|
+
if (texture.rotation !== 0) {
|
|
84668
|
+
transformDef.rotation = texture.rotation;
|
|
84669
|
+
didTransform = true;
|
|
84670
|
+
}
|
|
84671
|
+
if (texture.repeat.x !== 1 || texture.repeat.y !== 1) {
|
|
84672
|
+
transformDef.scale = texture.repeat.toArray();
|
|
84673
|
+
didTransform = true;
|
|
84674
|
+
}
|
|
84675
|
+
if (didTransform) {
|
|
84676
|
+
mapDef.extensions = mapDef.extensions || {};
|
|
84677
|
+
mapDef.extensions["KHR_texture_transform"] = transformDef;
|
|
84678
|
+
this.extensionsUsed["KHR_texture_transform"] = true;
|
|
84679
|
+
}
|
|
84680
|
+
}
|
|
84681
|
+
buildMetalRoughTexture(metalnessMap, roughnessMap) {
|
|
84682
|
+
if (metalnessMap === roughnessMap) return metalnessMap;
|
|
84683
|
+
function getEncodingConversion(map) {
|
|
84684
|
+
if (map.colorSpace === SRGBColorSpace) {
|
|
84685
|
+
return function SRGBToLinear2(c4) {
|
|
84686
|
+
return c4 < 0.04045 ? c4 * 0.0773993808 : Math.pow(c4 * 0.9478672986 + 0.0521327014, 2.4);
|
|
84687
|
+
};
|
|
84688
|
+
}
|
|
84689
|
+
return function LinearToLinear(c4) {
|
|
84690
|
+
return c4;
|
|
84691
|
+
};
|
|
84692
|
+
}
|
|
84693
|
+
console.warn("THREE.GLTFExporter: Merged metalnessMap and roughnessMap textures.");
|
|
84694
|
+
if (metalnessMap instanceof CompressedTexture) {
|
|
84695
|
+
metalnessMap = decompress(metalnessMap);
|
|
84696
|
+
}
|
|
84697
|
+
if (roughnessMap instanceof CompressedTexture) {
|
|
84698
|
+
roughnessMap = decompress(roughnessMap);
|
|
84699
|
+
}
|
|
84700
|
+
const metalness = metalnessMap ? metalnessMap.image : null;
|
|
84701
|
+
const roughness = roughnessMap ? roughnessMap.image : null;
|
|
84702
|
+
const width = Math.max(metalness ? metalness.width : 0, roughness ? roughness.width : 0);
|
|
84703
|
+
const height = Math.max(metalness ? metalness.height : 0, roughness ? roughness.height : 0);
|
|
84704
|
+
const canvas = getCanvas();
|
|
84705
|
+
canvas.width = width;
|
|
84706
|
+
canvas.height = height;
|
|
84707
|
+
const context = canvas.getContext("2d");
|
|
84708
|
+
context.fillStyle = "#00ffff";
|
|
84709
|
+
context.fillRect(0, 0, width, height);
|
|
84710
|
+
const composite = context.getImageData(0, 0, width, height);
|
|
84711
|
+
if (metalness) {
|
|
84712
|
+
context.drawImage(metalness, 0, 0, width, height);
|
|
84713
|
+
const convert = getEncodingConversion(metalnessMap);
|
|
84714
|
+
const data = context.getImageData(0, 0, width, height).data;
|
|
84715
|
+
for (let i4 = 2; i4 < data.length; i4 += 4) {
|
|
84716
|
+
composite.data[i4] = convert(data[i4] / 256) * 256;
|
|
84717
|
+
}
|
|
84718
|
+
}
|
|
84719
|
+
if (roughness) {
|
|
84720
|
+
context.drawImage(roughness, 0, 0, width, height);
|
|
84721
|
+
const convert = getEncodingConversion(roughnessMap);
|
|
84722
|
+
const data = context.getImageData(0, 0, width, height).data;
|
|
84723
|
+
for (let i4 = 1; i4 < data.length; i4 += 4) {
|
|
84724
|
+
composite.data[i4] = convert(data[i4] / 256) * 256;
|
|
84725
|
+
}
|
|
84726
|
+
}
|
|
84727
|
+
context.putImageData(composite, 0, 0);
|
|
84728
|
+
const reference = metalnessMap || roughnessMap;
|
|
84729
|
+
const texture = reference.clone();
|
|
84730
|
+
texture.source = new Source(canvas);
|
|
84731
|
+
texture.colorSpace = NoColorSpace;
|
|
84732
|
+
texture.channel = (metalnessMap || roughnessMap).channel;
|
|
84733
|
+
if (metalnessMap && roughnessMap && metalnessMap.channel !== roughnessMap.channel) {
|
|
84734
|
+
console.warn("THREE.GLTFExporter: UV channels for metalnessMap and roughnessMap textures must match.");
|
|
84735
|
+
}
|
|
84736
|
+
return texture;
|
|
84737
|
+
}
|
|
84738
|
+
/**
|
|
84739
|
+
* Process a buffer to append to the default one.
|
|
84740
|
+
* @param {ArrayBuffer} buffer
|
|
84741
|
+
* @return {Integer}
|
|
84742
|
+
*/
|
|
84743
|
+
processBuffer(buffer2) {
|
|
84744
|
+
const json = this.json;
|
|
84745
|
+
const buffers = this.buffers;
|
|
84746
|
+
if (!json.buffers) json.buffers = [{ byteLength: 0 }];
|
|
84747
|
+
buffers.push(buffer2);
|
|
84748
|
+
return 0;
|
|
84749
|
+
}
|
|
84750
|
+
/**
|
|
84751
|
+
* Process and generate a BufferView
|
|
84752
|
+
* @param {BufferAttribute} attribute
|
|
84753
|
+
* @param {number} componentType
|
|
84754
|
+
* @param {number} start
|
|
84755
|
+
* @param {number} count
|
|
84756
|
+
* @param {number} target (Optional) Target usage of the BufferView
|
|
84757
|
+
* @return {Object}
|
|
84758
|
+
*/
|
|
84759
|
+
processBufferView(attribute, componentType, start, count, target) {
|
|
84760
|
+
const json = this.json;
|
|
84761
|
+
if (!json.bufferViews) json.bufferViews = [];
|
|
84762
|
+
let componentSize;
|
|
84763
|
+
switch (componentType) {
|
|
84764
|
+
case WEBGL_CONSTANTS.BYTE:
|
|
84765
|
+
case WEBGL_CONSTANTS.UNSIGNED_BYTE:
|
|
84766
|
+
componentSize = 1;
|
|
84767
|
+
break;
|
|
84768
|
+
case WEBGL_CONSTANTS.SHORT:
|
|
84769
|
+
case WEBGL_CONSTANTS.UNSIGNED_SHORT:
|
|
84770
|
+
componentSize = 2;
|
|
84771
|
+
break;
|
|
84772
|
+
default:
|
|
84773
|
+
componentSize = 4;
|
|
84774
|
+
}
|
|
84775
|
+
const byteLength = getPaddedBufferSize(count * attribute.itemSize * componentSize);
|
|
84776
|
+
const dataView = new DataView(new ArrayBuffer(byteLength));
|
|
84777
|
+
let offset = 0;
|
|
84778
|
+
for (let i4 = start; i4 < start + count; i4++) {
|
|
84779
|
+
for (let a4 = 0; a4 < attribute.itemSize; a4++) {
|
|
84780
|
+
let value;
|
|
84781
|
+
if (attribute.itemSize > 4) {
|
|
84782
|
+
value = attribute.array[i4 * attribute.itemSize + a4];
|
|
84783
|
+
} else {
|
|
84784
|
+
if (a4 === 0) value = attribute.getX(i4);
|
|
84785
|
+
else if (a4 === 1) value = attribute.getY(i4);
|
|
84786
|
+
else if (a4 === 2) value = attribute.getZ(i4);
|
|
84787
|
+
else if (a4 === 3) value = attribute.getW(i4);
|
|
84788
|
+
if (attribute.normalized === true) {
|
|
84789
|
+
value = MathUtils.normalize(value, attribute.array);
|
|
84790
|
+
}
|
|
84791
|
+
}
|
|
84792
|
+
if (componentType === WEBGL_CONSTANTS.FLOAT) {
|
|
84793
|
+
dataView.setFloat32(offset, value, true);
|
|
84794
|
+
} else if (componentType === WEBGL_CONSTANTS.INT) {
|
|
84795
|
+
dataView.setInt32(offset, value, true);
|
|
84796
|
+
} else if (componentType === WEBGL_CONSTANTS.UNSIGNED_INT) {
|
|
84797
|
+
dataView.setUint32(offset, value, true);
|
|
84798
|
+
} else if (componentType === WEBGL_CONSTANTS.SHORT) {
|
|
84799
|
+
dataView.setInt16(offset, value, true);
|
|
84800
|
+
} else if (componentType === WEBGL_CONSTANTS.UNSIGNED_SHORT) {
|
|
84801
|
+
dataView.setUint16(offset, value, true);
|
|
84802
|
+
} else if (componentType === WEBGL_CONSTANTS.BYTE) {
|
|
84803
|
+
dataView.setInt8(offset, value);
|
|
84804
|
+
} else if (componentType === WEBGL_CONSTANTS.UNSIGNED_BYTE) {
|
|
84805
|
+
dataView.setUint8(offset, value);
|
|
84806
|
+
}
|
|
84807
|
+
offset += componentSize;
|
|
84808
|
+
}
|
|
84809
|
+
}
|
|
84810
|
+
const bufferViewDef = {
|
|
84811
|
+
buffer: this.processBuffer(dataView.buffer),
|
|
84812
|
+
byteOffset: this.byteOffset,
|
|
84813
|
+
byteLength
|
|
84814
|
+
};
|
|
84815
|
+
if (target !== void 0) bufferViewDef.target = target;
|
|
84816
|
+
if (target === WEBGL_CONSTANTS.ARRAY_BUFFER) {
|
|
84817
|
+
bufferViewDef.byteStride = attribute.itemSize * componentSize;
|
|
84818
|
+
}
|
|
84819
|
+
this.byteOffset += byteLength;
|
|
84820
|
+
json.bufferViews.push(bufferViewDef);
|
|
84821
|
+
const output = {
|
|
84822
|
+
id: json.bufferViews.length - 1,
|
|
84823
|
+
byteLength: 0
|
|
84824
|
+
};
|
|
84825
|
+
return output;
|
|
84826
|
+
}
|
|
84827
|
+
/**
|
|
84828
|
+
* Process and generate a BufferView from an image Blob.
|
|
84829
|
+
* @param {Blob} blob
|
|
84830
|
+
* @return {Promise<Integer>}
|
|
84831
|
+
*/
|
|
84832
|
+
processBufferViewImage(blob) {
|
|
84833
|
+
const writer = this;
|
|
84834
|
+
const json = writer.json;
|
|
84835
|
+
if (!json.bufferViews) json.bufferViews = [];
|
|
84836
|
+
return new Promise(function(resolve) {
|
|
84837
|
+
const reader = new FileReader();
|
|
84838
|
+
reader.readAsArrayBuffer(blob);
|
|
84839
|
+
reader.onloadend = function() {
|
|
84840
|
+
const buffer2 = getPaddedArrayBuffer(reader.result);
|
|
84841
|
+
const bufferViewDef = {
|
|
84842
|
+
buffer: writer.processBuffer(buffer2),
|
|
84843
|
+
byteOffset: writer.byteOffset,
|
|
84844
|
+
byteLength: buffer2.byteLength
|
|
84845
|
+
};
|
|
84846
|
+
writer.byteOffset += buffer2.byteLength;
|
|
84847
|
+
resolve(json.bufferViews.push(bufferViewDef) - 1);
|
|
84848
|
+
};
|
|
84849
|
+
});
|
|
84850
|
+
}
|
|
84851
|
+
/**
|
|
84852
|
+
* Process attribute to generate an accessor
|
|
84853
|
+
* @param {BufferAttribute} attribute Attribute to process
|
|
84854
|
+
* @param {THREE.BufferGeometry} geometry (Optional) Geometry used for truncated draw range
|
|
84855
|
+
* @param {Integer} start (Optional)
|
|
84856
|
+
* @param {Integer} count (Optional)
|
|
84857
|
+
* @return {Integer|null} Index of the processed accessor on the "accessors" array
|
|
84858
|
+
*/
|
|
84859
|
+
processAccessor(attribute, geometry, start, count) {
|
|
84860
|
+
const json = this.json;
|
|
84861
|
+
const types2 = {
|
|
84862
|
+
1: "SCALAR",
|
|
84863
|
+
2: "VEC2",
|
|
84864
|
+
3: "VEC3",
|
|
84865
|
+
4: "VEC4",
|
|
84866
|
+
9: "MAT3",
|
|
84867
|
+
16: "MAT4"
|
|
84868
|
+
};
|
|
84869
|
+
let componentType;
|
|
84870
|
+
if (attribute.array.constructor === Float32Array) {
|
|
84871
|
+
componentType = WEBGL_CONSTANTS.FLOAT;
|
|
84872
|
+
} else if (attribute.array.constructor === Int32Array) {
|
|
84873
|
+
componentType = WEBGL_CONSTANTS.INT;
|
|
84874
|
+
} else if (attribute.array.constructor === Uint32Array) {
|
|
84875
|
+
componentType = WEBGL_CONSTANTS.UNSIGNED_INT;
|
|
84876
|
+
} else if (attribute.array.constructor === Int16Array) {
|
|
84877
|
+
componentType = WEBGL_CONSTANTS.SHORT;
|
|
84878
|
+
} else if (attribute.array.constructor === Uint16Array) {
|
|
84879
|
+
componentType = WEBGL_CONSTANTS.UNSIGNED_SHORT;
|
|
84880
|
+
} else if (attribute.array.constructor === Int8Array) {
|
|
84881
|
+
componentType = WEBGL_CONSTANTS.BYTE;
|
|
84882
|
+
} else if (attribute.array.constructor === Uint8Array) {
|
|
84883
|
+
componentType = WEBGL_CONSTANTS.UNSIGNED_BYTE;
|
|
84884
|
+
} else {
|
|
84885
|
+
throw new Error("THREE.GLTFExporter: Unsupported bufferAttribute component type: " + attribute.array.constructor.name);
|
|
84886
|
+
}
|
|
84887
|
+
if (start === void 0) start = 0;
|
|
84888
|
+
if (count === void 0 || count === Infinity) count = attribute.count;
|
|
84889
|
+
if (count === 0) return null;
|
|
84890
|
+
const minMax = getMinMax(attribute, start, count);
|
|
84891
|
+
let bufferViewTarget;
|
|
84892
|
+
if (geometry !== void 0) {
|
|
84893
|
+
bufferViewTarget = attribute === geometry.index ? WEBGL_CONSTANTS.ELEMENT_ARRAY_BUFFER : WEBGL_CONSTANTS.ARRAY_BUFFER;
|
|
84894
|
+
}
|
|
84895
|
+
const bufferView = this.processBufferView(attribute, componentType, start, count, bufferViewTarget);
|
|
84896
|
+
const accessorDef = {
|
|
84897
|
+
bufferView: bufferView.id,
|
|
84898
|
+
byteOffset: bufferView.byteOffset,
|
|
84899
|
+
componentType,
|
|
84900
|
+
count,
|
|
84901
|
+
max: minMax.max,
|
|
84902
|
+
min: minMax.min,
|
|
84903
|
+
type: types2[attribute.itemSize]
|
|
84904
|
+
};
|
|
84905
|
+
if (attribute.normalized === true) accessorDef.normalized = true;
|
|
84906
|
+
if (!json.accessors) json.accessors = [];
|
|
84907
|
+
return json.accessors.push(accessorDef) - 1;
|
|
84908
|
+
}
|
|
84909
|
+
/**
|
|
84910
|
+
* Process image
|
|
84911
|
+
* @param {Image} image to process
|
|
84912
|
+
* @param {Integer} format of the image (RGBAFormat)
|
|
84913
|
+
* @param {Boolean} flipY before writing out the image
|
|
84914
|
+
* @param {String} mimeType export format
|
|
84915
|
+
* @return {Integer} Index of the processed texture in the "images" array
|
|
84916
|
+
*/
|
|
84917
|
+
processImage(image, format2, flipY, mimeType = "image/png") {
|
|
84918
|
+
if (image !== null) {
|
|
84919
|
+
const writer = this;
|
|
84920
|
+
const cache = writer.cache;
|
|
84921
|
+
const json = writer.json;
|
|
84922
|
+
const options = writer.options;
|
|
84923
|
+
const pending = writer.pending;
|
|
84924
|
+
if (!cache.images.has(image)) cache.images.set(image, {});
|
|
84925
|
+
const cachedImages = cache.images.get(image);
|
|
84926
|
+
const key = mimeType + ":flipY/" + flipY.toString();
|
|
84927
|
+
if (cachedImages[key] !== void 0) return cachedImages[key];
|
|
84928
|
+
if (!json.images) json.images = [];
|
|
84929
|
+
const imageDef = { mimeType };
|
|
84930
|
+
const canvas = getCanvas();
|
|
84931
|
+
canvas.width = Math.min(image.width, options.maxTextureSize);
|
|
84932
|
+
canvas.height = Math.min(image.height, options.maxTextureSize);
|
|
84933
|
+
const ctx2 = canvas.getContext("2d");
|
|
84934
|
+
if (flipY === true) {
|
|
84935
|
+
ctx2.translate(0, canvas.height);
|
|
84936
|
+
ctx2.scale(1, -1);
|
|
84937
|
+
}
|
|
84938
|
+
if (image.data !== void 0) {
|
|
84939
|
+
if (format2 !== RGBAFormat) {
|
|
84940
|
+
console.error("GLTFExporter: Only RGBAFormat is supported.", format2);
|
|
84941
|
+
}
|
|
84942
|
+
if (image.width > options.maxTextureSize || image.height > options.maxTextureSize) {
|
|
84943
|
+
console.warn("GLTFExporter: Image size is bigger than maxTextureSize", image);
|
|
84944
|
+
}
|
|
84945
|
+
const data = new Uint8ClampedArray(image.height * image.width * 4);
|
|
84946
|
+
for (let i4 = 0; i4 < data.length; i4 += 4) {
|
|
84947
|
+
data[i4 + 0] = image.data[i4 + 0];
|
|
84948
|
+
data[i4 + 1] = image.data[i4 + 1];
|
|
84949
|
+
data[i4 + 2] = image.data[i4 + 2];
|
|
84950
|
+
data[i4 + 3] = image.data[i4 + 3];
|
|
84951
|
+
}
|
|
84952
|
+
ctx2.putImageData(new ImageData(data, image.width, image.height), 0, 0);
|
|
84953
|
+
} else {
|
|
84954
|
+
ctx2.drawImage(image, 0, 0, canvas.width, canvas.height);
|
|
84955
|
+
}
|
|
84956
|
+
if (options.binary === true) {
|
|
84957
|
+
pending.push(
|
|
84958
|
+
getToBlobPromise(canvas, mimeType).then((blob) => writer.processBufferViewImage(blob)).then((bufferViewIndex) => {
|
|
84959
|
+
imageDef.bufferView = bufferViewIndex;
|
|
84960
|
+
})
|
|
84961
|
+
);
|
|
84962
|
+
} else {
|
|
84963
|
+
if (canvas.toDataURL !== void 0) {
|
|
84964
|
+
imageDef.uri = canvas.toDataURL(mimeType);
|
|
84965
|
+
} else {
|
|
84966
|
+
pending.push(
|
|
84967
|
+
getToBlobPromise(canvas, mimeType).then((blob) => new FileReader().readAsDataURL(blob)).then((dataURL) => {
|
|
84968
|
+
imageDef.uri = dataURL;
|
|
84969
|
+
})
|
|
84970
|
+
);
|
|
84971
|
+
}
|
|
84972
|
+
}
|
|
84973
|
+
const index = json.images.push(imageDef) - 1;
|
|
84974
|
+
cachedImages[key] = index;
|
|
84975
|
+
return index;
|
|
84976
|
+
} else {
|
|
84977
|
+
throw new Error("THREE.GLTFExporter: No valid image data found. Unable to process texture.");
|
|
84978
|
+
}
|
|
84979
|
+
}
|
|
84980
|
+
/**
|
|
84981
|
+
* Process sampler
|
|
84982
|
+
* @param {Texture} map Texture to process
|
|
84983
|
+
* @return {Integer} Index of the processed texture in the "samplers" array
|
|
84984
|
+
*/
|
|
84985
|
+
processSampler(map) {
|
|
84986
|
+
const json = this.json;
|
|
84987
|
+
if (!json.samplers) json.samplers = [];
|
|
84988
|
+
const samplerDef = {
|
|
84989
|
+
magFilter: THREE_TO_WEBGL[map.magFilter],
|
|
84990
|
+
minFilter: THREE_TO_WEBGL[map.minFilter],
|
|
84991
|
+
wrapS: THREE_TO_WEBGL[map.wrapS],
|
|
84992
|
+
wrapT: THREE_TO_WEBGL[map.wrapT]
|
|
84993
|
+
};
|
|
84994
|
+
return json.samplers.push(samplerDef) - 1;
|
|
84995
|
+
}
|
|
84996
|
+
/**
|
|
84997
|
+
* Process texture
|
|
84998
|
+
* @param {Texture} map Map to process
|
|
84999
|
+
* @return {Integer} Index of the processed texture in the "textures" array
|
|
85000
|
+
*/
|
|
85001
|
+
processTexture(map) {
|
|
85002
|
+
const writer = this;
|
|
85003
|
+
const options = writer.options;
|
|
85004
|
+
const cache = this.cache;
|
|
85005
|
+
const json = this.json;
|
|
85006
|
+
if (cache.textures.has(map)) return cache.textures.get(map);
|
|
85007
|
+
if (!json.textures) json.textures = [];
|
|
85008
|
+
if (map instanceof CompressedTexture) {
|
|
85009
|
+
map = decompress(map, options.maxTextureSize);
|
|
85010
|
+
}
|
|
85011
|
+
let mimeType = map.userData.mimeType;
|
|
85012
|
+
if (mimeType === "image/webp") mimeType = "image/png";
|
|
85013
|
+
const textureDef = {
|
|
85014
|
+
sampler: this.processSampler(map),
|
|
85015
|
+
source: this.processImage(map.image, map.format, map.flipY, mimeType)
|
|
85016
|
+
};
|
|
85017
|
+
if (map.name) textureDef.name = map.name;
|
|
85018
|
+
this._invokeAll(function(ext) {
|
|
85019
|
+
ext.writeTexture && ext.writeTexture(map, textureDef);
|
|
85020
|
+
});
|
|
85021
|
+
const index = json.textures.push(textureDef) - 1;
|
|
85022
|
+
cache.textures.set(map, index);
|
|
85023
|
+
return index;
|
|
85024
|
+
}
|
|
85025
|
+
/**
|
|
85026
|
+
* Process material
|
|
85027
|
+
* @param {THREE.Material} material Material to process
|
|
85028
|
+
* @return {Integer|null} Index of the processed material in the "materials" array
|
|
85029
|
+
*/
|
|
85030
|
+
processMaterial(material) {
|
|
85031
|
+
const cache = this.cache;
|
|
85032
|
+
const json = this.json;
|
|
85033
|
+
if (cache.materials.has(material)) return cache.materials.get(material);
|
|
85034
|
+
if (material.isShaderMaterial) {
|
|
85035
|
+
console.warn("GLTFExporter: THREE.ShaderMaterial not supported.");
|
|
85036
|
+
return null;
|
|
85037
|
+
}
|
|
85038
|
+
if (!json.materials) json.materials = [];
|
|
85039
|
+
const materialDef = { pbrMetallicRoughness: {} };
|
|
85040
|
+
if (material.isMeshStandardMaterial !== true && material.isMeshBasicMaterial !== true) {
|
|
85041
|
+
console.warn("GLTFExporter: Use MeshStandardMaterial or MeshBasicMaterial for best results.");
|
|
85042
|
+
}
|
|
85043
|
+
const color2 = material.color.toArray().concat([material.opacity]);
|
|
85044
|
+
if (!equalArray(color2, [1, 1, 1, 1])) {
|
|
85045
|
+
materialDef.pbrMetallicRoughness.baseColorFactor = color2;
|
|
85046
|
+
}
|
|
85047
|
+
if (material.isMeshStandardMaterial) {
|
|
85048
|
+
materialDef.pbrMetallicRoughness.metallicFactor = material.metalness;
|
|
85049
|
+
materialDef.pbrMetallicRoughness.roughnessFactor = material.roughness;
|
|
85050
|
+
} else {
|
|
85051
|
+
materialDef.pbrMetallicRoughness.metallicFactor = 0.5;
|
|
85052
|
+
materialDef.pbrMetallicRoughness.roughnessFactor = 0.5;
|
|
85053
|
+
}
|
|
85054
|
+
if (material.metalnessMap || material.roughnessMap) {
|
|
85055
|
+
const metalRoughTexture = this.buildMetalRoughTexture(material.metalnessMap, material.roughnessMap);
|
|
85056
|
+
const metalRoughMapDef = {
|
|
85057
|
+
index: this.processTexture(metalRoughTexture),
|
|
85058
|
+
channel: metalRoughTexture.channel
|
|
85059
|
+
};
|
|
85060
|
+
this.applyTextureTransform(metalRoughMapDef, metalRoughTexture);
|
|
85061
|
+
materialDef.pbrMetallicRoughness.metallicRoughnessTexture = metalRoughMapDef;
|
|
85062
|
+
}
|
|
85063
|
+
if (material.map) {
|
|
85064
|
+
const baseColorMapDef = {
|
|
85065
|
+
index: this.processTexture(material.map),
|
|
85066
|
+
texCoord: material.map.channel
|
|
85067
|
+
};
|
|
85068
|
+
this.applyTextureTransform(baseColorMapDef, material.map);
|
|
85069
|
+
materialDef.pbrMetallicRoughness.baseColorTexture = baseColorMapDef;
|
|
85070
|
+
}
|
|
85071
|
+
if (material.emissive) {
|
|
85072
|
+
const emissive = material.emissive;
|
|
85073
|
+
const maxEmissiveComponent = Math.max(emissive.r, emissive.g, emissive.b);
|
|
85074
|
+
if (maxEmissiveComponent > 0) {
|
|
85075
|
+
materialDef.emissiveFactor = material.emissive.toArray();
|
|
85076
|
+
}
|
|
85077
|
+
if (material.emissiveMap) {
|
|
85078
|
+
const emissiveMapDef = {
|
|
85079
|
+
index: this.processTexture(material.emissiveMap),
|
|
85080
|
+
texCoord: material.emissiveMap.channel
|
|
85081
|
+
};
|
|
85082
|
+
this.applyTextureTransform(emissiveMapDef, material.emissiveMap);
|
|
85083
|
+
materialDef.emissiveTexture = emissiveMapDef;
|
|
85084
|
+
}
|
|
85085
|
+
}
|
|
85086
|
+
if (material.normalMap) {
|
|
85087
|
+
const normalMapDef = {
|
|
85088
|
+
index: this.processTexture(material.normalMap),
|
|
85089
|
+
texCoord: material.normalMap.channel
|
|
85090
|
+
};
|
|
85091
|
+
if (material.normalScale && material.normalScale.x !== 1) {
|
|
85092
|
+
normalMapDef.scale = material.normalScale.x;
|
|
85093
|
+
}
|
|
85094
|
+
this.applyTextureTransform(normalMapDef, material.normalMap);
|
|
85095
|
+
materialDef.normalTexture = normalMapDef;
|
|
85096
|
+
}
|
|
85097
|
+
if (material.aoMap) {
|
|
85098
|
+
const occlusionMapDef = {
|
|
85099
|
+
index: this.processTexture(material.aoMap),
|
|
85100
|
+
texCoord: material.aoMap.channel
|
|
85101
|
+
};
|
|
85102
|
+
if (material.aoMapIntensity !== 1) {
|
|
85103
|
+
occlusionMapDef.strength = material.aoMapIntensity;
|
|
85104
|
+
}
|
|
85105
|
+
this.applyTextureTransform(occlusionMapDef, material.aoMap);
|
|
85106
|
+
materialDef.occlusionTexture = occlusionMapDef;
|
|
85107
|
+
}
|
|
85108
|
+
if (material.transparent) {
|
|
85109
|
+
materialDef.alphaMode = "BLEND";
|
|
85110
|
+
} else {
|
|
85111
|
+
if (material.alphaTest > 0) {
|
|
85112
|
+
materialDef.alphaMode = "MASK";
|
|
85113
|
+
materialDef.alphaCutoff = material.alphaTest;
|
|
85114
|
+
}
|
|
85115
|
+
}
|
|
85116
|
+
if (material.side === DoubleSide) materialDef.doubleSided = true;
|
|
85117
|
+
if (material.name !== "") materialDef.name = material.name;
|
|
85118
|
+
this.serializeUserData(material, materialDef);
|
|
85119
|
+
this._invokeAll(function(ext) {
|
|
85120
|
+
ext.writeMaterial && ext.writeMaterial(material, materialDef);
|
|
85121
|
+
});
|
|
85122
|
+
const index = json.materials.push(materialDef) - 1;
|
|
85123
|
+
cache.materials.set(material, index);
|
|
85124
|
+
return index;
|
|
85125
|
+
}
|
|
85126
|
+
/**
|
|
85127
|
+
* Process mesh
|
|
85128
|
+
* @param {THREE.Mesh} mesh Mesh to process
|
|
85129
|
+
* @return {Integer|null} Index of the processed mesh in the "meshes" array
|
|
85130
|
+
*/
|
|
85131
|
+
processMesh(mesh) {
|
|
85132
|
+
const cache = this.cache;
|
|
85133
|
+
const json = this.json;
|
|
85134
|
+
const meshCacheKeyParts = [mesh.geometry.uuid];
|
|
85135
|
+
if (Array.isArray(mesh.material)) {
|
|
85136
|
+
for (let i4 = 0, l4 = mesh.material.length; i4 < l4; i4++) {
|
|
85137
|
+
meshCacheKeyParts.push(mesh.material[i4].uuid);
|
|
85138
|
+
}
|
|
85139
|
+
} else {
|
|
85140
|
+
meshCacheKeyParts.push(mesh.material.uuid);
|
|
85141
|
+
}
|
|
85142
|
+
const meshCacheKey = meshCacheKeyParts.join(":");
|
|
85143
|
+
if (cache.meshes.has(meshCacheKey)) return cache.meshes.get(meshCacheKey);
|
|
85144
|
+
const geometry = mesh.geometry;
|
|
85145
|
+
let mode2;
|
|
85146
|
+
if (mesh.isLineSegments) {
|
|
85147
|
+
mode2 = WEBGL_CONSTANTS.LINES;
|
|
85148
|
+
} else if (mesh.isLineLoop) {
|
|
85149
|
+
mode2 = WEBGL_CONSTANTS.LINE_LOOP;
|
|
85150
|
+
} else if (mesh.isLine) {
|
|
85151
|
+
mode2 = WEBGL_CONSTANTS.LINE_STRIP;
|
|
85152
|
+
} else if (mesh.isPoints) {
|
|
85153
|
+
mode2 = WEBGL_CONSTANTS.POINTS;
|
|
85154
|
+
} else {
|
|
85155
|
+
mode2 = mesh.material.wireframe ? WEBGL_CONSTANTS.LINES : WEBGL_CONSTANTS.TRIANGLES;
|
|
85156
|
+
}
|
|
85157
|
+
const meshDef = {};
|
|
85158
|
+
const attributes = {};
|
|
85159
|
+
const primitives = [];
|
|
85160
|
+
const targets = [];
|
|
85161
|
+
const nameConversion = {
|
|
85162
|
+
uv: "TEXCOORD_0",
|
|
85163
|
+
uv1: "TEXCOORD_1",
|
|
85164
|
+
uv2: "TEXCOORD_2",
|
|
85165
|
+
uv3: "TEXCOORD_3",
|
|
85166
|
+
color: "COLOR_0",
|
|
85167
|
+
skinWeight: "WEIGHTS_0",
|
|
85168
|
+
skinIndex: "JOINTS_0"
|
|
85169
|
+
};
|
|
85170
|
+
const originalNormal = geometry.getAttribute("normal");
|
|
85171
|
+
if (originalNormal !== void 0 && !this.isNormalizedNormalAttribute(originalNormal)) {
|
|
85172
|
+
console.warn("THREE.GLTFExporter: Creating normalized normal attribute from the non-normalized one.");
|
|
85173
|
+
geometry.setAttribute("normal", this.createNormalizedNormalAttribute(originalNormal));
|
|
85174
|
+
}
|
|
85175
|
+
let modifiedAttribute = null;
|
|
85176
|
+
for (let attributeName in geometry.attributes) {
|
|
85177
|
+
if (attributeName.slice(0, 5) === "morph") continue;
|
|
85178
|
+
const attribute = geometry.attributes[attributeName];
|
|
85179
|
+
attributeName = nameConversion[attributeName] || attributeName.toUpperCase();
|
|
85180
|
+
const validVertexAttributes = /^(POSITION|NORMAL|TANGENT|TEXCOORD_\d+|COLOR_\d+|JOINTS_\d+|WEIGHTS_\d+)$/;
|
|
85181
|
+
if (!validVertexAttributes.test(attributeName)) attributeName = "_" + attributeName;
|
|
85182
|
+
if (cache.attributes.has(this.getUID(attribute))) {
|
|
85183
|
+
attributes[attributeName] = cache.attributes.get(this.getUID(attribute));
|
|
85184
|
+
continue;
|
|
85185
|
+
}
|
|
85186
|
+
modifiedAttribute = null;
|
|
85187
|
+
const array = attribute.array;
|
|
85188
|
+
if (attributeName === "JOINTS_0" && !(array instanceof Uint16Array) && !(array instanceof Uint8Array)) {
|
|
85189
|
+
console.warn('GLTFExporter: Attribute "skinIndex" converted to type UNSIGNED_SHORT.');
|
|
85190
|
+
modifiedAttribute = new BufferAttribute(new Uint16Array(array), attribute.itemSize, attribute.normalized);
|
|
85191
|
+
}
|
|
85192
|
+
const accessor = this.processAccessor(modifiedAttribute || attribute, geometry);
|
|
85193
|
+
if (accessor !== null) {
|
|
85194
|
+
if (!attributeName.startsWith("_")) {
|
|
85195
|
+
this.detectMeshQuantization(attributeName, attribute);
|
|
85196
|
+
}
|
|
85197
|
+
attributes[attributeName] = accessor;
|
|
85198
|
+
cache.attributes.set(this.getUID(attribute), accessor);
|
|
85199
|
+
}
|
|
85200
|
+
}
|
|
85201
|
+
if (originalNormal !== void 0) geometry.setAttribute("normal", originalNormal);
|
|
85202
|
+
if (Object.keys(attributes).length === 0) return null;
|
|
85203
|
+
if (mesh.morphTargetInfluences !== void 0 && mesh.morphTargetInfluences.length > 0) {
|
|
85204
|
+
const weights = [];
|
|
85205
|
+
const targetNames = [];
|
|
85206
|
+
const reverseDictionary = {};
|
|
85207
|
+
if (mesh.morphTargetDictionary !== void 0) {
|
|
85208
|
+
for (const key in mesh.morphTargetDictionary) {
|
|
85209
|
+
reverseDictionary[mesh.morphTargetDictionary[key]] = key;
|
|
85210
|
+
}
|
|
85211
|
+
}
|
|
85212
|
+
for (let i4 = 0; i4 < mesh.morphTargetInfluences.length; ++i4) {
|
|
85213
|
+
const target = {};
|
|
85214
|
+
let warned = false;
|
|
85215
|
+
for (const attributeName in geometry.morphAttributes) {
|
|
85216
|
+
if (attributeName !== "position" && attributeName !== "normal") {
|
|
85217
|
+
if (!warned) {
|
|
85218
|
+
console.warn("GLTFExporter: Only POSITION and NORMAL morph are supported.");
|
|
85219
|
+
warned = true;
|
|
85220
|
+
}
|
|
85221
|
+
continue;
|
|
85222
|
+
}
|
|
85223
|
+
const attribute = geometry.morphAttributes[attributeName][i4];
|
|
85224
|
+
const gltfAttributeName = attributeName.toUpperCase();
|
|
85225
|
+
const baseAttribute = geometry.attributes[attributeName];
|
|
85226
|
+
if (cache.attributes.has(this.getUID(attribute, true))) {
|
|
85227
|
+
target[gltfAttributeName] = cache.attributes.get(this.getUID(attribute, true));
|
|
85228
|
+
continue;
|
|
85229
|
+
}
|
|
85230
|
+
const relativeAttribute = attribute.clone();
|
|
85231
|
+
if (!geometry.morphTargetsRelative) {
|
|
85232
|
+
for (let j4 = 0, jl = attribute.count; j4 < jl; j4++) {
|
|
85233
|
+
for (let a4 = 0; a4 < attribute.itemSize; a4++) {
|
|
85234
|
+
if (a4 === 0) relativeAttribute.setX(j4, attribute.getX(j4) - baseAttribute.getX(j4));
|
|
85235
|
+
if (a4 === 1) relativeAttribute.setY(j4, attribute.getY(j4) - baseAttribute.getY(j4));
|
|
85236
|
+
if (a4 === 2) relativeAttribute.setZ(j4, attribute.getZ(j4) - baseAttribute.getZ(j4));
|
|
85237
|
+
if (a4 === 3) relativeAttribute.setW(j4, attribute.getW(j4) - baseAttribute.getW(j4));
|
|
85238
|
+
}
|
|
85239
|
+
}
|
|
85240
|
+
}
|
|
85241
|
+
target[gltfAttributeName] = this.processAccessor(relativeAttribute, geometry);
|
|
85242
|
+
cache.attributes.set(this.getUID(baseAttribute, true), target[gltfAttributeName]);
|
|
85243
|
+
}
|
|
85244
|
+
targets.push(target);
|
|
85245
|
+
weights.push(mesh.morphTargetInfluences[i4]);
|
|
85246
|
+
if (mesh.morphTargetDictionary !== void 0) targetNames.push(reverseDictionary[i4]);
|
|
85247
|
+
}
|
|
85248
|
+
meshDef.weights = weights;
|
|
85249
|
+
if (targetNames.length > 0) {
|
|
85250
|
+
meshDef.extras = {};
|
|
85251
|
+
meshDef.extras.targetNames = targetNames;
|
|
85252
|
+
}
|
|
85253
|
+
}
|
|
85254
|
+
const isMultiMaterial = Array.isArray(mesh.material);
|
|
85255
|
+
if (isMultiMaterial && geometry.groups.length === 0) return null;
|
|
85256
|
+
const materials = isMultiMaterial ? mesh.material : [mesh.material];
|
|
85257
|
+
const groups = isMultiMaterial ? geometry.groups : [{ materialIndex: 0, start: void 0, count: void 0 }];
|
|
85258
|
+
for (let i4 = 0, il = groups.length; i4 < il; i4++) {
|
|
85259
|
+
const primitive = {
|
|
85260
|
+
mode: mode2,
|
|
85261
|
+
attributes
|
|
85262
|
+
};
|
|
85263
|
+
this.serializeUserData(geometry, primitive);
|
|
85264
|
+
if (targets.length > 0) primitive.targets = targets;
|
|
85265
|
+
if (geometry.index !== null) {
|
|
85266
|
+
let cacheKey = this.getUID(geometry.index);
|
|
85267
|
+
if (groups[i4].start !== void 0 || groups[i4].count !== void 0) {
|
|
85268
|
+
cacheKey += ":" + groups[i4].start + ":" + groups[i4].count;
|
|
85269
|
+
}
|
|
85270
|
+
if (cache.attributes.has(cacheKey)) {
|
|
85271
|
+
primitive.indices = cache.attributes.get(cacheKey);
|
|
85272
|
+
} else {
|
|
85273
|
+
primitive.indices = this.processAccessor(geometry.index, geometry, groups[i4].start, groups[i4].count);
|
|
85274
|
+
cache.attributes.set(cacheKey, primitive.indices);
|
|
85275
|
+
}
|
|
85276
|
+
if (primitive.indices === null) delete primitive.indices;
|
|
85277
|
+
}
|
|
85278
|
+
const material = this.processMaterial(materials[groups[i4].materialIndex]);
|
|
85279
|
+
if (material !== null) primitive.material = material;
|
|
85280
|
+
primitives.push(primitive);
|
|
85281
|
+
}
|
|
85282
|
+
meshDef.primitives = primitives;
|
|
85283
|
+
if (!json.meshes) json.meshes = [];
|
|
85284
|
+
this._invokeAll(function(ext) {
|
|
85285
|
+
ext.writeMesh && ext.writeMesh(mesh, meshDef);
|
|
85286
|
+
});
|
|
85287
|
+
const index = json.meshes.push(meshDef) - 1;
|
|
85288
|
+
cache.meshes.set(meshCacheKey, index);
|
|
85289
|
+
return index;
|
|
85290
|
+
}
|
|
85291
|
+
/**
|
|
85292
|
+
* If a vertex attribute with a
|
|
85293
|
+
* [non-standard data type](https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html#meshes-overview)
|
|
85294
|
+
* is used, it is checked whether it is a valid data type according to the
|
|
85295
|
+
* [KHR_mesh_quantization](https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_mesh_quantization/README.md)
|
|
85296
|
+
* extension.
|
|
85297
|
+
* In this case the extension is automatically added to the list of used extensions.
|
|
85298
|
+
*
|
|
85299
|
+
* @param {string} attributeName
|
|
85300
|
+
* @param {THREE.BufferAttribute} attribute
|
|
85301
|
+
*/
|
|
85302
|
+
detectMeshQuantization(attributeName, attribute) {
|
|
85303
|
+
if (this.extensionsUsed[KHR_MESH_QUANTIZATION]) return;
|
|
85304
|
+
let attrType = void 0;
|
|
85305
|
+
switch (attribute.array.constructor) {
|
|
85306
|
+
case Int8Array:
|
|
85307
|
+
attrType = "byte";
|
|
85308
|
+
break;
|
|
85309
|
+
case Uint8Array:
|
|
85310
|
+
attrType = "unsigned byte";
|
|
85311
|
+
break;
|
|
85312
|
+
case Int16Array:
|
|
85313
|
+
attrType = "short";
|
|
85314
|
+
break;
|
|
85315
|
+
case Uint16Array:
|
|
85316
|
+
attrType = "unsigned short";
|
|
85317
|
+
break;
|
|
85318
|
+
default:
|
|
85319
|
+
return;
|
|
85320
|
+
}
|
|
85321
|
+
if (attribute.normalized) attrType += " normalized";
|
|
85322
|
+
const attrNamePrefix = attributeName.split("_", 1)[0];
|
|
85323
|
+
if (KHR_mesh_quantization_ExtraAttrTypes[attrNamePrefix] && KHR_mesh_quantization_ExtraAttrTypes[attrNamePrefix].includes(attrType)) {
|
|
85324
|
+
this.extensionsUsed[KHR_MESH_QUANTIZATION] = true;
|
|
85325
|
+
this.extensionsRequired[KHR_MESH_QUANTIZATION] = true;
|
|
85326
|
+
}
|
|
85327
|
+
}
|
|
85328
|
+
/**
|
|
85329
|
+
* Process camera
|
|
85330
|
+
* @param {THREE.Camera} camera Camera to process
|
|
85331
|
+
* @return {Integer} Index of the processed mesh in the "camera" array
|
|
85332
|
+
*/
|
|
85333
|
+
processCamera(camera) {
|
|
85334
|
+
const json = this.json;
|
|
85335
|
+
if (!json.cameras) json.cameras = [];
|
|
85336
|
+
const isOrtho = camera.isOrthographicCamera;
|
|
85337
|
+
const cameraDef = {
|
|
85338
|
+
type: isOrtho ? "orthographic" : "perspective"
|
|
85339
|
+
};
|
|
85340
|
+
if (isOrtho) {
|
|
85341
|
+
cameraDef.orthographic = {
|
|
85342
|
+
xmag: camera.right * 2,
|
|
85343
|
+
ymag: camera.top * 2,
|
|
85344
|
+
zfar: camera.far <= 0 ? 1e-3 : camera.far,
|
|
85345
|
+
znear: camera.near < 0 ? 0 : camera.near
|
|
85346
|
+
};
|
|
85347
|
+
} else {
|
|
85348
|
+
cameraDef.perspective = {
|
|
85349
|
+
aspectRatio: camera.aspect,
|
|
85350
|
+
yfov: MathUtils.degToRad(camera.fov),
|
|
85351
|
+
zfar: camera.far <= 0 ? 1e-3 : camera.far,
|
|
85352
|
+
znear: camera.near < 0 ? 0 : camera.near
|
|
85353
|
+
};
|
|
85354
|
+
}
|
|
85355
|
+
if (camera.name !== "") cameraDef.name = camera.type;
|
|
85356
|
+
return json.cameras.push(cameraDef) - 1;
|
|
85357
|
+
}
|
|
85358
|
+
/**
|
|
85359
|
+
* Creates glTF animation entry from AnimationClip object.
|
|
85360
|
+
*
|
|
85361
|
+
* Status:
|
|
85362
|
+
* - Only properties listed in PATH_PROPERTIES may be animated.
|
|
85363
|
+
*
|
|
85364
|
+
* @param {THREE.AnimationClip} clip
|
|
85365
|
+
* @param {THREE.Object3D} root
|
|
85366
|
+
* @return {number|null}
|
|
85367
|
+
*/
|
|
85368
|
+
processAnimation(clip, root) {
|
|
85369
|
+
const json = this.json;
|
|
85370
|
+
const nodeMap = this.nodeMap;
|
|
85371
|
+
if (!json.animations) json.animations = [];
|
|
85372
|
+
clip = GLTFExporter.Utils.mergeMorphTargetTracks(clip.clone(), root);
|
|
85373
|
+
const tracks = clip.tracks;
|
|
85374
|
+
const channels = [];
|
|
85375
|
+
const samplers = [];
|
|
85376
|
+
for (let i4 = 0; i4 < tracks.length; ++i4) {
|
|
85377
|
+
const track = tracks[i4];
|
|
85378
|
+
const trackBinding = PropertyBinding.parseTrackName(track.name);
|
|
85379
|
+
let trackNode = PropertyBinding.findNode(root, trackBinding.nodeName);
|
|
85380
|
+
const trackProperty = PATH_PROPERTIES[trackBinding.propertyName];
|
|
85381
|
+
if (trackBinding.objectName === "bones") {
|
|
85382
|
+
if (trackNode.isSkinnedMesh === true) {
|
|
85383
|
+
trackNode = trackNode.skeleton.getBoneByName(trackBinding.objectIndex);
|
|
85384
|
+
} else {
|
|
85385
|
+
trackNode = void 0;
|
|
85386
|
+
}
|
|
85387
|
+
}
|
|
85388
|
+
if (!trackNode || !trackProperty) {
|
|
85389
|
+
console.warn('THREE.GLTFExporter: Could not export animation track "%s".', track.name);
|
|
85390
|
+
return null;
|
|
85391
|
+
}
|
|
85392
|
+
const inputItemSize = 1;
|
|
85393
|
+
let outputItemSize = track.values.length / track.times.length;
|
|
85394
|
+
if (trackProperty === PATH_PROPERTIES.morphTargetInfluences) {
|
|
85395
|
+
outputItemSize /= trackNode.morphTargetInfluences.length;
|
|
85396
|
+
}
|
|
85397
|
+
let interpolation;
|
|
85398
|
+
if (track.createInterpolant.isInterpolantFactoryMethodGLTFCubicSpline === true) {
|
|
85399
|
+
interpolation = "CUBICSPLINE";
|
|
85400
|
+
outputItemSize /= 3;
|
|
85401
|
+
} else if (track.getInterpolation() === InterpolateDiscrete) {
|
|
85402
|
+
interpolation = "STEP";
|
|
85403
|
+
} else {
|
|
85404
|
+
interpolation = "LINEAR";
|
|
85405
|
+
}
|
|
85406
|
+
samplers.push({
|
|
85407
|
+
input: this.processAccessor(new BufferAttribute(track.times, inputItemSize)),
|
|
85408
|
+
output: this.processAccessor(new BufferAttribute(track.values, outputItemSize)),
|
|
85409
|
+
interpolation
|
|
85410
|
+
});
|
|
85411
|
+
channels.push({
|
|
85412
|
+
sampler: samplers.length - 1,
|
|
85413
|
+
target: {
|
|
85414
|
+
node: nodeMap.get(trackNode),
|
|
85415
|
+
path: trackProperty
|
|
85416
|
+
}
|
|
85417
|
+
});
|
|
85418
|
+
}
|
|
85419
|
+
json.animations.push({
|
|
85420
|
+
name: clip.name || "clip_" + json.animations.length,
|
|
85421
|
+
samplers,
|
|
85422
|
+
channels
|
|
85423
|
+
});
|
|
85424
|
+
return json.animations.length - 1;
|
|
85425
|
+
}
|
|
85426
|
+
/**
|
|
85427
|
+
* @param {THREE.Object3D} object
|
|
85428
|
+
* @return {number|null}
|
|
85429
|
+
*/
|
|
85430
|
+
processSkin(object) {
|
|
85431
|
+
const json = this.json;
|
|
85432
|
+
const nodeMap = this.nodeMap;
|
|
85433
|
+
const node = json.nodes[nodeMap.get(object)];
|
|
85434
|
+
const skeleton = object.skeleton;
|
|
85435
|
+
if (skeleton === void 0) return null;
|
|
85436
|
+
const rootJoint = object.skeleton.bones[0];
|
|
85437
|
+
if (rootJoint === void 0) return null;
|
|
85438
|
+
const joints = [];
|
|
85439
|
+
const inverseBindMatrices = new Float32Array(skeleton.bones.length * 16);
|
|
85440
|
+
const temporaryBoneInverse = new Matrix4();
|
|
85441
|
+
for (let i4 = 0; i4 < skeleton.bones.length; ++i4) {
|
|
85442
|
+
joints.push(nodeMap.get(skeleton.bones[i4]));
|
|
85443
|
+
temporaryBoneInverse.copy(skeleton.boneInverses[i4]);
|
|
85444
|
+
temporaryBoneInverse.multiply(object.bindMatrix).toArray(inverseBindMatrices, i4 * 16);
|
|
85445
|
+
}
|
|
85446
|
+
if (json.skins === void 0) json.skins = [];
|
|
85447
|
+
json.skins.push({
|
|
85448
|
+
inverseBindMatrices: this.processAccessor(new BufferAttribute(inverseBindMatrices, 16)),
|
|
85449
|
+
joints,
|
|
85450
|
+
skeleton: nodeMap.get(rootJoint)
|
|
85451
|
+
});
|
|
85452
|
+
const skinIndex = node.skin = json.skins.length - 1;
|
|
85453
|
+
return skinIndex;
|
|
85454
|
+
}
|
|
85455
|
+
/**
|
|
85456
|
+
* Process Object3D node
|
|
85457
|
+
* @param {THREE.Object3D} node Object3D to processNode
|
|
85458
|
+
* @return {Integer} Index of the node in the nodes list
|
|
85459
|
+
*/
|
|
85460
|
+
processNode(object) {
|
|
85461
|
+
const json = this.json;
|
|
85462
|
+
const options = this.options;
|
|
85463
|
+
const nodeMap = this.nodeMap;
|
|
85464
|
+
if (!json.nodes) json.nodes = [];
|
|
85465
|
+
const nodeDef = {};
|
|
85466
|
+
if (options.trs) {
|
|
85467
|
+
const rotation = object.quaternion.toArray();
|
|
85468
|
+
const position = object.position.toArray();
|
|
85469
|
+
const scale = object.scale.toArray();
|
|
85470
|
+
if (!equalArray(rotation, [0, 0, 0, 1])) {
|
|
85471
|
+
nodeDef.rotation = rotation;
|
|
85472
|
+
}
|
|
85473
|
+
if (!equalArray(position, [0, 0, 0])) {
|
|
85474
|
+
nodeDef.translation = position;
|
|
85475
|
+
}
|
|
85476
|
+
if (!equalArray(scale, [1, 1, 1])) {
|
|
85477
|
+
nodeDef.scale = scale;
|
|
85478
|
+
}
|
|
85479
|
+
} else {
|
|
85480
|
+
if (object.matrixAutoUpdate) {
|
|
85481
|
+
object.updateMatrix();
|
|
85482
|
+
}
|
|
85483
|
+
if (isIdentityMatrix(object.matrix) === false) {
|
|
85484
|
+
nodeDef.matrix = object.matrix.elements;
|
|
85485
|
+
}
|
|
85486
|
+
}
|
|
85487
|
+
if (object.name !== "") nodeDef.name = String(object.name);
|
|
85488
|
+
this.serializeUserData(object, nodeDef);
|
|
85489
|
+
if (object.isMesh || object.isLine || object.isPoints) {
|
|
85490
|
+
const meshIndex = this.processMesh(object);
|
|
85491
|
+
if (meshIndex !== null) nodeDef.mesh = meshIndex;
|
|
85492
|
+
} else if (object.isCamera) {
|
|
85493
|
+
nodeDef.camera = this.processCamera(object);
|
|
85494
|
+
}
|
|
85495
|
+
if (object.isSkinnedMesh) this.skins.push(object);
|
|
85496
|
+
if (object.children.length > 0) {
|
|
85497
|
+
const children = [];
|
|
85498
|
+
for (let i4 = 0, l4 = object.children.length; i4 < l4; i4++) {
|
|
85499
|
+
const child = object.children[i4];
|
|
85500
|
+
if (child.visible || options.onlyVisible === false) {
|
|
85501
|
+
const nodeIndex2 = this.processNode(child);
|
|
85502
|
+
if (nodeIndex2 !== null) children.push(nodeIndex2);
|
|
85503
|
+
}
|
|
85504
|
+
}
|
|
85505
|
+
if (children.length > 0) nodeDef.children = children;
|
|
85506
|
+
}
|
|
85507
|
+
this._invokeAll(function(ext) {
|
|
85508
|
+
ext.writeNode && ext.writeNode(object, nodeDef);
|
|
85509
|
+
});
|
|
85510
|
+
const nodeIndex = json.nodes.push(nodeDef) - 1;
|
|
85511
|
+
nodeMap.set(object, nodeIndex);
|
|
85512
|
+
return nodeIndex;
|
|
85513
|
+
}
|
|
85514
|
+
/**
|
|
85515
|
+
* Process Scene
|
|
85516
|
+
* @param {Scene} node Scene to process
|
|
85517
|
+
*/
|
|
85518
|
+
processScene(scene) {
|
|
85519
|
+
const json = this.json;
|
|
85520
|
+
const options = this.options;
|
|
85521
|
+
if (!json.scenes) {
|
|
85522
|
+
json.scenes = [];
|
|
85523
|
+
json.scene = 0;
|
|
85524
|
+
}
|
|
85525
|
+
const sceneDef = {};
|
|
85526
|
+
if (scene.name !== "") sceneDef.name = scene.name;
|
|
85527
|
+
json.scenes.push(sceneDef);
|
|
85528
|
+
const nodes = [];
|
|
85529
|
+
for (let i4 = 0, l4 = scene.children.length; i4 < l4; i4++) {
|
|
85530
|
+
const child = scene.children[i4];
|
|
85531
|
+
if (child.visible || options.onlyVisible === false) {
|
|
85532
|
+
const nodeIndex = this.processNode(child);
|
|
85533
|
+
if (nodeIndex !== null) nodes.push(nodeIndex);
|
|
85534
|
+
}
|
|
85535
|
+
}
|
|
85536
|
+
if (nodes.length > 0) sceneDef.nodes = nodes;
|
|
85537
|
+
this.serializeUserData(scene, sceneDef);
|
|
85538
|
+
}
|
|
85539
|
+
/**
|
|
85540
|
+
* Creates a Scene to hold a list of objects and parse it
|
|
85541
|
+
* @param {Array} objects List of objects to process
|
|
85542
|
+
*/
|
|
85543
|
+
processObjects(objects) {
|
|
85544
|
+
const scene = new Scene();
|
|
85545
|
+
scene.name = "AuxScene";
|
|
85546
|
+
for (let i4 = 0; i4 < objects.length; i4++) {
|
|
85547
|
+
scene.children.push(objects[i4]);
|
|
85548
|
+
}
|
|
85549
|
+
this.processScene(scene);
|
|
85550
|
+
}
|
|
85551
|
+
/**
|
|
85552
|
+
* @param {THREE.Object3D|Array<THREE.Object3D>} input
|
|
85553
|
+
*/
|
|
85554
|
+
processInput(input) {
|
|
85555
|
+
const options = this.options;
|
|
85556
|
+
input = input instanceof Array ? input : [input];
|
|
85557
|
+
this._invokeAll(function(ext) {
|
|
85558
|
+
ext.beforeParse && ext.beforeParse(input);
|
|
85559
|
+
});
|
|
85560
|
+
const objectsWithoutScene = [];
|
|
85561
|
+
for (let i4 = 0; i4 < input.length; i4++) {
|
|
85562
|
+
if (input[i4] instanceof Scene) {
|
|
85563
|
+
this.processScene(input[i4]);
|
|
85564
|
+
} else {
|
|
85565
|
+
objectsWithoutScene.push(input[i4]);
|
|
85566
|
+
}
|
|
85567
|
+
}
|
|
85568
|
+
if (objectsWithoutScene.length > 0) this.processObjects(objectsWithoutScene);
|
|
85569
|
+
for (let i4 = 0; i4 < this.skins.length; ++i4) {
|
|
85570
|
+
this.processSkin(this.skins[i4]);
|
|
85571
|
+
}
|
|
85572
|
+
for (let i4 = 0; i4 < options.animations.length; ++i4) {
|
|
85573
|
+
this.processAnimation(options.animations[i4], input[0]);
|
|
85574
|
+
}
|
|
85575
|
+
this._invokeAll(function(ext) {
|
|
85576
|
+
ext.afterParse && ext.afterParse(input);
|
|
85577
|
+
});
|
|
85578
|
+
}
|
|
85579
|
+
_invokeAll(func) {
|
|
85580
|
+
for (let i4 = 0, il = this.plugins.length; i4 < il; i4++) {
|
|
85581
|
+
func(this.plugins[i4]);
|
|
85582
|
+
}
|
|
85583
|
+
}
|
|
85584
|
+
};
|
|
85585
|
+
var GLTFLightExtension = class {
|
|
85586
|
+
constructor(writer) {
|
|
85587
|
+
this.writer = writer;
|
|
85588
|
+
this.name = "KHR_lights_punctual";
|
|
85589
|
+
}
|
|
85590
|
+
writeNode(light, nodeDef) {
|
|
85591
|
+
if (!light.isLight) return;
|
|
85592
|
+
if (!light.isDirectionalLight && !light.isPointLight && !light.isSpotLight) {
|
|
85593
|
+
console.warn("THREE.GLTFExporter: Only directional, point, and spot lights are supported.", light);
|
|
85594
|
+
return;
|
|
85595
|
+
}
|
|
85596
|
+
const writer = this.writer;
|
|
85597
|
+
const json = writer.json;
|
|
85598
|
+
const extensionsUsed = writer.extensionsUsed;
|
|
85599
|
+
const lightDef = {};
|
|
85600
|
+
if (light.name) lightDef.name = light.name;
|
|
85601
|
+
lightDef.color = light.color.toArray();
|
|
85602
|
+
lightDef.intensity = light.intensity;
|
|
85603
|
+
if (light.isDirectionalLight) {
|
|
85604
|
+
lightDef.type = "directional";
|
|
85605
|
+
} else if (light.isPointLight) {
|
|
85606
|
+
lightDef.type = "point";
|
|
85607
|
+
if (light.distance > 0) lightDef.range = light.distance;
|
|
85608
|
+
} else if (light.isSpotLight) {
|
|
85609
|
+
lightDef.type = "spot";
|
|
85610
|
+
if (light.distance > 0) lightDef.range = light.distance;
|
|
85611
|
+
lightDef.spot = {};
|
|
85612
|
+
lightDef.spot.innerConeAngle = (1 - light.penumbra) * light.angle;
|
|
85613
|
+
lightDef.spot.outerConeAngle = light.angle;
|
|
85614
|
+
}
|
|
85615
|
+
if (light.decay !== void 0 && light.decay !== 2) {
|
|
85616
|
+
console.warn("THREE.GLTFExporter: Light decay may be lost. glTF is physically-based, and expects light.decay=2.");
|
|
85617
|
+
}
|
|
85618
|
+
if (light.target && (light.target.parent !== light || light.target.position.x !== 0 || light.target.position.y !== 0 || light.target.position.z !== -1)) {
|
|
85619
|
+
console.warn("THREE.GLTFExporter: Light direction may be lost. For best results, make light.target a child of the light with position 0,0,-1.");
|
|
85620
|
+
}
|
|
85621
|
+
if (!extensionsUsed[this.name]) {
|
|
85622
|
+
json.extensions = json.extensions || {};
|
|
85623
|
+
json.extensions[this.name] = { lights: [] };
|
|
85624
|
+
extensionsUsed[this.name] = true;
|
|
85625
|
+
}
|
|
85626
|
+
const lights = json.extensions[this.name].lights;
|
|
85627
|
+
lights.push(lightDef);
|
|
85628
|
+
nodeDef.extensions = nodeDef.extensions || {};
|
|
85629
|
+
nodeDef.extensions[this.name] = { light: lights.length - 1 };
|
|
85630
|
+
}
|
|
85631
|
+
};
|
|
85632
|
+
var GLTFMaterialsUnlitExtension = class {
|
|
85633
|
+
constructor(writer) {
|
|
85634
|
+
this.writer = writer;
|
|
85635
|
+
this.name = "KHR_materials_unlit";
|
|
85636
|
+
}
|
|
85637
|
+
writeMaterial(material, materialDef) {
|
|
85638
|
+
if (!material.isMeshBasicMaterial) return;
|
|
85639
|
+
const writer = this.writer;
|
|
85640
|
+
const extensionsUsed = writer.extensionsUsed;
|
|
85641
|
+
materialDef.extensions = materialDef.extensions || {};
|
|
85642
|
+
materialDef.extensions[this.name] = {};
|
|
85643
|
+
extensionsUsed[this.name] = true;
|
|
85644
|
+
materialDef.pbrMetallicRoughness.metallicFactor = 0;
|
|
85645
|
+
materialDef.pbrMetallicRoughness.roughnessFactor = 0.9;
|
|
85646
|
+
}
|
|
85647
|
+
};
|
|
85648
|
+
var GLTFMaterialsClearcoatExtension = class {
|
|
85649
|
+
constructor(writer) {
|
|
85650
|
+
this.writer = writer;
|
|
85651
|
+
this.name = "KHR_materials_clearcoat";
|
|
85652
|
+
}
|
|
85653
|
+
writeMaterial(material, materialDef) {
|
|
85654
|
+
if (!material.isMeshPhysicalMaterial || material.clearcoat === 0) return;
|
|
85655
|
+
const writer = this.writer;
|
|
85656
|
+
const extensionsUsed = writer.extensionsUsed;
|
|
85657
|
+
const extensionDef = {};
|
|
85658
|
+
extensionDef.clearcoatFactor = material.clearcoat;
|
|
85659
|
+
if (material.clearcoatMap) {
|
|
85660
|
+
const clearcoatMapDef = {
|
|
85661
|
+
index: writer.processTexture(material.clearcoatMap),
|
|
85662
|
+
texCoord: material.clearcoatMap.channel
|
|
85663
|
+
};
|
|
85664
|
+
writer.applyTextureTransform(clearcoatMapDef, material.clearcoatMap);
|
|
85665
|
+
extensionDef.clearcoatTexture = clearcoatMapDef;
|
|
85666
|
+
}
|
|
85667
|
+
extensionDef.clearcoatRoughnessFactor = material.clearcoatRoughness;
|
|
85668
|
+
if (material.clearcoatRoughnessMap) {
|
|
85669
|
+
const clearcoatRoughnessMapDef = {
|
|
85670
|
+
index: writer.processTexture(material.clearcoatRoughnessMap),
|
|
85671
|
+
texCoord: material.clearcoatRoughnessMap.channel
|
|
85672
|
+
};
|
|
85673
|
+
writer.applyTextureTransform(clearcoatRoughnessMapDef, material.clearcoatRoughnessMap);
|
|
85674
|
+
extensionDef.clearcoatRoughnessTexture = clearcoatRoughnessMapDef;
|
|
85675
|
+
}
|
|
85676
|
+
if (material.clearcoatNormalMap) {
|
|
85677
|
+
const clearcoatNormalMapDef = {
|
|
85678
|
+
index: writer.processTexture(material.clearcoatNormalMap),
|
|
85679
|
+
texCoord: material.clearcoatNormalMap.channel
|
|
85680
|
+
};
|
|
85681
|
+
writer.applyTextureTransform(clearcoatNormalMapDef, material.clearcoatNormalMap);
|
|
85682
|
+
extensionDef.clearcoatNormalTexture = clearcoatNormalMapDef;
|
|
85683
|
+
}
|
|
85684
|
+
materialDef.extensions = materialDef.extensions || {};
|
|
85685
|
+
materialDef.extensions[this.name] = extensionDef;
|
|
85686
|
+
extensionsUsed[this.name] = true;
|
|
85687
|
+
}
|
|
85688
|
+
};
|
|
85689
|
+
var GLTFMaterialsIridescenceExtension = class {
|
|
85690
|
+
constructor(writer) {
|
|
85691
|
+
this.writer = writer;
|
|
85692
|
+
this.name = "KHR_materials_iridescence";
|
|
85693
|
+
}
|
|
85694
|
+
writeMaterial(material, materialDef) {
|
|
85695
|
+
if (!material.isMeshPhysicalMaterial || material.iridescence === 0) return;
|
|
85696
|
+
const writer = this.writer;
|
|
85697
|
+
const extensionsUsed = writer.extensionsUsed;
|
|
85698
|
+
const extensionDef = {};
|
|
85699
|
+
extensionDef.iridescenceFactor = material.iridescence;
|
|
85700
|
+
if (material.iridescenceMap) {
|
|
85701
|
+
const iridescenceMapDef = {
|
|
85702
|
+
index: writer.processTexture(material.iridescenceMap),
|
|
85703
|
+
texCoord: material.iridescenceMap.channel
|
|
85704
|
+
};
|
|
85705
|
+
writer.applyTextureTransform(iridescenceMapDef, material.iridescenceMap);
|
|
85706
|
+
extensionDef.iridescenceTexture = iridescenceMapDef;
|
|
85707
|
+
}
|
|
85708
|
+
extensionDef.iridescenceIor = material.iridescenceIOR;
|
|
85709
|
+
extensionDef.iridescenceThicknessMinimum = material.iridescenceThicknessRange[0];
|
|
85710
|
+
extensionDef.iridescenceThicknessMaximum = material.iridescenceThicknessRange[1];
|
|
85711
|
+
if (material.iridescenceThicknessMap) {
|
|
85712
|
+
const iridescenceThicknessMapDef = {
|
|
85713
|
+
index: writer.processTexture(material.iridescenceThicknessMap),
|
|
85714
|
+
texCoord: material.iridescenceThicknessMap.channel
|
|
85715
|
+
};
|
|
85716
|
+
writer.applyTextureTransform(iridescenceThicknessMapDef, material.iridescenceThicknessMap);
|
|
85717
|
+
extensionDef.iridescenceThicknessTexture = iridescenceThicknessMapDef;
|
|
85718
|
+
}
|
|
85719
|
+
materialDef.extensions = materialDef.extensions || {};
|
|
85720
|
+
materialDef.extensions[this.name] = extensionDef;
|
|
85721
|
+
extensionsUsed[this.name] = true;
|
|
85722
|
+
}
|
|
85723
|
+
};
|
|
85724
|
+
var GLTFMaterialsTransmissionExtension = class {
|
|
85725
|
+
constructor(writer) {
|
|
85726
|
+
this.writer = writer;
|
|
85727
|
+
this.name = "KHR_materials_transmission";
|
|
85728
|
+
}
|
|
85729
|
+
writeMaterial(material, materialDef) {
|
|
85730
|
+
if (!material.isMeshPhysicalMaterial || material.transmission === 0) return;
|
|
85731
|
+
const writer = this.writer;
|
|
85732
|
+
const extensionsUsed = writer.extensionsUsed;
|
|
85733
|
+
const extensionDef = {};
|
|
85734
|
+
extensionDef.transmissionFactor = material.transmission;
|
|
85735
|
+
if (material.transmissionMap) {
|
|
85736
|
+
const transmissionMapDef = {
|
|
85737
|
+
index: writer.processTexture(material.transmissionMap),
|
|
85738
|
+
texCoord: material.transmissionMap.channel
|
|
85739
|
+
};
|
|
85740
|
+
writer.applyTextureTransform(transmissionMapDef, material.transmissionMap);
|
|
85741
|
+
extensionDef.transmissionTexture = transmissionMapDef;
|
|
85742
|
+
}
|
|
85743
|
+
materialDef.extensions = materialDef.extensions || {};
|
|
85744
|
+
materialDef.extensions[this.name] = extensionDef;
|
|
85745
|
+
extensionsUsed[this.name] = true;
|
|
85746
|
+
}
|
|
85747
|
+
};
|
|
85748
|
+
var GLTFMaterialsVolumeExtension = class {
|
|
85749
|
+
constructor(writer) {
|
|
85750
|
+
this.writer = writer;
|
|
85751
|
+
this.name = "KHR_materials_volume";
|
|
85752
|
+
}
|
|
85753
|
+
writeMaterial(material, materialDef) {
|
|
85754
|
+
if (!material.isMeshPhysicalMaterial || material.transmission === 0) return;
|
|
85755
|
+
const writer = this.writer;
|
|
85756
|
+
const extensionsUsed = writer.extensionsUsed;
|
|
85757
|
+
const extensionDef = {};
|
|
85758
|
+
extensionDef.thicknessFactor = material.thickness;
|
|
85759
|
+
if (material.thicknessMap) {
|
|
85760
|
+
const thicknessMapDef = {
|
|
85761
|
+
index: writer.processTexture(material.thicknessMap),
|
|
85762
|
+
texCoord: material.thicknessMap.channel
|
|
85763
|
+
};
|
|
85764
|
+
writer.applyTextureTransform(thicknessMapDef, material.thicknessMap);
|
|
85765
|
+
extensionDef.thicknessTexture = thicknessMapDef;
|
|
85766
|
+
}
|
|
85767
|
+
extensionDef.attenuationDistance = material.attenuationDistance;
|
|
85768
|
+
extensionDef.attenuationColor = material.attenuationColor.toArray();
|
|
85769
|
+
materialDef.extensions = materialDef.extensions || {};
|
|
85770
|
+
materialDef.extensions[this.name] = extensionDef;
|
|
85771
|
+
extensionsUsed[this.name] = true;
|
|
85772
|
+
}
|
|
85773
|
+
};
|
|
85774
|
+
var GLTFMaterialsIorExtension = class {
|
|
85775
|
+
constructor(writer) {
|
|
85776
|
+
this.writer = writer;
|
|
85777
|
+
this.name = "KHR_materials_ior";
|
|
85778
|
+
}
|
|
85779
|
+
writeMaterial(material, materialDef) {
|
|
85780
|
+
if (!material.isMeshPhysicalMaterial || material.ior === 1.5) return;
|
|
85781
|
+
const writer = this.writer;
|
|
85782
|
+
const extensionsUsed = writer.extensionsUsed;
|
|
85783
|
+
const extensionDef = {};
|
|
85784
|
+
extensionDef.ior = material.ior;
|
|
85785
|
+
materialDef.extensions = materialDef.extensions || {};
|
|
85786
|
+
materialDef.extensions[this.name] = extensionDef;
|
|
85787
|
+
extensionsUsed[this.name] = true;
|
|
85788
|
+
}
|
|
85789
|
+
};
|
|
85790
|
+
var GLTFMaterialsSpecularExtension = class {
|
|
85791
|
+
constructor(writer) {
|
|
85792
|
+
this.writer = writer;
|
|
85793
|
+
this.name = "KHR_materials_specular";
|
|
85794
|
+
}
|
|
85795
|
+
writeMaterial(material, materialDef) {
|
|
85796
|
+
if (!material.isMeshPhysicalMaterial || material.specularIntensity === 1 && material.specularColor.equals(DEFAULT_SPECULAR_COLOR) && !material.specularIntensityMap && !material.specularColorTexture) return;
|
|
85797
|
+
const writer = this.writer;
|
|
85798
|
+
const extensionsUsed = writer.extensionsUsed;
|
|
85799
|
+
const extensionDef = {};
|
|
85800
|
+
if (material.specularIntensityMap) {
|
|
85801
|
+
const specularIntensityMapDef = {
|
|
85802
|
+
index: writer.processTexture(material.specularIntensityMap),
|
|
85803
|
+
texCoord: material.specularIntensityMap.channel
|
|
85804
|
+
};
|
|
85805
|
+
writer.applyTextureTransform(specularIntensityMapDef, material.specularIntensityMap);
|
|
85806
|
+
extensionDef.specularTexture = specularIntensityMapDef;
|
|
85807
|
+
}
|
|
85808
|
+
if (material.specularColorMap) {
|
|
85809
|
+
const specularColorMapDef = {
|
|
85810
|
+
index: writer.processTexture(material.specularColorMap),
|
|
85811
|
+
texCoord: material.specularColorMap.channel
|
|
85812
|
+
};
|
|
85813
|
+
writer.applyTextureTransform(specularColorMapDef, material.specularColorMap);
|
|
85814
|
+
extensionDef.specularColorTexture = specularColorMapDef;
|
|
85815
|
+
}
|
|
85816
|
+
extensionDef.specularFactor = material.specularIntensity;
|
|
85817
|
+
extensionDef.specularColorFactor = material.specularColor.toArray();
|
|
85818
|
+
materialDef.extensions = materialDef.extensions || {};
|
|
85819
|
+
materialDef.extensions[this.name] = extensionDef;
|
|
85820
|
+
extensionsUsed[this.name] = true;
|
|
85821
|
+
}
|
|
85822
|
+
};
|
|
85823
|
+
var GLTFMaterialsSheenExtension = class {
|
|
85824
|
+
constructor(writer) {
|
|
85825
|
+
this.writer = writer;
|
|
85826
|
+
this.name = "KHR_materials_sheen";
|
|
85827
|
+
}
|
|
85828
|
+
writeMaterial(material, materialDef) {
|
|
85829
|
+
if (!material.isMeshPhysicalMaterial || material.sheen == 0) return;
|
|
85830
|
+
const writer = this.writer;
|
|
85831
|
+
const extensionsUsed = writer.extensionsUsed;
|
|
85832
|
+
const extensionDef = {};
|
|
85833
|
+
if (material.sheenRoughnessMap) {
|
|
85834
|
+
const sheenRoughnessMapDef = {
|
|
85835
|
+
index: writer.processTexture(material.sheenRoughnessMap),
|
|
85836
|
+
texCoord: material.sheenRoughnessMap.channel
|
|
85837
|
+
};
|
|
85838
|
+
writer.applyTextureTransform(sheenRoughnessMapDef, material.sheenRoughnessMap);
|
|
85839
|
+
extensionDef.sheenRoughnessTexture = sheenRoughnessMapDef;
|
|
85840
|
+
}
|
|
85841
|
+
if (material.sheenColorMap) {
|
|
85842
|
+
const sheenColorMapDef = {
|
|
85843
|
+
index: writer.processTexture(material.sheenColorMap),
|
|
85844
|
+
texCoord: material.sheenColorMap.channel
|
|
85845
|
+
};
|
|
85846
|
+
writer.applyTextureTransform(sheenColorMapDef, material.sheenColorMap);
|
|
85847
|
+
extensionDef.sheenColorTexture = sheenColorMapDef;
|
|
85848
|
+
}
|
|
85849
|
+
extensionDef.sheenRoughnessFactor = material.sheenRoughness;
|
|
85850
|
+
extensionDef.sheenColorFactor = material.sheenColor.toArray();
|
|
85851
|
+
materialDef.extensions = materialDef.extensions || {};
|
|
85852
|
+
materialDef.extensions[this.name] = extensionDef;
|
|
85853
|
+
extensionsUsed[this.name] = true;
|
|
85854
|
+
}
|
|
85855
|
+
};
|
|
85856
|
+
var GLTFMaterialsAnisotropyExtension = class {
|
|
85857
|
+
constructor(writer) {
|
|
85858
|
+
this.writer = writer;
|
|
85859
|
+
this.name = "KHR_materials_anisotropy";
|
|
85860
|
+
}
|
|
85861
|
+
writeMaterial(material, materialDef) {
|
|
85862
|
+
if (!material.isMeshPhysicalMaterial || material.anisotropy == 0) return;
|
|
85863
|
+
const writer = this.writer;
|
|
85864
|
+
const extensionsUsed = writer.extensionsUsed;
|
|
85865
|
+
const extensionDef = {};
|
|
85866
|
+
if (material.anisotropyMap) {
|
|
85867
|
+
const anisotropyMapDef = { index: writer.processTexture(material.anisotropyMap) };
|
|
85868
|
+
writer.applyTextureTransform(anisotropyMapDef, material.anisotropyMap);
|
|
85869
|
+
extensionDef.anisotropyTexture = anisotropyMapDef;
|
|
85870
|
+
}
|
|
85871
|
+
extensionDef.anisotropyStrength = material.anisotropy;
|
|
85872
|
+
extensionDef.anisotropyRotation = material.anisotropyRotation;
|
|
85873
|
+
materialDef.extensions = materialDef.extensions || {};
|
|
85874
|
+
materialDef.extensions[this.name] = extensionDef;
|
|
85875
|
+
extensionsUsed[this.name] = true;
|
|
85876
|
+
}
|
|
85877
|
+
};
|
|
85878
|
+
var GLTFMaterialsEmissiveStrengthExtension = class {
|
|
85879
|
+
constructor(writer) {
|
|
85880
|
+
this.writer = writer;
|
|
85881
|
+
this.name = "KHR_materials_emissive_strength";
|
|
85882
|
+
}
|
|
85883
|
+
writeMaterial(material, materialDef) {
|
|
85884
|
+
if (!material.isMeshStandardMaterial || material.emissiveIntensity === 1) return;
|
|
85885
|
+
const writer = this.writer;
|
|
85886
|
+
const extensionsUsed = writer.extensionsUsed;
|
|
85887
|
+
const extensionDef = {};
|
|
85888
|
+
extensionDef.emissiveStrength = material.emissiveIntensity;
|
|
85889
|
+
materialDef.extensions = materialDef.extensions || {};
|
|
85890
|
+
materialDef.extensions[this.name] = extensionDef;
|
|
85891
|
+
extensionsUsed[this.name] = true;
|
|
85892
|
+
}
|
|
85893
|
+
};
|
|
85894
|
+
var GLTFMeshGpuInstancing = class {
|
|
85895
|
+
constructor(writer) {
|
|
85896
|
+
this.writer = writer;
|
|
85897
|
+
this.name = "EXT_mesh_gpu_instancing";
|
|
85898
|
+
}
|
|
85899
|
+
writeNode(object, nodeDef) {
|
|
85900
|
+
if (!object.isInstancedMesh) return;
|
|
85901
|
+
const writer = this.writer;
|
|
85902
|
+
const mesh = object;
|
|
85903
|
+
const translationAttr = new Float32Array(mesh.count * 3);
|
|
85904
|
+
const rotationAttr = new Float32Array(mesh.count * 4);
|
|
85905
|
+
const scaleAttr = new Float32Array(mesh.count * 3);
|
|
85906
|
+
const matrix = new Matrix4();
|
|
85907
|
+
const position = new Vector3();
|
|
85908
|
+
const quaternion = new Quaternion();
|
|
85909
|
+
const scale = new Vector3();
|
|
85910
|
+
for (let i4 = 0; i4 < mesh.count; i4++) {
|
|
85911
|
+
mesh.getMatrixAt(i4, matrix);
|
|
85912
|
+
matrix.decompose(position, quaternion, scale);
|
|
85913
|
+
position.toArray(translationAttr, i4 * 3);
|
|
85914
|
+
quaternion.toArray(rotationAttr, i4 * 4);
|
|
85915
|
+
scale.toArray(scaleAttr, i4 * 3);
|
|
85916
|
+
}
|
|
85917
|
+
const attributes = {
|
|
85918
|
+
TRANSLATION: writer.processAccessor(new BufferAttribute(translationAttr, 3)),
|
|
85919
|
+
ROTATION: writer.processAccessor(new BufferAttribute(rotationAttr, 4)),
|
|
85920
|
+
SCALE: writer.processAccessor(new BufferAttribute(scaleAttr, 3))
|
|
85921
|
+
};
|
|
85922
|
+
if (mesh.instanceColor)
|
|
85923
|
+
attributes._COLOR_0 = writer.processAccessor(mesh.instanceColor);
|
|
85924
|
+
nodeDef.extensions = nodeDef.extensions || {};
|
|
85925
|
+
nodeDef.extensions[this.name] = { attributes };
|
|
85926
|
+
writer.extensionsUsed[this.name] = true;
|
|
85927
|
+
writer.extensionsRequired[this.name] = true;
|
|
85928
|
+
}
|
|
85929
|
+
};
|
|
85930
|
+
GLTFExporter.Utils = {
|
|
85931
|
+
insertKeyframe: function(track, time) {
|
|
85932
|
+
const tolerance = 1e-3;
|
|
85933
|
+
const valueSize = track.getValueSize();
|
|
85934
|
+
const times = new track.TimeBufferType(track.times.length + 1);
|
|
85935
|
+
const values = new track.ValueBufferType(track.values.length + valueSize);
|
|
85936
|
+
const interpolant = track.createInterpolant(new track.ValueBufferType(valueSize));
|
|
85937
|
+
let index;
|
|
85938
|
+
if (track.times.length === 0) {
|
|
85939
|
+
times[0] = time;
|
|
85940
|
+
for (let i4 = 0; i4 < valueSize; i4++) {
|
|
85941
|
+
values[i4] = 0;
|
|
85942
|
+
}
|
|
85943
|
+
index = 0;
|
|
85944
|
+
} else if (time < track.times[0]) {
|
|
85945
|
+
if (Math.abs(track.times[0] - time) < tolerance) return 0;
|
|
85946
|
+
times[0] = time;
|
|
85947
|
+
times.set(track.times, 1);
|
|
85948
|
+
values.set(interpolant.evaluate(time), 0);
|
|
85949
|
+
values.set(track.values, valueSize);
|
|
85950
|
+
index = 0;
|
|
85951
|
+
} else if (time > track.times[track.times.length - 1]) {
|
|
85952
|
+
if (Math.abs(track.times[track.times.length - 1] - time) < tolerance) {
|
|
85953
|
+
return track.times.length - 1;
|
|
85954
|
+
}
|
|
85955
|
+
times[times.length - 1] = time;
|
|
85956
|
+
times.set(track.times, 0);
|
|
85957
|
+
values.set(track.values, 0);
|
|
85958
|
+
values.set(interpolant.evaluate(time), track.values.length);
|
|
85959
|
+
index = times.length - 1;
|
|
85960
|
+
} else {
|
|
85961
|
+
for (let i4 = 0; i4 < track.times.length; i4++) {
|
|
85962
|
+
if (Math.abs(track.times[i4] - time) < tolerance) return i4;
|
|
85963
|
+
if (track.times[i4] < time && track.times[i4 + 1] > time) {
|
|
85964
|
+
times.set(track.times.slice(0, i4 + 1), 0);
|
|
85965
|
+
times[i4 + 1] = time;
|
|
85966
|
+
times.set(track.times.slice(i4 + 1), i4 + 2);
|
|
85967
|
+
values.set(track.values.slice(0, (i4 + 1) * valueSize), 0);
|
|
85968
|
+
values.set(interpolant.evaluate(time), (i4 + 1) * valueSize);
|
|
85969
|
+
values.set(track.values.slice((i4 + 1) * valueSize), (i4 + 2) * valueSize);
|
|
85970
|
+
index = i4 + 1;
|
|
85971
|
+
break;
|
|
85972
|
+
}
|
|
85973
|
+
}
|
|
85974
|
+
}
|
|
85975
|
+
track.times = times;
|
|
85976
|
+
track.values = values;
|
|
85977
|
+
return index;
|
|
85978
|
+
},
|
|
85979
|
+
mergeMorphTargetTracks: function(clip, root) {
|
|
85980
|
+
const tracks = [];
|
|
85981
|
+
const mergedTracks = {};
|
|
85982
|
+
const sourceTracks = clip.tracks;
|
|
85983
|
+
for (let i4 = 0; i4 < sourceTracks.length; ++i4) {
|
|
85984
|
+
let sourceTrack = sourceTracks[i4];
|
|
85985
|
+
const sourceTrackBinding = PropertyBinding.parseTrackName(sourceTrack.name);
|
|
85986
|
+
const sourceTrackNode = PropertyBinding.findNode(root, sourceTrackBinding.nodeName);
|
|
85987
|
+
if (sourceTrackBinding.propertyName !== "morphTargetInfluences" || sourceTrackBinding.propertyIndex === void 0) {
|
|
85988
|
+
tracks.push(sourceTrack);
|
|
85989
|
+
continue;
|
|
85990
|
+
}
|
|
85991
|
+
if (sourceTrack.createInterpolant !== sourceTrack.InterpolantFactoryMethodDiscrete && sourceTrack.createInterpolant !== sourceTrack.InterpolantFactoryMethodLinear) {
|
|
85992
|
+
if (sourceTrack.createInterpolant.isInterpolantFactoryMethodGLTFCubicSpline) {
|
|
85993
|
+
throw new Error("THREE.GLTFExporter: Cannot merge tracks with glTF CUBICSPLINE interpolation.");
|
|
85994
|
+
}
|
|
85995
|
+
console.warn("THREE.GLTFExporter: Morph target interpolation mode not yet supported. Using LINEAR instead.");
|
|
85996
|
+
sourceTrack = sourceTrack.clone();
|
|
85997
|
+
sourceTrack.setInterpolation(InterpolateLinear);
|
|
85998
|
+
}
|
|
85999
|
+
const targetCount = sourceTrackNode.morphTargetInfluences.length;
|
|
86000
|
+
const targetIndex = sourceTrackNode.morphTargetDictionary[sourceTrackBinding.propertyIndex];
|
|
86001
|
+
if (targetIndex === void 0) {
|
|
86002
|
+
throw new Error("THREE.GLTFExporter: Morph target name not found: " + sourceTrackBinding.propertyIndex);
|
|
86003
|
+
}
|
|
86004
|
+
let mergedTrack;
|
|
86005
|
+
if (mergedTracks[sourceTrackNode.uuid] === void 0) {
|
|
86006
|
+
mergedTrack = sourceTrack.clone();
|
|
86007
|
+
const values = new mergedTrack.ValueBufferType(targetCount * mergedTrack.times.length);
|
|
86008
|
+
for (let j4 = 0; j4 < mergedTrack.times.length; j4++) {
|
|
86009
|
+
values[j4 * targetCount + targetIndex] = mergedTrack.values[j4];
|
|
86010
|
+
}
|
|
86011
|
+
mergedTrack.name = (sourceTrackBinding.nodeName || "") + ".morphTargetInfluences";
|
|
86012
|
+
mergedTrack.values = values;
|
|
86013
|
+
mergedTracks[sourceTrackNode.uuid] = mergedTrack;
|
|
86014
|
+
tracks.push(mergedTrack);
|
|
86015
|
+
continue;
|
|
86016
|
+
}
|
|
86017
|
+
const sourceInterpolant = sourceTrack.createInterpolant(new sourceTrack.ValueBufferType(1));
|
|
86018
|
+
mergedTrack = mergedTracks[sourceTrackNode.uuid];
|
|
86019
|
+
for (let j4 = 0; j4 < mergedTrack.times.length; j4++) {
|
|
86020
|
+
mergedTrack.values[j4 * targetCount + targetIndex] = sourceInterpolant.evaluate(mergedTrack.times[j4]);
|
|
86021
|
+
}
|
|
86022
|
+
for (let j4 = 0; j4 < sourceTrack.times.length; j4++) {
|
|
86023
|
+
const keyframeIndex = this.insertKeyframe(mergedTrack, sourceTrack.times[j4]);
|
|
86024
|
+
mergedTrack.values[keyframeIndex * targetCount + targetIndex] = sourceTrack.values[j4];
|
|
86025
|
+
}
|
|
86026
|
+
}
|
|
86027
|
+
clip.tracks = tracks;
|
|
86028
|
+
return clip;
|
|
86029
|
+
}
|
|
86030
|
+
};
|
|
86031
|
+
|
|
86032
|
+
// src/export/SceneExporter.ts
|
|
86033
|
+
init_MineRenderError();
|
|
86034
|
+
init_DisplayTransforms();
|
|
86035
|
+
init_CanvasCompat();
|
|
86036
|
+
var SceneExporter = class {
|
|
86037
|
+
/** Returns OBJ geometry with normals and UVs; material files and textures are not included. */
|
|
86038
|
+
static toObj(root) {
|
|
86039
|
+
const snapshot = createSnapshot(root, false);
|
|
86040
|
+
try {
|
|
86041
|
+
return new OBJExporter().parse(snapshot.scene);
|
|
86042
|
+
} finally {
|
|
86043
|
+
snapshot.dispose();
|
|
86044
|
+
}
|
|
86045
|
+
}
|
|
86046
|
+
/** Returns PLY geometry with vertex colors and UVs; texture images are not included. */
|
|
86047
|
+
static toPLY(root, options) {
|
|
86048
|
+
const snapshot = createSnapshot(root, false, true);
|
|
86049
|
+
try {
|
|
86050
|
+
const result = new PLYExporter().parse(snapshot.scene, void 0, options);
|
|
86051
|
+
if (result === null) throw new MineRenderError("The scene could not be exported as PLY");
|
|
86052
|
+
return result;
|
|
86053
|
+
} finally {
|
|
86054
|
+
snapshot.dispose();
|
|
86055
|
+
}
|
|
86056
|
+
}
|
|
86057
|
+
/**
|
|
86058
|
+
* Exports a static glTF/GLB snapshot in a browser. Atlas textures and vertex tints are retained;
|
|
86059
|
+
* MineRender's custom directional lighting is not baked into the exported materials.
|
|
86060
|
+
*/
|
|
86061
|
+
static async toGLTF(root, options = {}) {
|
|
86062
|
+
if (typeof document === "undefined" || typeof FileReader === "undefined") {
|
|
86063
|
+
throw new MineRenderError("glTF export requires a browser with canvas and FileReader support");
|
|
86064
|
+
}
|
|
86065
|
+
if (options.maxTextureSize !== void 0 && !(options.maxTextureSize >= 1)) {
|
|
86066
|
+
throw new MineRenderError("maxTextureSize must be at least 1 pixel");
|
|
86067
|
+
}
|
|
86068
|
+
const snapshot = createSnapshot(root, true);
|
|
86069
|
+
try {
|
|
86070
|
+
return await new GLTFExporter().parseAsync(snapshot.scene, {
|
|
86071
|
+
binary: options.binary ?? false,
|
|
86072
|
+
maxTextureSize: options.maxTextureSize ?? Infinity
|
|
86073
|
+
});
|
|
86074
|
+
} finally {
|
|
86075
|
+
snapshot.dispose();
|
|
86076
|
+
}
|
|
86077
|
+
}
|
|
86078
|
+
};
|
|
86079
|
+
function localMatrix(object) {
|
|
86080
|
+
return object.matrixAutoUpdate ? new Matrix4().compose(object.position, object.quaternion, object.scale) : object.matrix.clone();
|
|
86081
|
+
}
|
|
86082
|
+
function createSnapshot(root, gltf, bakeColors = false) {
|
|
86083
|
+
const scene = new Scene();
|
|
86084
|
+
const geometries = [];
|
|
86085
|
+
const materials = [];
|
|
86086
|
+
const textures = [];
|
|
86087
|
+
const textureCopies = /* @__PURE__ */ new Map();
|
|
86088
|
+
const dispose = () => {
|
|
86089
|
+
for (const geometry of geometries) geometry.dispose();
|
|
86090
|
+
for (const material of materials) material.dispose();
|
|
86091
|
+
for (const texture of textures) texture.dispose();
|
|
86092
|
+
};
|
|
86093
|
+
const copyMaterial = (source, geometry) => {
|
|
86094
|
+
let material;
|
|
86095
|
+
const shader = source;
|
|
86096
|
+
if (shader.isShaderMaterial && gltf) {
|
|
86097
|
+
const uniforms = shader.uniforms;
|
|
86098
|
+
if (!uniforms.map?.value?.isTexture || !uniforms.SHADE || !uniforms.BRIGHTNESS || !uniforms.EMISSIVE) {
|
|
86099
|
+
throw new MineRenderError("glTF export does not support this custom ShaderMaterial");
|
|
86100
|
+
}
|
|
86101
|
+
material = new MeshBasicMaterial({
|
|
86102
|
+
map: uniforms.map.value,
|
|
86103
|
+
vertexColors: source.vertexColors,
|
|
86104
|
+
transparent: source.transparent,
|
|
86105
|
+
side: source.side,
|
|
86106
|
+
alphaTest: 0.01,
|
|
86107
|
+
depthWrite: source.depthWrite
|
|
86108
|
+
});
|
|
86109
|
+
material.name = source.name;
|
|
86110
|
+
} else if (shader.isShaderMaterial) {
|
|
86111
|
+
material = new MeshBasicMaterial({ vertexColors: source.vertexColors });
|
|
86112
|
+
material.name = source.name;
|
|
86113
|
+
} else {
|
|
86114
|
+
const copySource = Object.create(source);
|
|
86115
|
+
copySource.userData = {};
|
|
86116
|
+
material = source.clone.call(copySource);
|
|
86117
|
+
}
|
|
86118
|
+
materials.push(material);
|
|
86119
|
+
if (gltf) {
|
|
86120
|
+
selectAlphaMode(material, geometry);
|
|
86121
|
+
for (const [key, value] of Object.entries(material)) {
|
|
86122
|
+
if (value?.isDataTexture) {
|
|
86123
|
+
let texture = textureCopies.get(value);
|
|
86124
|
+
if (!texture) {
|
|
86125
|
+
texture = copyDataTexture(value);
|
|
86126
|
+
textureCopies.set(value, texture);
|
|
86127
|
+
textures.push(texture);
|
|
86128
|
+
}
|
|
86129
|
+
material[key] = texture;
|
|
86130
|
+
}
|
|
86131
|
+
}
|
|
86132
|
+
}
|
|
86133
|
+
return material;
|
|
86134
|
+
};
|
|
86135
|
+
const addMesh = (mesh, world, instanceColor) => {
|
|
86136
|
+
if (world.determinant() === 0 || !mesh.geometry.getAttribute("position")) return;
|
|
86137
|
+
const source = mesh.geometry;
|
|
86138
|
+
const count = source.index?.count ?? source.getAttribute("position").count;
|
|
86139
|
+
const groups = Array.isArray(mesh.material) ? source.groups : [{ start: 0, count, materialIndex: 0 }];
|
|
86140
|
+
for (const group of groups) {
|
|
86141
|
+
const sourceMaterial = Array.isArray(mesh.material) ? mesh.material[group.materialIndex ?? 0] : mesh.material;
|
|
86142
|
+
if (!sourceMaterial?.visible) continue;
|
|
86143
|
+
const start = Math.max(group.start, source.drawRange.start);
|
|
86144
|
+
const end = Math.min(count, group.start + group.count, source.drawRange.start + source.drawRange.count);
|
|
86145
|
+
const indices = [];
|
|
86146
|
+
for (let i4 = start; i4 + 2 < end; i4 += 3) {
|
|
86147
|
+
for (let corner = 0; corner < 3; corner++) indices.push(source.index?.getX(i4 + corner) ?? i4 + corner);
|
|
86148
|
+
}
|
|
86149
|
+
if (!indices.length) continue;
|
|
86150
|
+
let geometry = source.clone();
|
|
86151
|
+
geometry.setIndex(indices);
|
|
86152
|
+
if (new Set(indices).size < geometry.getAttribute("position").count) {
|
|
86153
|
+
const compact = geometry.toNonIndexed();
|
|
86154
|
+
geometry.dispose();
|
|
86155
|
+
geometry = compact;
|
|
86156
|
+
}
|
|
86157
|
+
geometries.push(geometry);
|
|
86158
|
+
geometry.userData = {};
|
|
86159
|
+
geometry.clearGroups();
|
|
86160
|
+
geometry.setDrawRange(0, Infinity);
|
|
86161
|
+
DisplayTransforms.apply(geometry, world);
|
|
86162
|
+
const material = copyMaterial(sourceMaterial, geometry);
|
|
86163
|
+
if (!sourceMaterial.vertexColors) geometry.deleteAttribute("color");
|
|
86164
|
+
if (bakeColors || instanceColor) {
|
|
86165
|
+
const tint = (material.color ?? new Color()).clone();
|
|
86166
|
+
if (instanceColor) tint.multiply(instanceColor);
|
|
86167
|
+
if (bakeColors) {
|
|
86168
|
+
const original = geometry.getAttribute("color");
|
|
86169
|
+
const colors = new Float32BufferAttribute(new Float32Array(geometry.getAttribute("position").count * 3), 3);
|
|
86170
|
+
for (let i4 = 0; i4 < colors.count; i4++) {
|
|
86171
|
+
colors.setXYZ(i4, (original?.getX(i4) ?? 1) * tint.r, (original?.getY(i4) ?? 1) * tint.g, (original?.getZ(i4) ?? 1) * tint.b);
|
|
86172
|
+
}
|
|
86173
|
+
geometry.setAttribute("color", colors);
|
|
86174
|
+
} else if (material.color) {
|
|
86175
|
+
material.color.copy(tint);
|
|
86176
|
+
}
|
|
86177
|
+
}
|
|
86178
|
+
const copy = new Mesh(geometry, material);
|
|
86179
|
+
copy.name = mesh.name;
|
|
86180
|
+
copy.renderOrder = mesh.renderOrder;
|
|
86181
|
+
scene.add(copy);
|
|
86182
|
+
}
|
|
86183
|
+
};
|
|
86184
|
+
const visit = (object, parentWorld) => {
|
|
86185
|
+
if (!object.visible) return;
|
|
86186
|
+
const world = parentWorld.clone().multiply(localMatrix(object));
|
|
86187
|
+
const mesh = object;
|
|
86188
|
+
if (mesh.isMesh) {
|
|
86189
|
+
const instanced = mesh;
|
|
86190
|
+
if (instanced.isInstancedMesh) {
|
|
86191
|
+
for (let i4 = 0; i4 < instanced.count; i4++) {
|
|
86192
|
+
const matrix = new Matrix4();
|
|
86193
|
+
instanced.getMatrixAt(i4, matrix);
|
|
86194
|
+
const color2 = instanced.instanceColor ? new Color().fromBufferAttribute(instanced.instanceColor, i4) : void 0;
|
|
86195
|
+
addMesh(mesh, world.clone().multiply(matrix), color2);
|
|
86196
|
+
}
|
|
86197
|
+
} else {
|
|
86198
|
+
addMesh(mesh, world);
|
|
86199
|
+
}
|
|
86200
|
+
}
|
|
86201
|
+
for (const child of object.children) visit(child, world);
|
|
86202
|
+
};
|
|
86203
|
+
try {
|
|
86204
|
+
const ancestors = [];
|
|
86205
|
+
for (let parent = root.parent; parent; parent = parent.parent) ancestors.unshift(parent);
|
|
86206
|
+
const world = new Matrix4();
|
|
86207
|
+
for (const ancestor of ancestors) {
|
|
86208
|
+
if (!ancestor.visible) return { scene, dispose };
|
|
86209
|
+
world.multiply(localMatrix(ancestor));
|
|
86210
|
+
}
|
|
86211
|
+
visit(root, world);
|
|
86212
|
+
return { scene, dispose };
|
|
86213
|
+
} catch (error) {
|
|
86214
|
+
dispose();
|
|
86215
|
+
throw error;
|
|
86216
|
+
}
|
|
86217
|
+
}
|
|
86218
|
+
function selectAlphaMode(material, geometry) {
|
|
86219
|
+
const texture = material.map;
|
|
86220
|
+
if (material.type !== "MeshBasicMaterial" || !material.transparent || !material.depthWrite || material.opacity !== 1 || material.alphaMap || !texture?.isDataTexture || texture.format !== RGBAFormat || texture.type !== UnsignedByteType || texture.wrapS !== ClampToEdgeWrapping || texture.wrapT !== ClampToEdgeWrapping || texture.magFilter !== NearestFilter || texture.minFilter !== NearestFilter || texture.anisotropy > 1 || texture.offset.x !== 0 || texture.offset.y !== 0 || texture.repeat.x !== 1 || texture.repeat.y !== 1 || texture.rotation !== 0 || !texture.matrixAutoUpdate && !texture.matrix.elements.every((value, i4) => value === (i4 % 4 === 0 ? 1 : 0))) return;
|
|
86221
|
+
const uv = geometry.getAttribute(texture.channel === 0 ? "uv" : `uv${texture.channel}`);
|
|
86222
|
+
const colors = geometry.getAttribute("color");
|
|
86223
|
+
if (!uv || material.vertexColors && colors?.itemSize === 4) return;
|
|
86224
|
+
const { data, width, height } = texture.image;
|
|
86225
|
+
if (!data || width < 1 || height < 1 || data.length < width * height * 4) return;
|
|
86226
|
+
const count = geometry.index?.count ?? uv.count;
|
|
86227
|
+
let holes = false;
|
|
86228
|
+
for (let i4 = 0; i4 + 2 < count; i4 += 3) {
|
|
86229
|
+
let minU = Infinity, maxU = -Infinity, minV = Infinity, maxV = -Infinity;
|
|
86230
|
+
for (let corner = 0; corner < 3; corner++) {
|
|
86231
|
+
const index = geometry.index?.getX(i4 + corner) ?? i4 + corner;
|
|
86232
|
+
const u4 = uv.getX(index), v5 = texture.flipY ? 1 - uv.getY(index) : uv.getY(index);
|
|
86233
|
+
if (!Number.isFinite(u4) || !Number.isFinite(v5)) return;
|
|
86234
|
+
minU = Math.min(minU, u4);
|
|
86235
|
+
maxU = Math.max(maxU, u4);
|
|
86236
|
+
minV = Math.min(minV, v5);
|
|
86237
|
+
maxV = Math.max(maxV, v5);
|
|
86238
|
+
}
|
|
86239
|
+
const minX = Math.max(0, Math.min(width - 1, Math.floor(minU * width)));
|
|
86240
|
+
const maxX = Math.max(minX, Math.min(width - 1, Math.ceil(maxU * width) - 1));
|
|
86241
|
+
const minY = Math.max(0, Math.min(height - 1, Math.floor(minV * height)));
|
|
86242
|
+
const maxY = Math.max(minY, Math.min(height - 1, Math.ceil(maxV * height) - 1));
|
|
86243
|
+
for (let y5 = minY; y5 <= maxY; y5++) {
|
|
86244
|
+
for (let x4 = minX; x4 <= maxX; x4++) {
|
|
86245
|
+
const alpha = data[(y5 * width + x4) * 4 + 3];
|
|
86246
|
+
if (alpha === 255) continue;
|
|
86247
|
+
if (alpha !== 0 && alpha / 255 >= material.alphaTest) return;
|
|
86248
|
+
holes = true;
|
|
86249
|
+
}
|
|
86250
|
+
}
|
|
86251
|
+
}
|
|
86252
|
+
material.transparent = false;
|
|
86253
|
+
if (holes && material.alphaTest === 0) material.alphaTest = 1 / 255;
|
|
86254
|
+
}
|
|
86255
|
+
function copyDataTexture(source) {
|
|
86256
|
+
const image = source.image;
|
|
86257
|
+
if (source.format !== RGBAFormat || source.type !== UnsignedByteType) {
|
|
86258
|
+
throw new MineRenderError("glTF export requires RGBA unsigned-byte data textures");
|
|
86259
|
+
}
|
|
86260
|
+
const canvas = createCanvas(image.width, image.height);
|
|
86261
|
+
const context = canvas.getContext("2d");
|
|
86262
|
+
if (!context) throw new MineRenderError("glTF export could not create a 2D canvas context");
|
|
86263
|
+
const pixels = context.createImageData(image.width, image.height);
|
|
86264
|
+
pixels.data.set(image.data);
|
|
86265
|
+
context.putImageData(pixels, 0, 0);
|
|
86266
|
+
const copySource = Object.create(source);
|
|
86267
|
+
copySource.userData = {};
|
|
86268
|
+
copySource.source = new Source(canvas);
|
|
86269
|
+
return new Texture().copy(copySource);
|
|
86270
|
+
}
|
|
86271
|
+
|
|
83702
86272
|
// src/gui/index.ts
|
|
83703
86273
|
init_dirname();
|
|
83704
86274
|
init_buffer2();
|
|
@@ -90556,6 +93126,9 @@ uniform float opacity;varying vec2 vUv;void main(){vec4 texel=texture2D(inputBuf
|
|
|
90556
93126
|
if (next !== void 0 && t5 + 0.1 < next) return;
|
|
90557
93127
|
this._nextFrameTime = next !== void 0 && t5 - next < interval ? next + interval : t5 + interval;
|
|
90558
93128
|
}
|
|
93129
|
+
this.drawFrame();
|
|
93130
|
+
}
|
|
93131
|
+
drawFrame() {
|
|
90559
93132
|
if (this._stats) {
|
|
90560
93133
|
this._stats.begin();
|
|
90561
93134
|
}
|
|
@@ -90570,8 +93143,28 @@ uniform float opacity;varying vec2 vUv;void main(){vec4 texel=texture2D(inputBuf
|
|
|
90570
93143
|
}
|
|
90571
93144
|
}
|
|
90572
93145
|
//</editor-fold>
|
|
90573
|
-
|
|
90574
|
-
|
|
93146
|
+
/**
|
|
93147
|
+
* Renders a fresh frame and returns an image data URL, including while the animation loop is stopped.
|
|
93148
|
+
* Trimming removes transparent borders; an empty image becomes one transparent pixel.
|
|
93149
|
+
* MIME type support and lossy quality (0–1) follow the canvas encoder.
|
|
93150
|
+
*/
|
|
93151
|
+
toImage(trim = false, mime = "image/png", quality) {
|
|
93152
|
+
if (this._disposed) throw new Error("Cannot export an image from a disposed renderer");
|
|
93153
|
+
if (this._controls?.enabled) {
|
|
93154
|
+
this._controls.update();
|
|
93155
|
+
}
|
|
93156
|
+
this.drawFrame();
|
|
93157
|
+
const canvas = trim ? trimCanvas(this.renderer.domElement) : this.renderer.domElement;
|
|
93158
|
+
return canvas.toDataURL(mime, quality);
|
|
93159
|
+
}
|
|
93160
|
+
toObj() {
|
|
93161
|
+
return SceneExporter.toObj(this.scene);
|
|
93162
|
+
}
|
|
93163
|
+
toPLY(options) {
|
|
93164
|
+
return SceneExporter.toPLY(this.scene, options);
|
|
93165
|
+
}
|
|
93166
|
+
toGLTF(options) {
|
|
93167
|
+
return SceneExporter.toGLTF(this.scene, options);
|
|
90575
93168
|
}
|
|
90576
93169
|
///
|
|
90577
93170
|
get attachedToBody() {
|