super-three 0.144.0 → 0.147.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/build/three.cjs +735 -387
- package/build/three.js +735 -387
- package/build/three.min.js +1 -1
- package/build/three.module.js +910 -408
- package/examples/js/animation/AnimationClipCreator.js +0 -8
- package/examples/js/animation/CCDIKSolver.js +50 -67
- package/examples/js/animation/MMDAnimationHelper.js +66 -137
- package/examples/js/animation/MMDPhysics.js +70 -134
- package/examples/js/cameras/CinematicCamera.js +33 -22
- package/examples/js/controls/ArcballControls.js +138 -405
- package/examples/js/controls/DragControls.js +8 -33
- package/examples/js/controls/FirstPersonControls.js +32 -54
- package/examples/js/controls/FlyControls.js +29 -55
- package/examples/js/controls/OrbitControls.js +125 -99
- package/examples/js/controls/PointerLockControls.js +5 -14
- package/examples/js/controls/TrackballControls.js +33 -86
- package/examples/js/controls/TransformControls.js +85 -170
- package/examples/js/csm/CSM.js +4 -39
- package/examples/js/csm/CSMFrustum.js +3 -9
- package/examples/js/csm/CSMHelper.js +24 -4
- package/examples/js/csm/CSMShader.js +2 -6
- package/examples/js/curves/CurveExtras.js +27 -27
- package/examples/js/curves/NURBSCurve.js +4 -16
- package/examples/js/curves/NURBSSurface.js +3 -9
- package/examples/js/curves/NURBSUtils.js +8 -45
- package/examples/js/effects/AnaglyphEffect.js +4 -18
- package/examples/js/effects/AsciiEffect.js +32 -31
- package/examples/js/effects/OutlineEffect.js +26 -30
- package/examples/js/effects/ParallaxBarrierEffect.js +0 -13
- package/examples/js/effects/PeppersGhostEffect.js +12 -39
- package/examples/js/effects/StereoEffect.js +0 -4
- package/examples/js/environments/RoomEnvironment.js +12 -10
- package/examples/js/exporters/ColladaExporter.js +48 -65
- package/examples/js/exporters/DRACOExporter.js +22 -22
- package/examples/js/exporters/EXRExporter.js +15 -18
- package/examples/js/exporters/GLTFExporter.js +141 -317
- package/examples/js/exporters/MMDExporter.js +5 -12
- package/examples/js/exporters/OBJExporter.js +42 -33
- package/examples/js/exporters/PLYExporter.js +38 -33
- package/examples/js/exporters/STLExporter.js +5 -7
- package/examples/js/exporters/USDZExporter.js +113 -27
- package/examples/js/geometries/BoxLineGeometry.js +0 -1
- package/examples/js/geometries/ConvexGeometry.js +11 -6
- package/examples/js/geometries/DecalGeometry.js +53 -20
- package/examples/js/geometries/LightningStrike.js +54 -67
- package/examples/js/geometries/ParametricGeometries.js +8 -7
- package/examples/js/geometries/ParametricGeometry.js +25 -12
- package/examples/js/geometries/RoundedBoxGeometry.js +21 -19
- package/examples/js/geometries/TeapotGeometry.js +54 -50
- package/examples/js/geometries/TextGeometry.js +6 -4
- package/examples/js/helpers/LightProbeHelper.js +1 -2
- package/examples/js/helpers/OctreeHelper.js +22 -20
- package/examples/js/helpers/PositionalAudioHelper.js +8 -6
- package/examples/js/helpers/RectAreaLightHelper.js +6 -7
- package/examples/js/helpers/VertexNormalsHelper.js +15 -13
- package/examples/js/helpers/VertexTangentsHelper.js +15 -9
- package/examples/js/helpers/ViewHelper.js +31 -16
- package/examples/js/interactive/HTMLMesh.js +25 -39
- package/examples/js/interactive/InteractiveGroup.js +9 -14
- package/examples/js/interactive/SelectionBox.js +3 -70
- package/examples/js/interactive/SelectionHelper.js +0 -8
- package/examples/js/lights/LightProbeGenerator.js +32 -39
- package/examples/js/lights/RectAreaLightUniformsLib.js +5 -1
- package/examples/js/lines/LineGeometry.js +3 -5
- package/examples/js/lines/LineMaterial.js +4 -11
- package/examples/js/lines/LineSegments2.js +40 -89
- package/examples/js/lines/LineSegmentsGeometry.js +7 -28
- package/examples/js/lines/Wireframe.js +2 -7
- package/examples/js/lines/WireframeGeometry2.js +3 -1
- package/examples/js/loaders/3DMLoader.js +58 -155
- package/examples/js/loaders/3MFLoader.js +72 -106
- package/examples/js/loaders/AMFLoader.js +0 -25
- package/examples/js/loaders/BVHLoader.js +44 -43
- package/examples/js/loaders/BasisTextureLoader.js +16 -46
- package/examples/js/loaders/ColladaLoader.js +228 -359
- package/examples/js/loaders/DDSLoader.js +24 -25
- package/examples/js/loaders/DRACOLoader.js +29 -66
- package/examples/js/loaders/EXRLoader.js +67 -164
- package/examples/js/loaders/FBXLoader.js +287 -441
- package/examples/js/loaders/FontLoader.js +6 -15
- package/examples/js/loaders/GCodeLoader.js +15 -16
- package/examples/js/loaders/GLTFLoader.js +409 -706
- package/examples/js/loaders/HDRCubeTextureLoader.js +0 -6
- package/examples/js/loaders/KMZLoader.js +3 -7
- package/examples/js/loaders/KTXLoader.js +12 -30
- package/examples/js/loaders/LDrawLoader.js +178 -289
- package/examples/js/loaders/LUT3dlLoader.js +7 -11
- package/examples/js/loaders/LUTCubeLoader.js +0 -8
- package/examples/js/loaders/LWOLoader.js +59 -124
- package/examples/js/loaders/LogLuvLoader.js +27 -77
- package/examples/js/loaders/LottieLoader.js +4 -4
- package/examples/js/loaders/MD2Loader.js +26 -27
- package/examples/js/loaders/MDDLoader.js +6 -10
- package/examples/js/loaders/MMDLoader.js +180 -189
- package/examples/js/loaders/MTLLoader.js +18 -47
- package/examples/js/loaders/NRRDLoader.js +44 -84
- package/examples/js/loaders/OBJLoader.js +50 -65
- package/examples/js/loaders/PCDLoader.js +34 -29
- package/examples/js/loaders/PDBLoader.js +17 -13
- package/examples/js/loaders/PLYLoader.js +62 -48
- package/examples/js/loaders/PRWMLoader.js +11 -22
- package/examples/js/loaders/PVRLoader.js +7 -16
- package/examples/js/loaders/RGBELoader.js +36 -61
- package/examples/js/loaders/RGBMLoader.js +26 -87
- package/examples/js/loaders/STLLoader.js +20 -27
- package/examples/js/loaders/SVGLoader.js +361 -233
- package/examples/js/loaders/TDSLoader.js +81 -118
- package/examples/js/loaders/TGALoader.js +39 -41
- package/examples/js/loaders/TIFFLoader.js +0 -1
- package/examples/js/loaders/TTFLoader.js +0 -8
- package/examples/js/loaders/TiltLoader.js +14 -15
- package/examples/js/loaders/VOXLoader.js +8 -16
- package/examples/js/loaders/VRMLLoader.js +243 -340
- package/examples/js/loaders/VTKLoader.js +101 -118
- package/examples/js/loaders/XYZLoader.js +2 -4
- package/examples/js/loaders/lwo/IFFParser.js +55 -136
- package/examples/js/loaders/lwo/LWO2Parser.js +32 -83
- package/examples/js/loaders/lwo/LWO3Parser.js +31 -73
- package/examples/js/materials/MeshGouraudMaterial.js +15 -13
- package/examples/js/math/Capsule.js +0 -17
- package/examples/js/math/ColorConverter.js +3 -3
- package/examples/js/math/ConvexHull.js +185 -141
- package/examples/js/math/ImprovedNoise.js +1 -1
- package/examples/js/math/Lut.js +8 -15
- package/examples/js/math/MeshSurfaceSampler.js +6 -28
- package/examples/js/math/OBB.js +90 -49
- package/examples/js/math/Octree.js +2 -57
- package/examples/js/math/SimplexNoise.js +74 -88
- package/examples/js/misc/ConvexObjectBreaker.js +37 -48
- package/examples/js/misc/GPUComputationRenderer.js +26 -16
- package/examples/js/misc/Gyroscope.js +5 -9
- package/examples/js/misc/MD2Character.js +14 -23
- package/examples/js/misc/MD2CharacterComplex.js +73 -54
- package/examples/js/misc/MorphAnimMesh.js +0 -6
- package/examples/js/misc/MorphBlendMesh.js +3 -30
- package/examples/js/misc/ProgressiveLightMap.js +47 -43
- package/examples/js/misc/RollerCoaster.js +17 -24
- package/examples/js/misc/TubePainter.js +18 -12
- package/examples/js/misc/Volume.js +16 -45
- package/examples/js/misc/VolumeSlice.js +14 -24
- package/examples/js/modifiers/CurveModifier.js +19 -21
- package/examples/js/modifiers/EdgeSplitModifier.js +0 -30
- package/examples/js/modifiers/SimplifyModifier.js +56 -59
- package/examples/js/modifiers/TessellateModifier.js +2 -9
- package/examples/js/objects/GroundProjectedEnv.js +2 -14
- package/examples/js/objects/Lensflare.js +47 -38
- package/examples/js/objects/LightningStorm.js +10 -13
- package/examples/js/objects/MarchingCubes.js +80 -59
- package/examples/js/objects/Reflector.js +22 -20
- package/examples/js/objects/ReflectorForSSRPass.js +19 -23
- package/examples/js/objects/Refractor.js +52 -30
- package/examples/js/objects/ShadowMesh.js +1 -2
- package/examples/js/objects/Sky.js +2 -7
- package/examples/js/objects/Water.js +23 -18
- package/examples/js/objects/Water2.js +20 -19
- package/examples/js/physics/AmmoPhysics.js +23 -20
- package/examples/js/physics/OimoPhysics.js +19 -17
- package/examples/js/postprocessing/AdaptiveToneMappingPass.js +13 -20
- package/examples/js/postprocessing/AfterimagePass.js +19 -12
- package/examples/js/postprocessing/BloomPass.js +38 -17
- package/examples/js/postprocessing/BokehPass.js +29 -12
- package/examples/js/postprocessing/ClearPass.js +1 -6
- package/examples/js/postprocessing/CubeTexturePass.js +12 -9
- package/examples/js/postprocessing/DotScreenPass.js +7 -5
- package/examples/js/postprocessing/EffectComposer.js +25 -32
- package/examples/js/postprocessing/FilmPass.js +7 -5
- package/examples/js/postprocessing/GlitchPass.js +10 -11
- package/examples/js/postprocessing/HalftonePass.js +9 -9
- package/examples/js/postprocessing/LUTPass.js +2 -15
- package/examples/js/postprocessing/MaskPass.js +20 -17
- package/examples/js/postprocessing/OutlinePass.js +45 -36
- package/examples/js/postprocessing/Pass.js +11 -14
- package/examples/js/postprocessing/RenderPass.js +3 -7
- package/examples/js/postprocessing/RenderPixelatedPass.js +215 -0
- package/examples/js/postprocessing/SAOPass.js +40 -32
- package/examples/js/postprocessing/SMAAPass.js +34 -17
- package/examples/js/postprocessing/SSAARenderPass.js +14 -14
- package/examples/js/postprocessing/SSAOPass.js +56 -42
- package/examples/js/postprocessing/SSRPass.js +78 -61
- package/examples/js/postprocessing/SavePass.js +14 -6
- package/examples/js/postprocessing/ShaderPass.js +9 -8
- package/examples/js/postprocessing/TAARenderPass.js +11 -9
- package/examples/js/postprocessing/TexturePass.js +7 -4
- package/examples/js/postprocessing/UnrealBloomPass.js +43 -25
- package/examples/js/renderers/CSS2DRenderer.js +2 -21
- package/examples/js/renderers/CSS3DRenderer.js +3 -24
- package/examples/js/renderers/Projector.js +29 -85
- package/examples/js/renderers/SVGRenderer.js +4 -50
- package/examples/js/shaders/ACESFilmicToneMappingShader.js +3 -6
- package/examples/js/shaders/AfterimageShader.js +3 -6
- package/examples/js/shaders/BasicShader.js +3 -6
- package/examples/js/shaders/BleachBypassShader.js +3 -6
- package/examples/js/shaders/BlendShader.js +3 -6
- package/examples/js/shaders/BokehShader.js +3 -6
- package/examples/js/shaders/BokehShader2.js +4 -13
- package/examples/js/shaders/BrightnessContrastShader.js +3 -6
- package/examples/js/shaders/ColorCorrectionShader.js +2 -6
- package/examples/js/shaders/ColorifyShader.js +2 -6
- package/examples/js/shaders/ConvolutionShader.js +5 -10
- package/examples/js/shaders/CopyShader.js +3 -6
- package/examples/js/shaders/DOFMipMapShader.js +3 -6
- package/examples/js/shaders/DepthLimitedBlurShader.js +2 -9
- package/examples/js/shaders/DigitalGlitch.js +3 -6
- package/examples/js/shaders/DotScreenShader.js +2 -6
- package/examples/js/shaders/FXAAShader.js +1 -3
- package/examples/js/shaders/FilmShader.js +3 -6
- package/examples/js/shaders/FocusShader.js +3 -6
- package/examples/js/shaders/FreiChenShader.js +2 -6
- package/examples/js/shaders/GammaCorrectionShader.js +3 -6
- package/examples/js/shaders/GodRaysShader.js +11 -24
- package/examples/js/shaders/HalftoneShader.js +3 -6
- package/examples/js/shaders/HorizontalBlurShader.js +3 -6
- package/examples/js/shaders/HorizontalTiltShiftShader.js +3 -6
- package/examples/js/shaders/HueSaturationShader.js +3 -6
- package/examples/js/shaders/KaleidoShader.js +3 -6
- package/examples/js/shaders/LuminosityHighPassShader.js +2 -6
- package/examples/js/shaders/LuminosityShader.js +3 -6
- package/examples/js/shaders/MMDToonShader.js +2 -8
- package/examples/js/shaders/MirrorShader.js +3 -6
- package/examples/js/shaders/NormalMapShader.js +2 -6
- package/examples/js/shaders/RGBShiftShader.js +3 -6
- package/examples/js/shaders/SAOShader.js +2 -6
- package/examples/js/shaders/SMAAShader.js +6 -18
- package/examples/js/shaders/SSAOShader.js +2 -6
- package/examples/js/shaders/SSRShader.js +6 -18
- package/examples/js/shaders/SepiaShader.js +3 -6
- package/examples/js/shaders/SobelOperatorShader.js +2 -6
- package/examples/js/shaders/TechnicolorShader.js +3 -6
- package/examples/js/shaders/ToneMapShader.js +3 -6
- package/examples/js/shaders/ToonShader.js +8 -24
- package/examples/js/shaders/TriangleBlurShader.js +2 -6
- package/examples/js/shaders/UnpackDepthRGBAShader.js +3 -6
- package/examples/js/shaders/VelocityShader.js +126 -0
- package/examples/js/shaders/VerticalBlurShader.js +3 -6
- package/examples/js/shaders/VerticalTiltShiftShader.js +3 -6
- package/examples/js/shaders/VignetteShader.js +3 -6
- package/examples/js/shaders/VolumeShader.js +2 -6
- package/examples/js/shaders/WaterRefractionShader.js +2 -6
- package/examples/js/textures/FlakesTexture.js +0 -1
- package/examples/js/utils/BufferGeometryUtils.js +236 -170
- package/examples/js/utils/CameraUtils.js +5 -20
- package/examples/js/utils/GPUStatsPanel.js +3 -12
- package/examples/js/utils/GeometryCompressionUtils.js +19 -44
- package/examples/js/utils/GeometryUtils.js +13 -18
- package/examples/js/utils/LDrawUtils.js +8 -11
- package/examples/js/utils/PackedPhongMaterial.js +6 -4
- package/examples/js/utils/SceneUtils.js +117 -6
- package/examples/js/utils/ShadowMapViewer.js +17 -14
- package/examples/js/utils/SkeletonUtils.js +13 -27
- package/examples/js/utils/UVsDebug.js +20 -12
- package/examples/js/utils/WorkerPool.js +1 -11
- package/examples/jsm/animation/CCDIKSolver.js +27 -3
- package/examples/jsm/animation/MMDPhysics.js +25 -0
- package/examples/jsm/capabilities/WebGPU.js +3 -1
- package/examples/jsm/controls/FirstPersonControls.js +20 -20
- package/examples/jsm/controls/FlyControls.js +16 -17
- package/examples/jsm/controls/OrbitControls.js +44 -4
- package/examples/jsm/controls/TrackballControls.js +14 -2
- package/examples/jsm/controls/TransformControls.js +1 -1
- package/examples/jsm/csm/CSM.js +1 -0
- package/examples/jsm/csm/CSMHelper.js +30 -0
- package/examples/jsm/exporters/GLTFExporter.js +0 -79
- package/examples/jsm/exporters/USDZExporter.js +93 -1
- package/examples/jsm/helpers/OctreeHelper.js +22 -8
- package/examples/jsm/helpers/VertexNormalsHelper.js +7 -1
- package/examples/jsm/helpers/VertexTangentsHelper.js +7 -0
- package/examples/jsm/helpers/ViewHelper.js +24 -0
- package/examples/jsm/interactive/HTMLMesh.js +5 -6
- package/examples/jsm/interactive/InteractiveGroup.js +4 -2
- package/examples/jsm/libs/flow.module.js +610 -160
- package/examples/jsm/libs/lottie_canvas.module.js +14844 -0
- package/examples/jsm/lines/LineSegments2.js +4 -0
- package/examples/jsm/loaders/3DMLoader.js +1 -2
- package/examples/jsm/loaders/ColladaLoader.js +28 -0
- package/examples/jsm/loaders/FBXLoader.js +18 -2
- package/examples/jsm/loaders/GLTFLoader.js +269 -428
- package/examples/jsm/loaders/KTX2Loader.js +68 -29
- package/examples/jsm/loaders/LDrawLoader.js +14 -13
- package/examples/jsm/loaders/LottieLoader.js +4 -2
- package/examples/jsm/loaders/MaterialXLoader.js +728 -0
- package/examples/jsm/loaders/PCDLoader.js +1 -1
- package/examples/jsm/loaders/PLYLoader.js +68 -16
- package/examples/jsm/loaders/SVGLoader.js +227 -14
- package/examples/jsm/loaders/USDZLoader.js +351 -111
- package/examples/jsm/loaders/VRMLLoader.js +13 -1
- package/examples/jsm/math/ConvexHull.js +4 -4
- package/examples/jsm/math/Octree.js +1 -1
- package/examples/jsm/node-editor/NodeEditor.js +91 -12
- package/examples/jsm/node-editor/core/BaseNode.js +10 -3
- package/examples/jsm/node-editor/materials/BasicMaterialEditor.js +6 -9
- package/examples/jsm/node-editor/materials/StandardMaterialEditor.js +6 -9
- package/examples/jsm/node-editor/math/AngleEditor.js +3 -3
- package/examples/jsm/node-editor/math/InvertEditor.js +2 -2
- package/examples/jsm/node-editor/scene/MeshEditor.js +11 -8
- package/examples/jsm/node-editor/utils/PreviewEditor.js +4 -0
- package/examples/jsm/nodes/Nodes.js +30 -3
- package/examples/jsm/nodes/accessors/BitangentNode.js +62 -0
- package/examples/jsm/nodes/accessors/NormalNode.js +6 -6
- package/examples/jsm/nodes/accessors/Object3DNode.js +1 -1
- package/examples/jsm/nodes/accessors/PositionNode.js +6 -0
- package/examples/jsm/nodes/accessors/ReferenceNode.js +1 -1
- package/examples/jsm/nodes/accessors/SkinningNode.js +8 -1
- package/examples/jsm/nodes/accessors/TangentNode.js +95 -0
- package/examples/jsm/nodes/core/AttributeNode.js +31 -8
- package/examples/jsm/nodes/core/Node.js +1 -1
- package/examples/jsm/nodes/core/NodeBuilder.js +55 -6
- package/examples/jsm/nodes/core/NodeFrame.js +2 -2
- package/examples/jsm/nodes/core/NodeVarying.js +7 -4
- package/examples/jsm/nodes/core/VaryingNode.js +6 -4
- package/examples/jsm/nodes/core/constants.js +13 -13
- package/examples/jsm/nodes/display/BlendModeNode.js +85 -0
- package/examples/jsm/nodes/display/ColorAdjustmentNode.js +2 -12
- package/examples/jsm/nodes/display/NormalMapNode.js +19 -12
- package/examples/jsm/nodes/display/PosterizeNode.js +25 -0
- package/examples/jsm/nodes/display/ViewportNode.js +106 -0
- package/examples/jsm/nodes/functions/BSDF/BRDF_GGX.js +5 -5
- package/examples/jsm/nodes/functions/PhysicalLightingModel.js +3 -3
- package/examples/jsm/nodes/functions/light/getDistanceAttenuation.js +2 -2
- package/examples/jsm/nodes/gpgpu/ComputeNode.js +1 -1
- package/examples/jsm/nodes/lighting/AnalyticLightNode.js +1 -1
- package/examples/jsm/nodes/loaders/NodeMaterialLoader.js +3 -1
- package/examples/jsm/nodes/materials/Materials.js +9 -7
- package/examples/jsm/nodes/materials/NodeMaterial.js +9 -1
- package/examples/jsm/nodes/materialx/{Disclaimer.md → DISCLAIMER.md} +1 -1
- package/examples/jsm/nodes/materialx/MaterialXNodes.js +59 -0
- package/examples/jsm/nodes/materialx/{functions/lib → lib}/mx_hsv.js +1 -1
- package/examples/jsm/nodes/materialx/{functions/lib → lib}/mx_noise.js +13 -3
- package/examples/jsm/nodes/materialx/lib/mx_transform_color.js +18 -0
- package/examples/jsm/nodes/math/MathNode.js +5 -5
- package/examples/jsm/nodes/math/OperatorNode.js +16 -3
- package/examples/jsm/nodes/shadernode/ShaderNode.js +35 -20
- package/examples/jsm/nodes/shadernode/ShaderNodeBaseElements.js +87 -63
- package/examples/jsm/nodes/shadernode/ShaderNodeElements.js +29 -0
- package/examples/jsm/nodes/utils/ConvertNode.js +15 -14
- package/examples/jsm/nodes/utils/EquirectUVNode.js +27 -0
- package/examples/jsm/nodes/utils/JoinNode.js +8 -2
- package/examples/jsm/nodes/utils/MatcapUVNode.js +2 -4
- package/examples/jsm/nodes/utils/MaxMipLevelNode.js +1 -1
- package/examples/jsm/nodes/utils/OscNode.js +2 -2
- package/examples/jsm/nodes/utils/RemapNode.js +34 -0
- package/examples/jsm/nodes/utils/SpriteSheetUVNode.js +8 -10
- package/examples/jsm/nodes/utils/TimerNode.js +21 -1
- package/examples/jsm/nodes/utils/TriplanarTexturesNode.js +51 -0
- package/examples/jsm/postprocessing/AfterimagePass.js +17 -4
- package/examples/jsm/postprocessing/BloomPass.js +22 -3
- package/examples/jsm/postprocessing/BokehPass.js +18 -4
- package/examples/jsm/postprocessing/CubeTexturePass.js +12 -5
- package/examples/jsm/postprocessing/DotScreenPass.js +8 -0
- package/examples/jsm/postprocessing/EffectComposer.js +9 -0
- package/examples/jsm/postprocessing/FilmPass.js +8 -0
- package/examples/jsm/postprocessing/GlitchPass.js +13 -1
- package/examples/jsm/postprocessing/HalftonePass.js +8 -0
- package/examples/jsm/postprocessing/OutlinePass.js +21 -1
- package/examples/jsm/postprocessing/Pass.js +2 -0
- package/examples/jsm/postprocessing/RenderPixelatedPass.js +234 -0
- package/examples/jsm/postprocessing/SAOPass.js +20 -0
- package/examples/jsm/postprocessing/SMAAPass.js +16 -0
- package/examples/jsm/postprocessing/SSAARenderPass.js +4 -0
- package/examples/jsm/postprocessing/SavePass.js +17 -1
- package/examples/jsm/postprocessing/ShaderPass.js +8 -0
- package/examples/jsm/postprocessing/TAARenderPass.js +9 -0
- package/examples/jsm/postprocessing/TexturePass.js +8 -0
- package/examples/jsm/postprocessing/UnrealBloomPass.js +16 -0
- package/examples/jsm/renderers/webgl/nodes/WebGLNodeBuilder.js +56 -35
- package/examples/jsm/renderers/webgpu/WebGPUAnimation.js +58 -0
- package/examples/jsm/renderers/webgpu/WebGPUAttributes.js +63 -5
- package/examples/jsm/renderers/webgpu/WebGPUBackground.js +36 -7
- package/examples/jsm/renderers/webgpu/WebGPURenderer.js +47 -12
- package/examples/jsm/renderers/webgpu/nodes/WebGPUNodeBuilder.js +41 -9
- package/examples/jsm/shaders/MMDToonShader.js +0 -2
- package/examples/jsm/shaders/VelocityShader.js +128 -0
- package/examples/jsm/utils/BufferGeometryUtils.js +174 -42
- package/examples/jsm/utils/SceneUtils.js +129 -4
- package/examples/jsm/webxr/OculusHandModel.js +3 -2
- package/examples/jsm/webxr/XRHandMeshModel.js +8 -3
- package/package.json +13 -13
- package/src/Three.js +1 -0
- package/src/animation/PropertyBinding.js +7 -0
- package/src/audio/AudioContext.js +5 -5
- package/src/cameras/CubeCamera.js +14 -14
- package/src/constants.js +1 -1
- package/src/core/InstancedBufferGeometry.js +1 -7
- package/src/core/InterleavedBufferAttribute.js +4 -4
- package/src/extras/Earcut.js +67 -67
- package/src/geometries/PolyhedronGeometry.js +1 -1
- package/src/geometries/ShapeGeometry.js +1 -1
- package/src/helpers/ArrowHelper.js +9 -0
- package/src/helpers/Box3Helper.js +7 -0
- package/src/helpers/BoxHelper.js +7 -1
- package/src/helpers/DirectionalLightHelper.js +5 -1
- package/src/helpers/GridHelper.js +7 -0
- package/src/helpers/HemisphereLightHelper.js +4 -1
- package/src/helpers/PlaneHelper.js +9 -0
- package/src/helpers/PointLightHelper.js +2 -1
- package/src/helpers/PolarGridHelper.js +7 -0
- package/src/helpers/SkeletonHelper.js +7 -0
- package/src/helpers/SpotLightHelper.js +4 -2
- package/src/lights/LightShadow.js +1 -2
- package/src/lights/PointLight.js +2 -2
- package/src/lights/SpotLight.js +2 -2
- package/src/loaders/FileLoader.js +4 -1
- package/src/loaders/ObjectLoader.js +5 -1
- package/src/materials/Material.js +1 -1
- package/src/materials/MeshPhysicalMaterial.js +1 -1
- package/src/math/Color.js +5 -5
- package/src/math/Matrix3.js +53 -18
- package/src/math/Ray.js +2 -5
- package/src/math/Sphere.js +36 -21
- package/src/objects/InstancedMesh.js +7 -0
- package/src/objects/LOD.js +25 -6
- package/src/renderers/WebGL3DRenderTarget.js +1 -1
- package/src/renderers/WebGLArrayRenderTarget.js +1 -1
- package/src/renderers/WebGLCubeRenderTarget.js +1 -1
- package/src/renderers/WebGLMultipleRenderTargets.js +1 -1
- package/src/renderers/WebGLRenderTarget.js +1 -1
- package/src/renderers/WebGLRenderer.js +36 -62
- package/src/renderers/shaders/ShaderChunk/envmap_fragment.glsl.js +0 -4
- package/src/renderers/shaders/ShaderChunk/lights_fragment_begin.glsl.js +0 -1
- package/src/renderers/shaders/ShaderChunk/lights_lambert_pars_fragment.glsl.js +0 -2
- package/src/renderers/shaders/ShaderChunk/lights_phong_pars_fragment.glsl.js +0 -2
- package/src/renderers/shaders/ShaderChunk/lights_toon_pars_fragment.glsl.js +0 -2
- package/src/renderers/shaders/ShaderChunk/normal_fragment_begin.glsl.js +2 -4
- package/src/renderers/shaders/ShaderChunk/packing.glsl.js +8 -0
- package/src/renderers/shaders/ShaderChunk/transmission_pars_fragment.glsl.js +2 -2
- package/src/renderers/shaders/ShaderChunk.js +3 -0
- package/src/renderers/shaders/ShaderLib/background.glsl.js +7 -2
- package/src/renderers/shaders/ShaderLib/backgroundCube.glsl.js +62 -0
- package/src/renderers/shaders/ShaderLib/cube.glsl.js +4 -6
- package/src/renderers/shaders/ShaderLib/vsm.glsl.js +0 -3
- package/src/renderers/shaders/ShaderLib.js +20 -6
- package/src/renderers/shaders/UniformsLib.js +1 -1
- package/src/renderers/shaders/UniformsUtils.js +15 -0
- package/src/renderers/webgl/WebGLAttributes.js +2 -0
- package/src/renderers/webgl/WebGLBackground.js +15 -7
- package/src/renderers/webgl/WebGLLights.js +0 -4
- package/src/renderers/webgl/WebGLMaterials.js +2 -1
- package/src/renderers/webgl/WebGLShadowMap.js +3 -1
- package/src/renderers/webgl/WebGLState.js +78 -41
- package/src/renderers/webgl/WebGLTextures.js +94 -39
- package/src/renderers/webgl/WebGLUniforms.js +152 -24
- package/src/renderers/webgl/WebGLUtils.js +1 -1
- package/src/renderers/webxr/WebXRController.js +46 -13
- package/src/renderers/webxr/WebXRManager.js +70 -2
- package/src/scenes/Scene.js +8 -0
- package/src/textures/CompressedArrayTexture.js +18 -0
- package/src/textures/Texture.js +2 -1
- package/examples/js/libs/lottie_canvas.js +0 -12751
- package/examples/js/shaders/PixelShader.js +0 -51
- package/examples/jsm/shaders/PixelShader.js +0 -44
|
@@ -14,11 +14,6 @@
|
|
|
14
14
|
|
|
15
15
|
return new GLTFMaterialsUnlitExtension( writer );
|
|
16
16
|
|
|
17
|
-
} );
|
|
18
|
-
this.register( function ( writer ) {
|
|
19
|
-
|
|
20
|
-
return new GLTFMaterialsPBRSpecularGlossiness( writer );
|
|
21
|
-
|
|
22
17
|
} );
|
|
23
18
|
this.register( function ( writer ) {
|
|
24
19
|
|
|
@@ -42,7 +37,6 @@
|
|
|
42
37
|
} );
|
|
43
38
|
|
|
44
39
|
}
|
|
45
|
-
|
|
46
40
|
register( callback ) {
|
|
47
41
|
|
|
48
42
|
if ( this.pluginCallbacks.indexOf( callback ) === - 1 ) {
|
|
@@ -54,7 +48,6 @@
|
|
|
54
48
|
return this;
|
|
55
49
|
|
|
56
50
|
}
|
|
57
|
-
|
|
58
51
|
unregister( callback ) {
|
|
59
52
|
|
|
60
53
|
if ( this.pluginCallbacks.indexOf( callback ) !== - 1 ) {
|
|
@@ -66,6 +59,7 @@
|
|
|
66
59
|
return this;
|
|
67
60
|
|
|
68
61
|
}
|
|
62
|
+
|
|
69
63
|
/**
|
|
70
64
|
* Parse scenes and generate GLTF output
|
|
71
65
|
* @param {Scene or [THREE.Scenes]} input THREE.Scene or Array of THREE.Scenes
|
|
@@ -73,13 +67,10 @@
|
|
|
73
67
|
* @param {Function} onError Callback on errors
|
|
74
68
|
* @param {Object} options options
|
|
75
69
|
*/
|
|
76
|
-
|
|
77
|
-
|
|
78
70
|
parse( input, onDone, onError, options ) {
|
|
79
71
|
|
|
80
72
|
const writer = new GLTFWriter();
|
|
81
73
|
const plugins = [];
|
|
82
|
-
|
|
83
74
|
for ( let i = 0, il = this.pluginCallbacks.length; i < il; i ++ ) {
|
|
84
75
|
|
|
85
76
|
plugins.push( this.pluginCallbacks[ i ]( writer ) );
|
|
@@ -90,7 +81,6 @@
|
|
|
90
81
|
writer.write( input, onDone, options ).catch( onError );
|
|
91
82
|
|
|
92
83
|
}
|
|
93
|
-
|
|
94
84
|
parseAsync( input, options ) {
|
|
95
85
|
|
|
96
86
|
const scope = this;
|
|
@@ -102,11 +92,12 @@
|
|
|
102
92
|
|
|
103
93
|
}
|
|
104
94
|
|
|
105
|
-
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
//------------------------------------------------------------------------------
|
|
106
98
|
// Constants
|
|
107
99
|
//------------------------------------------------------------------------------
|
|
108
100
|
|
|
109
|
-
|
|
110
101
|
const WEBGL_CONSTANTS = {
|
|
111
102
|
POINTS: 0x0000,
|
|
112
103
|
LINES: 0x0001,
|
|
@@ -146,7 +137,9 @@
|
|
|
146
137
|
position: 'translation',
|
|
147
138
|
quaternion: 'rotation',
|
|
148
139
|
morphTargetInfluences: 'weights'
|
|
149
|
-
};
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
// GLB constants
|
|
150
143
|
// https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#glb-file-format-specification
|
|
151
144
|
|
|
152
145
|
const GLB_HEADER_BYTES = 12;
|
|
@@ -154,7 +147,9 @@
|
|
|
154
147
|
const GLB_VERSION = 2;
|
|
155
148
|
const GLB_CHUNK_PREFIX_BYTES = 8;
|
|
156
149
|
const GLB_CHUNK_TYPE_JSON = 0x4E4F534A;
|
|
157
|
-
const GLB_CHUNK_TYPE_BIN = 0x004E4942;
|
|
150
|
+
const GLB_CHUNK_TYPE_BIN = 0x004E4942;
|
|
151
|
+
|
|
152
|
+
//------------------------------------------------------------------------------
|
|
158
153
|
// Utility functions
|
|
159
154
|
//------------------------------------------------------------------------------
|
|
160
155
|
|
|
@@ -164,7 +159,6 @@
|
|
|
164
159
|
* @param {Array} array2 Array 2 to compare
|
|
165
160
|
* @return {Boolean} Returns true if both arrays are equal
|
|
166
161
|
*/
|
|
167
|
-
|
|
168
162
|
function equalArray( array1, array2 ) {
|
|
169
163
|
|
|
170
164
|
return array1.length === array2.length && array1.every( function ( element, index ) {
|
|
@@ -174,31 +168,30 @@
|
|
|
174
168
|
} );
|
|
175
169
|
|
|
176
170
|
}
|
|
171
|
+
|
|
177
172
|
/**
|
|
178
173
|
* Converts a string to an ArrayBuffer.
|
|
179
174
|
* @param {string} text
|
|
180
175
|
* @return {ArrayBuffer}
|
|
181
176
|
*/
|
|
182
|
-
|
|
183
|
-
|
|
184
177
|
function stringToArrayBuffer( text ) {
|
|
185
178
|
|
|
186
179
|
return new TextEncoder().encode( text ).buffer;
|
|
187
180
|
|
|
188
181
|
}
|
|
182
|
+
|
|
189
183
|
/**
|
|
190
184
|
* Is identity matrix
|
|
191
185
|
*
|
|
192
186
|
* @param {Matrix4} matrix
|
|
193
187
|
* @returns {Boolean} Returns true, if parameter is identity matrix
|
|
194
188
|
*/
|
|
195
|
-
|
|
196
|
-
|
|
197
189
|
function isIdentityMatrix( matrix ) {
|
|
198
190
|
|
|
199
191
|
return equalArray( matrix.elements, [ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 ] );
|
|
200
192
|
|
|
201
193
|
}
|
|
194
|
+
|
|
202
195
|
/**
|
|
203
196
|
* Get the min and max vectors from the given attribute
|
|
204
197
|
* @param {BufferAttribute} attribute Attribute to find the min/max in range from start to start + count
|
|
@@ -206,24 +199,21 @@
|
|
|
206
199
|
* @param {Integer} count
|
|
207
200
|
* @return {Object} Object containing the `min` and `max` values (As an array of attribute.itemSize components)
|
|
208
201
|
*/
|
|
209
|
-
|
|
210
|
-
|
|
211
202
|
function getMinMax( attribute, start, count ) {
|
|
212
203
|
|
|
213
204
|
const output = {
|
|
214
205
|
min: new Array( attribute.itemSize ).fill( Number.POSITIVE_INFINITY ),
|
|
215
206
|
max: new Array( attribute.itemSize ).fill( Number.NEGATIVE_INFINITY )
|
|
216
207
|
};
|
|
217
|
-
|
|
218
208
|
for ( let i = start; i < start + count; i ++ ) {
|
|
219
209
|
|
|
220
210
|
for ( let a = 0; a < attribute.itemSize; a ++ ) {
|
|
221
211
|
|
|
222
212
|
let value;
|
|
223
|
-
|
|
224
213
|
if ( attribute.itemSize > 4 ) {
|
|
225
214
|
|
|
226
215
|
// no support for interleaved data for itemSize > 4
|
|
216
|
+
|
|
227
217
|
value = attribute.array[ i * attribute.itemSize + a ];
|
|
228
218
|
|
|
229
219
|
} else {
|
|
@@ -242,6 +232,7 @@
|
|
|
242
232
|
return output;
|
|
243
233
|
|
|
244
234
|
}
|
|
235
|
+
|
|
245
236
|
/**
|
|
246
237
|
* Get the required size + padding for a buffer, rounded to the next 4-byte boundary.
|
|
247
238
|
* https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#data-alignment
|
|
@@ -250,13 +241,12 @@
|
|
|
250
241
|
* @returns {Integer} new buffer size with required padding.
|
|
251
242
|
*
|
|
252
243
|
*/
|
|
253
|
-
|
|
254
|
-
|
|
255
244
|
function getPaddedBufferSize( bufferSize ) {
|
|
256
245
|
|
|
257
246
|
return Math.ceil( bufferSize / 4 ) * 4;
|
|
258
247
|
|
|
259
248
|
}
|
|
249
|
+
|
|
260
250
|
/**
|
|
261
251
|
* Returns a buffer aligned to 4-byte boundary.
|
|
262
252
|
*
|
|
@@ -264,17 +254,13 @@
|
|
|
264
254
|
* @param {Integer} paddingByte (Optional)
|
|
265
255
|
* @returns {ArrayBuffer} The same buffer if it's already aligned to 4-byte boundary or a new buffer
|
|
266
256
|
*/
|
|
267
|
-
|
|
268
|
-
|
|
269
257
|
function getPaddedArrayBuffer( arrayBuffer, paddingByte = 0 ) {
|
|
270
258
|
|
|
271
259
|
const paddedLength = getPaddedBufferSize( arrayBuffer.byteLength );
|
|
272
|
-
|
|
273
260
|
if ( paddedLength !== arrayBuffer.byteLength ) {
|
|
274
261
|
|
|
275
262
|
const array = new Uint8Array( paddedLength );
|
|
276
263
|
array.set( new Uint8Array( arrayBuffer ) );
|
|
277
|
-
|
|
278
264
|
if ( paddingByte !== 0 ) {
|
|
279
265
|
|
|
280
266
|
for ( let i = arrayBuffer.byteLength; i < paddedLength; i ++ ) {
|
|
@@ -313,9 +299,10 @@
|
|
|
313
299
|
|
|
314
300
|
}
|
|
315
301
|
|
|
316
|
-
let quality;
|
|
317
|
-
// Use the Blink default quality levels of toBlob instead so that file sizes are comparable.
|
|
302
|
+
let quality;
|
|
318
303
|
|
|
304
|
+
// Blink's implementation of convertToBlob seems to default to a quality level of 100%
|
|
305
|
+
// Use the Blink default quality levels of toBlob instead so that file sizes are comparable.
|
|
319
306
|
if ( mimeType === 'image/jpeg' ) {
|
|
320
307
|
|
|
321
308
|
quality = 0.92;
|
|
@@ -332,11 +319,10 @@
|
|
|
332
319
|
} );
|
|
333
320
|
|
|
334
321
|
}
|
|
322
|
+
|
|
335
323
|
/**
|
|
336
324
|
* Writer
|
|
337
325
|
*/
|
|
338
|
-
|
|
339
|
-
|
|
340
326
|
class GLTFWriter {
|
|
341
327
|
|
|
342
328
|
constructor() {
|
|
@@ -368,20 +354,18 @@
|
|
|
368
354
|
};
|
|
369
355
|
|
|
370
356
|
}
|
|
371
|
-
|
|
372
357
|
setPlugins( plugins ) {
|
|
373
358
|
|
|
374
359
|
this.plugins = plugins;
|
|
375
360
|
|
|
376
361
|
}
|
|
362
|
+
|
|
377
363
|
/**
|
|
378
364
|
* Parse scenes and generate GLTF output
|
|
379
365
|
* @param {Scene or [THREE.Scenes]} input THREE.Scene or Array of THREE.Scenes
|
|
380
366
|
* @param {Function} onDone Callback on completed
|
|
381
367
|
* @param {Object} options options
|
|
382
368
|
*/
|
|
383
|
-
|
|
384
|
-
|
|
385
369
|
async write( input, onDone, options ) {
|
|
386
370
|
|
|
387
371
|
this.options = Object.assign( {}, {
|
|
@@ -389,12 +373,10 @@
|
|
|
389
373
|
binary: false,
|
|
390
374
|
trs: false,
|
|
391
375
|
onlyVisible: true,
|
|
392
|
-
truncateDrawRange: true,
|
|
393
376
|
maxTextureSize: Infinity,
|
|
394
377
|
animations: [],
|
|
395
378
|
includeCustomExtensions: false
|
|
396
379
|
}, options );
|
|
397
|
-
|
|
398
380
|
if ( this.options.animations.length > 0 ) {
|
|
399
381
|
|
|
400
382
|
// Only TRS properties, and not matrices, may be targeted by animation.
|
|
@@ -408,36 +390,40 @@
|
|
|
408
390
|
const buffers = writer.buffers;
|
|
409
391
|
const json = writer.json;
|
|
410
392
|
options = writer.options;
|
|
411
|
-
const extensionsUsed = writer.extensionsUsed;
|
|
393
|
+
const extensionsUsed = writer.extensionsUsed;
|
|
412
394
|
|
|
395
|
+
// Merge buffers.
|
|
413
396
|
const blob = new Blob( buffers, {
|
|
414
397
|
type: 'application/octet-stream'
|
|
415
|
-
} );
|
|
398
|
+
} );
|
|
416
399
|
|
|
400
|
+
// Declare extensions.
|
|
417
401
|
const extensionsUsedList = Object.keys( extensionsUsed );
|
|
418
|
-
if ( extensionsUsedList.length > 0 ) json.extensionsUsed = extensionsUsedList;
|
|
402
|
+
if ( extensionsUsedList.length > 0 ) json.extensionsUsed = extensionsUsedList;
|
|
419
403
|
|
|
404
|
+
// Update bytelength of the single buffer.
|
|
420
405
|
if ( json.buffers && json.buffers.length > 0 ) json.buffers[ 0 ].byteLength = blob.size;
|
|
421
|
-
|
|
422
406
|
if ( options.binary === true ) {
|
|
423
407
|
|
|
424
408
|
// https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#glb-file-format-specification
|
|
409
|
+
|
|
425
410
|
const reader = new FileReader();
|
|
426
411
|
reader.readAsArrayBuffer( blob );
|
|
427
|
-
|
|
428
412
|
reader.onloadend = function () {
|
|
429
413
|
|
|
430
414
|
// Binary chunk.
|
|
431
415
|
const binaryChunk = getPaddedArrayBuffer( reader.result );
|
|
432
416
|
const binaryChunkPrefix = new DataView( new ArrayBuffer( GLB_CHUNK_PREFIX_BYTES ) );
|
|
433
417
|
binaryChunkPrefix.setUint32( 0, binaryChunk.byteLength, true );
|
|
434
|
-
binaryChunkPrefix.setUint32( 4, GLB_CHUNK_TYPE_BIN, true );
|
|
418
|
+
binaryChunkPrefix.setUint32( 4, GLB_CHUNK_TYPE_BIN, true );
|
|
435
419
|
|
|
420
|
+
// JSON chunk.
|
|
436
421
|
const jsonChunk = getPaddedArrayBuffer( stringToArrayBuffer( JSON.stringify( json ) ), 0x20 );
|
|
437
422
|
const jsonChunkPrefix = new DataView( new ArrayBuffer( GLB_CHUNK_PREFIX_BYTES ) );
|
|
438
423
|
jsonChunkPrefix.setUint32( 0, jsonChunk.byteLength, true );
|
|
439
|
-
jsonChunkPrefix.setUint32( 4, GLB_CHUNK_TYPE_JSON, true );
|
|
424
|
+
jsonChunkPrefix.setUint32( 4, GLB_CHUNK_TYPE_JSON, true );
|
|
440
425
|
|
|
426
|
+
// GLB header.
|
|
441
427
|
const header = new ArrayBuffer( GLB_HEADER_BYTES );
|
|
442
428
|
const headerView = new DataView( header );
|
|
443
429
|
headerView.setUint32( 0, GLB_HEADER_MAGIC, true );
|
|
@@ -449,7 +435,6 @@
|
|
|
449
435
|
} );
|
|
450
436
|
const glbReader = new FileReader();
|
|
451
437
|
glbReader.readAsArrayBuffer( glbBlob );
|
|
452
|
-
|
|
453
438
|
glbReader.onloadend = function () {
|
|
454
439
|
|
|
455
440
|
onDone( glbReader.result );
|
|
@@ -464,7 +449,6 @@
|
|
|
464
449
|
|
|
465
450
|
const reader = new FileReader();
|
|
466
451
|
reader.readAsDataURL( blob );
|
|
467
|
-
|
|
468
452
|
reader.onloadend = function () {
|
|
469
453
|
|
|
470
454
|
const base64data = reader.result;
|
|
@@ -482,28 +466,24 @@
|
|
|
482
466
|
}
|
|
483
467
|
|
|
484
468
|
}
|
|
469
|
+
|
|
485
470
|
/**
|
|
486
471
|
* Serializes a userData.
|
|
487
472
|
*
|
|
488
473
|
* @param {THREE.Object3D|THREE.Material} object
|
|
489
474
|
* @param {Object} objectDef
|
|
490
475
|
*/
|
|
491
|
-
|
|
492
|
-
|
|
493
476
|
serializeUserData( object, objectDef ) {
|
|
494
477
|
|
|
495
478
|
if ( Object.keys( object.userData ).length === 0 ) return;
|
|
496
479
|
const options = this.options;
|
|
497
480
|
const extensionsUsed = this.extensionsUsed;
|
|
498
|
-
|
|
499
481
|
try {
|
|
500
482
|
|
|
501
483
|
const json = JSON.parse( JSON.stringify( object.userData ) );
|
|
502
|
-
|
|
503
484
|
if ( options.includeCustomExtensions && json.gltfExtensions ) {
|
|
504
485
|
|
|
505
486
|
if ( objectDef.extensions === undefined ) objectDef.extensions = {};
|
|
506
|
-
|
|
507
487
|
for ( const extensionName in json.gltfExtensions ) {
|
|
508
488
|
|
|
509
489
|
objectDef.extensions[ extensionName ] = json.gltfExtensions[ extensionName ];
|
|
@@ -524,13 +504,12 @@
|
|
|
524
504
|
}
|
|
525
505
|
|
|
526
506
|
}
|
|
507
|
+
|
|
527
508
|
/**
|
|
528
509
|
* Returns ids for buffer attributes.
|
|
529
510
|
* @param {Object} object
|
|
530
511
|
* @return {Integer}
|
|
531
512
|
*/
|
|
532
|
-
|
|
533
|
-
|
|
534
513
|
getUID( attribute, isRelativeCopy = false ) {
|
|
535
514
|
|
|
536
515
|
if ( this.uids.has( attribute ) === false ) {
|
|
@@ -546,20 +525,18 @@
|
|
|
546
525
|
return uids.get( isRelativeCopy );
|
|
547
526
|
|
|
548
527
|
}
|
|
528
|
+
|
|
549
529
|
/**
|
|
550
530
|
* Checks if normal attribute values are normalized.
|
|
551
531
|
*
|
|
552
532
|
* @param {BufferAttribute} normal
|
|
553
533
|
* @returns {Boolean}
|
|
554
534
|
*/
|
|
555
|
-
|
|
556
|
-
|
|
557
535
|
isNormalizedNormalAttribute( normal ) {
|
|
558
536
|
|
|
559
537
|
const cache = this.cache;
|
|
560
538
|
if ( cache.attributesNormalized.has( normal ) ) return false;
|
|
561
539
|
const v = new THREE.Vector3();
|
|
562
|
-
|
|
563
540
|
for ( let i = 0, il = normal.count; i < il; i ++ ) {
|
|
564
541
|
|
|
565
542
|
// 0.0005 is from glTF-validator
|
|
@@ -570,6 +547,7 @@
|
|
|
570
547
|
return true;
|
|
571
548
|
|
|
572
549
|
}
|
|
550
|
+
|
|
573
551
|
/**
|
|
574
552
|
* Creates normalized normal buffer attribute.
|
|
575
553
|
*
|
|
@@ -577,19 +555,15 @@
|
|
|
577
555
|
* @returns {BufferAttribute}
|
|
578
556
|
*
|
|
579
557
|
*/
|
|
580
|
-
|
|
581
|
-
|
|
582
558
|
createNormalizedNormalAttribute( normal ) {
|
|
583
559
|
|
|
584
560
|
const cache = this.cache;
|
|
585
561
|
if ( cache.attributesNormalized.has( normal ) ) return cache.attributesNormalized.get( normal );
|
|
586
562
|
const attribute = normal.clone();
|
|
587
563
|
const v = new THREE.Vector3();
|
|
588
|
-
|
|
589
564
|
for ( let i = 0, il = attribute.count; i < il; i ++ ) {
|
|
590
565
|
|
|
591
566
|
v.fromBufferAttribute( attribute, i );
|
|
592
|
-
|
|
593
567
|
if ( v.x === 0 && v.y === 0 && v.z === 0 ) {
|
|
594
568
|
|
|
595
569
|
// if values can't be normalized set (1, 0, 0)
|
|
@@ -609,6 +583,7 @@
|
|
|
609
583
|
return attribute;
|
|
610
584
|
|
|
611
585
|
}
|
|
586
|
+
|
|
612
587
|
/**
|
|
613
588
|
* Applies a texture transform, if present, to the map definition. Requires
|
|
614
589
|
* the KHR_texture_transform extension.
|
|
@@ -616,13 +591,10 @@
|
|
|
616
591
|
* @param {Object} mapDef
|
|
617
592
|
* @param {THREE.Texture} texture
|
|
618
593
|
*/
|
|
619
|
-
|
|
620
|
-
|
|
621
594
|
applyTextureTransform( mapDef, texture ) {
|
|
622
595
|
|
|
623
596
|
let didTransform = false;
|
|
624
597
|
const transformDef = {};
|
|
625
|
-
|
|
626
598
|
if ( texture.offset.x !== 0 || texture.offset.y !== 0 ) {
|
|
627
599
|
|
|
628
600
|
transformDef.offset = texture.offset.toArray();
|
|
@@ -653,11 +625,9 @@
|
|
|
653
625
|
}
|
|
654
626
|
|
|
655
627
|
}
|
|
656
|
-
|
|
657
628
|
buildMetalRoughTexture( metalnessMap, roughnessMap ) {
|
|
658
629
|
|
|
659
630
|
if ( metalnessMap === roughnessMap ) return metalnessMap;
|
|
660
|
-
|
|
661
631
|
function getEncodingConversion( map ) {
|
|
662
632
|
|
|
663
633
|
if ( map.encoding === THREE.sRGBEncoding ) {
|
|
@@ -690,13 +660,11 @@
|
|
|
690
660
|
context.fillStyle = '#00ffff';
|
|
691
661
|
context.fillRect( 0, 0, width, height );
|
|
692
662
|
const composite = context.getImageData( 0, 0, width, height );
|
|
693
|
-
|
|
694
663
|
if ( metalness ) {
|
|
695
664
|
|
|
696
665
|
context.drawImage( metalness, 0, 0, width, height );
|
|
697
666
|
const convert = getEncodingConversion( metalnessMap );
|
|
698
667
|
const data = context.getImageData( 0, 0, width, height ).data;
|
|
699
|
-
|
|
700
668
|
for ( let i = 2; i < data.length; i += 4 ) {
|
|
701
669
|
|
|
702
670
|
composite.data[ i ] = convert( data[ i ] / 256 ) * 256;
|
|
@@ -710,7 +678,6 @@
|
|
|
710
678
|
context.drawImage( roughness, 0, 0, width, height );
|
|
711
679
|
const convert = getEncodingConversion( roughnessMap );
|
|
712
680
|
const data = context.getImageData( 0, 0, width, height ).data;
|
|
713
|
-
|
|
714
681
|
for ( let i = 1; i < data.length; i += 4 ) {
|
|
715
682
|
|
|
716
683
|
composite.data[ i ] = convert( data[ i ] / 256 ) * 256;
|
|
@@ -719,7 +686,9 @@
|
|
|
719
686
|
|
|
720
687
|
}
|
|
721
688
|
|
|
722
|
-
context.putImageData( composite, 0, 0 );
|
|
689
|
+
context.putImageData( composite, 0, 0 );
|
|
690
|
+
|
|
691
|
+
//
|
|
723
692
|
|
|
724
693
|
const reference = metalnessMap || roughnessMap;
|
|
725
694
|
const texture = reference.clone();
|
|
@@ -728,25 +697,26 @@
|
|
|
728
697
|
return texture;
|
|
729
698
|
|
|
730
699
|
}
|
|
700
|
+
|
|
731
701
|
/**
|
|
732
702
|
* Process a buffer to append to the default one.
|
|
733
703
|
* @param {ArrayBuffer} buffer
|
|
734
704
|
* @return {Integer}
|
|
735
705
|
*/
|
|
736
|
-
|
|
737
|
-
|
|
738
706
|
processBuffer( buffer ) {
|
|
739
707
|
|
|
740
708
|
const json = this.json;
|
|
741
709
|
const buffers = this.buffers;
|
|
742
710
|
if ( ! json.buffers ) json.buffers = [ {
|
|
743
711
|
byteLength: 0
|
|
744
|
-
} ];
|
|
712
|
+
} ];
|
|
745
713
|
|
|
714
|
+
// All buffers are merged before export.
|
|
746
715
|
buffers.push( buffer );
|
|
747
716
|
return 0;
|
|
748
717
|
|
|
749
718
|
}
|
|
719
|
+
|
|
750
720
|
/**
|
|
751
721
|
* Process and generate a BufferView
|
|
752
722
|
* @param {BufferAttribute} attribute
|
|
@@ -756,15 +726,14 @@
|
|
|
756
726
|
* @param {number} target (Optional) Target usage of the BufferView
|
|
757
727
|
* @return {Object}
|
|
758
728
|
*/
|
|
759
|
-
|
|
760
|
-
|
|
761
729
|
processBufferView( attribute, componentType, start, count, target ) {
|
|
762
730
|
|
|
763
731
|
const json = this.json;
|
|
764
|
-
if ( ! json.bufferViews ) json.bufferViews = [];
|
|
732
|
+
if ( ! json.bufferViews ) json.bufferViews = [];
|
|
765
733
|
|
|
766
|
-
|
|
734
|
+
// Create a new dataview and dump the attribute's array into it
|
|
767
735
|
|
|
736
|
+
let componentSize;
|
|
768
737
|
if ( componentType === WEBGL_CONSTANTS.UNSIGNED_BYTE ) {
|
|
769
738
|
|
|
770
739
|
componentSize = 1;
|
|
@@ -782,16 +751,15 @@
|
|
|
782
751
|
const byteLength = getPaddedBufferSize( count * attribute.itemSize * componentSize );
|
|
783
752
|
const dataView = new DataView( new ArrayBuffer( byteLength ) );
|
|
784
753
|
let offset = 0;
|
|
785
|
-
|
|
786
754
|
for ( let i = start; i < start + count; i ++ ) {
|
|
787
755
|
|
|
788
756
|
for ( let a = 0; a < attribute.itemSize; a ++ ) {
|
|
789
757
|
|
|
790
758
|
let value;
|
|
791
|
-
|
|
792
759
|
if ( attribute.itemSize > 4 ) {
|
|
793
760
|
|
|
794
761
|
// no support for interleaved data for itemSize > 4
|
|
762
|
+
|
|
795
763
|
value = attribute.array[ i * attribute.itemSize + a ];
|
|
796
764
|
|
|
797
765
|
} else {
|
|
@@ -830,7 +798,6 @@
|
|
|
830
798
|
byteLength: byteLength
|
|
831
799
|
};
|
|
832
800
|
if ( target !== undefined ) bufferViewDef.target = target;
|
|
833
|
-
|
|
834
801
|
if ( target === WEBGL_CONSTANTS.ARRAY_BUFFER ) {
|
|
835
802
|
|
|
836
803
|
// Only define byteStride for vertex attributes.
|
|
@@ -839,8 +806,9 @@
|
|
|
839
806
|
}
|
|
840
807
|
|
|
841
808
|
this.byteOffset += byteLength;
|
|
842
|
-
json.bufferViews.push( bufferViewDef );
|
|
809
|
+
json.bufferViews.push( bufferViewDef );
|
|
843
810
|
|
|
811
|
+
// @TODO Merge bufferViews where possible.
|
|
844
812
|
const output = {
|
|
845
813
|
id: json.bufferViews.length - 1,
|
|
846
814
|
byteLength: 0
|
|
@@ -848,13 +816,12 @@
|
|
|
848
816
|
return output;
|
|
849
817
|
|
|
850
818
|
}
|
|
819
|
+
|
|
851
820
|
/**
|
|
852
821
|
* Process and generate a BufferView from an image Blob.
|
|
853
822
|
* @param {Blob} blob
|
|
854
823
|
* @return {Promise<Integer>}
|
|
855
824
|
*/
|
|
856
|
-
|
|
857
|
-
|
|
858
825
|
processBufferViewImage( blob ) {
|
|
859
826
|
|
|
860
827
|
const writer = this;
|
|
@@ -864,7 +831,6 @@
|
|
|
864
831
|
|
|
865
832
|
const reader = new FileReader();
|
|
866
833
|
reader.readAsArrayBuffer( blob );
|
|
867
|
-
|
|
868
834
|
reader.onloadend = function () {
|
|
869
835
|
|
|
870
836
|
const buffer = getPaddedArrayBuffer( reader.result );
|
|
@@ -881,6 +847,7 @@
|
|
|
881
847
|
} );
|
|
882
848
|
|
|
883
849
|
}
|
|
850
|
+
|
|
884
851
|
/**
|
|
885
852
|
* Process attribute to generate an accessor
|
|
886
853
|
* @param {BufferAttribute} attribute Attribute to process
|
|
@@ -889,11 +856,8 @@
|
|
|
889
856
|
* @param {Integer} count (Optional)
|
|
890
857
|
* @return {Integer|null} Index of the processed accessor on the "accessors" array
|
|
891
858
|
*/
|
|
892
|
-
|
|
893
|
-
|
|
894
859
|
processAccessor( attribute, geometry, start, count ) {
|
|
895
860
|
|
|
896
|
-
const options = this.options;
|
|
897
861
|
const json = this.json;
|
|
898
862
|
const types = {
|
|
899
863
|
1: 'SCALAR',
|
|
@@ -902,8 +866,9 @@
|
|
|
902
866
|
4: 'VEC4',
|
|
903
867
|
16: 'MAT4'
|
|
904
868
|
};
|
|
905
|
-
let componentType;
|
|
869
|
+
let componentType;
|
|
906
870
|
|
|
871
|
+
// Detect the component type of the attribute array (float, uint or ushort)
|
|
907
872
|
if ( attribute.array.constructor === Float32Array ) {
|
|
908
873
|
|
|
909
874
|
componentType = WEBGL_CONSTANTS.FLOAT;
|
|
@@ -927,24 +892,15 @@
|
|
|
927
892
|
}
|
|
928
893
|
|
|
929
894
|
if ( start === undefined ) start = 0;
|
|
930
|
-
if ( count === undefined ) count = attribute.count;
|
|
931
|
-
|
|
932
|
-
if ( options.truncateDrawRange && geometry !== undefined && geometry.index === null ) {
|
|
933
|
-
|
|
934
|
-
const end = start + count;
|
|
935
|
-
const end2 = geometry.drawRange.count === Infinity ? attribute.count : geometry.drawRange.start + geometry.drawRange.count;
|
|
936
|
-
start = Math.max( start, geometry.drawRange.start );
|
|
937
|
-
count = Math.min( end, end2 ) - start;
|
|
938
|
-
if ( count < 0 ) count = 0;
|
|
939
|
-
|
|
940
|
-
} // Skip creating an accessor if the attribute doesn't have data to export
|
|
941
|
-
|
|
895
|
+
if ( count === undefined ) count = attribute.count;
|
|
942
896
|
|
|
897
|
+
// Skip creating an accessor if the attribute doesn't have data to export
|
|
943
898
|
if ( count === 0 ) return null;
|
|
944
899
|
const minMax = getMinMax( attribute, start, count );
|
|
945
|
-
let bufferViewTarget;
|
|
946
|
-
// animation samplers, target must not be set.
|
|
900
|
+
let bufferViewTarget;
|
|
947
901
|
|
|
902
|
+
// If geometry isn't provided, don't infer the target usage of the bufferView. For
|
|
903
|
+
// animation samplers, target must not be set.
|
|
948
904
|
if ( geometry !== undefined ) {
|
|
949
905
|
|
|
950
906
|
bufferViewTarget = attribute === geometry.index ? WEBGL_CONSTANTS.ELEMENT_ARRAY_BUFFER : WEBGL_CONSTANTS.ARRAY_BUFFER;
|
|
@@ -966,6 +922,7 @@
|
|
|
966
922
|
return json.accessors.push( accessorDef ) - 1;
|
|
967
923
|
|
|
968
924
|
}
|
|
925
|
+
|
|
969
926
|
/**
|
|
970
927
|
* Process image
|
|
971
928
|
* @param {Image} image to process
|
|
@@ -974,8 +931,6 @@
|
|
|
974
931
|
* @param {String} mimeType export format
|
|
975
932
|
* @return {Integer} Index of the processed texture in the "images" array
|
|
976
933
|
*/
|
|
977
|
-
|
|
978
|
-
|
|
979
934
|
processImage( image, format, flipY, mimeType = 'image/png' ) {
|
|
980
935
|
|
|
981
936
|
const writer = this;
|
|
@@ -995,7 +950,6 @@
|
|
|
995
950
|
canvas.width = Math.min( image.width, options.maxTextureSize );
|
|
996
951
|
canvas.height = Math.min( image.height, options.maxTextureSize );
|
|
997
952
|
const ctx = canvas.getContext( '2d' );
|
|
998
|
-
|
|
999
953
|
if ( flipY === true ) {
|
|
1000
954
|
|
|
1001
955
|
ctx.translate( 0, canvas.height );
|
|
@@ -1006,6 +960,7 @@
|
|
|
1006
960
|
if ( image.data !== undefined ) {
|
|
1007
961
|
|
|
1008
962
|
// THREE.DataTexture
|
|
963
|
+
|
|
1009
964
|
if ( format !== THREE.RGBAFormat ) {
|
|
1010
965
|
|
|
1011
966
|
console.error( 'GLTFExporter: Only THREE.RGBAFormat is supported.' );
|
|
@@ -1019,7 +974,6 @@
|
|
|
1019
974
|
}
|
|
1020
975
|
|
|
1021
976
|
const data = new Uint8ClampedArray( image.height * image.width * 4 );
|
|
1022
|
-
|
|
1023
977
|
for ( let i = 0; i < data.length; i += 4 ) {
|
|
1024
978
|
|
|
1025
979
|
data[ i + 0 ] = image.data[ i + 0 ];
|
|
@@ -1068,13 +1022,12 @@
|
|
|
1068
1022
|
return index;
|
|
1069
1023
|
|
|
1070
1024
|
}
|
|
1025
|
+
|
|
1071
1026
|
/**
|
|
1072
1027
|
* Process sampler
|
|
1073
1028
|
* @param {Texture} map Texture to process
|
|
1074
1029
|
* @return {Integer} Index of the processed texture in the "samplers" array
|
|
1075
1030
|
*/
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
1031
|
processSampler( map ) {
|
|
1079
1032
|
|
|
1080
1033
|
const json = this.json;
|
|
@@ -1088,13 +1041,12 @@
|
|
|
1088
1041
|
return json.samplers.push( samplerDef ) - 1;
|
|
1089
1042
|
|
|
1090
1043
|
}
|
|
1044
|
+
|
|
1091
1045
|
/**
|
|
1092
1046
|
* Process texture
|
|
1093
1047
|
* @param {Texture} map Map to process
|
|
1094
1048
|
* @return {Integer} Index of the processed texture in the "textures" array
|
|
1095
1049
|
*/
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
1050
|
processTexture( map ) {
|
|
1099
1051
|
|
|
1100
1052
|
const cache = this.cache;
|
|
@@ -1108,31 +1060,27 @@
|
|
|
1108
1060
|
source: this.processImage( map.image, map.format, map.flipY, mimeType )
|
|
1109
1061
|
};
|
|
1110
1062
|
if ( map.name ) textureDef.name = map.name;
|
|
1111
|
-
|
|
1112
1063
|
this._invokeAll( function ( ext ) {
|
|
1113
1064
|
|
|
1114
1065
|
ext.writeTexture && ext.writeTexture( map, textureDef );
|
|
1115
1066
|
|
|
1116
1067
|
} );
|
|
1117
|
-
|
|
1118
1068
|
const index = json.textures.push( textureDef ) - 1;
|
|
1119
1069
|
cache.textures.set( map, index );
|
|
1120
1070
|
return index;
|
|
1121
1071
|
|
|
1122
1072
|
}
|
|
1073
|
+
|
|
1123
1074
|
/**
|
|
1124
1075
|
* Process material
|
|
1125
1076
|
* @param {THREE.Material} material Material to process
|
|
1126
1077
|
* @return {Integer|null} Index of the processed material in the "materials" array
|
|
1127
1078
|
*/
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
1079
|
processMaterial( material ) {
|
|
1131
1080
|
|
|
1132
1081
|
const cache = this.cache;
|
|
1133
1082
|
const json = this.json;
|
|
1134
1083
|
if ( cache.materials.has( material ) ) return cache.materials.get( material );
|
|
1135
|
-
|
|
1136
1084
|
if ( material.isShaderMaterial ) {
|
|
1137
1085
|
|
|
1138
1086
|
console.warn( 'GLTFExporter: THREE.ShaderMaterial not supported.' );
|
|
@@ -1140,21 +1088,20 @@
|
|
|
1140
1088
|
|
|
1141
1089
|
}
|
|
1142
1090
|
|
|
1143
|
-
if ( ! json.materials ) json.materials = [];
|
|
1091
|
+
if ( ! json.materials ) json.materials = [];
|
|
1144
1092
|
|
|
1093
|
+
// @QUESTION Should we avoid including any attribute that has the default value?
|
|
1145
1094
|
const materialDef = {
|
|
1146
1095
|
pbrMetallicRoughness: {}
|
|
1147
1096
|
};
|
|
1148
|
-
|
|
1149
1097
|
if ( material.isMeshStandardMaterial !== true && material.isMeshBasicMaterial !== true ) {
|
|
1150
1098
|
|
|
1151
1099
|
console.warn( 'GLTFExporter: Use MeshStandardMaterial or MeshBasicMaterial for best results.' );
|
|
1152
1100
|
|
|
1153
|
-
}
|
|
1154
|
-
|
|
1101
|
+
}
|
|
1155
1102
|
|
|
1103
|
+
// pbrMetallicRoughness.baseColorFactor
|
|
1156
1104
|
const color = material.color.toArray().concat( [ material.opacity ] );
|
|
1157
|
-
|
|
1158
1105
|
if ( ! equalArray( color, [ 1, 1, 1, 1 ] ) ) {
|
|
1159
1106
|
|
|
1160
1107
|
materialDef.pbrMetallicRoughness.baseColorFactor = color;
|
|
@@ -1171,9 +1118,9 @@
|
|
|
1171
1118
|
materialDef.pbrMetallicRoughness.metallicFactor = 0.5;
|
|
1172
1119
|
materialDef.pbrMetallicRoughness.roughnessFactor = 0.5;
|
|
1173
1120
|
|
|
1174
|
-
}
|
|
1175
|
-
|
|
1121
|
+
}
|
|
1176
1122
|
|
|
1123
|
+
// pbrMetallicRoughness.metallicRoughnessTexture
|
|
1177
1124
|
if ( material.metalnessMap || material.roughnessMap ) {
|
|
1178
1125
|
|
|
1179
1126
|
const metalRoughTexture = this.buildMetalRoughTexture( material.metalnessMap, material.roughnessMap );
|
|
@@ -1183,9 +1130,9 @@
|
|
|
1183
1130
|
this.applyTextureTransform( metalRoughMapDef, metalRoughTexture );
|
|
1184
1131
|
materialDef.pbrMetallicRoughness.metallicRoughnessTexture = metalRoughMapDef;
|
|
1185
1132
|
|
|
1186
|
-
}
|
|
1187
|
-
|
|
1133
|
+
}
|
|
1188
1134
|
|
|
1135
|
+
// pbrMetallicRoughness.baseColorTexture or pbrSpecularGlossiness diffuseTexture
|
|
1189
1136
|
if ( material.map ) {
|
|
1190
1137
|
|
|
1191
1138
|
const baseColorMapDef = {
|
|
@@ -1201,7 +1148,6 @@
|
|
|
1201
1148
|
// note: emissive components are limited to stay within the 0 - 1 range to accommodate glTF spec. see #21849 and #22000.
|
|
1202
1149
|
const emissive = material.emissive.clone().multiplyScalar( material.emissiveIntensity );
|
|
1203
1150
|
const maxEmissiveComponent = Math.max( emissive.r, emissive.g, emissive.b );
|
|
1204
|
-
|
|
1205
1151
|
if ( maxEmissiveComponent > 1 ) {
|
|
1206
1152
|
|
|
1207
1153
|
emissive.multiplyScalar( 1 / maxEmissiveComponent );
|
|
@@ -1213,9 +1159,9 @@
|
|
|
1213
1159
|
|
|
1214
1160
|
materialDef.emissiveFactor = emissive.toArray();
|
|
1215
1161
|
|
|
1216
|
-
}
|
|
1217
|
-
|
|
1162
|
+
}
|
|
1218
1163
|
|
|
1164
|
+
// emissiveTexture
|
|
1219
1165
|
if ( material.emissiveMap ) {
|
|
1220
1166
|
|
|
1221
1167
|
const emissiveMapDef = {
|
|
@@ -1226,15 +1172,14 @@
|
|
|
1226
1172
|
|
|
1227
1173
|
}
|
|
1228
1174
|
|
|
1229
|
-
}
|
|
1230
|
-
|
|
1175
|
+
}
|
|
1231
1176
|
|
|
1177
|
+
// normalTexture
|
|
1232
1178
|
if ( material.normalMap ) {
|
|
1233
1179
|
|
|
1234
1180
|
const normalMapDef = {
|
|
1235
1181
|
index: this.processTexture( material.normalMap )
|
|
1236
1182
|
};
|
|
1237
|
-
|
|
1238
1183
|
if ( material.normalScale && material.normalScale.x !== 1 ) {
|
|
1239
1184
|
|
|
1240
1185
|
// glTF normal scale is univariate. Ignore `y`, which may be flipped.
|
|
@@ -1246,16 +1191,15 @@
|
|
|
1246
1191
|
this.applyTextureTransform( normalMapDef, material.normalMap );
|
|
1247
1192
|
materialDef.normalTexture = normalMapDef;
|
|
1248
1193
|
|
|
1249
|
-
}
|
|
1250
|
-
|
|
1194
|
+
}
|
|
1251
1195
|
|
|
1196
|
+
// occlusionTexture
|
|
1252
1197
|
if ( material.aoMap ) {
|
|
1253
1198
|
|
|
1254
1199
|
const occlusionMapDef = {
|
|
1255
1200
|
index: this.processTexture( material.aoMap ),
|
|
1256
1201
|
texCoord: 1
|
|
1257
1202
|
};
|
|
1258
|
-
|
|
1259
1203
|
if ( material.aoMapIntensity !== 1.0 ) {
|
|
1260
1204
|
|
|
1261
1205
|
occlusionMapDef.strength = material.aoMapIntensity;
|
|
@@ -1265,9 +1209,9 @@
|
|
|
1265
1209
|
this.applyTextureTransform( occlusionMapDef, material.aoMap );
|
|
1266
1210
|
materialDef.occlusionTexture = occlusionMapDef;
|
|
1267
1211
|
|
|
1268
|
-
}
|
|
1269
|
-
|
|
1212
|
+
}
|
|
1270
1213
|
|
|
1214
|
+
// alphaMode
|
|
1271
1215
|
if ( material.transparent ) {
|
|
1272
1216
|
|
|
1273
1217
|
materialDef.alphaMode = 'BLEND';
|
|
@@ -1281,37 +1225,33 @@
|
|
|
1281
1225
|
|
|
1282
1226
|
}
|
|
1283
1227
|
|
|
1284
|
-
}
|
|
1285
|
-
|
|
1228
|
+
}
|
|
1286
1229
|
|
|
1230
|
+
// doubleSided
|
|
1287
1231
|
if ( material.side === THREE.DoubleSide ) materialDef.doubleSided = true;
|
|
1288
1232
|
if ( material.name !== '' ) materialDef.name = material.name;
|
|
1289
1233
|
this.serializeUserData( material, materialDef );
|
|
1290
|
-
|
|
1291
1234
|
this._invokeAll( function ( ext ) {
|
|
1292
1235
|
|
|
1293
1236
|
ext.writeMaterial && ext.writeMaterial( material, materialDef );
|
|
1294
1237
|
|
|
1295
1238
|
} );
|
|
1296
|
-
|
|
1297
1239
|
const index = json.materials.push( materialDef ) - 1;
|
|
1298
1240
|
cache.materials.set( material, index );
|
|
1299
1241
|
return index;
|
|
1300
1242
|
|
|
1301
1243
|
}
|
|
1244
|
+
|
|
1302
1245
|
/**
|
|
1303
1246
|
* Process mesh
|
|
1304
1247
|
* @param {THREE.Mesh} mesh Mesh to process
|
|
1305
1248
|
* @return {Integer|null} Index of the processed mesh in the "meshes" array
|
|
1306
1249
|
*/
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
1250
|
processMesh( mesh ) {
|
|
1310
1251
|
|
|
1311
1252
|
const cache = this.cache;
|
|
1312
1253
|
const json = this.json;
|
|
1313
1254
|
const meshCacheKeyParts = [ mesh.geometry.uuid ];
|
|
1314
|
-
|
|
1315
1255
|
if ( Array.isArray( mesh.material ) ) {
|
|
1316
1256
|
|
|
1317
1257
|
for ( let i = 0, l = mesh.material.length; i < l; i ++ ) {
|
|
@@ -1329,8 +1269,9 @@
|
|
|
1329
1269
|
const meshCacheKey = meshCacheKeyParts.join( ':' );
|
|
1330
1270
|
if ( cache.meshes.has( meshCacheKey ) ) return cache.meshes.get( meshCacheKey );
|
|
1331
1271
|
const geometry = mesh.geometry;
|
|
1332
|
-
let mode;
|
|
1272
|
+
let mode;
|
|
1333
1273
|
|
|
1274
|
+
// Use the correct mode
|
|
1334
1275
|
if ( mesh.isLineSegments ) {
|
|
1335
1276
|
|
|
1336
1277
|
mode = WEBGL_CONSTANTS.LINES;
|
|
@@ -1356,8 +1297,9 @@
|
|
|
1356
1297
|
const meshDef = {};
|
|
1357
1298
|
const attributes = {};
|
|
1358
1299
|
const primitives = [];
|
|
1359
|
-
const targets = [];
|
|
1300
|
+
const targets = [];
|
|
1360
1301
|
|
|
1302
|
+
// Conversion between attributes names in threejs and gltf spec
|
|
1361
1303
|
const nameConversion = {
|
|
1362
1304
|
uv: 'TEXCOORD_0',
|
|
1363
1305
|
uv2: 'TEXCOORD_1',
|
|
@@ -1366,40 +1308,37 @@
|
|
|
1366
1308
|
skinIndex: 'JOINTS_0'
|
|
1367
1309
|
};
|
|
1368
1310
|
const originalNormal = geometry.getAttribute( 'normal' );
|
|
1369
|
-
|
|
1370
1311
|
if ( originalNormal !== undefined && ! this.isNormalizedNormalAttribute( originalNormal ) ) {
|
|
1371
1312
|
|
|
1372
1313
|
console.warn( 'THREE.GLTFExporter: Creating normalized normal attribute from the non-normalized one.' );
|
|
1373
1314
|
geometry.setAttribute( 'normal', this.createNormalizedNormalAttribute( originalNormal ) );
|
|
1374
1315
|
|
|
1375
|
-
}
|
|
1376
|
-
// For every attribute create an accessor
|
|
1377
|
-
|
|
1316
|
+
}
|
|
1378
1317
|
|
|
1318
|
+
// @QUESTION Detect if .vertexColors = true?
|
|
1319
|
+
// For every attribute create an accessor
|
|
1379
1320
|
let modifiedAttribute = null;
|
|
1380
|
-
|
|
1381
1321
|
for ( let attributeName in geometry.attributes ) {
|
|
1382
1322
|
|
|
1383
1323
|
// Ignore morph target attributes, which are exported later.
|
|
1384
1324
|
if ( attributeName.slice( 0, 5 ) === 'morph' ) continue;
|
|
1385
1325
|
const attribute = geometry.attributes[ attributeName ];
|
|
1386
|
-
attributeName = nameConversion[ attributeName ] || attributeName.toUpperCase();
|
|
1387
|
-
// listed in the spec; non-spec attributes are considered custom.
|
|
1326
|
+
attributeName = nameConversion[ attributeName ] || attributeName.toUpperCase();
|
|
1388
1327
|
|
|
1328
|
+
// Prefix all geometry attributes except the ones specifically
|
|
1329
|
+
// listed in the spec; non-spec attributes are considered custom.
|
|
1389
1330
|
const validVertexAttributes = /^(POSITION|NORMAL|TANGENT|TEXCOORD_\d+|COLOR_\d+|JOINTS_\d+|WEIGHTS_\d+)$/;
|
|
1390
1331
|
if ( ! validVertexAttributes.test( attributeName ) ) attributeName = '_' + attributeName;
|
|
1391
|
-
|
|
1392
1332
|
if ( cache.attributes.has( this.getUID( attribute ) ) ) {
|
|
1393
1333
|
|
|
1394
1334
|
attributes[ attributeName ] = cache.attributes.get( this.getUID( attribute ) );
|
|
1395
1335
|
continue;
|
|
1396
1336
|
|
|
1397
|
-
}
|
|
1398
|
-
|
|
1337
|
+
}
|
|
1399
1338
|
|
|
1339
|
+
// JOINTS_0 must be UNSIGNED_BYTE or UNSIGNED_SHORT.
|
|
1400
1340
|
modifiedAttribute = null;
|
|
1401
1341
|
const array = attribute.array;
|
|
1402
|
-
|
|
1403
1342
|
if ( attributeName === 'JOINTS_0' && ! ( array instanceof Uint16Array ) && ! ( array instanceof Uint8Array ) ) {
|
|
1404
1343
|
|
|
1405
1344
|
console.warn( 'GLTFExporter: Attribute "skinIndex" converted to type UNSIGNED_SHORT.' );
|
|
@@ -1408,7 +1347,6 @@
|
|
|
1408
1347
|
}
|
|
1409
1348
|
|
|
1410
1349
|
const accessor = this.processAccessor( modifiedAttribute || attribute, geometry );
|
|
1411
|
-
|
|
1412
1350
|
if ( accessor !== null ) {
|
|
1413
1351
|
|
|
1414
1352
|
attributes[ attributeName ] = accessor;
|
|
@@ -1418,16 +1356,17 @@
|
|
|
1418
1356
|
|
|
1419
1357
|
}
|
|
1420
1358
|
|
|
1421
|
-
if ( originalNormal !== undefined ) geometry.setAttribute( 'normal', originalNormal );
|
|
1359
|
+
if ( originalNormal !== undefined ) geometry.setAttribute( 'normal', originalNormal );
|
|
1422
1360
|
|
|
1423
|
-
if
|
|
1361
|
+
// Skip if no exportable attributes found
|
|
1362
|
+
if ( Object.keys( attributes ).length === 0 ) return null;
|
|
1424
1363
|
|
|
1364
|
+
// Morph targets
|
|
1425
1365
|
if ( mesh.morphTargetInfluences !== undefined && mesh.morphTargetInfluences.length > 0 ) {
|
|
1426
1366
|
|
|
1427
1367
|
const weights = [];
|
|
1428
1368
|
const targetNames = [];
|
|
1429
1369
|
const reverseDictionary = {};
|
|
1430
|
-
|
|
1431
1370
|
if ( mesh.morphTargetDictionary !== undefined ) {
|
|
1432
1371
|
|
|
1433
1372
|
for ( const key in mesh.morphTargetDictionary ) {
|
|
@@ -1442,11 +1381,11 @@
|
|
|
1442
1381
|
|
|
1443
1382
|
const target = {};
|
|
1444
1383
|
let warned = false;
|
|
1445
|
-
|
|
1446
1384
|
for ( const attributeName in geometry.morphAttributes ) {
|
|
1447
1385
|
|
|
1448
1386
|
// glTF 2.0 morph supports only POSITION/NORMAL/TANGENT.
|
|
1449
1387
|
// Three.js doesn't support TANGENT yet.
|
|
1388
|
+
|
|
1450
1389
|
if ( attributeName !== 'position' && attributeName !== 'normal' ) {
|
|
1451
1390
|
|
|
1452
1391
|
if ( ! warned ) {
|
|
@@ -1461,23 +1400,23 @@
|
|
|
1461
1400
|
}
|
|
1462
1401
|
|
|
1463
1402
|
const attribute = geometry.morphAttributes[ attributeName ][ i ];
|
|
1464
|
-
const gltfAttributeName = attributeName.toUpperCase();
|
|
1403
|
+
const gltfAttributeName = attributeName.toUpperCase();
|
|
1404
|
+
|
|
1405
|
+
// Three.js morph attribute has absolute values while the one of glTF has relative values.
|
|
1465
1406
|
//
|
|
1466
1407
|
// glTF 2.0 Specification:
|
|
1467
1408
|
// https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#morph-targets
|
|
1468
1409
|
|
|
1469
1410
|
const baseAttribute = geometry.attributes[ attributeName ];
|
|
1470
|
-
|
|
1471
1411
|
if ( cache.attributes.has( this.getUID( attribute, true ) ) ) {
|
|
1472
1412
|
|
|
1473
1413
|
target[ gltfAttributeName ] = cache.attributes.get( this.getUID( attribute, true ) );
|
|
1474
1414
|
continue;
|
|
1475
1415
|
|
|
1476
|
-
}
|
|
1477
|
-
|
|
1416
|
+
}
|
|
1478
1417
|
|
|
1418
|
+
// Clones attribute not to override
|
|
1479
1419
|
const relativeAttribute = attribute.clone();
|
|
1480
|
-
|
|
1481
1420
|
if ( ! geometry.morphTargetsRelative ) {
|
|
1482
1421
|
|
|
1483
1422
|
for ( let j = 0, jl = attribute.count; j < jl; j ++ ) {
|
|
@@ -1500,7 +1439,6 @@
|
|
|
1500
1439
|
}
|
|
1501
1440
|
|
|
1502
1441
|
meshDef.weights = weights;
|
|
1503
|
-
|
|
1504
1442
|
if ( targetNames.length > 0 ) {
|
|
1505
1443
|
|
|
1506
1444
|
meshDef.extras = {};
|
|
@@ -1518,7 +1456,6 @@
|
|
|
1518
1456
|
start: undefined,
|
|
1519
1457
|
count: undefined
|
|
1520
1458
|
} ];
|
|
1521
|
-
|
|
1522
1459
|
for ( let i = 0, il = groups.length; i < il; i ++ ) {
|
|
1523
1460
|
|
|
1524
1461
|
const primitive = {
|
|
@@ -1527,11 +1464,9 @@
|
|
|
1527
1464
|
};
|
|
1528
1465
|
this.serializeUserData( geometry, primitive );
|
|
1529
1466
|
if ( targets.length > 0 ) primitive.targets = targets;
|
|
1530
|
-
|
|
1531
1467
|
if ( geometry.index !== null ) {
|
|
1532
1468
|
|
|
1533
1469
|
let cacheKey = this.getUID( geometry.index );
|
|
1534
|
-
|
|
1535
1470
|
if ( groups[ i ].start !== undefined || groups[ i ].count !== undefined ) {
|
|
1536
1471
|
|
|
1537
1472
|
cacheKey += ':' + groups[ i ].start + ':' + groups[ i ].count;
|
|
@@ -1561,25 +1496,22 @@
|
|
|
1561
1496
|
|
|
1562
1497
|
meshDef.primitives = primitives;
|
|
1563
1498
|
if ( ! json.meshes ) json.meshes = [];
|
|
1564
|
-
|
|
1565
1499
|
this._invokeAll( function ( ext ) {
|
|
1566
1500
|
|
|
1567
1501
|
ext.writeMesh && ext.writeMesh( mesh, meshDef );
|
|
1568
1502
|
|
|
1569
1503
|
} );
|
|
1570
|
-
|
|
1571
1504
|
const index = json.meshes.push( meshDef ) - 1;
|
|
1572
1505
|
cache.meshes.set( meshCacheKey, index );
|
|
1573
1506
|
return index;
|
|
1574
1507
|
|
|
1575
1508
|
}
|
|
1509
|
+
|
|
1576
1510
|
/**
|
|
1577
1511
|
* Process camera
|
|
1578
1512
|
* @param {THREE.Camera} camera Camera to process
|
|
1579
1513
|
* @return {Integer} Index of the processed mesh in the "camera" array
|
|
1580
1514
|
*/
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
1515
|
processCamera( camera ) {
|
|
1584
1516
|
|
|
1585
1517
|
const json = this.json;
|
|
@@ -1588,7 +1520,6 @@
|
|
|
1588
1520
|
const cameraDef = {
|
|
1589
1521
|
type: isOrtho ? 'orthographic' : 'perspective'
|
|
1590
1522
|
};
|
|
1591
|
-
|
|
1592
1523
|
if ( isOrtho ) {
|
|
1593
1524
|
|
|
1594
1525
|
cameraDef.orthographic = {
|
|
@@ -1607,13 +1538,14 @@
|
|
|
1607
1538
|
znear: camera.near < 0 ? 0 : camera.near
|
|
1608
1539
|
};
|
|
1609
1540
|
|
|
1610
|
-
}
|
|
1611
|
-
|
|
1541
|
+
}
|
|
1612
1542
|
|
|
1543
|
+
// Question: Is saving "type" as name intentional?
|
|
1613
1544
|
if ( camera.name !== '' ) cameraDef.name = camera.type;
|
|
1614
1545
|
return json.cameras.push( cameraDef ) - 1;
|
|
1615
1546
|
|
|
1616
1547
|
}
|
|
1548
|
+
|
|
1617
1549
|
/**
|
|
1618
1550
|
* Creates glTF animation entry from AnimationClip object.
|
|
1619
1551
|
*
|
|
@@ -1624,8 +1556,6 @@
|
|
|
1624
1556
|
* @param {THREE.Object3D} root
|
|
1625
1557
|
* @return {number|null}
|
|
1626
1558
|
*/
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
1559
|
processAnimation( clip, root ) {
|
|
1630
1560
|
|
|
1631
1561
|
const json = this.json;
|
|
@@ -1635,14 +1565,12 @@
|
|
|
1635
1565
|
const tracks = clip.tracks;
|
|
1636
1566
|
const channels = [];
|
|
1637
1567
|
const samplers = [];
|
|
1638
|
-
|
|
1639
1568
|
for ( let i = 0; i < tracks.length; ++ i ) {
|
|
1640
1569
|
|
|
1641
1570
|
const track = tracks[ i ];
|
|
1642
1571
|
const trackBinding = THREE.PropertyBinding.parseTrackName( track.name );
|
|
1643
1572
|
let trackNode = THREE.PropertyBinding.findNode( root, trackBinding.nodeName );
|
|
1644
1573
|
const trackProperty = PATH_PROPERTIES[ trackBinding.propertyName ];
|
|
1645
|
-
|
|
1646
1574
|
if ( trackBinding.objectName === 'bones' ) {
|
|
1647
1575
|
|
|
1648
1576
|
if ( trackNode.isSkinnedMesh === true ) {
|
|
@@ -1666,24 +1594,26 @@
|
|
|
1666
1594
|
|
|
1667
1595
|
const inputItemSize = 1;
|
|
1668
1596
|
let outputItemSize = track.values.length / track.times.length;
|
|
1669
|
-
|
|
1670
1597
|
if ( trackProperty === PATH_PROPERTIES.morphTargetInfluences ) {
|
|
1671
1598
|
|
|
1672
1599
|
outputItemSize /= trackNode.morphTargetInfluences.length;
|
|
1673
1600
|
|
|
1674
1601
|
}
|
|
1675
1602
|
|
|
1676
|
-
let interpolation;
|
|
1603
|
+
let interpolation;
|
|
1604
|
+
|
|
1605
|
+
// @TODO export CubicInterpolant(InterpolateSmooth) as CUBICSPLINE
|
|
1606
|
+
|
|
1677
1607
|
// Detecting glTF cubic spline interpolant by checking factory method's special property
|
|
1678
1608
|
// GLTFCubicSplineInterpolant is a custom interpolant and track doesn't return
|
|
1679
1609
|
// valid value from .getInterpolation().
|
|
1680
|
-
|
|
1681
1610
|
if ( track.createInterpolant.isInterpolantFactoryMethodGLTFCubicSpline === true ) {
|
|
1682
1611
|
|
|
1683
|
-
interpolation = 'CUBICSPLINE';
|
|
1612
|
+
interpolation = 'CUBICSPLINE';
|
|
1613
|
+
|
|
1614
|
+
// itemSize of CUBICSPLINE keyframe is 9
|
|
1684
1615
|
// (VEC3 * 3: inTangent, splineVertex, and outTangent)
|
|
1685
1616
|
// but needs to be stored as VEC3 so dividing by 3 here.
|
|
1686
|
-
|
|
1687
1617
|
outputItemSize /= 3;
|
|
1688
1618
|
|
|
1689
1619
|
} else if ( track.getInterpolation() === THREE.InterpolateDiscrete ) {
|
|
@@ -1719,12 +1649,11 @@
|
|
|
1719
1649
|
return json.animations.length - 1;
|
|
1720
1650
|
|
|
1721
1651
|
}
|
|
1652
|
+
|
|
1722
1653
|
/**
|
|
1723
1654
|
* @param {THREE.Object3D} object
|
|
1724
1655
|
* @return {number|null}
|
|
1725
1656
|
*/
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
1657
|
processSkin( object ) {
|
|
1729
1658
|
|
|
1730
1659
|
const json = this.json;
|
|
@@ -1737,7 +1666,6 @@
|
|
|
1737
1666
|
const joints = [];
|
|
1738
1667
|
const inverseBindMatrices = new Float32Array( skeleton.bones.length * 16 );
|
|
1739
1668
|
const temporaryBoneInverse = new THREE.Matrix4();
|
|
1740
|
-
|
|
1741
1669
|
for ( let i = 0; i < skeleton.bones.length; ++ i ) {
|
|
1742
1670
|
|
|
1743
1671
|
joints.push( nodeMap.get( skeleton.bones[ i ] ) );
|
|
@@ -1756,13 +1684,12 @@
|
|
|
1756
1684
|
return skinIndex;
|
|
1757
1685
|
|
|
1758
1686
|
}
|
|
1687
|
+
|
|
1759
1688
|
/**
|
|
1760
1689
|
* Process Object3D node
|
|
1761
1690
|
* @param {THREE.Object3D} node Object3D to processNode
|
|
1762
1691
|
* @return {Integer} Index of the node in the nodes list
|
|
1763
1692
|
*/
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
1693
|
processNode( object ) {
|
|
1767
1694
|
|
|
1768
1695
|
const json = this.json;
|
|
@@ -1770,13 +1697,11 @@
|
|
|
1770
1697
|
const nodeMap = this.nodeMap;
|
|
1771
1698
|
if ( ! json.nodes ) json.nodes = [];
|
|
1772
1699
|
const nodeDef = {};
|
|
1773
|
-
|
|
1774
1700
|
if ( options.trs ) {
|
|
1775
1701
|
|
|
1776
1702
|
const rotation = object.quaternion.toArray();
|
|
1777
1703
|
const position = object.position.toArray();
|
|
1778
1704
|
const scale = object.scale.toArray();
|
|
1779
|
-
|
|
1780
1705
|
if ( ! equalArray( rotation, [ 0, 0, 0, 1 ] ) ) {
|
|
1781
1706
|
|
|
1782
1707
|
nodeDef.rotation = rotation;
|
|
@@ -1809,12 +1734,11 @@
|
|
|
1809
1734
|
|
|
1810
1735
|
}
|
|
1811
1736
|
|
|
1812
|
-
}
|
|
1813
|
-
|
|
1737
|
+
}
|
|
1814
1738
|
|
|
1739
|
+
// We don't export empty strings name because it represents no-name in Three.js.
|
|
1815
1740
|
if ( object.name !== '' ) nodeDef.name = String( object.name );
|
|
1816
1741
|
this.serializeUserData( object, nodeDef );
|
|
1817
|
-
|
|
1818
1742
|
if ( object.isMesh || object.isLine || object.isPoints ) {
|
|
1819
1743
|
|
|
1820
1744
|
const meshIndex = this.processMesh( object );
|
|
@@ -1827,15 +1751,12 @@
|
|
|
1827
1751
|
}
|
|
1828
1752
|
|
|
1829
1753
|
if ( object.isSkinnedMesh ) this.skins.push( object );
|
|
1830
|
-
|
|
1831
1754
|
if ( object.children.length > 0 ) {
|
|
1832
1755
|
|
|
1833
1756
|
const children = [];
|
|
1834
|
-
|
|
1835
1757
|
for ( let i = 0, l = object.children.length; i < l; i ++ ) {
|
|
1836
1758
|
|
|
1837
1759
|
const child = object.children[ i ];
|
|
1838
|
-
|
|
1839
1760
|
if ( child.visible || options.onlyVisible === false ) {
|
|
1840
1761
|
|
|
1841
1762
|
const nodeIndex = this.processNode( child );
|
|
@@ -1854,23 +1775,20 @@
|
|
|
1854
1775
|
ext.writeNode && ext.writeNode( object, nodeDef );
|
|
1855
1776
|
|
|
1856
1777
|
} );
|
|
1857
|
-
|
|
1858
1778
|
const nodeIndex = json.nodes.push( nodeDef ) - 1;
|
|
1859
1779
|
nodeMap.set( object, nodeIndex );
|
|
1860
1780
|
return nodeIndex;
|
|
1861
1781
|
|
|
1862
1782
|
}
|
|
1783
|
+
|
|
1863
1784
|
/**
|
|
1864
1785
|
* Process THREE.Scene
|
|
1865
1786
|
* @param {Scene} node THREE.Scene to process
|
|
1866
1787
|
*/
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
1788
|
processScene( scene ) {
|
|
1870
1789
|
|
|
1871
1790
|
const json = this.json;
|
|
1872
1791
|
const options = this.options;
|
|
1873
|
-
|
|
1874
1792
|
if ( ! json.scenes ) {
|
|
1875
1793
|
|
|
1876
1794
|
json.scenes = [];
|
|
@@ -1882,11 +1800,9 @@
|
|
|
1882
1800
|
if ( scene.name !== '' ) sceneDef.name = scene.name;
|
|
1883
1801
|
json.scenes.push( sceneDef );
|
|
1884
1802
|
const nodes = [];
|
|
1885
|
-
|
|
1886
1803
|
for ( let i = 0, l = scene.children.length; i < l; i ++ ) {
|
|
1887
1804
|
|
|
1888
1805
|
const child = scene.children[ i ];
|
|
1889
|
-
|
|
1890
1806
|
if ( child.visible || options.onlyVisible === false ) {
|
|
1891
1807
|
|
|
1892
1808
|
const nodeIndex = this.processNode( child );
|
|
@@ -1900,17 +1816,15 @@
|
|
|
1900
1816
|
this.serializeUserData( scene, sceneDef );
|
|
1901
1817
|
|
|
1902
1818
|
}
|
|
1819
|
+
|
|
1903
1820
|
/**
|
|
1904
1821
|
* Creates a THREE.Scene to hold a list of objects and parse it
|
|
1905
1822
|
* @param {Array} objects List of objects to process
|
|
1906
1823
|
*/
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
1824
|
processObjects( objects ) {
|
|
1910
1825
|
|
|
1911
1826
|
const scene = new THREE.Scene();
|
|
1912
1827
|
scene.name = 'AuxScene';
|
|
1913
|
-
|
|
1914
1828
|
for ( let i = 0; i < objects.length; i ++ ) {
|
|
1915
1829
|
|
|
1916
1830
|
// We push directly to children instead of calling `add` to prevent
|
|
@@ -1922,24 +1836,20 @@
|
|
|
1922
1836
|
this.processScene( scene );
|
|
1923
1837
|
|
|
1924
1838
|
}
|
|
1839
|
+
|
|
1925
1840
|
/**
|
|
1926
1841
|
* @param {THREE.Object3D|Array<THREE.Object3D>} input
|
|
1927
1842
|
*/
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
1843
|
processInput( input ) {
|
|
1931
1844
|
|
|
1932
1845
|
const options = this.options;
|
|
1933
1846
|
input = input instanceof Array ? input : [ input ];
|
|
1934
|
-
|
|
1935
1847
|
this._invokeAll( function ( ext ) {
|
|
1936
1848
|
|
|
1937
1849
|
ext.beforeParse && ext.beforeParse( input );
|
|
1938
1850
|
|
|
1939
1851
|
} );
|
|
1940
|
-
|
|
1941
1852
|
const objectsWithoutScene = [];
|
|
1942
|
-
|
|
1943
1853
|
for ( let i = 0; i < input.length; i ++ ) {
|
|
1944
1854
|
|
|
1945
1855
|
if ( input[ i ] instanceof THREE.Scene ) {
|
|
@@ -1955,7 +1865,6 @@
|
|
|
1955
1865
|
}
|
|
1956
1866
|
|
|
1957
1867
|
if ( objectsWithoutScene.length > 0 ) this.processObjects( objectsWithoutScene );
|
|
1958
|
-
|
|
1959
1868
|
for ( let i = 0; i < this.skins.length; ++ i ) {
|
|
1960
1869
|
|
|
1961
1870
|
this.processSkin( this.skins[ i ] );
|
|
@@ -1975,7 +1884,6 @@
|
|
|
1975
1884
|
} );
|
|
1976
1885
|
|
|
1977
1886
|
}
|
|
1978
|
-
|
|
1979
1887
|
_invokeAll( func ) {
|
|
1980
1888
|
|
|
1981
1889
|
for ( let i = 0, il = this.plugins.length; i < il; i ++ ) {
|
|
@@ -1987,13 +1895,12 @@
|
|
|
1987
1895
|
}
|
|
1988
1896
|
|
|
1989
1897
|
}
|
|
1898
|
+
|
|
1990
1899
|
/**
|
|
1991
1900
|
* Punctual Lights Extension
|
|
1992
1901
|
*
|
|
1993
1902
|
* Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_lights_punctual
|
|
1994
1903
|
*/
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
1904
|
class GLTFLightExtension {
|
|
1998
1905
|
|
|
1999
1906
|
constructor( writer ) {
|
|
@@ -2002,11 +1909,9 @@
|
|
|
2002
1909
|
this.name = 'KHR_lights_punctual';
|
|
2003
1910
|
|
|
2004
1911
|
}
|
|
2005
|
-
|
|
2006
1912
|
writeNode( light, nodeDef ) {
|
|
2007
1913
|
|
|
2008
1914
|
if ( ! light.isLight ) return;
|
|
2009
|
-
|
|
2010
1915
|
if ( ! light.isDirectionalLight && ! light.isPointLight && ! light.isSpotLight ) {
|
|
2011
1916
|
|
|
2012
1917
|
console.warn( 'THREE.GLTFExporter: Only directional, point, and spot lights are supported.', light );
|
|
@@ -2021,7 +1926,6 @@
|
|
|
2021
1926
|
if ( light.name ) lightDef.name = light.name;
|
|
2022
1927
|
lightDef.color = light.color.toArray();
|
|
2023
1928
|
lightDef.intensity = light.intensity;
|
|
2024
|
-
|
|
2025
1929
|
if ( light.isDirectionalLight ) {
|
|
2026
1930
|
|
|
2027
1931
|
lightDef.type = 'directional';
|
|
@@ -2073,13 +1977,12 @@
|
|
|
2073
1977
|
}
|
|
2074
1978
|
|
|
2075
1979
|
}
|
|
1980
|
+
|
|
2076
1981
|
/**
|
|
2077
1982
|
* Unlit Materials Extension
|
|
2078
1983
|
*
|
|
2079
1984
|
* Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_unlit
|
|
2080
1985
|
*/
|
|
2081
|
-
|
|
2082
|
-
|
|
2083
1986
|
class GLTFMaterialsUnlitExtension {
|
|
2084
1987
|
|
|
2085
1988
|
constructor( writer ) {
|
|
@@ -2088,7 +1991,6 @@
|
|
|
2088
1991
|
this.name = 'KHR_materials_unlit';
|
|
2089
1992
|
|
|
2090
1993
|
}
|
|
2091
|
-
|
|
2092
1994
|
writeMaterial( material, materialDef ) {
|
|
2093
1995
|
|
|
2094
1996
|
if ( ! material.isMeshBasicMaterial ) return;
|
|
@@ -2103,70 +2005,12 @@
|
|
|
2103
2005
|
}
|
|
2104
2006
|
|
|
2105
2007
|
}
|
|
2106
|
-
/**
|
|
2107
|
-
* Specular-Glossiness Extension
|
|
2108
|
-
*
|
|
2109
|
-
* Specification: https://github.com/KhronosGroup/glTF/tree/main/extensions/2.0/Archived/KHR_materials_pbrSpecularGlossiness
|
|
2110
|
-
*/
|
|
2111
|
-
|
|
2112
|
-
|
|
2113
|
-
class GLTFMaterialsPBRSpecularGlossiness {
|
|
2114
|
-
|
|
2115
|
-
constructor( writer ) {
|
|
2116
|
-
|
|
2117
|
-
this.writer = writer;
|
|
2118
|
-
this.name = 'KHR_materials_pbrSpecularGlossiness';
|
|
2119
|
-
|
|
2120
|
-
}
|
|
2121
|
-
|
|
2122
|
-
writeMaterial( material, materialDef ) {
|
|
2123
|
-
|
|
2124
|
-
if ( ! material.isGLTFSpecularGlossinessMaterial ) return;
|
|
2125
|
-
const writer = this.writer;
|
|
2126
|
-
const extensionsUsed = writer.extensionsUsed;
|
|
2127
|
-
const extensionDef = {};
|
|
2128
|
-
|
|
2129
|
-
if ( materialDef.pbrMetallicRoughness.baseColorFactor ) {
|
|
2130
|
-
|
|
2131
|
-
extensionDef.diffuseFactor = materialDef.pbrMetallicRoughness.baseColorFactor;
|
|
2132
|
-
|
|
2133
|
-
}
|
|
2134
2008
|
|
|
2135
|
-
const specularFactor = [ 1, 1, 1 ];
|
|
2136
|
-
material.specular.toArray( specularFactor, 0 );
|
|
2137
|
-
extensionDef.specularFactor = specularFactor;
|
|
2138
|
-
extensionDef.glossinessFactor = material.glossiness;
|
|
2139
|
-
|
|
2140
|
-
if ( materialDef.pbrMetallicRoughness.baseColorTexture ) {
|
|
2141
|
-
|
|
2142
|
-
extensionDef.diffuseTexture = materialDef.pbrMetallicRoughness.baseColorTexture;
|
|
2143
|
-
|
|
2144
|
-
}
|
|
2145
|
-
|
|
2146
|
-
if ( material.specularMap ) {
|
|
2147
|
-
|
|
2148
|
-
const specularMapDef = {
|
|
2149
|
-
index: writer.processTexture( material.specularMap )
|
|
2150
|
-
};
|
|
2151
|
-
writer.applyTextureTransform( specularMapDef, material.specularMap );
|
|
2152
|
-
extensionDef.specularGlossinessTexture = specularMapDef;
|
|
2153
|
-
|
|
2154
|
-
}
|
|
2155
|
-
|
|
2156
|
-
materialDef.extensions = materialDef.extensions || {};
|
|
2157
|
-
materialDef.extensions[ this.name ] = extensionDef;
|
|
2158
|
-
extensionsUsed[ this.name ] = true;
|
|
2159
|
-
|
|
2160
|
-
}
|
|
2161
|
-
|
|
2162
|
-
}
|
|
2163
2009
|
/**
|
|
2164
2010
|
* Clearcoat Materials Extension
|
|
2165
2011
|
*
|
|
2166
2012
|
* Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_clearcoat
|
|
2167
2013
|
*/
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
2014
|
class GLTFMaterialsClearcoatExtension {
|
|
2171
2015
|
|
|
2172
2016
|
constructor( writer ) {
|
|
@@ -2175,7 +2019,6 @@
|
|
|
2175
2019
|
this.name = 'KHR_materials_clearcoat';
|
|
2176
2020
|
|
|
2177
2021
|
}
|
|
2178
|
-
|
|
2179
2022
|
writeMaterial( material, materialDef ) {
|
|
2180
2023
|
|
|
2181
2024
|
if ( ! material.isMeshPhysicalMaterial ) return;
|
|
@@ -2183,7 +2026,6 @@
|
|
|
2183
2026
|
const extensionsUsed = writer.extensionsUsed;
|
|
2184
2027
|
const extensionDef = {};
|
|
2185
2028
|
extensionDef.clearcoatFactor = material.clearcoat;
|
|
2186
|
-
|
|
2187
2029
|
if ( material.clearcoatMap ) {
|
|
2188
2030
|
|
|
2189
2031
|
const clearcoatMapDef = {
|
|
@@ -2195,7 +2037,6 @@
|
|
|
2195
2037
|
}
|
|
2196
2038
|
|
|
2197
2039
|
extensionDef.clearcoatRoughnessFactor = material.clearcoatRoughness;
|
|
2198
|
-
|
|
2199
2040
|
if ( material.clearcoatRoughnessMap ) {
|
|
2200
2041
|
|
|
2201
2042
|
const clearcoatRoughnessMapDef = {
|
|
@@ -2223,13 +2064,12 @@
|
|
|
2223
2064
|
}
|
|
2224
2065
|
|
|
2225
2066
|
}
|
|
2067
|
+
|
|
2226
2068
|
/**
|
|
2227
2069
|
* Iridescence Materials Extension
|
|
2228
2070
|
*
|
|
2229
2071
|
* Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_iridescence
|
|
2230
2072
|
*/
|
|
2231
|
-
|
|
2232
|
-
|
|
2233
2073
|
class GLTFMaterialsIridescenceExtension {
|
|
2234
2074
|
|
|
2235
2075
|
constructor( writer ) {
|
|
@@ -2238,7 +2078,6 @@
|
|
|
2238
2078
|
this.name = 'KHR_materials_iridescence';
|
|
2239
2079
|
|
|
2240
2080
|
}
|
|
2241
|
-
|
|
2242
2081
|
writeMaterial( material, materialDef ) {
|
|
2243
2082
|
|
|
2244
2083
|
if ( ! material.isMeshPhysicalMaterial ) return;
|
|
@@ -2246,7 +2085,6 @@
|
|
|
2246
2085
|
const extensionsUsed = writer.extensionsUsed;
|
|
2247
2086
|
const extensionDef = {};
|
|
2248
2087
|
extensionDef.iridescenceFactor = material.iridescence;
|
|
2249
|
-
|
|
2250
2088
|
if ( material.iridescenceMap ) {
|
|
2251
2089
|
|
|
2252
2090
|
const iridescenceMapDef = {
|
|
@@ -2260,7 +2098,6 @@
|
|
|
2260
2098
|
extensionDef.iridescenceIor = material.iridescenceIOR;
|
|
2261
2099
|
extensionDef.iridescenceThicknessMinimum = material.iridescenceThicknessRange[ 0 ];
|
|
2262
2100
|
extensionDef.iridescenceThicknessMaximum = material.iridescenceThicknessRange[ 1 ];
|
|
2263
|
-
|
|
2264
2101
|
if ( material.iridescenceThicknessMap ) {
|
|
2265
2102
|
|
|
2266
2103
|
const iridescenceThicknessMapDef = {
|
|
@@ -2278,13 +2115,12 @@
|
|
|
2278
2115
|
}
|
|
2279
2116
|
|
|
2280
2117
|
}
|
|
2118
|
+
|
|
2281
2119
|
/**
|
|
2282
2120
|
* Transmission Materials Extension
|
|
2283
2121
|
*
|
|
2284
2122
|
* Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_transmission
|
|
2285
2123
|
*/
|
|
2286
|
-
|
|
2287
|
-
|
|
2288
2124
|
class GLTFMaterialsTransmissionExtension {
|
|
2289
2125
|
|
|
2290
2126
|
constructor( writer ) {
|
|
@@ -2293,7 +2129,6 @@
|
|
|
2293
2129
|
this.name = 'KHR_materials_transmission';
|
|
2294
2130
|
|
|
2295
2131
|
}
|
|
2296
|
-
|
|
2297
2132
|
writeMaterial( material, materialDef ) {
|
|
2298
2133
|
|
|
2299
2134
|
if ( ! material.isMeshPhysicalMaterial || material.transmission === 0 ) return;
|
|
@@ -2301,7 +2136,6 @@
|
|
|
2301
2136
|
const extensionsUsed = writer.extensionsUsed;
|
|
2302
2137
|
const extensionDef = {};
|
|
2303
2138
|
extensionDef.transmissionFactor = material.transmission;
|
|
2304
|
-
|
|
2305
2139
|
if ( material.transmissionMap ) {
|
|
2306
2140
|
|
|
2307
2141
|
const transmissionMapDef = {
|
|
@@ -2319,13 +2153,12 @@
|
|
|
2319
2153
|
}
|
|
2320
2154
|
|
|
2321
2155
|
}
|
|
2156
|
+
|
|
2322
2157
|
/**
|
|
2323
2158
|
* Materials Volume Extension
|
|
2324
2159
|
*
|
|
2325
2160
|
* Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_volume
|
|
2326
2161
|
*/
|
|
2327
|
-
|
|
2328
|
-
|
|
2329
2162
|
class GLTFMaterialsVolumeExtension {
|
|
2330
2163
|
|
|
2331
2164
|
constructor( writer ) {
|
|
@@ -2334,7 +2167,6 @@
|
|
|
2334
2167
|
this.name = 'KHR_materials_volume';
|
|
2335
2168
|
|
|
2336
2169
|
}
|
|
2337
|
-
|
|
2338
2170
|
writeMaterial( material, materialDef ) {
|
|
2339
2171
|
|
|
2340
2172
|
if ( ! material.isMeshPhysicalMaterial || material.transmission === 0 ) return;
|
|
@@ -2342,7 +2174,6 @@
|
|
|
2342
2174
|
const extensionsUsed = writer.extensionsUsed;
|
|
2343
2175
|
const extensionDef = {};
|
|
2344
2176
|
extensionDef.thicknessFactor = material.thickness;
|
|
2345
|
-
|
|
2346
2177
|
if ( material.thicknessMap ) {
|
|
2347
2178
|
|
|
2348
2179
|
const thicknessMapDef = {
|
|
@@ -2362,26 +2193,22 @@
|
|
|
2362
2193
|
}
|
|
2363
2194
|
|
|
2364
2195
|
}
|
|
2196
|
+
|
|
2365
2197
|
/**
|
|
2366
2198
|
* Static utility functions
|
|
2367
2199
|
*/
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
2200
|
GLTFExporter.Utils = {
|
|
2371
2201
|
insertKeyframe: function ( track, time ) {
|
|
2372
2202
|
|
|
2373
2203
|
const tolerance = 0.001; // 1ms
|
|
2374
|
-
|
|
2375
2204
|
const valueSize = track.getValueSize();
|
|
2376
2205
|
const times = new track.TimeBufferType( track.times.length + 1 );
|
|
2377
2206
|
const values = new track.ValueBufferType( track.values.length + valueSize );
|
|
2378
2207
|
const interpolant = track.createInterpolant( new track.ValueBufferType( valueSize ) );
|
|
2379
2208
|
let index;
|
|
2380
|
-
|
|
2381
2209
|
if ( track.times.length === 0 ) {
|
|
2382
2210
|
|
|
2383
2211
|
times[ 0 ] = time;
|
|
2384
|
-
|
|
2385
2212
|
for ( let i = 0; i < valueSize; i ++ ) {
|
|
2386
2213
|
|
|
2387
2214
|
values[ i ] = 0;
|
|
@@ -2418,7 +2245,6 @@
|
|
|
2418
2245
|
for ( let i = 0; i < track.times.length; i ++ ) {
|
|
2419
2246
|
|
|
2420
2247
|
if ( Math.abs( track.times[ i ] - time ) < tolerance ) return i;
|
|
2421
|
-
|
|
2422
2248
|
if ( track.times[ i ] < time && track.times[ i + 1 ] > time ) {
|
|
2423
2249
|
|
|
2424
2250
|
times.set( track.times.slice( 0, i + 1 ), 0 );
|
|
@@ -2446,13 +2272,11 @@
|
|
|
2446
2272
|
const tracks = [];
|
|
2447
2273
|
const mergedTracks = {};
|
|
2448
2274
|
const sourceTracks = clip.tracks;
|
|
2449
|
-
|
|
2450
2275
|
for ( let i = 0; i < sourceTracks.length; ++ i ) {
|
|
2451
2276
|
|
|
2452
2277
|
let sourceTrack = sourceTracks[ i ];
|
|
2453
2278
|
const sourceTrackBinding = THREE.PropertyBinding.parseTrackName( sourceTrack.name );
|
|
2454
2279
|
const sourceTrackNode = THREE.PropertyBinding.findNode( root, sourceTrackBinding.nodeName );
|
|
2455
|
-
|
|
2456
2280
|
if ( sourceTrackBinding.propertyName !== 'morphTargetInfluences' || sourceTrackBinding.propertyIndex === undefined ) {
|
|
2457
2281
|
|
|
2458
2282
|
// Tracks that don't affect morph targets, or that affect all morph targets together, can be left as-is.
|
|
@@ -2479,29 +2303,28 @@
|
|
|
2479
2303
|
|
|
2480
2304
|
const targetCount = sourceTrackNode.morphTargetInfluences.length;
|
|
2481
2305
|
const targetIndex = sourceTrackNode.morphTargetDictionary[ sourceTrackBinding.propertyIndex ];
|
|
2482
|
-
|
|
2483
2306
|
if ( targetIndex === undefined ) {
|
|
2484
2307
|
|
|
2485
2308
|
throw new Error( 'THREE.GLTFExporter: Morph target name not found: ' + sourceTrackBinding.propertyIndex );
|
|
2486
2309
|
|
|
2487
2310
|
}
|
|
2488
2311
|
|
|
2489
|
-
let mergedTrack;
|
|
2490
|
-
// track to store merged keyframe data for each morph target.
|
|
2312
|
+
let mergedTrack;
|
|
2491
2313
|
|
|
2314
|
+
// If this is the first time we've seen this object, create a new
|
|
2315
|
+
// track to store merged keyframe data for each morph target.
|
|
2492
2316
|
if ( mergedTracks[ sourceTrackNode.uuid ] === undefined ) {
|
|
2493
2317
|
|
|
2494
2318
|
mergedTrack = sourceTrack.clone();
|
|
2495
2319
|
const values = new mergedTrack.ValueBufferType( targetCount * mergedTrack.times.length );
|
|
2496
|
-
|
|
2497
2320
|
for ( let j = 0; j < mergedTrack.times.length; j ++ ) {
|
|
2498
2321
|
|
|
2499
2322
|
values[ j * targetCount + targetIndex ] = mergedTrack.values[ j ];
|
|
2500
2323
|
|
|
2501
|
-
}
|
|
2502
|
-
// of our original un-merged morphTarget animation.
|
|
2503
|
-
|
|
2324
|
+
}
|
|
2504
2325
|
|
|
2326
|
+
// We need to take into consideration the intended target node
|
|
2327
|
+
// of our original un-merged morphTarget animation.
|
|
2505
2328
|
mergedTrack.name = ( sourceTrackBinding.nodeName || '' ) + '.morphTargetInfluences';
|
|
2506
2329
|
mergedTrack.values = values;
|
|
2507
2330
|
mergedTracks[ sourceTrackNode.uuid ] = mergedTrack;
|
|
@@ -2511,18 +2334,19 @@
|
|
|
2511
2334
|
}
|
|
2512
2335
|
|
|
2513
2336
|
const sourceInterpolant = sourceTrack.createInterpolant( new sourceTrack.ValueBufferType( 1 ) );
|
|
2514
|
-
mergedTrack = mergedTracks[ sourceTrackNode.uuid ];
|
|
2515
|
-
// interpolated) value from the source track.
|
|
2337
|
+
mergedTrack = mergedTracks[ sourceTrackNode.uuid ];
|
|
2516
2338
|
|
|
2339
|
+
// For every existing keyframe of the merged track, write a (possibly
|
|
2340
|
+
// interpolated) value from the source track.
|
|
2517
2341
|
for ( let j = 0; j < mergedTrack.times.length; j ++ ) {
|
|
2518
2342
|
|
|
2519
2343
|
mergedTrack.values[ j * targetCount + targetIndex ] = sourceInterpolant.evaluate( mergedTrack.times[ j ] );
|
|
2520
2344
|
|
|
2521
|
-
}
|
|
2345
|
+
}
|
|
2346
|
+
|
|
2347
|
+
// For every existing keyframe of the source track, write a (possibly
|
|
2522
2348
|
// new) keyframe to the merged track. Values from the previous loop may
|
|
2523
2349
|
// be written again, but keyframes are de-duplicated.
|
|
2524
|
-
|
|
2525
|
-
|
|
2526
2350
|
for ( let j = 0; j < sourceTrack.times.length; j ++ ) {
|
|
2527
2351
|
|
|
2528
2352
|
const keyframeIndex = this.insertKeyframe( mergedTrack, sourceTrack.times[ j ] );
|