@needle-tools/three 0.145.4 → 0.146.2
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 +32586 -35951
- package/build/three.js +32600 -35965
- package/build/three.min.js +6 -7
- package/build/three.module.js +1547 -1154
- package/examples/js/animation/AnimationClipCreator.js +0 -8
- package/examples/js/animation/CCDIKSolver.js +49 -66
- 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 +85 -95
- package/examples/js/controls/PointerLockControls.js +5 -14
- package/examples/js/controls/TrackballControls.js +33 -86
- package/examples/js/controls/TransformControls.js +84 -169
- 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 +143 -261
- 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 +110 -25
- 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 +22 -33
- package/examples/js/interactive/InteractiveGroup.js +6 -12
- 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 +38 -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 +201 -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 +286 -441
- package/examples/js/loaders/FontLoader.js +6 -15
- package/examples/js/loaders/GCodeLoader.js +15 -16
- package/examples/js/loaders/GLTFLoader.js +354 -405
- 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/MaterialXLoader.js +392 -0
- 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 +9 -39
- 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 +183 -139
- 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 +14 -18
- 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/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 -6
- 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 +234 -168
- 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 +1 -1
- package/examples/jsm/capabilities/WebGPU.js +3 -1
- package/examples/jsm/controls/OrbitControls.js +44 -4
- package/examples/jsm/exporters/GLTFExporter.js +17 -131
- package/examples/jsm/exporters/USDZExporter.js +75 -19
- package/examples/jsm/interactive/HTMLMesh.js +2 -0
- package/examples/jsm/libs/lottie_canvas.module.js +14844 -0
- package/examples/jsm/loaders/3DMLoader.js +1 -2
- package/examples/jsm/loaders/ColladaLoader.js +28 -0
- package/examples/jsm/loaders/FBXLoader.js +16 -2
- package/examples/jsm/loaders/GLTFLoader.js +204 -377
- 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 +31 -16
- package/examples/jsm/nodes/Nodes.js +14 -2
- 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 +1 -1
- package/examples/jsm/nodes/core/Node.js +1 -1
- package/examples/jsm/nodes/core/NodeBuilder.js +36 -4
- 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/PosterizeNode.js +25 -0
- package/examples/jsm/nodes/display/ViewportNode.js +106 -0
- 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/MaterialXNodes.js +6 -2
- package/examples/jsm/nodes/materialx/lib/mx_transform_color.js +18 -0
- package/examples/jsm/nodes/math/MathNode.js +5 -0
- package/examples/jsm/nodes/math/OperatorNode.js +6 -1
- package/examples/jsm/nodes/shadernode/ShaderNode.js +26 -13
- package/examples/jsm/nodes/shadernode/ShaderNodeBaseElements.js +2 -0
- package/examples/jsm/nodes/shadernode/ShaderNodeElements.js +18 -0
- 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/SpriteSheetUVNode.js +8 -10
- package/examples/jsm/nodes/utils/TimerNode.js +1 -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 +10 -0
- 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 +39 -16
- 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 +35 -5
- package/examples/jsm/shaders/MMDToonShader.js +0 -2
- package/examples/jsm/shaders/VelocityShader.js +128 -0
- package/examples/jsm/utils/BufferGeometryUtils.js +130 -6
- package/examples/jsm/utils/SceneUtils.js +129 -4
- package/examples/jsm/utils/TextureUtils.js +85 -0
- package/examples/jsm/webxr/OculusHandModel.js +1 -1
- package/examples/jsm/webxr/XRHandMeshModel.js +6 -3
- package/package.json +11 -12
- package/src/Three.js +1 -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/extras/Earcut.js +67 -67
- package/src/helpers/DirectionalLightHelper.js +5 -1
- package/src/helpers/HemisphereLightHelper.js +4 -1
- package/src/helpers/PointLightHelper.js +2 -1
- package/src/helpers/SpotLightHelper.js +4 -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/math/Color.js +5 -5
- package/src/math/Matrix3.js +53 -18
- package/src/math/Ray.js +2 -5
- package/src/math/Sphere.js +19 -26
- 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/packing.glsl.js +8 -0
- 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.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 +31 -1
- package/src/renderers/webgl/WebGLTextures.js +71 -18
- package/src/renderers/webgl/WebGLUniforms.js +116 -20
- package/src/renderers/webgl/WebGLUtils.js +1 -1
- package/src/renderers/webxr/WebXRController.js +46 -13
- package/src/renderers/webxr/WebXRManager.js +85 -3
- package/src/scenes/Scene.js +8 -0
- package/src/textures/CompressedArrayTexture.js +18 -0
- 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
|
@@ -42,7 +42,6 @@
|
|
|
42
42
|
} );
|
|
43
43
|
|
|
44
44
|
}
|
|
45
|
-
|
|
46
45
|
register( callback ) {
|
|
47
46
|
|
|
48
47
|
if ( this.pluginCallbacks.indexOf( callback ) === - 1 ) {
|
|
@@ -54,7 +53,6 @@
|
|
|
54
53
|
return this;
|
|
55
54
|
|
|
56
55
|
}
|
|
57
|
-
|
|
58
56
|
unregister( callback ) {
|
|
59
57
|
|
|
60
58
|
if ( this.pluginCallbacks.indexOf( callback ) !== - 1 ) {
|
|
@@ -66,6 +64,7 @@
|
|
|
66
64
|
return this;
|
|
67
65
|
|
|
68
66
|
}
|
|
67
|
+
|
|
69
68
|
/**
|
|
70
69
|
* Parse scenes and generate GLTF output
|
|
71
70
|
* @param {Scene or [THREE.Scenes]} input THREE.Scene or Array of THREE.Scenes
|
|
@@ -73,13 +72,10 @@
|
|
|
73
72
|
* @param {Function} onError Callback on errors
|
|
74
73
|
* @param {Object} options options
|
|
75
74
|
*/
|
|
76
|
-
|
|
77
|
-
|
|
78
75
|
parse( input, onDone, onError, options ) {
|
|
79
76
|
|
|
80
77
|
const writer = new GLTFWriter();
|
|
81
78
|
const plugins = [];
|
|
82
|
-
|
|
83
79
|
for ( let i = 0, il = this.pluginCallbacks.length; i < il; i ++ ) {
|
|
84
80
|
|
|
85
81
|
plugins.push( this.pluginCallbacks[ i ]( writer ) );
|
|
@@ -90,7 +86,6 @@
|
|
|
90
86
|
writer.write( input, onDone, options ).catch( onError );
|
|
91
87
|
|
|
92
88
|
}
|
|
93
|
-
|
|
94
89
|
parseAsync( input, options ) {
|
|
95
90
|
|
|
96
91
|
const scope = this;
|
|
@@ -102,11 +97,12 @@
|
|
|
102
97
|
|
|
103
98
|
}
|
|
104
99
|
|
|
105
|
-
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
//------------------------------------------------------------------------------
|
|
106
103
|
// Constants
|
|
107
104
|
//------------------------------------------------------------------------------
|
|
108
105
|
|
|
109
|
-
|
|
110
106
|
const WEBGL_CONSTANTS = {
|
|
111
107
|
POINTS: 0x0000,
|
|
112
108
|
LINES: 0x0001,
|
|
@@ -146,7 +142,9 @@
|
|
|
146
142
|
position: 'translation',
|
|
147
143
|
quaternion: 'rotation',
|
|
148
144
|
morphTargetInfluences: 'weights'
|
|
149
|
-
};
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
// GLB constants
|
|
150
148
|
// https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#glb-file-format-specification
|
|
151
149
|
|
|
152
150
|
const GLB_HEADER_BYTES = 12;
|
|
@@ -154,7 +152,9 @@
|
|
|
154
152
|
const GLB_VERSION = 2;
|
|
155
153
|
const GLB_CHUNK_PREFIX_BYTES = 8;
|
|
156
154
|
const GLB_CHUNK_TYPE_JSON = 0x4E4F534A;
|
|
157
|
-
const GLB_CHUNK_TYPE_BIN = 0x004E4942;
|
|
155
|
+
const GLB_CHUNK_TYPE_BIN = 0x004E4942;
|
|
156
|
+
|
|
157
|
+
//------------------------------------------------------------------------------
|
|
158
158
|
// Utility functions
|
|
159
159
|
//------------------------------------------------------------------------------
|
|
160
160
|
|
|
@@ -164,7 +164,6 @@
|
|
|
164
164
|
* @param {Array} array2 Array 2 to compare
|
|
165
165
|
* @return {Boolean} Returns true if both arrays are equal
|
|
166
166
|
*/
|
|
167
|
-
|
|
168
167
|
function equalArray( array1, array2 ) {
|
|
169
168
|
|
|
170
169
|
return array1.length === array2.length && array1.every( function ( element, index ) {
|
|
@@ -174,31 +173,30 @@
|
|
|
174
173
|
} );
|
|
175
174
|
|
|
176
175
|
}
|
|
176
|
+
|
|
177
177
|
/**
|
|
178
178
|
* Converts a string to an ArrayBuffer.
|
|
179
179
|
* @param {string} text
|
|
180
180
|
* @return {ArrayBuffer}
|
|
181
181
|
*/
|
|
182
|
-
|
|
183
|
-
|
|
184
182
|
function stringToArrayBuffer( text ) {
|
|
185
183
|
|
|
186
184
|
return new TextEncoder().encode( text ).buffer;
|
|
187
185
|
|
|
188
186
|
}
|
|
187
|
+
|
|
189
188
|
/**
|
|
190
189
|
* Is identity matrix
|
|
191
190
|
*
|
|
192
191
|
* @param {Matrix4} matrix
|
|
193
192
|
* @returns {Boolean} Returns true, if parameter is identity matrix
|
|
194
193
|
*/
|
|
195
|
-
|
|
196
|
-
|
|
197
194
|
function isIdentityMatrix( matrix ) {
|
|
198
195
|
|
|
199
196
|
return equalArray( matrix.elements, [ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 ] );
|
|
200
197
|
|
|
201
198
|
}
|
|
199
|
+
|
|
202
200
|
/**
|
|
203
201
|
* Get the min and max vectors from the given attribute
|
|
204
202
|
* @param {BufferAttribute} attribute Attribute to find the min/max in range from start to start + count
|
|
@@ -206,24 +204,21 @@
|
|
|
206
204
|
* @param {Integer} count
|
|
207
205
|
* @return {Object} Object containing the `min` and `max` values (As an array of attribute.itemSize components)
|
|
208
206
|
*/
|
|
209
|
-
|
|
210
|
-
|
|
211
207
|
function getMinMax( attribute, start, count ) {
|
|
212
208
|
|
|
213
209
|
const output = {
|
|
214
210
|
min: new Array( attribute.itemSize ).fill( Number.POSITIVE_INFINITY ),
|
|
215
211
|
max: new Array( attribute.itemSize ).fill( Number.NEGATIVE_INFINITY )
|
|
216
212
|
};
|
|
217
|
-
|
|
218
213
|
for ( let i = start; i < start + count; i ++ ) {
|
|
219
214
|
|
|
220
215
|
for ( let a = 0; a < attribute.itemSize; a ++ ) {
|
|
221
216
|
|
|
222
217
|
let value;
|
|
223
|
-
|
|
224
218
|
if ( attribute.itemSize > 4 ) {
|
|
225
219
|
|
|
226
220
|
// no support for interleaved data for itemSize > 4
|
|
221
|
+
|
|
227
222
|
value = attribute.array[ i * attribute.itemSize + a ];
|
|
228
223
|
|
|
229
224
|
} else {
|
|
@@ -242,6 +237,7 @@
|
|
|
242
237
|
return output;
|
|
243
238
|
|
|
244
239
|
}
|
|
240
|
+
|
|
245
241
|
/**
|
|
246
242
|
* Get the required size + padding for a buffer, rounded to the next 4-byte boundary.
|
|
247
243
|
* https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#data-alignment
|
|
@@ -250,13 +246,12 @@
|
|
|
250
246
|
* @returns {Integer} new buffer size with required padding.
|
|
251
247
|
*
|
|
252
248
|
*/
|
|
253
|
-
|
|
254
|
-
|
|
255
249
|
function getPaddedBufferSize( bufferSize ) {
|
|
256
250
|
|
|
257
251
|
return Math.ceil( bufferSize / 4 ) * 4;
|
|
258
252
|
|
|
259
253
|
}
|
|
254
|
+
|
|
260
255
|
/**
|
|
261
256
|
* Returns a buffer aligned to 4-byte boundary.
|
|
262
257
|
*
|
|
@@ -264,17 +259,13 @@
|
|
|
264
259
|
* @param {Integer} paddingByte (Optional)
|
|
265
260
|
* @returns {ArrayBuffer} The same buffer if it's already aligned to 4-byte boundary or a new buffer
|
|
266
261
|
*/
|
|
267
|
-
|
|
268
|
-
|
|
269
262
|
function getPaddedArrayBuffer( arrayBuffer, paddingByte = 0 ) {
|
|
270
263
|
|
|
271
264
|
const paddedLength = getPaddedBufferSize( arrayBuffer.byteLength );
|
|
272
|
-
|
|
273
265
|
if ( paddedLength !== arrayBuffer.byteLength ) {
|
|
274
266
|
|
|
275
267
|
const array = new Uint8Array( paddedLength );
|
|
276
268
|
array.set( new Uint8Array( arrayBuffer ) );
|
|
277
|
-
|
|
278
269
|
if ( paddingByte !== 0 ) {
|
|
279
270
|
|
|
280
271
|
for ( let i = arrayBuffer.byteLength; i < paddedLength; i ++ ) {
|
|
@@ -313,9 +304,10 @@
|
|
|
313
304
|
|
|
314
305
|
}
|
|
315
306
|
|
|
316
|
-
let quality;
|
|
317
|
-
// Use the Blink default quality levels of toBlob instead so that file sizes are comparable.
|
|
307
|
+
let quality;
|
|
318
308
|
|
|
309
|
+
// Blink's implementation of convertToBlob seems to default to a quality level of 100%
|
|
310
|
+
// Use the Blink default quality levels of toBlob instead so that file sizes are comparable.
|
|
319
311
|
if ( mimeType === 'image/jpeg' ) {
|
|
320
312
|
|
|
321
313
|
quality = 0.92;
|
|
@@ -332,11 +324,10 @@
|
|
|
332
324
|
} );
|
|
333
325
|
|
|
334
326
|
}
|
|
327
|
+
|
|
335
328
|
/**
|
|
336
329
|
* Writer
|
|
337
330
|
*/
|
|
338
|
-
|
|
339
|
-
|
|
340
331
|
class GLTFWriter {
|
|
341
332
|
|
|
342
333
|
constructor() {
|
|
@@ -368,20 +359,18 @@
|
|
|
368
359
|
};
|
|
369
360
|
|
|
370
361
|
}
|
|
371
|
-
|
|
372
362
|
setPlugins( plugins ) {
|
|
373
363
|
|
|
374
364
|
this.plugins = plugins;
|
|
375
365
|
|
|
376
366
|
}
|
|
367
|
+
|
|
377
368
|
/**
|
|
378
369
|
* Parse scenes and generate GLTF output
|
|
379
370
|
* @param {Scene or [THREE.Scenes]} input THREE.Scene or Array of THREE.Scenes
|
|
380
371
|
* @param {Function} onDone Callback on completed
|
|
381
372
|
* @param {Object} options options
|
|
382
373
|
*/
|
|
383
|
-
|
|
384
|
-
|
|
385
374
|
async write( input, onDone, options ) {
|
|
386
375
|
|
|
387
376
|
this.options = Object.assign( {}, {
|
|
@@ -389,12 +378,10 @@
|
|
|
389
378
|
binary: false,
|
|
390
379
|
trs: false,
|
|
391
380
|
onlyVisible: true,
|
|
392
|
-
truncateDrawRange: true,
|
|
393
381
|
maxTextureSize: Infinity,
|
|
394
382
|
animations: [],
|
|
395
383
|
includeCustomExtensions: false
|
|
396
384
|
}, options );
|
|
397
|
-
|
|
398
385
|
if ( this.options.animations.length > 0 ) {
|
|
399
386
|
|
|
400
387
|
// Only TRS properties, and not matrices, may be targeted by animation.
|
|
@@ -408,36 +395,40 @@
|
|
|
408
395
|
const buffers = writer.buffers;
|
|
409
396
|
const json = writer.json;
|
|
410
397
|
options = writer.options;
|
|
411
|
-
const extensionsUsed = writer.extensionsUsed;
|
|
398
|
+
const extensionsUsed = writer.extensionsUsed;
|
|
412
399
|
|
|
400
|
+
// Merge buffers.
|
|
413
401
|
const blob = new Blob( buffers, {
|
|
414
402
|
type: 'application/octet-stream'
|
|
415
|
-
} );
|
|
403
|
+
} );
|
|
416
404
|
|
|
405
|
+
// Declare extensions.
|
|
417
406
|
const extensionsUsedList = Object.keys( extensionsUsed );
|
|
418
|
-
if ( extensionsUsedList.length > 0 ) json.extensionsUsed = extensionsUsedList;
|
|
407
|
+
if ( extensionsUsedList.length > 0 ) json.extensionsUsed = extensionsUsedList;
|
|
419
408
|
|
|
409
|
+
// Update bytelength of the single buffer.
|
|
420
410
|
if ( json.buffers && json.buffers.length > 0 ) json.buffers[ 0 ].byteLength = blob.size;
|
|
421
|
-
|
|
422
411
|
if ( options.binary === true ) {
|
|
423
412
|
|
|
424
413
|
// https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#glb-file-format-specification
|
|
414
|
+
|
|
425
415
|
const reader = new FileReader();
|
|
426
416
|
reader.readAsArrayBuffer( blob );
|
|
427
|
-
|
|
428
417
|
reader.onloadend = function () {
|
|
429
418
|
|
|
430
419
|
// Binary chunk.
|
|
431
420
|
const binaryChunk = getPaddedArrayBuffer( reader.result );
|
|
432
421
|
const binaryChunkPrefix = new DataView( new ArrayBuffer( GLB_CHUNK_PREFIX_BYTES ) );
|
|
433
422
|
binaryChunkPrefix.setUint32( 0, binaryChunk.byteLength, true );
|
|
434
|
-
binaryChunkPrefix.setUint32( 4, GLB_CHUNK_TYPE_BIN, true );
|
|
423
|
+
binaryChunkPrefix.setUint32( 4, GLB_CHUNK_TYPE_BIN, true );
|
|
435
424
|
|
|
425
|
+
// JSON chunk.
|
|
436
426
|
const jsonChunk = getPaddedArrayBuffer( stringToArrayBuffer( JSON.stringify( json ) ), 0x20 );
|
|
437
427
|
const jsonChunkPrefix = new DataView( new ArrayBuffer( GLB_CHUNK_PREFIX_BYTES ) );
|
|
438
428
|
jsonChunkPrefix.setUint32( 0, jsonChunk.byteLength, true );
|
|
439
|
-
jsonChunkPrefix.setUint32( 4, GLB_CHUNK_TYPE_JSON, true );
|
|
429
|
+
jsonChunkPrefix.setUint32( 4, GLB_CHUNK_TYPE_JSON, true );
|
|
440
430
|
|
|
431
|
+
// GLB header.
|
|
441
432
|
const header = new ArrayBuffer( GLB_HEADER_BYTES );
|
|
442
433
|
const headerView = new DataView( header );
|
|
443
434
|
headerView.setUint32( 0, GLB_HEADER_MAGIC, true );
|
|
@@ -449,7 +440,6 @@
|
|
|
449
440
|
} );
|
|
450
441
|
const glbReader = new FileReader();
|
|
451
442
|
glbReader.readAsArrayBuffer( glbBlob );
|
|
452
|
-
|
|
453
443
|
glbReader.onloadend = function () {
|
|
454
444
|
|
|
455
445
|
onDone( glbReader.result );
|
|
@@ -464,7 +454,6 @@
|
|
|
464
454
|
|
|
465
455
|
const reader = new FileReader();
|
|
466
456
|
reader.readAsDataURL( blob );
|
|
467
|
-
|
|
468
457
|
reader.onloadend = function () {
|
|
469
458
|
|
|
470
459
|
const base64data = reader.result;
|
|
@@ -482,28 +471,24 @@
|
|
|
482
471
|
}
|
|
483
472
|
|
|
484
473
|
}
|
|
474
|
+
|
|
485
475
|
/**
|
|
486
476
|
* Serializes a userData.
|
|
487
477
|
*
|
|
488
478
|
* @param {THREE.Object3D|THREE.Material} object
|
|
489
479
|
* @param {Object} objectDef
|
|
490
480
|
*/
|
|
491
|
-
|
|
492
|
-
|
|
493
481
|
serializeUserData( object, objectDef ) {
|
|
494
482
|
|
|
495
483
|
if ( Object.keys( object.userData ).length === 0 ) return;
|
|
496
484
|
const options = this.options;
|
|
497
485
|
const extensionsUsed = this.extensionsUsed;
|
|
498
|
-
|
|
499
486
|
try {
|
|
500
487
|
|
|
501
488
|
const json = JSON.parse( JSON.stringify( object.userData ) );
|
|
502
|
-
|
|
503
489
|
if ( options.includeCustomExtensions && json.gltfExtensions ) {
|
|
504
490
|
|
|
505
491
|
if ( objectDef.extensions === undefined ) objectDef.extensions = {};
|
|
506
|
-
|
|
507
492
|
for ( const extensionName in json.gltfExtensions ) {
|
|
508
493
|
|
|
509
494
|
objectDef.extensions[ extensionName ] = json.gltfExtensions[ extensionName ];
|
|
@@ -524,13 +509,12 @@
|
|
|
524
509
|
}
|
|
525
510
|
|
|
526
511
|
}
|
|
512
|
+
|
|
527
513
|
/**
|
|
528
514
|
* Returns ids for buffer attributes.
|
|
529
515
|
* @param {Object} object
|
|
530
516
|
* @return {Integer}
|
|
531
517
|
*/
|
|
532
|
-
|
|
533
|
-
|
|
534
518
|
getUID( attribute, isRelativeCopy = false ) {
|
|
535
519
|
|
|
536
520
|
if ( this.uids.has( attribute ) === false ) {
|
|
@@ -546,20 +530,18 @@
|
|
|
546
530
|
return uids.get( isRelativeCopy );
|
|
547
531
|
|
|
548
532
|
}
|
|
533
|
+
|
|
549
534
|
/**
|
|
550
535
|
* Checks if normal attribute values are normalized.
|
|
551
536
|
*
|
|
552
537
|
* @param {BufferAttribute} normal
|
|
553
538
|
* @returns {Boolean}
|
|
554
539
|
*/
|
|
555
|
-
|
|
556
|
-
|
|
557
540
|
isNormalizedNormalAttribute( normal ) {
|
|
558
541
|
|
|
559
542
|
const cache = this.cache;
|
|
560
543
|
if ( cache.attributesNormalized.has( normal ) ) return false;
|
|
561
544
|
const v = new THREE.Vector3();
|
|
562
|
-
|
|
563
545
|
for ( let i = 0, il = normal.count; i < il; i ++ ) {
|
|
564
546
|
|
|
565
547
|
// 0.0005 is from glTF-validator
|
|
@@ -570,6 +552,7 @@
|
|
|
570
552
|
return true;
|
|
571
553
|
|
|
572
554
|
}
|
|
555
|
+
|
|
573
556
|
/**
|
|
574
557
|
* Creates normalized normal buffer attribute.
|
|
575
558
|
*
|
|
@@ -577,19 +560,15 @@
|
|
|
577
560
|
* @returns {BufferAttribute}
|
|
578
561
|
*
|
|
579
562
|
*/
|
|
580
|
-
|
|
581
|
-
|
|
582
563
|
createNormalizedNormalAttribute( normal ) {
|
|
583
564
|
|
|
584
565
|
const cache = this.cache;
|
|
585
566
|
if ( cache.attributesNormalized.has( normal ) ) return cache.attributesNormalized.get( normal );
|
|
586
567
|
const attribute = normal.clone();
|
|
587
568
|
const v = new THREE.Vector3();
|
|
588
|
-
|
|
589
569
|
for ( let i = 0, il = attribute.count; i < il; i ++ ) {
|
|
590
570
|
|
|
591
571
|
v.fromBufferAttribute( attribute, i );
|
|
592
|
-
|
|
593
572
|
if ( v.x === 0 && v.y === 0 && v.z === 0 ) {
|
|
594
573
|
|
|
595
574
|
// if values can't be normalized set (1, 0, 0)
|
|
@@ -609,6 +588,7 @@
|
|
|
609
588
|
return attribute;
|
|
610
589
|
|
|
611
590
|
}
|
|
591
|
+
|
|
612
592
|
/**
|
|
613
593
|
* Applies a texture transform, if present, to the map definition. Requires
|
|
614
594
|
* the KHR_texture_transform extension.
|
|
@@ -616,13 +596,10 @@
|
|
|
616
596
|
* @param {Object} mapDef
|
|
617
597
|
* @param {THREE.Texture} texture
|
|
618
598
|
*/
|
|
619
|
-
|
|
620
|
-
|
|
621
599
|
applyTextureTransform( mapDef, texture ) {
|
|
622
600
|
|
|
623
601
|
let didTransform = false;
|
|
624
602
|
const transformDef = {};
|
|
625
|
-
|
|
626
603
|
if ( texture.offset.x !== 0 || texture.offset.y !== 0 ) {
|
|
627
604
|
|
|
628
605
|
transformDef.offset = texture.offset.toArray();
|
|
@@ -653,11 +630,9 @@
|
|
|
653
630
|
}
|
|
654
631
|
|
|
655
632
|
}
|
|
656
|
-
|
|
657
633
|
buildMetalRoughTexture( metalnessMap, roughnessMap ) {
|
|
658
634
|
|
|
659
635
|
if ( metalnessMap === roughnessMap ) return metalnessMap;
|
|
660
|
-
|
|
661
636
|
function getEncodingConversion( map ) {
|
|
662
637
|
|
|
663
638
|
if ( map.encoding === THREE.sRGBEncoding ) {
|
|
@@ -690,13 +665,11 @@
|
|
|
690
665
|
context.fillStyle = '#00ffff';
|
|
691
666
|
context.fillRect( 0, 0, width, height );
|
|
692
667
|
const composite = context.getImageData( 0, 0, width, height );
|
|
693
|
-
|
|
694
668
|
if ( metalness ) {
|
|
695
669
|
|
|
696
670
|
context.drawImage( metalness, 0, 0, width, height );
|
|
697
671
|
const convert = getEncodingConversion( metalnessMap );
|
|
698
672
|
const data = context.getImageData( 0, 0, width, height ).data;
|
|
699
|
-
|
|
700
673
|
for ( let i = 2; i < data.length; i += 4 ) {
|
|
701
674
|
|
|
702
675
|
composite.data[ i ] = convert( data[ i ] / 256 ) * 256;
|
|
@@ -710,7 +683,6 @@
|
|
|
710
683
|
context.drawImage( roughness, 0, 0, width, height );
|
|
711
684
|
const convert = getEncodingConversion( roughnessMap );
|
|
712
685
|
const data = context.getImageData( 0, 0, width, height ).data;
|
|
713
|
-
|
|
714
686
|
for ( let i = 1; i < data.length; i += 4 ) {
|
|
715
687
|
|
|
716
688
|
composite.data[ i ] = convert( data[ i ] / 256 ) * 256;
|
|
@@ -719,7 +691,9 @@
|
|
|
719
691
|
|
|
720
692
|
}
|
|
721
693
|
|
|
722
|
-
context.putImageData( composite, 0, 0 );
|
|
694
|
+
context.putImageData( composite, 0, 0 );
|
|
695
|
+
|
|
696
|
+
//
|
|
723
697
|
|
|
724
698
|
const reference = metalnessMap || roughnessMap;
|
|
725
699
|
const texture = reference.clone();
|
|
@@ -728,25 +702,26 @@
|
|
|
728
702
|
return texture;
|
|
729
703
|
|
|
730
704
|
}
|
|
705
|
+
|
|
731
706
|
/**
|
|
732
707
|
* Process a buffer to append to the default one.
|
|
733
708
|
* @param {ArrayBuffer} buffer
|
|
734
709
|
* @return {Integer}
|
|
735
710
|
*/
|
|
736
|
-
|
|
737
|
-
|
|
738
711
|
processBuffer( buffer ) {
|
|
739
712
|
|
|
740
713
|
const json = this.json;
|
|
741
714
|
const buffers = this.buffers;
|
|
742
715
|
if ( ! json.buffers ) json.buffers = [ {
|
|
743
716
|
byteLength: 0
|
|
744
|
-
} ];
|
|
717
|
+
} ];
|
|
745
718
|
|
|
719
|
+
// All buffers are merged before export.
|
|
746
720
|
buffers.push( buffer );
|
|
747
721
|
return 0;
|
|
748
722
|
|
|
749
723
|
}
|
|
724
|
+
|
|
750
725
|
/**
|
|
751
726
|
* Process and generate a BufferView
|
|
752
727
|
* @param {BufferAttribute} attribute
|
|
@@ -756,15 +731,14 @@
|
|
|
756
731
|
* @param {number} target (Optional) Target usage of the BufferView
|
|
757
732
|
* @return {Object}
|
|
758
733
|
*/
|
|
759
|
-
|
|
760
|
-
|
|
761
734
|
processBufferView( attribute, componentType, start, count, target ) {
|
|
762
735
|
|
|
763
736
|
const json = this.json;
|
|
764
|
-
if ( ! json.bufferViews ) json.bufferViews = [];
|
|
737
|
+
if ( ! json.bufferViews ) json.bufferViews = [];
|
|
765
738
|
|
|
766
|
-
|
|
739
|
+
// Create a new dataview and dump the attribute's array into it
|
|
767
740
|
|
|
741
|
+
let componentSize;
|
|
768
742
|
if ( componentType === WEBGL_CONSTANTS.UNSIGNED_BYTE ) {
|
|
769
743
|
|
|
770
744
|
componentSize = 1;
|
|
@@ -782,16 +756,15 @@
|
|
|
782
756
|
const byteLength = getPaddedBufferSize( count * attribute.itemSize * componentSize );
|
|
783
757
|
const dataView = new DataView( new ArrayBuffer( byteLength ) );
|
|
784
758
|
let offset = 0;
|
|
785
|
-
|
|
786
759
|
for ( let i = start; i < start + count; i ++ ) {
|
|
787
760
|
|
|
788
761
|
for ( let a = 0; a < attribute.itemSize; a ++ ) {
|
|
789
762
|
|
|
790
763
|
let value;
|
|
791
|
-
|
|
792
764
|
if ( attribute.itemSize > 4 ) {
|
|
793
765
|
|
|
794
766
|
// no support for interleaved data for itemSize > 4
|
|
767
|
+
|
|
795
768
|
value = attribute.array[ i * attribute.itemSize + a ];
|
|
796
769
|
|
|
797
770
|
} else {
|
|
@@ -830,7 +803,6 @@
|
|
|
830
803
|
byteLength: byteLength
|
|
831
804
|
};
|
|
832
805
|
if ( target !== undefined ) bufferViewDef.target = target;
|
|
833
|
-
|
|
834
806
|
if ( target === WEBGL_CONSTANTS.ARRAY_BUFFER ) {
|
|
835
807
|
|
|
836
808
|
// Only define byteStride for vertex attributes.
|
|
@@ -839,8 +811,9 @@
|
|
|
839
811
|
}
|
|
840
812
|
|
|
841
813
|
this.byteOffset += byteLength;
|
|
842
|
-
json.bufferViews.push( bufferViewDef );
|
|
814
|
+
json.bufferViews.push( bufferViewDef );
|
|
843
815
|
|
|
816
|
+
// @TODO Merge bufferViews where possible.
|
|
844
817
|
const output = {
|
|
845
818
|
id: json.bufferViews.length - 1,
|
|
846
819
|
byteLength: 0
|
|
@@ -848,13 +821,12 @@
|
|
|
848
821
|
return output;
|
|
849
822
|
|
|
850
823
|
}
|
|
824
|
+
|
|
851
825
|
/**
|
|
852
826
|
* Process and generate a BufferView from an image Blob.
|
|
853
827
|
* @param {Blob} blob
|
|
854
828
|
* @return {Promise<Integer>}
|
|
855
829
|
*/
|
|
856
|
-
|
|
857
|
-
|
|
858
830
|
processBufferViewImage( blob ) {
|
|
859
831
|
|
|
860
832
|
const writer = this;
|
|
@@ -864,7 +836,6 @@
|
|
|
864
836
|
|
|
865
837
|
const reader = new FileReader();
|
|
866
838
|
reader.readAsArrayBuffer( blob );
|
|
867
|
-
|
|
868
839
|
reader.onloadend = function () {
|
|
869
840
|
|
|
870
841
|
const buffer = getPaddedArrayBuffer( reader.result );
|
|
@@ -881,6 +852,7 @@
|
|
|
881
852
|
} );
|
|
882
853
|
|
|
883
854
|
}
|
|
855
|
+
|
|
884
856
|
/**
|
|
885
857
|
* Process attribute to generate an accessor
|
|
886
858
|
* @param {BufferAttribute} attribute Attribute to process
|
|
@@ -889,11 +861,8 @@
|
|
|
889
861
|
* @param {Integer} count (Optional)
|
|
890
862
|
* @return {Integer|null} Index of the processed accessor on the "accessors" array
|
|
891
863
|
*/
|
|
892
|
-
|
|
893
|
-
|
|
894
864
|
processAccessor( attribute, geometry, start, count ) {
|
|
895
865
|
|
|
896
|
-
const options = this.options;
|
|
897
866
|
const json = this.json;
|
|
898
867
|
const types = {
|
|
899
868
|
1: 'SCALAR',
|
|
@@ -902,8 +871,9 @@
|
|
|
902
871
|
4: 'VEC4',
|
|
903
872
|
16: 'MAT4'
|
|
904
873
|
};
|
|
905
|
-
let componentType;
|
|
874
|
+
let componentType;
|
|
906
875
|
|
|
876
|
+
// Detect the component type of the attribute array (float, uint or ushort)
|
|
907
877
|
if ( attribute.array.constructor === Float32Array ) {
|
|
908
878
|
|
|
909
879
|
componentType = WEBGL_CONSTANTS.FLOAT;
|
|
@@ -927,24 +897,15 @@
|
|
|
927
897
|
}
|
|
928
898
|
|
|
929
899
|
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
|
-
|
|
900
|
+
if ( count === undefined ) count = attribute.count;
|
|
942
901
|
|
|
902
|
+
// Skip creating an accessor if the attribute doesn't have data to export
|
|
943
903
|
if ( count === 0 ) return null;
|
|
944
904
|
const minMax = getMinMax( attribute, start, count );
|
|
945
|
-
let bufferViewTarget;
|
|
946
|
-
// animation samplers, target must not be set.
|
|
905
|
+
let bufferViewTarget;
|
|
947
906
|
|
|
907
|
+
// If geometry isn't provided, don't infer the target usage of the bufferView. For
|
|
908
|
+
// animation samplers, target must not be set.
|
|
948
909
|
if ( geometry !== undefined ) {
|
|
949
910
|
|
|
950
911
|
bufferViewTarget = attribute === geometry.index ? WEBGL_CONSTANTS.ELEMENT_ARRAY_BUFFER : WEBGL_CONSTANTS.ARRAY_BUFFER;
|
|
@@ -966,6 +927,7 @@
|
|
|
966
927
|
return json.accessors.push( accessorDef ) - 1;
|
|
967
928
|
|
|
968
929
|
}
|
|
930
|
+
|
|
969
931
|
/**
|
|
970
932
|
* Process image
|
|
971
933
|
* @param {Image} image to process
|
|
@@ -974,8 +936,6 @@
|
|
|
974
936
|
* @param {String} mimeType export format
|
|
975
937
|
* @return {Integer} Index of the processed texture in the "images" array
|
|
976
938
|
*/
|
|
977
|
-
|
|
978
|
-
|
|
979
939
|
processImage( image, format, flipY, mimeType = 'image/png' ) {
|
|
980
940
|
|
|
981
941
|
const writer = this;
|
|
@@ -995,7 +955,6 @@
|
|
|
995
955
|
canvas.width = Math.min( image.width, options.maxTextureSize );
|
|
996
956
|
canvas.height = Math.min( image.height, options.maxTextureSize );
|
|
997
957
|
const ctx = canvas.getContext( '2d' );
|
|
998
|
-
|
|
999
958
|
if ( flipY === true ) {
|
|
1000
959
|
|
|
1001
960
|
ctx.translate( 0, canvas.height );
|
|
@@ -1006,6 +965,7 @@
|
|
|
1006
965
|
if ( image.data !== undefined ) {
|
|
1007
966
|
|
|
1008
967
|
// THREE.DataTexture
|
|
968
|
+
|
|
1009
969
|
if ( format !== THREE.RGBAFormat ) {
|
|
1010
970
|
|
|
1011
971
|
console.error( 'GLTFExporter: Only THREE.RGBAFormat is supported.' );
|
|
@@ -1019,7 +979,6 @@
|
|
|
1019
979
|
}
|
|
1020
980
|
|
|
1021
981
|
const data = new Uint8ClampedArray( image.height * image.width * 4 );
|
|
1022
|
-
|
|
1023
982
|
for ( let i = 0; i < data.length; i += 4 ) {
|
|
1024
983
|
|
|
1025
984
|
data[ i + 0 ] = image.data[ i + 0 ];
|
|
@@ -1068,13 +1027,12 @@
|
|
|
1068
1027
|
return index;
|
|
1069
1028
|
|
|
1070
1029
|
}
|
|
1030
|
+
|
|
1071
1031
|
/**
|
|
1072
1032
|
* Process sampler
|
|
1073
1033
|
* @param {Texture} map Texture to process
|
|
1074
1034
|
* @return {Integer} Index of the processed texture in the "samplers" array
|
|
1075
1035
|
*/
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
1036
|
processSampler( map ) {
|
|
1079
1037
|
|
|
1080
1038
|
const json = this.json;
|
|
@@ -1088,13 +1046,12 @@
|
|
|
1088
1046
|
return json.samplers.push( samplerDef ) - 1;
|
|
1089
1047
|
|
|
1090
1048
|
}
|
|
1049
|
+
|
|
1091
1050
|
/**
|
|
1092
1051
|
* Process texture
|
|
1093
1052
|
* @param {Texture} map Map to process
|
|
1094
1053
|
* @return {Integer} Index of the processed texture in the "textures" array
|
|
1095
1054
|
*/
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
1055
|
processTexture( map ) {
|
|
1099
1056
|
|
|
1100
1057
|
const cache = this.cache;
|
|
@@ -1108,31 +1065,27 @@
|
|
|
1108
1065
|
source: this.processImage( map.image, map.format, map.flipY, mimeType )
|
|
1109
1066
|
};
|
|
1110
1067
|
if ( map.name ) textureDef.name = map.name;
|
|
1111
|
-
|
|
1112
1068
|
this._invokeAll( function ( ext ) {
|
|
1113
1069
|
|
|
1114
1070
|
ext.writeTexture && ext.writeTexture( map, textureDef );
|
|
1115
1071
|
|
|
1116
1072
|
} );
|
|
1117
|
-
|
|
1118
1073
|
const index = json.textures.push( textureDef ) - 1;
|
|
1119
1074
|
cache.textures.set( map, index );
|
|
1120
1075
|
return index;
|
|
1121
1076
|
|
|
1122
1077
|
}
|
|
1078
|
+
|
|
1123
1079
|
/**
|
|
1124
1080
|
* Process material
|
|
1125
1081
|
* @param {THREE.Material} material Material to process
|
|
1126
1082
|
* @return {Integer|null} Index of the processed material in the "materials" array
|
|
1127
1083
|
*/
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
1084
|
processMaterial( material ) {
|
|
1131
1085
|
|
|
1132
1086
|
const cache = this.cache;
|
|
1133
1087
|
const json = this.json;
|
|
1134
1088
|
if ( cache.materials.has( material ) ) return cache.materials.get( material );
|
|
1135
|
-
|
|
1136
1089
|
if ( material.isShaderMaterial ) {
|
|
1137
1090
|
|
|
1138
1091
|
console.warn( 'GLTFExporter: THREE.ShaderMaterial not supported.' );
|
|
@@ -1140,21 +1093,20 @@
|
|
|
1140
1093
|
|
|
1141
1094
|
}
|
|
1142
1095
|
|
|
1143
|
-
if ( ! json.materials ) json.materials = [];
|
|
1096
|
+
if ( ! json.materials ) json.materials = [];
|
|
1144
1097
|
|
|
1098
|
+
// @QUESTION Should we avoid including any attribute that has the default value?
|
|
1145
1099
|
const materialDef = {
|
|
1146
1100
|
pbrMetallicRoughness: {}
|
|
1147
1101
|
};
|
|
1148
|
-
|
|
1149
1102
|
if ( material.isMeshStandardMaterial !== true && material.isMeshBasicMaterial !== true ) {
|
|
1150
1103
|
|
|
1151
1104
|
console.warn( 'GLTFExporter: Use MeshStandardMaterial or MeshBasicMaterial for best results.' );
|
|
1152
1105
|
|
|
1153
|
-
}
|
|
1154
|
-
|
|
1106
|
+
}
|
|
1155
1107
|
|
|
1108
|
+
// pbrMetallicRoughness.baseColorFactor
|
|
1156
1109
|
const color = material.color.toArray().concat( [ material.opacity ] );
|
|
1157
|
-
|
|
1158
1110
|
if ( ! equalArray( color, [ 1, 1, 1, 1 ] ) ) {
|
|
1159
1111
|
|
|
1160
1112
|
materialDef.pbrMetallicRoughness.baseColorFactor = color;
|
|
@@ -1171,9 +1123,9 @@
|
|
|
1171
1123
|
materialDef.pbrMetallicRoughness.metallicFactor = 0.5;
|
|
1172
1124
|
materialDef.pbrMetallicRoughness.roughnessFactor = 0.5;
|
|
1173
1125
|
|
|
1174
|
-
}
|
|
1175
|
-
|
|
1126
|
+
}
|
|
1176
1127
|
|
|
1128
|
+
// pbrMetallicRoughness.metallicRoughnessTexture
|
|
1177
1129
|
if ( material.metalnessMap || material.roughnessMap ) {
|
|
1178
1130
|
|
|
1179
1131
|
const metalRoughTexture = this.buildMetalRoughTexture( material.metalnessMap, material.roughnessMap );
|
|
@@ -1183,9 +1135,9 @@
|
|
|
1183
1135
|
this.applyTextureTransform( metalRoughMapDef, metalRoughTexture );
|
|
1184
1136
|
materialDef.pbrMetallicRoughness.metallicRoughnessTexture = metalRoughMapDef;
|
|
1185
1137
|
|
|
1186
|
-
}
|
|
1187
|
-
|
|
1138
|
+
}
|
|
1188
1139
|
|
|
1140
|
+
// pbrMetallicRoughness.baseColorTexture or pbrSpecularGlossiness diffuseTexture
|
|
1189
1141
|
if ( material.map ) {
|
|
1190
1142
|
|
|
1191
1143
|
const baseColorMapDef = {
|
|
@@ -1201,7 +1153,6 @@
|
|
|
1201
1153
|
// note: emissive components are limited to stay within the 0 - 1 range to accommodate glTF spec. see #21849 and #22000.
|
|
1202
1154
|
const emissive = material.emissive.clone().multiplyScalar( material.emissiveIntensity );
|
|
1203
1155
|
const maxEmissiveComponent = Math.max( emissive.r, emissive.g, emissive.b );
|
|
1204
|
-
|
|
1205
1156
|
if ( maxEmissiveComponent > 1 ) {
|
|
1206
1157
|
|
|
1207
1158
|
emissive.multiplyScalar( 1 / maxEmissiveComponent );
|
|
@@ -1213,9 +1164,9 @@
|
|
|
1213
1164
|
|
|
1214
1165
|
materialDef.emissiveFactor = emissive.toArray();
|
|
1215
1166
|
|
|
1216
|
-
}
|
|
1217
|
-
|
|
1167
|
+
}
|
|
1218
1168
|
|
|
1169
|
+
// emissiveTexture
|
|
1219
1170
|
if ( material.emissiveMap ) {
|
|
1220
1171
|
|
|
1221
1172
|
const emissiveMapDef = {
|
|
@@ -1226,15 +1177,14 @@
|
|
|
1226
1177
|
|
|
1227
1178
|
}
|
|
1228
1179
|
|
|
1229
|
-
}
|
|
1230
|
-
|
|
1180
|
+
}
|
|
1231
1181
|
|
|
1182
|
+
// normalTexture
|
|
1232
1183
|
if ( material.normalMap ) {
|
|
1233
1184
|
|
|
1234
1185
|
const normalMapDef = {
|
|
1235
1186
|
index: this.processTexture( material.normalMap )
|
|
1236
1187
|
};
|
|
1237
|
-
|
|
1238
1188
|
if ( material.normalScale && material.normalScale.x !== 1 ) {
|
|
1239
1189
|
|
|
1240
1190
|
// glTF normal scale is univariate. Ignore `y`, which may be flipped.
|
|
@@ -1246,16 +1196,15 @@
|
|
|
1246
1196
|
this.applyTextureTransform( normalMapDef, material.normalMap );
|
|
1247
1197
|
materialDef.normalTexture = normalMapDef;
|
|
1248
1198
|
|
|
1249
|
-
}
|
|
1250
|
-
|
|
1199
|
+
}
|
|
1251
1200
|
|
|
1201
|
+
// occlusionTexture
|
|
1252
1202
|
if ( material.aoMap ) {
|
|
1253
1203
|
|
|
1254
1204
|
const occlusionMapDef = {
|
|
1255
1205
|
index: this.processTexture( material.aoMap ),
|
|
1256
1206
|
texCoord: 1
|
|
1257
1207
|
};
|
|
1258
|
-
|
|
1259
1208
|
if ( material.aoMapIntensity !== 1.0 ) {
|
|
1260
1209
|
|
|
1261
1210
|
occlusionMapDef.strength = material.aoMapIntensity;
|
|
@@ -1265,9 +1214,9 @@
|
|
|
1265
1214
|
this.applyTextureTransform( occlusionMapDef, material.aoMap );
|
|
1266
1215
|
materialDef.occlusionTexture = occlusionMapDef;
|
|
1267
1216
|
|
|
1268
|
-
}
|
|
1269
|
-
|
|
1217
|
+
}
|
|
1270
1218
|
|
|
1219
|
+
// alphaMode
|
|
1271
1220
|
if ( material.transparent ) {
|
|
1272
1221
|
|
|
1273
1222
|
materialDef.alphaMode = 'BLEND';
|
|
@@ -1281,37 +1230,33 @@
|
|
|
1281
1230
|
|
|
1282
1231
|
}
|
|
1283
1232
|
|
|
1284
|
-
}
|
|
1285
|
-
|
|
1233
|
+
}
|
|
1286
1234
|
|
|
1235
|
+
// doubleSided
|
|
1287
1236
|
if ( material.side === THREE.DoubleSide ) materialDef.doubleSided = true;
|
|
1288
1237
|
if ( material.name !== '' ) materialDef.name = material.name;
|
|
1289
1238
|
this.serializeUserData( material, materialDef );
|
|
1290
|
-
|
|
1291
1239
|
this._invokeAll( function ( ext ) {
|
|
1292
1240
|
|
|
1293
1241
|
ext.writeMaterial && ext.writeMaterial( material, materialDef );
|
|
1294
1242
|
|
|
1295
1243
|
} );
|
|
1296
|
-
|
|
1297
1244
|
const index = json.materials.push( materialDef ) - 1;
|
|
1298
1245
|
cache.materials.set( material, index );
|
|
1299
1246
|
return index;
|
|
1300
1247
|
|
|
1301
1248
|
}
|
|
1249
|
+
|
|
1302
1250
|
/**
|
|
1303
1251
|
* Process mesh
|
|
1304
1252
|
* @param {THREE.Mesh} mesh Mesh to process
|
|
1305
1253
|
* @return {Integer|null} Index of the processed mesh in the "meshes" array
|
|
1306
1254
|
*/
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
1255
|
processMesh( mesh ) {
|
|
1310
1256
|
|
|
1311
1257
|
const cache = this.cache;
|
|
1312
1258
|
const json = this.json;
|
|
1313
1259
|
const meshCacheKeyParts = [ mesh.geometry.uuid ];
|
|
1314
|
-
|
|
1315
1260
|
if ( Array.isArray( mesh.material ) ) {
|
|
1316
1261
|
|
|
1317
1262
|
for ( let i = 0, l = mesh.material.length; i < l; i ++ ) {
|
|
@@ -1329,8 +1274,9 @@
|
|
|
1329
1274
|
const meshCacheKey = meshCacheKeyParts.join( ':' );
|
|
1330
1275
|
if ( cache.meshes.has( meshCacheKey ) ) return cache.meshes.get( meshCacheKey );
|
|
1331
1276
|
const geometry = mesh.geometry;
|
|
1332
|
-
let mode;
|
|
1277
|
+
let mode;
|
|
1333
1278
|
|
|
1279
|
+
// Use the correct mode
|
|
1334
1280
|
if ( mesh.isLineSegments ) {
|
|
1335
1281
|
|
|
1336
1282
|
mode = WEBGL_CONSTANTS.LINES;
|
|
@@ -1356,8 +1302,9 @@
|
|
|
1356
1302
|
const meshDef = {};
|
|
1357
1303
|
const attributes = {};
|
|
1358
1304
|
const primitives = [];
|
|
1359
|
-
const targets = [];
|
|
1305
|
+
const targets = [];
|
|
1360
1306
|
|
|
1307
|
+
// Conversion between attributes names in threejs and gltf spec
|
|
1361
1308
|
const nameConversion = {
|
|
1362
1309
|
uv: 'TEXCOORD_0',
|
|
1363
1310
|
uv2: 'TEXCOORD_1',
|
|
@@ -1366,40 +1313,37 @@
|
|
|
1366
1313
|
skinIndex: 'JOINTS_0'
|
|
1367
1314
|
};
|
|
1368
1315
|
const originalNormal = geometry.getAttribute( 'normal' );
|
|
1369
|
-
|
|
1370
1316
|
if ( originalNormal !== undefined && ! this.isNormalizedNormalAttribute( originalNormal ) ) {
|
|
1371
1317
|
|
|
1372
1318
|
console.warn( 'THREE.GLTFExporter: Creating normalized normal attribute from the non-normalized one.' );
|
|
1373
1319
|
geometry.setAttribute( 'normal', this.createNormalizedNormalAttribute( originalNormal ) );
|
|
1374
1320
|
|
|
1375
|
-
}
|
|
1376
|
-
// For every attribute create an accessor
|
|
1377
|
-
|
|
1321
|
+
}
|
|
1378
1322
|
|
|
1323
|
+
// @QUESTION Detect if .vertexColors = true?
|
|
1324
|
+
// For every attribute create an accessor
|
|
1379
1325
|
let modifiedAttribute = null;
|
|
1380
|
-
|
|
1381
1326
|
for ( let attributeName in geometry.attributes ) {
|
|
1382
1327
|
|
|
1383
1328
|
// Ignore morph target attributes, which are exported later.
|
|
1384
1329
|
if ( attributeName.slice( 0, 5 ) === 'morph' ) continue;
|
|
1385
1330
|
const attribute = geometry.attributes[ attributeName ];
|
|
1386
|
-
attributeName = nameConversion[ attributeName ] || attributeName.toUpperCase();
|
|
1387
|
-
// listed in the spec; non-spec attributes are considered custom.
|
|
1331
|
+
attributeName = nameConversion[ attributeName ] || attributeName.toUpperCase();
|
|
1388
1332
|
|
|
1333
|
+
// Prefix all geometry attributes except the ones specifically
|
|
1334
|
+
// listed in the spec; non-spec attributes are considered custom.
|
|
1389
1335
|
const validVertexAttributes = /^(POSITION|NORMAL|TANGENT|TEXCOORD_\d+|COLOR_\d+|JOINTS_\d+|WEIGHTS_\d+)$/;
|
|
1390
1336
|
if ( ! validVertexAttributes.test( attributeName ) ) attributeName = '_' + attributeName;
|
|
1391
|
-
|
|
1392
1337
|
if ( cache.attributes.has( this.getUID( attribute ) ) ) {
|
|
1393
1338
|
|
|
1394
1339
|
attributes[ attributeName ] = cache.attributes.get( this.getUID( attribute ) );
|
|
1395
1340
|
continue;
|
|
1396
1341
|
|
|
1397
|
-
}
|
|
1398
|
-
|
|
1342
|
+
}
|
|
1399
1343
|
|
|
1344
|
+
// JOINTS_0 must be UNSIGNED_BYTE or UNSIGNED_SHORT.
|
|
1400
1345
|
modifiedAttribute = null;
|
|
1401
1346
|
const array = attribute.array;
|
|
1402
|
-
|
|
1403
1347
|
if ( attributeName === 'JOINTS_0' && ! ( array instanceof Uint16Array ) && ! ( array instanceof Uint8Array ) ) {
|
|
1404
1348
|
|
|
1405
1349
|
console.warn( 'GLTFExporter: Attribute "skinIndex" converted to type UNSIGNED_SHORT.' );
|
|
@@ -1408,7 +1352,6 @@
|
|
|
1408
1352
|
}
|
|
1409
1353
|
|
|
1410
1354
|
const accessor = this.processAccessor( modifiedAttribute || attribute, geometry );
|
|
1411
|
-
|
|
1412
1355
|
if ( accessor !== null ) {
|
|
1413
1356
|
|
|
1414
1357
|
attributes[ attributeName ] = accessor;
|
|
@@ -1418,16 +1361,17 @@
|
|
|
1418
1361
|
|
|
1419
1362
|
}
|
|
1420
1363
|
|
|
1421
|
-
if ( originalNormal !== undefined ) geometry.setAttribute( 'normal', originalNormal );
|
|
1364
|
+
if ( originalNormal !== undefined ) geometry.setAttribute( 'normal', originalNormal );
|
|
1422
1365
|
|
|
1423
|
-
if
|
|
1366
|
+
// Skip if no exportable attributes found
|
|
1367
|
+
if ( Object.keys( attributes ).length === 0 ) return null;
|
|
1424
1368
|
|
|
1369
|
+
// Morph targets
|
|
1425
1370
|
if ( mesh.morphTargetInfluences !== undefined && mesh.morphTargetInfluences.length > 0 ) {
|
|
1426
1371
|
|
|
1427
1372
|
const weights = [];
|
|
1428
1373
|
const targetNames = [];
|
|
1429
1374
|
const reverseDictionary = {};
|
|
1430
|
-
|
|
1431
1375
|
if ( mesh.morphTargetDictionary !== undefined ) {
|
|
1432
1376
|
|
|
1433
1377
|
for ( const key in mesh.morphTargetDictionary ) {
|
|
@@ -1442,11 +1386,11 @@
|
|
|
1442
1386
|
|
|
1443
1387
|
const target = {};
|
|
1444
1388
|
let warned = false;
|
|
1445
|
-
|
|
1446
1389
|
for ( const attributeName in geometry.morphAttributes ) {
|
|
1447
1390
|
|
|
1448
1391
|
// glTF 2.0 morph supports only POSITION/NORMAL/TANGENT.
|
|
1449
1392
|
// Three.js doesn't support TANGENT yet.
|
|
1393
|
+
|
|
1450
1394
|
if ( attributeName !== 'position' && attributeName !== 'normal' ) {
|
|
1451
1395
|
|
|
1452
1396
|
if ( ! warned ) {
|
|
@@ -1461,23 +1405,23 @@
|
|
|
1461
1405
|
}
|
|
1462
1406
|
|
|
1463
1407
|
const attribute = geometry.morphAttributes[ attributeName ][ i ];
|
|
1464
|
-
const gltfAttributeName = attributeName.toUpperCase();
|
|
1408
|
+
const gltfAttributeName = attributeName.toUpperCase();
|
|
1409
|
+
|
|
1410
|
+
// Three.js morph attribute has absolute values while the one of glTF has relative values.
|
|
1465
1411
|
//
|
|
1466
1412
|
// glTF 2.0 Specification:
|
|
1467
1413
|
// https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#morph-targets
|
|
1468
1414
|
|
|
1469
1415
|
const baseAttribute = geometry.attributes[ attributeName ];
|
|
1470
|
-
|
|
1471
1416
|
if ( cache.attributes.has( this.getUID( attribute, true ) ) ) {
|
|
1472
1417
|
|
|
1473
1418
|
target[ gltfAttributeName ] = cache.attributes.get( this.getUID( attribute, true ) );
|
|
1474
1419
|
continue;
|
|
1475
1420
|
|
|
1476
|
-
}
|
|
1477
|
-
|
|
1421
|
+
}
|
|
1478
1422
|
|
|
1423
|
+
// Clones attribute not to override
|
|
1479
1424
|
const relativeAttribute = attribute.clone();
|
|
1480
|
-
|
|
1481
1425
|
if ( ! geometry.morphTargetsRelative ) {
|
|
1482
1426
|
|
|
1483
1427
|
for ( let j = 0, jl = attribute.count; j < jl; j ++ ) {
|
|
@@ -1500,7 +1444,6 @@
|
|
|
1500
1444
|
}
|
|
1501
1445
|
|
|
1502
1446
|
meshDef.weights = weights;
|
|
1503
|
-
|
|
1504
1447
|
if ( targetNames.length > 0 ) {
|
|
1505
1448
|
|
|
1506
1449
|
meshDef.extras = {};
|
|
@@ -1518,7 +1461,6 @@
|
|
|
1518
1461
|
start: undefined,
|
|
1519
1462
|
count: undefined
|
|
1520
1463
|
} ];
|
|
1521
|
-
|
|
1522
1464
|
for ( let i = 0, il = groups.length; i < il; i ++ ) {
|
|
1523
1465
|
|
|
1524
1466
|
const primitive = {
|
|
@@ -1527,11 +1469,9 @@
|
|
|
1527
1469
|
};
|
|
1528
1470
|
this.serializeUserData( geometry, primitive );
|
|
1529
1471
|
if ( targets.length > 0 ) primitive.targets = targets;
|
|
1530
|
-
|
|
1531
1472
|
if ( geometry.index !== null ) {
|
|
1532
1473
|
|
|
1533
1474
|
let cacheKey = this.getUID( geometry.index );
|
|
1534
|
-
|
|
1535
1475
|
if ( groups[ i ].start !== undefined || groups[ i ].count !== undefined ) {
|
|
1536
1476
|
|
|
1537
1477
|
cacheKey += ':' + groups[ i ].start + ':' + groups[ i ].count;
|
|
@@ -1561,25 +1501,22 @@
|
|
|
1561
1501
|
|
|
1562
1502
|
meshDef.primitives = primitives;
|
|
1563
1503
|
if ( ! json.meshes ) json.meshes = [];
|
|
1564
|
-
|
|
1565
1504
|
this._invokeAll( function ( ext ) {
|
|
1566
1505
|
|
|
1567
1506
|
ext.writeMesh && ext.writeMesh( mesh, meshDef );
|
|
1568
1507
|
|
|
1569
1508
|
} );
|
|
1570
|
-
|
|
1571
1509
|
const index = json.meshes.push( meshDef ) - 1;
|
|
1572
1510
|
cache.meshes.set( meshCacheKey, index );
|
|
1573
1511
|
return index;
|
|
1574
1512
|
|
|
1575
1513
|
}
|
|
1514
|
+
|
|
1576
1515
|
/**
|
|
1577
1516
|
* Process camera
|
|
1578
1517
|
* @param {THREE.Camera} camera Camera to process
|
|
1579
1518
|
* @return {Integer} Index of the processed mesh in the "camera" array
|
|
1580
1519
|
*/
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
1520
|
processCamera( camera ) {
|
|
1584
1521
|
|
|
1585
1522
|
const json = this.json;
|
|
@@ -1588,7 +1525,6 @@
|
|
|
1588
1525
|
const cameraDef = {
|
|
1589
1526
|
type: isOrtho ? 'orthographic' : 'perspective'
|
|
1590
1527
|
};
|
|
1591
|
-
|
|
1592
1528
|
if ( isOrtho ) {
|
|
1593
1529
|
|
|
1594
1530
|
cameraDef.orthographic = {
|
|
@@ -1607,13 +1543,14 @@
|
|
|
1607
1543
|
znear: camera.near < 0 ? 0 : camera.near
|
|
1608
1544
|
};
|
|
1609
1545
|
|
|
1610
|
-
}
|
|
1611
|
-
|
|
1546
|
+
}
|
|
1612
1547
|
|
|
1548
|
+
// Question: Is saving "type" as name intentional?
|
|
1613
1549
|
if ( camera.name !== '' ) cameraDef.name = camera.type;
|
|
1614
1550
|
return json.cameras.push( cameraDef ) - 1;
|
|
1615
1551
|
|
|
1616
1552
|
}
|
|
1553
|
+
|
|
1617
1554
|
/**
|
|
1618
1555
|
* Creates glTF animation entry from AnimationClip object.
|
|
1619
1556
|
*
|
|
@@ -1624,8 +1561,6 @@
|
|
|
1624
1561
|
* @param {THREE.Object3D} root
|
|
1625
1562
|
* @return {number|null}
|
|
1626
1563
|
*/
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
1564
|
processAnimation( clip, root ) {
|
|
1630
1565
|
|
|
1631
1566
|
const json = this.json;
|
|
@@ -1635,14 +1570,12 @@
|
|
|
1635
1570
|
const tracks = clip.tracks;
|
|
1636
1571
|
const channels = [];
|
|
1637
1572
|
const samplers = [];
|
|
1638
|
-
|
|
1639
1573
|
for ( let i = 0; i < tracks.length; ++ i ) {
|
|
1640
1574
|
|
|
1641
1575
|
const track = tracks[ i ];
|
|
1642
1576
|
const trackBinding = THREE.PropertyBinding.parseTrackName( track.name );
|
|
1643
1577
|
let trackNode = THREE.PropertyBinding.findNode( root, trackBinding.nodeName );
|
|
1644
1578
|
const trackProperty = PATH_PROPERTIES[ trackBinding.propertyName ];
|
|
1645
|
-
|
|
1646
1579
|
if ( trackBinding.objectName === 'bones' ) {
|
|
1647
1580
|
|
|
1648
1581
|
if ( trackNode.isSkinnedMesh === true ) {
|
|
@@ -1666,24 +1599,26 @@
|
|
|
1666
1599
|
|
|
1667
1600
|
const inputItemSize = 1;
|
|
1668
1601
|
let outputItemSize = track.values.length / track.times.length;
|
|
1669
|
-
|
|
1670
1602
|
if ( trackProperty === PATH_PROPERTIES.morphTargetInfluences ) {
|
|
1671
1603
|
|
|
1672
1604
|
outputItemSize /= trackNode.morphTargetInfluences.length;
|
|
1673
1605
|
|
|
1674
1606
|
}
|
|
1675
1607
|
|
|
1676
|
-
let interpolation;
|
|
1608
|
+
let interpolation;
|
|
1609
|
+
|
|
1610
|
+
// @TODO export CubicInterpolant(InterpolateSmooth) as CUBICSPLINE
|
|
1611
|
+
|
|
1677
1612
|
// Detecting glTF cubic spline interpolant by checking factory method's special property
|
|
1678
1613
|
// GLTFCubicSplineInterpolant is a custom interpolant and track doesn't return
|
|
1679
1614
|
// valid value from .getInterpolation().
|
|
1680
|
-
|
|
1681
1615
|
if ( track.createInterpolant.isInterpolantFactoryMethodGLTFCubicSpline === true ) {
|
|
1682
1616
|
|
|
1683
|
-
interpolation = 'CUBICSPLINE';
|
|
1617
|
+
interpolation = 'CUBICSPLINE';
|
|
1618
|
+
|
|
1619
|
+
// itemSize of CUBICSPLINE keyframe is 9
|
|
1684
1620
|
// (VEC3 * 3: inTangent, splineVertex, and outTangent)
|
|
1685
1621
|
// but needs to be stored as VEC3 so dividing by 3 here.
|
|
1686
|
-
|
|
1687
1622
|
outputItemSize /= 3;
|
|
1688
1623
|
|
|
1689
1624
|
} else if ( track.getInterpolation() === THREE.InterpolateDiscrete ) {
|
|
@@ -1719,12 +1654,11 @@
|
|
|
1719
1654
|
return json.animations.length - 1;
|
|
1720
1655
|
|
|
1721
1656
|
}
|
|
1657
|
+
|
|
1722
1658
|
/**
|
|
1723
1659
|
* @param {THREE.Object3D} object
|
|
1724
1660
|
* @return {number|null}
|
|
1725
1661
|
*/
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
1662
|
processSkin( object ) {
|
|
1729
1663
|
|
|
1730
1664
|
const json = this.json;
|
|
@@ -1737,7 +1671,6 @@
|
|
|
1737
1671
|
const joints = [];
|
|
1738
1672
|
const inverseBindMatrices = new Float32Array( skeleton.bones.length * 16 );
|
|
1739
1673
|
const temporaryBoneInverse = new THREE.Matrix4();
|
|
1740
|
-
|
|
1741
1674
|
for ( let i = 0; i < skeleton.bones.length; ++ i ) {
|
|
1742
1675
|
|
|
1743
1676
|
joints.push( nodeMap.get( skeleton.bones[ i ] ) );
|
|
@@ -1756,13 +1689,12 @@
|
|
|
1756
1689
|
return skinIndex;
|
|
1757
1690
|
|
|
1758
1691
|
}
|
|
1692
|
+
|
|
1759
1693
|
/**
|
|
1760
1694
|
* Process Object3D node
|
|
1761
1695
|
* @param {THREE.Object3D} node Object3D to processNode
|
|
1762
1696
|
* @return {Integer} Index of the node in the nodes list
|
|
1763
1697
|
*/
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
1698
|
processNode( object ) {
|
|
1767
1699
|
|
|
1768
1700
|
const json = this.json;
|
|
@@ -1770,13 +1702,11 @@
|
|
|
1770
1702
|
const nodeMap = this.nodeMap;
|
|
1771
1703
|
if ( ! json.nodes ) json.nodes = [];
|
|
1772
1704
|
const nodeDef = {};
|
|
1773
|
-
|
|
1774
1705
|
if ( options.trs ) {
|
|
1775
1706
|
|
|
1776
1707
|
const rotation = object.quaternion.toArray();
|
|
1777
1708
|
const position = object.position.toArray();
|
|
1778
1709
|
const scale = object.scale.toArray();
|
|
1779
|
-
|
|
1780
1710
|
if ( ! equalArray( rotation, [ 0, 0, 0, 1 ] ) ) {
|
|
1781
1711
|
|
|
1782
1712
|
nodeDef.rotation = rotation;
|
|
@@ -1809,12 +1739,11 @@
|
|
|
1809
1739
|
|
|
1810
1740
|
}
|
|
1811
1741
|
|
|
1812
|
-
}
|
|
1813
|
-
|
|
1742
|
+
}
|
|
1814
1743
|
|
|
1744
|
+
// We don't export empty strings name because it represents no-name in Three.js.
|
|
1815
1745
|
if ( object.name !== '' ) nodeDef.name = String( object.name );
|
|
1816
1746
|
this.serializeUserData( object, nodeDef );
|
|
1817
|
-
|
|
1818
1747
|
if ( object.isMesh || object.isLine || object.isPoints ) {
|
|
1819
1748
|
|
|
1820
1749
|
const meshIndex = this.processMesh( object );
|
|
@@ -1827,15 +1756,12 @@
|
|
|
1827
1756
|
}
|
|
1828
1757
|
|
|
1829
1758
|
if ( object.isSkinnedMesh ) this.skins.push( object );
|
|
1830
|
-
|
|
1831
1759
|
if ( object.children.length > 0 ) {
|
|
1832
1760
|
|
|
1833
1761
|
const children = [];
|
|
1834
|
-
|
|
1835
1762
|
for ( let i = 0, l = object.children.length; i < l; i ++ ) {
|
|
1836
1763
|
|
|
1837
1764
|
const child = object.children[ i ];
|
|
1838
|
-
|
|
1839
1765
|
if ( child.visible || options.onlyVisible === false ) {
|
|
1840
1766
|
|
|
1841
1767
|
const nodeIndex = this.processNode( child );
|
|
@@ -1854,23 +1780,20 @@
|
|
|
1854
1780
|
ext.writeNode && ext.writeNode( object, nodeDef );
|
|
1855
1781
|
|
|
1856
1782
|
} );
|
|
1857
|
-
|
|
1858
1783
|
const nodeIndex = json.nodes.push( nodeDef ) - 1;
|
|
1859
1784
|
nodeMap.set( object, nodeIndex );
|
|
1860
1785
|
return nodeIndex;
|
|
1861
1786
|
|
|
1862
1787
|
}
|
|
1788
|
+
|
|
1863
1789
|
/**
|
|
1864
1790
|
* Process THREE.Scene
|
|
1865
1791
|
* @param {Scene} node THREE.Scene to process
|
|
1866
1792
|
*/
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
1793
|
processScene( scene ) {
|
|
1870
1794
|
|
|
1871
1795
|
const json = this.json;
|
|
1872
1796
|
const options = this.options;
|
|
1873
|
-
|
|
1874
1797
|
if ( ! json.scenes ) {
|
|
1875
1798
|
|
|
1876
1799
|
json.scenes = [];
|
|
@@ -1882,11 +1805,9 @@
|
|
|
1882
1805
|
if ( scene.name !== '' ) sceneDef.name = scene.name;
|
|
1883
1806
|
json.scenes.push( sceneDef );
|
|
1884
1807
|
const nodes = [];
|
|
1885
|
-
|
|
1886
1808
|
for ( let i = 0, l = scene.children.length; i < l; i ++ ) {
|
|
1887
1809
|
|
|
1888
1810
|
const child = scene.children[ i ];
|
|
1889
|
-
|
|
1890
1811
|
if ( child.visible || options.onlyVisible === false ) {
|
|
1891
1812
|
|
|
1892
1813
|
const nodeIndex = this.processNode( child );
|
|
@@ -1900,17 +1821,15 @@
|
|
|
1900
1821
|
this.serializeUserData( scene, sceneDef );
|
|
1901
1822
|
|
|
1902
1823
|
}
|
|
1824
|
+
|
|
1903
1825
|
/**
|
|
1904
1826
|
* Creates a THREE.Scene to hold a list of objects and parse it
|
|
1905
1827
|
* @param {Array} objects List of objects to process
|
|
1906
1828
|
*/
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
1829
|
processObjects( objects ) {
|
|
1910
1830
|
|
|
1911
1831
|
const scene = new THREE.Scene();
|
|
1912
1832
|
scene.name = 'AuxScene';
|
|
1913
|
-
|
|
1914
1833
|
for ( let i = 0; i < objects.length; i ++ ) {
|
|
1915
1834
|
|
|
1916
1835
|
// We push directly to children instead of calling `add` to prevent
|
|
@@ -1922,24 +1841,20 @@
|
|
|
1922
1841
|
this.processScene( scene );
|
|
1923
1842
|
|
|
1924
1843
|
}
|
|
1844
|
+
|
|
1925
1845
|
/**
|
|
1926
1846
|
* @param {THREE.Object3D|Array<THREE.Object3D>} input
|
|
1927
1847
|
*/
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
1848
|
processInput( input ) {
|
|
1931
1849
|
|
|
1932
1850
|
const options = this.options;
|
|
1933
1851
|
input = input instanceof Array ? input : [ input ];
|
|
1934
|
-
|
|
1935
1852
|
this._invokeAll( function ( ext ) {
|
|
1936
1853
|
|
|
1937
1854
|
ext.beforeParse && ext.beforeParse( input );
|
|
1938
1855
|
|
|
1939
1856
|
} );
|
|
1940
|
-
|
|
1941
1857
|
const objectsWithoutScene = [];
|
|
1942
|
-
|
|
1943
1858
|
for ( let i = 0; i < input.length; i ++ ) {
|
|
1944
1859
|
|
|
1945
1860
|
if ( input[ i ] instanceof THREE.Scene ) {
|
|
@@ -1955,7 +1870,6 @@
|
|
|
1955
1870
|
}
|
|
1956
1871
|
|
|
1957
1872
|
if ( objectsWithoutScene.length > 0 ) this.processObjects( objectsWithoutScene );
|
|
1958
|
-
|
|
1959
1873
|
for ( let i = 0; i < this.skins.length; ++ i ) {
|
|
1960
1874
|
|
|
1961
1875
|
this.processSkin( this.skins[ i ] );
|
|
@@ -1975,7 +1889,6 @@
|
|
|
1975
1889
|
} );
|
|
1976
1890
|
|
|
1977
1891
|
}
|
|
1978
|
-
|
|
1979
1892
|
_invokeAll( func ) {
|
|
1980
1893
|
|
|
1981
1894
|
for ( let i = 0, il = this.plugins.length; i < il; i ++ ) {
|
|
@@ -1987,13 +1900,12 @@
|
|
|
1987
1900
|
}
|
|
1988
1901
|
|
|
1989
1902
|
}
|
|
1903
|
+
|
|
1990
1904
|
/**
|
|
1991
1905
|
* Punctual Lights Extension
|
|
1992
1906
|
*
|
|
1993
1907
|
* Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_lights_punctual
|
|
1994
1908
|
*/
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
1909
|
class GLTFLightExtension {
|
|
1998
1910
|
|
|
1999
1911
|
constructor( writer ) {
|
|
@@ -2002,11 +1914,9 @@
|
|
|
2002
1914
|
this.name = 'KHR_lights_punctual';
|
|
2003
1915
|
|
|
2004
1916
|
}
|
|
2005
|
-
|
|
2006
1917
|
writeNode( light, nodeDef ) {
|
|
2007
1918
|
|
|
2008
1919
|
if ( ! light.isLight ) return;
|
|
2009
|
-
|
|
2010
1920
|
if ( ! light.isDirectionalLight && ! light.isPointLight && ! light.isSpotLight ) {
|
|
2011
1921
|
|
|
2012
1922
|
console.warn( 'THREE.GLTFExporter: Only directional, point, and spot lights are supported.', light );
|
|
@@ -2021,7 +1931,6 @@
|
|
|
2021
1931
|
if ( light.name ) lightDef.name = light.name;
|
|
2022
1932
|
lightDef.color = light.color.toArray();
|
|
2023
1933
|
lightDef.intensity = light.intensity;
|
|
2024
|
-
|
|
2025
1934
|
if ( light.isDirectionalLight ) {
|
|
2026
1935
|
|
|
2027
1936
|
lightDef.type = 'directional';
|
|
@@ -2073,13 +1982,12 @@
|
|
|
2073
1982
|
}
|
|
2074
1983
|
|
|
2075
1984
|
}
|
|
1985
|
+
|
|
2076
1986
|
/**
|
|
2077
1987
|
* Unlit Materials Extension
|
|
2078
1988
|
*
|
|
2079
1989
|
* Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_unlit
|
|
2080
1990
|
*/
|
|
2081
|
-
|
|
2082
|
-
|
|
2083
1991
|
class GLTFMaterialsUnlitExtension {
|
|
2084
1992
|
|
|
2085
1993
|
constructor( writer ) {
|
|
@@ -2088,7 +1996,6 @@
|
|
|
2088
1996
|
this.name = 'KHR_materials_unlit';
|
|
2089
1997
|
|
|
2090
1998
|
}
|
|
2091
|
-
|
|
2092
1999
|
writeMaterial( material, materialDef ) {
|
|
2093
2000
|
|
|
2094
2001
|
if ( ! material.isMeshBasicMaterial ) return;
|
|
@@ -2103,13 +2010,12 @@
|
|
|
2103
2010
|
}
|
|
2104
2011
|
|
|
2105
2012
|
}
|
|
2013
|
+
|
|
2106
2014
|
/**
|
|
2107
2015
|
* Specular-Glossiness Extension
|
|
2108
2016
|
*
|
|
2109
2017
|
* Specification: https://github.com/KhronosGroup/glTF/tree/main/extensions/2.0/Archived/KHR_materials_pbrSpecularGlossiness
|
|
2110
2018
|
*/
|
|
2111
|
-
|
|
2112
|
-
|
|
2113
2019
|
class GLTFMaterialsPBRSpecularGlossiness {
|
|
2114
2020
|
|
|
2115
2021
|
constructor( writer ) {
|
|
@@ -2118,14 +2024,12 @@
|
|
|
2118
2024
|
this.name = 'KHR_materials_pbrSpecularGlossiness';
|
|
2119
2025
|
|
|
2120
2026
|
}
|
|
2121
|
-
|
|
2122
2027
|
writeMaterial( material, materialDef ) {
|
|
2123
2028
|
|
|
2124
2029
|
if ( ! material.isGLTFSpecularGlossinessMaterial ) return;
|
|
2125
2030
|
const writer = this.writer;
|
|
2126
2031
|
const extensionsUsed = writer.extensionsUsed;
|
|
2127
2032
|
const extensionDef = {};
|
|
2128
|
-
|
|
2129
2033
|
if ( materialDef.pbrMetallicRoughness.baseColorFactor ) {
|
|
2130
2034
|
|
|
2131
2035
|
extensionDef.diffuseFactor = materialDef.pbrMetallicRoughness.baseColorFactor;
|
|
@@ -2136,7 +2040,6 @@
|
|
|
2136
2040
|
material.specular.toArray( specularFactor, 0 );
|
|
2137
2041
|
extensionDef.specularFactor = specularFactor;
|
|
2138
2042
|
extensionDef.glossinessFactor = material.glossiness;
|
|
2139
|
-
|
|
2140
2043
|
if ( materialDef.pbrMetallicRoughness.baseColorTexture ) {
|
|
2141
2044
|
|
|
2142
2045
|
extensionDef.diffuseTexture = materialDef.pbrMetallicRoughness.baseColorTexture;
|
|
@@ -2160,13 +2063,12 @@
|
|
|
2160
2063
|
}
|
|
2161
2064
|
|
|
2162
2065
|
}
|
|
2066
|
+
|
|
2163
2067
|
/**
|
|
2164
2068
|
* Clearcoat Materials Extension
|
|
2165
2069
|
*
|
|
2166
2070
|
* Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_clearcoat
|
|
2167
2071
|
*/
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
2072
|
class GLTFMaterialsClearcoatExtension {
|
|
2171
2073
|
|
|
2172
2074
|
constructor( writer ) {
|
|
@@ -2175,7 +2077,6 @@
|
|
|
2175
2077
|
this.name = 'KHR_materials_clearcoat';
|
|
2176
2078
|
|
|
2177
2079
|
}
|
|
2178
|
-
|
|
2179
2080
|
writeMaterial( material, materialDef ) {
|
|
2180
2081
|
|
|
2181
2082
|
if ( ! material.isMeshPhysicalMaterial ) return;
|
|
@@ -2183,7 +2084,6 @@
|
|
|
2183
2084
|
const extensionsUsed = writer.extensionsUsed;
|
|
2184
2085
|
const extensionDef = {};
|
|
2185
2086
|
extensionDef.clearcoatFactor = material.clearcoat;
|
|
2186
|
-
|
|
2187
2087
|
if ( material.clearcoatMap ) {
|
|
2188
2088
|
|
|
2189
2089
|
const clearcoatMapDef = {
|
|
@@ -2195,7 +2095,6 @@
|
|
|
2195
2095
|
}
|
|
2196
2096
|
|
|
2197
2097
|
extensionDef.clearcoatRoughnessFactor = material.clearcoatRoughness;
|
|
2198
|
-
|
|
2199
2098
|
if ( material.clearcoatRoughnessMap ) {
|
|
2200
2099
|
|
|
2201
2100
|
const clearcoatRoughnessMapDef = {
|
|
@@ -2223,13 +2122,12 @@
|
|
|
2223
2122
|
}
|
|
2224
2123
|
|
|
2225
2124
|
}
|
|
2125
|
+
|
|
2226
2126
|
/**
|
|
2227
2127
|
* Iridescence Materials Extension
|
|
2228
2128
|
*
|
|
2229
2129
|
* Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_iridescence
|
|
2230
2130
|
*/
|
|
2231
|
-
|
|
2232
|
-
|
|
2233
2131
|
class GLTFMaterialsIridescenceExtension {
|
|
2234
2132
|
|
|
2235
2133
|
constructor( writer ) {
|
|
@@ -2238,7 +2136,6 @@
|
|
|
2238
2136
|
this.name = 'KHR_materials_iridescence';
|
|
2239
2137
|
|
|
2240
2138
|
}
|
|
2241
|
-
|
|
2242
2139
|
writeMaterial( material, materialDef ) {
|
|
2243
2140
|
|
|
2244
2141
|
if ( ! material.isMeshPhysicalMaterial ) return;
|
|
@@ -2246,7 +2143,6 @@
|
|
|
2246
2143
|
const extensionsUsed = writer.extensionsUsed;
|
|
2247
2144
|
const extensionDef = {};
|
|
2248
2145
|
extensionDef.iridescenceFactor = material.iridescence;
|
|
2249
|
-
|
|
2250
2146
|
if ( material.iridescenceMap ) {
|
|
2251
2147
|
|
|
2252
2148
|
const iridescenceMapDef = {
|
|
@@ -2260,7 +2156,6 @@
|
|
|
2260
2156
|
extensionDef.iridescenceIor = material.iridescenceIOR;
|
|
2261
2157
|
extensionDef.iridescenceThicknessMinimum = material.iridescenceThicknessRange[ 0 ];
|
|
2262
2158
|
extensionDef.iridescenceThicknessMaximum = material.iridescenceThicknessRange[ 1 ];
|
|
2263
|
-
|
|
2264
2159
|
if ( material.iridescenceThicknessMap ) {
|
|
2265
2160
|
|
|
2266
2161
|
const iridescenceThicknessMapDef = {
|
|
@@ -2278,13 +2173,12 @@
|
|
|
2278
2173
|
}
|
|
2279
2174
|
|
|
2280
2175
|
}
|
|
2176
|
+
|
|
2281
2177
|
/**
|
|
2282
2178
|
* Transmission Materials Extension
|
|
2283
2179
|
*
|
|
2284
2180
|
* Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_transmission
|
|
2285
2181
|
*/
|
|
2286
|
-
|
|
2287
|
-
|
|
2288
2182
|
class GLTFMaterialsTransmissionExtension {
|
|
2289
2183
|
|
|
2290
2184
|
constructor( writer ) {
|
|
@@ -2293,7 +2187,6 @@
|
|
|
2293
2187
|
this.name = 'KHR_materials_transmission';
|
|
2294
2188
|
|
|
2295
2189
|
}
|
|
2296
|
-
|
|
2297
2190
|
writeMaterial( material, materialDef ) {
|
|
2298
2191
|
|
|
2299
2192
|
if ( ! material.isMeshPhysicalMaterial || material.transmission === 0 ) return;
|
|
@@ -2301,7 +2194,6 @@
|
|
|
2301
2194
|
const extensionsUsed = writer.extensionsUsed;
|
|
2302
2195
|
const extensionDef = {};
|
|
2303
2196
|
extensionDef.transmissionFactor = material.transmission;
|
|
2304
|
-
|
|
2305
2197
|
if ( material.transmissionMap ) {
|
|
2306
2198
|
|
|
2307
2199
|
const transmissionMapDef = {
|
|
@@ -2319,13 +2211,12 @@
|
|
|
2319
2211
|
}
|
|
2320
2212
|
|
|
2321
2213
|
}
|
|
2214
|
+
|
|
2322
2215
|
/**
|
|
2323
2216
|
* Materials Volume Extension
|
|
2324
2217
|
*
|
|
2325
2218
|
* Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_volume
|
|
2326
2219
|
*/
|
|
2327
|
-
|
|
2328
|
-
|
|
2329
2220
|
class GLTFMaterialsVolumeExtension {
|
|
2330
2221
|
|
|
2331
2222
|
constructor( writer ) {
|
|
@@ -2334,7 +2225,6 @@
|
|
|
2334
2225
|
this.name = 'KHR_materials_volume';
|
|
2335
2226
|
|
|
2336
2227
|
}
|
|
2337
|
-
|
|
2338
2228
|
writeMaterial( material, materialDef ) {
|
|
2339
2229
|
|
|
2340
2230
|
if ( ! material.isMeshPhysicalMaterial || material.transmission === 0 ) return;
|
|
@@ -2342,7 +2232,6 @@
|
|
|
2342
2232
|
const extensionsUsed = writer.extensionsUsed;
|
|
2343
2233
|
const extensionDef = {};
|
|
2344
2234
|
extensionDef.thicknessFactor = material.thickness;
|
|
2345
|
-
|
|
2346
2235
|
if ( material.thicknessMap ) {
|
|
2347
2236
|
|
|
2348
2237
|
const thicknessMapDef = {
|
|
@@ -2362,26 +2251,22 @@
|
|
|
2362
2251
|
}
|
|
2363
2252
|
|
|
2364
2253
|
}
|
|
2254
|
+
|
|
2365
2255
|
/**
|
|
2366
2256
|
* Static utility functions
|
|
2367
2257
|
*/
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
2258
|
GLTFExporter.Utils = {
|
|
2371
2259
|
insertKeyframe: function ( track, time ) {
|
|
2372
2260
|
|
|
2373
2261
|
const tolerance = 0.001; // 1ms
|
|
2374
|
-
|
|
2375
2262
|
const valueSize = track.getValueSize();
|
|
2376
2263
|
const times = new track.TimeBufferType( track.times.length + 1 );
|
|
2377
2264
|
const values = new track.ValueBufferType( track.values.length + valueSize );
|
|
2378
2265
|
const interpolant = track.createInterpolant( new track.ValueBufferType( valueSize ) );
|
|
2379
2266
|
let index;
|
|
2380
|
-
|
|
2381
2267
|
if ( track.times.length === 0 ) {
|
|
2382
2268
|
|
|
2383
2269
|
times[ 0 ] = time;
|
|
2384
|
-
|
|
2385
2270
|
for ( let i = 0; i < valueSize; i ++ ) {
|
|
2386
2271
|
|
|
2387
2272
|
values[ i ] = 0;
|
|
@@ -2418,7 +2303,6 @@
|
|
|
2418
2303
|
for ( let i = 0; i < track.times.length; i ++ ) {
|
|
2419
2304
|
|
|
2420
2305
|
if ( Math.abs( track.times[ i ] - time ) < tolerance ) return i;
|
|
2421
|
-
|
|
2422
2306
|
if ( track.times[ i ] < time && track.times[ i + 1 ] > time ) {
|
|
2423
2307
|
|
|
2424
2308
|
times.set( track.times.slice( 0, i + 1 ), 0 );
|
|
@@ -2446,13 +2330,11 @@
|
|
|
2446
2330
|
const tracks = [];
|
|
2447
2331
|
const mergedTracks = {};
|
|
2448
2332
|
const sourceTracks = clip.tracks;
|
|
2449
|
-
|
|
2450
2333
|
for ( let i = 0; i < sourceTracks.length; ++ i ) {
|
|
2451
2334
|
|
|
2452
2335
|
let sourceTrack = sourceTracks[ i ];
|
|
2453
2336
|
const sourceTrackBinding = THREE.PropertyBinding.parseTrackName( sourceTrack.name );
|
|
2454
2337
|
const sourceTrackNode = THREE.PropertyBinding.findNode( root, sourceTrackBinding.nodeName );
|
|
2455
|
-
|
|
2456
2338
|
if ( sourceTrackBinding.propertyName !== 'morphTargetInfluences' || sourceTrackBinding.propertyIndex === undefined ) {
|
|
2457
2339
|
|
|
2458
2340
|
// Tracks that don't affect morph targets, or that affect all morph targets together, can be left as-is.
|
|
@@ -2479,29 +2361,28 @@
|
|
|
2479
2361
|
|
|
2480
2362
|
const targetCount = sourceTrackNode.morphTargetInfluences.length;
|
|
2481
2363
|
const targetIndex = sourceTrackNode.morphTargetDictionary[ sourceTrackBinding.propertyIndex ];
|
|
2482
|
-
|
|
2483
2364
|
if ( targetIndex === undefined ) {
|
|
2484
2365
|
|
|
2485
2366
|
throw new Error( 'THREE.GLTFExporter: Morph target name not found: ' + sourceTrackBinding.propertyIndex );
|
|
2486
2367
|
|
|
2487
2368
|
}
|
|
2488
2369
|
|
|
2489
|
-
let mergedTrack;
|
|
2490
|
-
// track to store merged keyframe data for each morph target.
|
|
2370
|
+
let mergedTrack;
|
|
2491
2371
|
|
|
2372
|
+
// If this is the first time we've seen this object, create a new
|
|
2373
|
+
// track to store merged keyframe data for each morph target.
|
|
2492
2374
|
if ( mergedTracks[ sourceTrackNode.uuid ] === undefined ) {
|
|
2493
2375
|
|
|
2494
2376
|
mergedTrack = sourceTrack.clone();
|
|
2495
2377
|
const values = new mergedTrack.ValueBufferType( targetCount * mergedTrack.times.length );
|
|
2496
|
-
|
|
2497
2378
|
for ( let j = 0; j < mergedTrack.times.length; j ++ ) {
|
|
2498
2379
|
|
|
2499
2380
|
values[ j * targetCount + targetIndex ] = mergedTrack.values[ j ];
|
|
2500
2381
|
|
|
2501
|
-
}
|
|
2502
|
-
// of our original un-merged morphTarget animation.
|
|
2503
|
-
|
|
2382
|
+
}
|
|
2504
2383
|
|
|
2384
|
+
// We need to take into consideration the intended target node
|
|
2385
|
+
// of our original un-merged morphTarget animation.
|
|
2505
2386
|
mergedTrack.name = ( sourceTrackBinding.nodeName || '' ) + '.morphTargetInfluences';
|
|
2506
2387
|
mergedTrack.values = values;
|
|
2507
2388
|
mergedTracks[ sourceTrackNode.uuid ] = mergedTrack;
|
|
@@ -2511,18 +2392,19 @@
|
|
|
2511
2392
|
}
|
|
2512
2393
|
|
|
2513
2394
|
const sourceInterpolant = sourceTrack.createInterpolant( new sourceTrack.ValueBufferType( 1 ) );
|
|
2514
|
-
mergedTrack = mergedTracks[ sourceTrackNode.uuid ];
|
|
2515
|
-
// interpolated) value from the source track.
|
|
2395
|
+
mergedTrack = mergedTracks[ sourceTrackNode.uuid ];
|
|
2516
2396
|
|
|
2397
|
+
// For every existing keyframe of the merged track, write a (possibly
|
|
2398
|
+
// interpolated) value from the source track.
|
|
2517
2399
|
for ( let j = 0; j < mergedTrack.times.length; j ++ ) {
|
|
2518
2400
|
|
|
2519
2401
|
mergedTrack.values[ j * targetCount + targetIndex ] = sourceInterpolant.evaluate( mergedTrack.times[ j ] );
|
|
2520
2402
|
|
|
2521
|
-
}
|
|
2403
|
+
}
|
|
2404
|
+
|
|
2405
|
+
// For every existing keyframe of the source track, write a (possibly
|
|
2522
2406
|
// new) keyframe to the merged track. Values from the previous loop may
|
|
2523
2407
|
// be written again, but keyframes are de-duplicated.
|
|
2524
|
-
|
|
2525
|
-
|
|
2526
2408
|
for ( let j = 0; j < sourceTrack.times.length; j ++ ) {
|
|
2527
2409
|
|
|
2528
2410
|
const keyframeIndex = this.insertKeyframe( mergedTrack, sourceTrack.times[ j ] );
|