super-three 0.184.0 → 0.185.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.
Files changed (366) hide show
  1. package/build/three.cjs +1260 -927
  2. package/build/three.core.js +1104 -829
  3. package/build/three.core.min.js +1 -1
  4. package/build/three.module.js +156 -98
  5. package/build/three.module.min.js +1 -1
  6. package/build/three.tsl.js +11 -4
  7. package/build/three.tsl.min.js +1 -1
  8. package/build/three.webgpu.js +7538 -3367
  9. package/build/three.webgpu.min.js +1 -1
  10. package/build/three.webgpu.nodes.js +7538 -3366
  11. package/build/three.webgpu.nodes.min.js +1 -1
  12. package/examples/jsm/Addons.js +3 -0
  13. package/examples/jsm/controls/ArcballControls.js +6 -2
  14. package/examples/jsm/controls/FirstPersonControls.js +79 -42
  15. package/examples/jsm/controls/TransformControls.js +68 -15
  16. package/examples/jsm/csm/CSMFrustum.js +31 -6
  17. package/examples/jsm/csm/CSMShadowNode.js +4 -1
  18. package/examples/jsm/effects/AsciiEffect.js +14 -1
  19. package/examples/jsm/exporters/DRACOExporter.js +27 -6
  20. package/examples/jsm/exporters/GLTFExporter.js +114 -12
  21. package/examples/jsm/exporters/PLYExporter.js +286 -73
  22. package/examples/jsm/exporters/USDZExporter.js +347 -112
  23. package/examples/jsm/generators/CityGenerator.js +346 -0
  24. package/examples/jsm/generators/ForestGenerator.js +347 -0
  25. package/examples/jsm/generators/TerrainGenerator.js +504 -0
  26. package/examples/jsm/generators/TreeGenerator.js +377 -0
  27. package/examples/jsm/generators/city/SidewalkGenerator.js +253 -0
  28. package/examples/jsm/generators/city/SkyscraperGenerator.js +1357 -0
  29. package/examples/jsm/geometries/LoftGeometry.js +355 -0
  30. package/examples/jsm/helpers/LightProbeGridHelper.js +1 -1
  31. package/examples/jsm/helpers/LightProbeHelper.js +5 -4
  32. package/examples/jsm/helpers/ViewHelper.js +16 -6
  33. package/examples/jsm/inspector/Inspector.js +53 -15
  34. package/examples/jsm/inspector/RendererInspector.js +152 -36
  35. package/examples/jsm/inspector/extensions/tsl-graph/TSLGraphEditor.js +1 -1
  36. package/examples/jsm/inspector/extensions/tsl-graph/TSLGraphLoader.js +1 -1
  37. package/examples/jsm/inspector/tabs/Console.js +200 -18
  38. package/examples/jsm/inspector/tabs/Memory.js +8 -0
  39. package/examples/jsm/inspector/tabs/Parameters.js +64 -4
  40. package/examples/jsm/inspector/tabs/Performance.js +21 -6
  41. package/examples/jsm/inspector/tabs/Settings.js +51 -9
  42. package/examples/jsm/inspector/tabs/Timeline.js +178 -93
  43. package/examples/jsm/inspector/tabs/Viewer.js +628 -16
  44. package/examples/jsm/inspector/ui/Graph.js +162 -25
  45. package/examples/jsm/inspector/ui/Item.js +92 -13
  46. package/examples/jsm/inspector/ui/List.js +1 -1
  47. package/examples/jsm/inspector/ui/Profiler.js +90 -45
  48. package/examples/jsm/inspector/ui/Style.js +1788 -1401
  49. package/examples/jsm/inspector/ui/Tab.js +5 -3
  50. package/examples/jsm/inspector/ui/Values.js +71 -6
  51. package/examples/jsm/inspector/ui/utils.js +130 -10
  52. package/examples/jsm/libs/basis/README.md +0 -1
  53. package/examples/jsm/libs/demuxer_mp4.js +3 -3
  54. package/examples/jsm/libs/draco/README.md +0 -1
  55. package/examples/jsm/libs/meshopt_clusterizer.module.js +421 -0
  56. package/examples/jsm/libs/meshopt_simplifier.module.js +627 -0
  57. package/examples/jsm/libs/mikktspace.module.js +34 -9
  58. package/examples/jsm/lighting/ClusteredLighting.js +55 -0
  59. package/examples/jsm/lighting/LightProbeGrid.js +106 -76
  60. package/examples/jsm/lines/LineMaterial.js +38 -15
  61. package/examples/jsm/lines/LineSegments2.js +8 -0
  62. package/examples/jsm/lines/webgpu/LineSegments2.js +8 -0
  63. package/examples/jsm/loaders/3DMLoader.js +1 -1
  64. package/examples/jsm/loaders/DRACOLoader.js +46 -13
  65. package/examples/jsm/loaders/EXRLoader.js +27 -55
  66. package/examples/jsm/loaders/HDRLoader.js +6 -28
  67. package/examples/jsm/loaders/KTX2Loader.js +31 -12
  68. package/examples/jsm/loaders/LDrawLoader.js +8 -8
  69. package/examples/jsm/loaders/LUT3dlLoader.js +2 -2
  70. package/examples/jsm/loaders/LUTCubeLoader.js +2 -2
  71. package/examples/jsm/loaders/LWOLoader.js +4 -0
  72. package/examples/jsm/loaders/LottieLoader.js +1 -1
  73. package/examples/jsm/loaders/MaterialXLoader.js +31 -9
  74. package/examples/jsm/loaders/NRRDLoader.js +3 -3
  75. package/examples/jsm/loaders/PCDLoader.js +7 -7
  76. package/examples/jsm/loaders/PLYLoader.js +218 -55
  77. package/examples/jsm/loaders/SVGLoader.js +547 -495
  78. package/examples/jsm/loaders/TTFLoader.js +1 -1
  79. package/examples/jsm/loaders/USDLoader.js +33 -9
  80. package/examples/jsm/loaders/VRMLLoader.js +1 -1
  81. package/examples/jsm/loaders/usd/USDAParser.js +93 -20
  82. package/examples/jsm/loaders/usd/USDCParser.js +1 -1
  83. package/examples/jsm/loaders/usd/USDComposer.js +52 -19
  84. package/examples/jsm/misc/TileCreasedNormalsPlugin.js +270 -0
  85. package/examples/jsm/misc/Volume.js +2 -2
  86. package/examples/jsm/objects/GroundedSkybox.js +1 -1
  87. package/examples/jsm/objects/Reflector.js +2 -3
  88. package/examples/jsm/objects/Water2Mesh.js +1 -1
  89. package/examples/jsm/physics/AmmoPhysics.js +15 -8
  90. package/examples/jsm/physics/RapierPhysics.js +27 -2
  91. package/examples/jsm/shaders/VolumeShader.js +31 -44
  92. package/examples/jsm/transpiler/GLSLDecoder.js +6 -6
  93. package/examples/jsm/transpiler/Linker.js +1 -1
  94. package/examples/jsm/tsl/display/BloomNode.js +59 -19
  95. package/examples/jsm/tsl/display/DepthOfFieldNode.js +2 -2
  96. package/examples/jsm/tsl/display/FXAANode.js +11 -12
  97. package/examples/jsm/tsl/display/GTAONode.js +34 -13
  98. package/examples/jsm/tsl/display/GodraysNode.js +1 -1
  99. package/examples/jsm/tsl/display/ImportanceSampledEnvironment.js +560 -0
  100. package/examples/jsm/tsl/display/PixelationPassNode.js +2 -2
  101. package/examples/jsm/tsl/display/RecurrentDenoiseNode.js +912 -0
  102. package/examples/jsm/tsl/display/SSAAPassNode.js +13 -25
  103. package/examples/jsm/tsl/display/SSGINode.js +89 -39
  104. package/examples/jsm/tsl/display/SSRNode.js +829 -132
  105. package/examples/jsm/tsl/display/SSSNode.js +2 -2
  106. package/examples/jsm/tsl/display/TemporalReprojectNode.js +1023 -0
  107. package/examples/jsm/tsl/lighting/ClusteredLightsNode.js +622 -0
  108. package/examples/jsm/tsl/lighting/DynamicLightsNode.js +1 -1
  109. package/examples/jsm/tsl/math/curlNoise.js +107 -0
  110. package/examples/jsm/tsl/shadows/TileShadowNode.js +1 -1
  111. package/examples/jsm/tsl/shadows/TileShadowNodeHelper.js +3 -3
  112. package/examples/jsm/tsl/utils/GroundedSkybox.js +62 -0
  113. package/examples/jsm/tsl/utils/RNoise.js +51 -0
  114. package/examples/jsm/tsl/utils/SpecularHelpers.js +325 -0
  115. package/examples/jsm/utils/BufferGeometryUtils.js +126 -59
  116. package/examples/jsm/utils/GeometryCompressionUtils.js +1 -1
  117. package/examples/jsm/utils/SceneOptimizer.js +1 -1
  118. package/examples/jsm/webxr/ARButton.js +1 -1
  119. package/examples/jsm/webxr/WebGLXRFallback.js +89 -0
  120. package/examples/jsm/webxr/XRControllerModelFactory.js +2 -2
  121. package/package.json +7 -7
  122. package/src/Three.TSL.js +10 -3
  123. package/src/Three.WebGPU.js +4 -0
  124. package/src/animation/AnimationAction.js +15 -11
  125. package/src/animation/AnimationClip.js +0 -139
  126. package/src/animation/KeyframeTrack.js +2 -2
  127. package/src/animation/PropertyBinding.js +2 -2
  128. package/src/cameras/Camera.js +2 -2
  129. package/src/cameras/StereoCamera.js +5 -2
  130. package/src/constants.js +1 -1
  131. package/src/core/BufferGeometry.js +29 -7
  132. package/src/core/Object3D.js +17 -7
  133. package/src/core/Raycaster.js +1 -1
  134. package/src/core/RenderTarget.js +15 -2
  135. package/src/extras/PMREMGenerator.js +6 -4
  136. package/src/extras/TextureUtils.js +1 -1
  137. package/src/extras/core/ShapePath.js +149 -160
  138. package/src/geometries/SphereGeometry.js +8 -3
  139. package/src/helpers/DirectionalLightHelper.js +2 -0
  140. package/src/helpers/HemisphereLightHelper.js +2 -0
  141. package/src/helpers/PointLightHelper.js +2 -0
  142. package/src/helpers/SpotLightHelper.js +1 -1
  143. package/src/loaders/DataTextureLoader.js +69 -38
  144. package/src/loaders/LoadingManager.js +5 -0
  145. package/src/loaders/MaterialLoader.js +36 -266
  146. package/src/loaders/ObjectLoader.js +3 -1
  147. package/src/materials/LineBasicMaterial.js +4 -0
  148. package/src/materials/Material.js +196 -1
  149. package/src/materials/MeshBasicMaterial.js +24 -0
  150. package/src/materials/MeshDepthMaterial.js +10 -0
  151. package/src/materials/MeshDistanceMaterial.js +10 -0
  152. package/src/materials/MeshLambertMaterial.js +40 -1
  153. package/src/materials/MeshMatcapMaterial.js +25 -1
  154. package/src/materials/MeshNormalMaterial.js +9 -1
  155. package/src/materials/MeshPhongMaterial.js +40 -1
  156. package/src/materials/MeshPhysicalMaterial.js +38 -0
  157. package/src/materials/MeshStandardMaterial.js +42 -1
  158. package/src/materials/MeshToonMaterial.js +34 -1
  159. package/src/materials/PointsMaterial.js +7 -0
  160. package/src/materials/ShaderMaterial.js +86 -0
  161. package/src/materials/SpriteMaterial.js +7 -0
  162. package/src/materials/nodes/Line2NodeMaterial.js +378 -322
  163. package/src/materials/nodes/MeshBasicNodeMaterial.js +2 -2
  164. package/src/materials/nodes/MeshNormalNodeMaterial.js +2 -2
  165. package/src/materials/nodes/MeshPhongNodeMaterial.js +0 -9
  166. package/src/materials/nodes/MeshPhysicalNodeMaterial.js +0 -30
  167. package/src/materials/nodes/MeshSSSNodeMaterial.js +0 -13
  168. package/src/materials/nodes/MeshStandardNodeMaterial.js +0 -11
  169. package/src/materials/nodes/NodeMaterial.js +115 -71
  170. package/src/materials/nodes/SpriteNodeMaterial.js +0 -10
  171. package/src/materials/nodes/manager/NodeMaterialObserver.js +49 -20
  172. package/src/math/Box3.js +5 -0
  173. package/src/math/FrustumArray.js +103 -133
  174. package/src/math/Interpolant.js +1 -1
  175. package/src/math/MathUtils.js +2 -2
  176. package/src/math/Matrix3.js +11 -0
  177. package/src/math/Matrix4.js +28 -3
  178. package/src/math/Vector2.js +2 -2
  179. package/src/math/Vector3.js +2 -2
  180. package/src/math/Vector4.js +2 -2
  181. package/src/math/interpolants/BezierInterpolant.js +4 -6
  182. package/src/nodes/Nodes.js +2 -5
  183. package/src/nodes/TSL.js +8 -6
  184. package/src/nodes/accessors/Arrays.js +4 -4
  185. package/src/nodes/accessors/Batch.js +108 -0
  186. package/src/nodes/accessors/Bitangent.js +2 -2
  187. package/src/nodes/accessors/BufferAttributeNode.js +13 -2
  188. package/src/nodes/accessors/Camera.js +7 -7
  189. package/src/nodes/accessors/ClippingNode.js +1 -1
  190. package/src/nodes/accessors/Instance.js +264 -0
  191. package/src/nodes/accessors/MaterialNode.js +18 -2
  192. package/src/nodes/accessors/MaterialProperties.js +4 -3
  193. package/src/nodes/accessors/{MorphNode.js → Morph.js} +99 -112
  194. package/src/nodes/accessors/Normal.js +13 -13
  195. package/src/nodes/accessors/Position.js +5 -1
  196. package/src/nodes/accessors/ReferenceNode.js +1 -0
  197. package/src/nodes/accessors/ReflectVector.js +3 -3
  198. package/src/nodes/accessors/SceneProperties.js +1 -1
  199. package/src/nodes/accessors/Skinning.js +263 -0
  200. package/src/nodes/accessors/StorageBufferNode.js +2 -2
  201. package/src/nodes/accessors/StorageTexture3DNode.js +100 -0
  202. package/src/nodes/accessors/StorageTextureNode.js +39 -7
  203. package/src/nodes/accessors/Tangent.js +4 -4
  204. package/src/nodes/accessors/TextureNode.js +60 -5
  205. package/src/nodes/code/FunctionNode.js +2 -16
  206. package/src/nodes/core/MRTNode.js +7 -2
  207. package/src/nodes/core/Node.js +39 -2
  208. package/src/nodes/core/NodeBuilder.js +201 -41
  209. package/src/nodes/core/NodeUtils.js +13 -13
  210. package/src/nodes/core/OutputStructNode.js +1 -1
  211. package/src/nodes/core/OverrideContextNode.js +153 -0
  212. package/src/nodes/core/PropertyNode.js +51 -5
  213. package/src/nodes/core/StackNode.js +56 -34
  214. package/src/nodes/core/StructNode.js +4 -6
  215. package/src/nodes/core/StructTypeNode.js +6 -6
  216. package/src/nodes/core/VarNode.js +8 -0
  217. package/src/nodes/core/VaryingNode.js +12 -2
  218. package/src/nodes/display/BlendModes.js +1 -41
  219. package/src/nodes/display/BumpMapNode.js +6 -1
  220. package/src/nodes/display/ColorAdjustment.js +10 -9
  221. package/src/nodes/display/FrontFacingNode.js +38 -9
  222. package/src/nodes/display/NormalMapNode.js +2 -2
  223. package/src/nodes/display/PassNode.js +35 -43
  224. package/src/nodes/display/PremultiplyAlphaFunctions.js +39 -0
  225. package/src/nodes/display/RenderOutputNode.js +12 -3
  226. package/src/nodes/functions/VolumetricLightingModel.js +40 -7
  227. package/src/nodes/gpgpu/WorkgroupInfoNode.js +1 -1
  228. package/src/nodes/lighting/EnvironmentNode.js +2 -2
  229. package/src/nodes/lighting/IESSpotLightNode.js +40 -2
  230. package/src/nodes/lighting/LightingContextNode.js +10 -2
  231. package/src/nodes/lighting/LightsNode.js +90 -37
  232. package/src/nodes/lighting/PointShadowNode.js +6 -1
  233. package/src/nodes/lighting/ShadowFilterNode.js +21 -52
  234. package/src/nodes/lighting/ShadowNode.js +34 -14
  235. package/src/nodes/materialx/lib/mx_noise.js +2 -2
  236. package/src/nodes/math/ConditionalNode.js +3 -3
  237. package/src/nodes/math/MathNode.js +39 -11
  238. package/src/nodes/math/OperatorNode.js +23 -23
  239. package/src/nodes/parsers/GLSLNodeFunction.js +1 -1
  240. package/src/nodes/pmrem/PMREMNode.js +33 -2
  241. package/src/nodes/tsl/TSLCore.js +63 -18
  242. package/src/nodes/utils/EquirectUV.js +30 -5
  243. package/src/nodes/utils/FunctionOverloadingNode.js +1 -1
  244. package/src/nodes/utils/Packing.js +35 -4
  245. package/src/nodes/utils/RTTNode.js +40 -24
  246. package/src/nodes/utils/ReflectorNode.js +1 -0
  247. package/src/nodes/utils/StorageArrayElementNode.js +1 -1
  248. package/src/objects/BatchedMesh.js +22 -14
  249. package/src/objects/InstancedMesh.js +0 -11
  250. package/src/objects/Skeleton.js +0 -9
  251. package/src/renderers/WebGLRenderer.js +19 -15
  252. package/src/renderers/common/Backend.js +49 -5
  253. package/src/renderers/common/Bindings.js +114 -45
  254. package/src/renderers/common/Buffer.js +9 -0
  255. package/src/renderers/common/ClippingContext.js +10 -2
  256. package/src/renderers/common/Info.js +63 -22
  257. package/src/renderers/common/Lighting.js +53 -5
  258. package/src/renderers/common/RenderList.js +41 -4
  259. package/src/renderers/common/RenderObject.js +73 -13
  260. package/src/renderers/common/Renderer.js +281 -108
  261. package/src/renderers/common/Sampler.js +16 -48
  262. package/src/renderers/common/Textures.js +32 -5
  263. package/src/renderers/common/TimestampQueryPool.js +1 -1
  264. package/src/renderers/common/UniformsGroup.js +31 -9
  265. package/src/renderers/common/XRManager.js +340 -22
  266. package/src/renderers/common/extras/PMREMGenerator.js +15 -38
  267. package/src/renderers/common/nodes/NodeBuilderState.js +9 -1
  268. package/src/renderers/common/nodes/NodeLibrary.js +4 -4
  269. package/src/renderers/common/nodes/NodeManager.js +63 -14
  270. package/src/renderers/common/nodes/NodeUniformBuffer.js +13 -0
  271. package/src/renderers/shaders/ShaderChunk/common.glsl.js +13 -4
  272. package/src/renderers/shaders/ShaderChunk/defaultnormal_vertex.glsl.js +0 -6
  273. package/src/renderers/shaders/ShaderChunk/envmap_fragment.glsl.js +1 -1
  274. package/src/renderers/shaders/ShaderChunk/envmap_physical_pars_fragment.glsl.js +2 -2
  275. package/src/renderers/shaders/ShaderChunk/envmap_vertex.glsl.js +1 -1
  276. package/src/renderers/shaders/ShaderChunk/lights_fragment_begin.glsl.js +1 -1
  277. package/src/renderers/shaders/ShaderChunk/lights_pars_begin.glsl.js +1 -1
  278. package/src/renderers/shaders/ShaderChunk/normal_fragment_begin.glsl.js +2 -2
  279. package/src/renderers/shaders/ShaderChunk/normal_vertex.glsl.js +6 -0
  280. package/src/renderers/shaders/ShaderChunk/shadowmap_vertex.glsl.js +1 -1
  281. package/src/renderers/shaders/ShaderChunk/transmission_fragment.glsl.js +1 -1
  282. package/src/renderers/shaders/ShaderLib/distance.glsl.js +1 -1
  283. package/src/renderers/webgl/WebGLOutput.js +2 -1
  284. package/src/renderers/webgl/WebGLProgram.js +5 -4
  285. package/src/renderers/webgl/WebGLPrograms.js +12 -5
  286. package/src/renderers/webgl/WebGLRenderLists.js +9 -1
  287. package/src/renderers/webgl/WebGLShaderCache.js +5 -11
  288. package/src/renderers/webgl/WebGLTextures.js +20 -7
  289. package/src/renderers/webgl/WebGLUniformsGroups.js +66 -38
  290. package/src/renderers/webgl-fallback/WebGLBackend.js +84 -25
  291. package/src/renderers/webgl-fallback/nodes/GLSLNodeBuilder.js +138 -8
  292. package/src/renderers/webgl-fallback/utils/WebGLAttributeUtils.js +1 -1
  293. package/src/renderers/webgl-fallback/utils/WebGLTextureUtils.js +52 -22
  294. package/src/renderers/webgl-fallback/utils/WebGLUtils.js +4 -2
  295. package/src/renderers/webgpu/WebGPUBackend.js +480 -169
  296. package/src/renderers/webgpu/descriptors/GPUBindGroupDescriptor.js +48 -0
  297. package/src/renderers/webgpu/descriptors/GPUBufferDescriptor.js +57 -0
  298. package/src/renderers/webgpu/descriptors/GPUCommandEncoderDescriptor.js +30 -0
  299. package/src/renderers/webgpu/descriptors/GPUComputePassDescriptor.js +38 -0
  300. package/src/renderers/webgpu/descriptors/GPUComputePipelineDescriptor.js +48 -0
  301. package/src/renderers/webgpu/descriptors/GPUCopyExternalImageDestInfo.js +47 -0
  302. package/src/renderers/webgpu/descriptors/GPUCopyExternalImageSourceInfo.js +50 -0
  303. package/src/renderers/webgpu/descriptors/GPUExtent3D.js +51 -0
  304. package/src/renderers/webgpu/descriptors/GPUPipelineLayoutDescriptor.js +39 -0
  305. package/src/renderers/webgpu/descriptors/GPUQuerySetDescriptor.js +47 -0
  306. package/src/renderers/webgpu/descriptors/GPURenderBundleEncoderDescriptor.js +74 -0
  307. package/src/renderers/webgpu/descriptors/GPURenderPassColorAttachment.js +72 -0
  308. package/src/renderers/webgpu/descriptors/GPURenderPassDepthStencilAttachment.js +99 -0
  309. package/src/renderers/webgpu/descriptors/GPURenderPassDescriptor.js +72 -0
  310. package/src/renderers/webgpu/descriptors/GPURenderPassTimestampWrites.js +49 -0
  311. package/src/renderers/webgpu/descriptors/GPURenderPipelineDescriptor.js +130 -0
  312. package/src/renderers/webgpu/descriptors/GPUSamplerDescriptor.js +119 -0
  313. package/src/renderers/webgpu/descriptors/GPUShaderModuleDescriptor.js +46 -0
  314. package/src/renderers/webgpu/descriptors/GPUTexelCopyBufferInfo.js +57 -0
  315. package/src/renderers/webgpu/descriptors/GPUTexelCopyBufferLayout.js +48 -0
  316. package/src/renderers/webgpu/descriptors/GPUTexelCopyTextureInfo.js +61 -0
  317. package/src/renderers/webgpu/descriptors/GPUTextureDescriptor.js +99 -0
  318. package/src/renderers/webgpu/descriptors/GPUTextureViewDescriptor.js +108 -0
  319. package/src/renderers/webgpu/nodes/StandardNodeLibrary.js +0 -1
  320. package/src/renderers/webgpu/nodes/WGSLNodeBuilder.js +164 -7
  321. package/src/renderers/webgpu/nodes/WGSLNodeFunction.js +1 -1
  322. package/src/renderers/webgpu/utils/WebGPUAttributeUtils.js +98 -38
  323. package/src/renderers/webgpu/utils/WebGPUBindingUtils.js +72 -68
  324. package/src/renderers/webgpu/utils/WebGPUPipelineUtils.js +164 -69
  325. package/src/renderers/webgpu/utils/WebGPUTexturePassUtils.js +158 -95
  326. package/src/renderers/webgpu/utils/WebGPUTextureUtils.js +297 -141
  327. package/src/renderers/webgpu/utils/WebGPUTimestampQueryPool.js +33 -18
  328. package/src/renderers/webgpu/utils/WebGPUUtils.js +38 -3
  329. package/src/textures/DepthTexture.js +1 -1
  330. package/src/textures/ExternalTexture.js +0 -3
  331. package/examples/fonts/LICENSE +0 -13
  332. package/examples/fonts/MPLUSRounded1c/MPLUSRounded1c-Regular.typeface.json.zip +0 -0
  333. package/examples/fonts/MPLUSRounded1c/OFL.txt +0 -91
  334. package/examples/fonts/README.md +0 -11
  335. package/examples/fonts/droid/NOTICE +0 -190
  336. package/examples/fonts/droid/README.txt +0 -18
  337. package/examples/fonts/droid/droid_sans_bold.typeface.json +0 -1
  338. package/examples/fonts/droid/droid_sans_mono_regular.typeface.json +0 -1
  339. package/examples/fonts/droid/droid_sans_regular.typeface.json +0 -1
  340. package/examples/fonts/droid/droid_serif_bold.typeface.json +0 -1
  341. package/examples/fonts/droid/droid_serif_regular.typeface.json +0 -1
  342. package/examples/fonts/gentilis_bold.typeface.json +0 -1
  343. package/examples/fonts/gentilis_regular.typeface.json +0 -1
  344. package/examples/fonts/helvetiker_bold.typeface.json +0 -1
  345. package/examples/fonts/helvetiker_regular.typeface.json +0 -1
  346. package/examples/fonts/optimer_bold.typeface.json +0 -1
  347. package/examples/fonts/optimer_regular.typeface.json +0 -1
  348. package/examples/fonts/ttf/README.md +0 -9
  349. package/examples/fonts/ttf/kenpixel.ttf +0 -0
  350. package/examples/jsm/inspector/extensions/extensions.json +0 -6
  351. package/examples/jsm/libs/ammo.wasm.js +0 -822
  352. package/examples/jsm/libs/ammo.wasm.wasm +0 -0
  353. package/examples/jsm/libs/draco/draco_encoder.js +0 -33
  354. package/examples/jsm/libs/draco/gltf/draco_encoder.js +0 -33
  355. package/examples/jsm/libs/lottie_canvas.module.js +0 -14849
  356. package/examples/jsm/libs/opentype.module.js +0 -14506
  357. package/examples/jsm/libs/rhino3dm/rhino3dm.js +0 -21
  358. package/examples/jsm/libs/rhino3dm/rhino3dm.module.js +0 -16
  359. package/examples/jsm/libs/rhino3dm/rhino3dm.wasm +0 -0
  360. package/examples/jsm/lighting/TiledLighting.js +0 -42
  361. package/examples/jsm/tsl/display/AnamorphicNode.js +0 -293
  362. package/examples/jsm/tsl/lighting/TiledLightsNode.js +0 -442
  363. package/src/nodes/accessors/BatchNode.js +0 -163
  364. package/src/nodes/accessors/InstanceNode.js +0 -349
  365. package/src/nodes/accessors/InstancedMeshNode.js +0 -50
  366. package/src/nodes/accessors/SkinningNode.js +0 -328
@@ -2,6 +2,7 @@ import {
2
2
  NoColorSpace,
3
3
  DoubleSide,
4
4
  Color,
5
+ PropertyBinding,
5
6
  } from 'three';
6
7
 
7
8
  import {
@@ -76,7 +77,7 @@ class USDNode {
76
77
 
77
78
  const properties = this.properties.map( ( l ) => {
78
79
 
79
- const property = l.property;
80
+ const property = l.property.replace( /\n/g, '\n' + pad + '\t' );
80
81
  const metadata = l.metadata.length
81
82
  ? ` (\n${l.metadata.map( ( m ) => `${pad}\t\t${m}` ).join( '\n' )}\n${pad}\t)`
82
83
  : '';
@@ -199,6 +200,8 @@ class USDZExporter {
199
200
  onlyVisible: true,
200
201
  quickLookCompatible: false,
201
202
  maxTextureSize: 1024,
203
+ animations: [],
204
+ animationFrameRate: 60,
202
205
  },
203
206
  options
204
207
  );
@@ -211,6 +214,9 @@ class USDZExporter {
211
214
  // model file should be first in USDZ archive so we init it here
212
215
  files[ modelFileName ] = null;
213
216
 
217
+ const animationTracks = buildAnimationTracks( scene, options.animations );
218
+ options.animationTracks = animationTracks;
219
+
214
220
  const root = new USDNode( 'Root', 'Xform' );
215
221
  const scenesNode = new USDNode( 'Scenes', 'Scope' );
216
222
  scenesNode.addMetadata( 'kind', '"sceneLibrary"' );
@@ -241,7 +247,15 @@ class USDZExporter {
241
247
  const materials = {};
242
248
  const textures = {};
243
249
 
244
- buildHierarchy( scene, sceneNode, materials, usedNames, files, options );
250
+ if ( scene.isScene ) {
251
+
252
+ buildHierarchy( scene, sceneNode, materials, usedNames, files, options );
253
+
254
+ } else {
255
+
256
+ buildNode( scene, sceneNode, materials, usedNames, files, options );
257
+
258
+ }
245
259
 
246
260
  const materialsNode = buildMaterials(
247
261
  materials,
@@ -249,8 +263,12 @@ class USDZExporter {
249
263
  options.quickLookCompatible
250
264
  );
251
265
 
266
+ const timeRange = animationTracks.size > 0
267
+ ? { fps: options.animationFrameRate, endTimeCode: getMaxClipDuration( options.animations ) * options.animationFrameRate }
268
+ : null;
269
+
252
270
  output =
253
- buildHeader() +
271
+ buildHeader( timeRange ) +
254
272
  '\n' +
255
273
  root.toString() +
256
274
  '\n\n' +
@@ -284,11 +302,14 @@ class USDZExporter {
284
302
  texture.flipY,
285
303
  options.maxTextureSize
286
304
  );
305
+
306
+ const mimeType = ( texture.userData.mimeType === 'image/jpeg' ) ? 'image/jpeg' : 'image/png';
307
+
287
308
  const blob = await new Promise( ( resolve ) =>
288
- canvas.toBlob( resolve, 'image/png', 1 )
309
+ canvas.toBlob( resolve, mimeType )
289
310
  );
290
311
 
291
- files[ `textures/Texture_${id}.png` ] = new Uint8Array(
312
+ files[ `textures/Texture_${id}.${getTextureExtension( texture )}` ] = new Uint8Array(
292
313
  await blob.arrayBuffer()
293
314
  );
294
315
 
@@ -363,6 +384,12 @@ function getName( object, namesSet ) {
363
384
 
364
385
  }
365
386
 
387
+ function getTextureExtension( texture ) {
388
+
389
+ return texture.userData.mimeType === 'image/jpeg' ? 'jpg' : 'png';
390
+
391
+ }
392
+
366
393
  function imageToCanvas( image, flipY, maxTextureSize ) {
367
394
 
368
395
  if (
@@ -410,7 +437,15 @@ function imageToCanvas( image, flipY, maxTextureSize ) {
410
437
 
411
438
  const PRECISION = 7;
412
439
 
413
- function buildHeader() {
440
+ function buildHeader( timeRange = null ) {
441
+
442
+ const timeMetadata = timeRange
443
+ ? `
444
+ startTimeCode = 0
445
+ endTimeCode = ${timeRange.endTimeCode}
446
+ timeCodesPerSecond = ${timeRange.fps}
447
+ framesPerSecond = ${timeRange.fps}`
448
+ : '';
414
449
 
415
450
  return `#usda 1.0
416
451
  (
@@ -419,140 +454,292 @@ function buildHeader() {
419
454
  }
420
455
  defaultPrim = "Root"
421
456
  metersPerUnit = 1
422
- upAxis = "Y"
457
+ upAxis = "Y"${timeMetadata}
423
458
  )
424
459
  `;
425
460
 
426
461
  }
427
462
 
463
+ function buildAnimationTracks( scene, clips ) {
464
+
465
+ // Map<Object3D, { position?: KeyframeTrack, quaternion?: KeyframeTrack, scale?: KeyframeTrack }>
466
+ const tracksByObject = new Map();
467
+
468
+ for ( let c = 0; c < clips.length; c ++ ) {
469
+
470
+ const clip = clips[ c ];
471
+
472
+ for ( let t = 0; t < clip.tracks.length; t ++ ) {
473
+
474
+ const track = clip.tracks[ t ];
475
+ const binding = PropertyBinding.parseTrackName( track.name );
476
+ const target = PropertyBinding.findNode( scene, binding.nodeName );
477
+
478
+ if ( target === null || target === undefined ) continue;
479
+
480
+ const property = binding.propertyName;
481
+ if ( property !== 'position' && property !== 'quaternion' && property !== 'scale' ) continue;
482
+
483
+ let entry = tracksByObject.get( target );
484
+ if ( entry === undefined ) {
485
+
486
+ entry = {};
487
+ tracksByObject.set( target, entry );
488
+
489
+ }
490
+
491
+ entry[ property ] = track;
492
+
493
+ }
494
+
495
+ }
496
+
497
+ return tracksByObject;
498
+
499
+ }
500
+
501
+ function getMaxClipDuration( clips ) {
502
+
503
+ let max = 0;
504
+ for ( let i = 0; i < clips.length; i ++ ) {
505
+
506
+ if ( clips[ i ].duration > max ) max = clips[ i ].duration;
507
+
508
+ }
509
+
510
+ return max;
511
+
512
+ }
513
+
514
+ function buildVector3TimeSamples( opName, opType, track, fps ) {
515
+
516
+ const times = track.times;
517
+ const values = track.values;
518
+ const samples = [];
519
+
520
+ for ( let i = 0; i < times.length; i ++ ) {
521
+
522
+ const o = i * 3;
523
+ samples.push( `${( times[ i ] * fps ).toPrecision( PRECISION )}: (${values[ o ].toPrecision( PRECISION )}, ${values[ o + 1 ].toPrecision( PRECISION )}, ${values[ o + 2 ].toPrecision( PRECISION )})` );
524
+
525
+ }
526
+
527
+ return `${opType} ${opName}.timeSamples = {\n\t${samples.join( ',\n\t' )},\n}`;
528
+
529
+ }
530
+
531
+ function buildQuaternionTimeSamples( track, fps ) {
532
+
533
+ const times = track.times;
534
+ const values = track.values;
535
+ const samples = [];
536
+
537
+ // three.js quaternion order: (x, y, z, w); USD quatf order: (w, x, y, z)
538
+ for ( let i = 0; i < times.length; i ++ ) {
539
+
540
+ const o = i * 4;
541
+ samples.push( `${( times[ i ] * fps ).toPrecision( PRECISION )}: (${values[ o + 3 ].toPrecision( PRECISION )}, ${values[ o ].toPrecision( PRECISION )}, ${values[ o + 1 ].toPrecision( PRECISION )}, ${values[ o + 2 ].toPrecision( PRECISION )})` );
542
+
543
+ }
544
+
545
+ return `quatf xformOp:orient.timeSamples = {\n\t${samples.join( ',\n\t' )},\n}`;
546
+
547
+ }
548
+
428
549
  // Xform
429
550
 
430
551
  function buildHierarchy( object, parentNode, materials, usedNames, files, options ) {
431
552
 
432
553
  for ( let i = 0, l = object.children.length; i < l; i ++ ) {
433
554
 
434
- const child = object.children[ i ];
555
+ buildNode( object.children[ i ], parentNode, materials, usedNames, files, options );
435
556
 
436
- if ( child.visible === false && options.onlyVisible === true ) continue;
557
+ }
437
558
 
438
- let childNode;
559
+ }
439
560
 
440
- if ( child.isMesh ) {
561
+ function buildNode( object, parentNode, materials, usedNames, files, options ) {
441
562
 
442
- const geometry = child.geometry;
443
- const material = child.material;
563
+ if ( object.visible === false && options.onlyVisible === true ) return;
444
564
 
445
- if ( material.isMeshStandardMaterial ) {
565
+ let childNode;
446
566
 
447
- const geometryFileName = 'geometries/Geometry_' + geometry.id + '.usda';
567
+ if ( object.isMesh ) {
448
568
 
449
- if ( ! ( geometryFileName in files ) ) {
569
+ const geometry = object.geometry;
570
+ const isMultiMaterial = Array.isArray( object.material );
450
571
 
451
- const meshObject = buildMeshObject( geometry );
452
- files[ geometryFileName ] = strToU8(
453
- buildHeader() + '\n' + meshObject.toString()
454
- );
572
+ const meshMaterials = isMultiMaterial ? object.material : [ object.material ];
455
573
 
456
- }
574
+ for ( let i = 0; i < meshMaterials.length; i ++ ) {
457
575
 
458
- if ( ! ( material.uuid in materials ) ) {
576
+ const material = meshMaterials[ i ];
459
577
 
460
- materials[ material.uuid ] = material;
578
+ if ( ! material.isMeshStandardMaterial ) {
461
579
 
462
- }
580
+ console.warn( 'THREE.USDZExporter: Use MeshStandardMaterial for best results.' );
463
581
 
464
- childNode = buildMesh(
465
- child,
466
- geometry,
467
- materials[ material.uuid ],
468
- usedNames
469
- );
582
+ }
470
583
 
471
- } else {
584
+ if ( ! ( material.uuid in materials ) ) {
472
585
 
473
- console.warn(
474
- 'THREE.USDZExporter: Unsupported material type (USDZ only supports MeshStandardMaterial)',
475
- child
476
- );
586
+ materials[ material.uuid ] = material;
477
587
 
478
588
  }
479
589
 
480
- } else if ( child.isCamera ) {
590
+ }
481
591
 
482
- childNode = buildCamera( child, usedNames );
592
+ const resolvedMaterials = meshMaterials.map( ( m ) => materials[ m.uuid ] );
483
593
 
484
- } else {
594
+ if ( isMultiMaterial === false ) {
485
595
 
486
- childNode = buildXform( child, usedNames );
596
+ const geometryFileName = `geometries/Geometry_${geometry.id}.usda`;
487
597
 
488
- }
598
+ if ( ! ( geometryFileName in files ) ) {
489
599
 
490
- if ( childNode ) {
600
+ const meshObject = buildMeshObject( geometry );
601
+ files[ geometryFileName ] = strToU8(
602
+ buildHeader() + '\n' + meshObject.toString()
603
+ );
491
604
 
492
- parentNode.addChild( childNode );
493
- buildHierarchy( child, childNode, materials, usedNames, files, options );
605
+ }
494
606
 
495
607
  }
496
608
 
609
+ childNode = buildMesh(
610
+ object,
611
+ geometry,
612
+ resolvedMaterials,
613
+ usedNames,
614
+ options
615
+ );
616
+
617
+ } else if ( object.isCamera ) {
618
+
619
+ childNode = buildCamera( object, usedNames, options );
620
+
621
+ } else {
622
+
623
+ childNode = buildXform( object, usedNames, options );
624
+
497
625
  }
498
626
 
627
+ parentNode.addChild( childNode );
628
+ buildHierarchy( object, childNode, materials, usedNames, files, options );
629
+
499
630
  }
500
631
 
501
- function buildXform( object, usedNames ) {
632
+ function addTransformProperties( node, object, options ) {
502
633
 
503
- const name = getName( object, usedNames );
634
+ const animTracks = options.animationTracks.get( object );
635
+ const hasPivot = object.pivot !== null;
504
636
 
505
- if ( object.matrix.determinant() < 0 ) {
637
+ if ( ! hasPivot && animTracks === undefined ) {
506
638
 
507
- console.warn(
508
- 'THREE.USDZExporter: USDZ does not support negative scales',
509
- object
510
- );
639
+ const transform = buildMatrix( object.matrix );
640
+ node.addProperty( `matrix4d xformOp:transform = ${transform}` );
641
+ node.addProperty( 'uniform token[] xformOpOrder = ["xformOp:transform"]' );
642
+ return;
511
643
 
512
644
  }
513
645
 
514
- const node = new USDNode( name, 'Xform' );
646
+ // Per-op layout: animated channels use timeSamples, others stay static.
647
+ // Pivot ops (when present) are always static.
515
648
 
516
- if ( object.pivot !== null ) {
649
+ const fps = options.animationFrameRate;
650
+ const p = object.position;
651
+ const q = object.quaternion;
652
+ const s = object.scale;
517
653
 
518
- // Export with pivot using separate transform ops
519
- const p = object.position;
520
- const q = object.quaternion;
521
- const s = object.scale;
522
- const piv = object.pivot;
654
+ if ( animTracks !== undefined && animTracks.position !== undefined ) {
655
+
656
+ node.addProperty( buildVector3TimeSamples( 'xformOp:translate', 'float3', animTracks.position, fps ) );
657
+
658
+ } else {
523
659
 
524
660
  node.addProperty( `float3 xformOp:translate = (${p.x.toPrecision( PRECISION )}, ${p.y.toPrecision( PRECISION )}, ${p.z.toPrecision( PRECISION )})` );
661
+
662
+ }
663
+
664
+ if ( hasPivot ) {
665
+
666
+ const piv = object.pivot;
525
667
  node.addProperty( `float3 xformOp:translate:pivot = (${piv.x.toPrecision( PRECISION )}, ${piv.y.toPrecision( PRECISION )}, ${piv.z.toPrecision( PRECISION )})` );
668
+
669
+ }
670
+
671
+ if ( animTracks !== undefined && animTracks.quaternion !== undefined ) {
672
+
673
+ node.addProperty( buildQuaternionTimeSamples( animTracks.quaternion, fps ) );
674
+
675
+ } else {
676
+
526
677
  node.addProperty( `quatf xformOp:orient = (${q.w.toPrecision( PRECISION )}, ${q.x.toPrecision( PRECISION )}, ${q.y.toPrecision( PRECISION )}, ${q.z.toPrecision( PRECISION )})` );
678
+
679
+ }
680
+
681
+ if ( animTracks !== undefined && animTracks.scale !== undefined ) {
682
+
683
+ node.addProperty( buildVector3TimeSamples( 'xformOp:scale', 'float3', animTracks.scale, fps ) );
684
+
685
+ } else {
686
+
527
687
  node.addProperty( `float3 xformOp:scale = (${s.x.toPrecision( PRECISION )}, ${s.y.toPrecision( PRECISION )}, ${s.z.toPrecision( PRECISION )})` );
688
+
689
+ }
690
+
691
+ if ( hasPivot ) {
692
+
528
693
  node.addProperty( 'uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:translate:pivot", "xformOp:orient", "xformOp:scale", "!invert!xformOp:translate:pivot"]' );
529
694
 
530
695
  } else {
531
696
 
532
- // Export as single transform matrix
533
- const transform = buildMatrix( object.matrix );
534
- node.addProperty( `matrix4d xformOp:transform = ${transform}` );
535
- node.addProperty( 'uniform token[] xformOpOrder = ["xformOp:transform"]' );
697
+ node.addProperty( 'uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"]' );
536
698
 
537
699
  }
538
700
 
701
+ }
702
+
703
+ function buildXform( object, usedNames, options ) {
704
+
705
+ const name = getName( object, usedNames );
706
+
707
+ if ( object.matrix.determinant() < 0 ) {
708
+
709
+ console.warn(
710
+ 'THREE.USDZExporter: USDZ does not support negative scales',
711
+ object
712
+ );
713
+
714
+ }
715
+
716
+ const node = new USDNode( name, 'Xform' );
717
+ addTransformProperties( node, object, options );
718
+
539
719
  return node;
540
720
 
541
721
  }
542
722
 
543
- function buildMesh( object, geometry, material, usedNames ) {
723
+ function buildMesh( object, geometry, materials, usedNames, options ) {
544
724
 
545
- const node = buildXform( object, usedNames );
725
+ const node = buildXform( object, usedNames, options );
546
726
 
547
- node.addMetadata(
548
- 'prepend references',
549
- `@./geometries/Geometry_${geometry.id}.usda@</Geometry>`
550
- );
551
- node.addMetadata( 'prepend apiSchemas', '["MaterialBindingAPI"]' );
727
+ if ( materials.length === 1 ) {
552
728
 
553
- node.addProperty(
554
- `rel material:binding = </Materials/Material_${material.id}>`
555
- );
729
+ node.addMetadata(
730
+ 'prepend references',
731
+ `@./geometries/Geometry_${geometry.id}.usda@</Geometry>`
732
+ );
733
+ node.addMetadata( 'prepend apiSchemas', '["MaterialBindingAPI"]' );
734
+ node.addProperty(
735
+ `rel material:binding = </Materials/Material_${materials[ 0 ].id}>`
736
+ );
737
+
738
+ } else {
739
+
740
+ node.addChild( buildMeshNode( geometry, materials ) );
741
+
742
+ }
556
743
 
557
744
  return node;
558
745
 
@@ -590,7 +777,7 @@ function buildMeshObject( geometry ) {
590
777
 
591
778
  }
592
779
 
593
- function buildMeshNode( geometry ) {
780
+ function buildMeshNode( geometry, materials = null ) {
594
781
 
595
782
  const name = 'Geometry';
596
783
  const attributes = geometry.attributes;
@@ -642,6 +829,41 @@ function buildMeshNode( geometry ) {
642
829
 
643
830
  node.addProperty( 'uniform token subdivisionScheme = "none"' );
644
831
 
832
+ if ( materials !== null ) {
833
+
834
+ const groups = geometry.groups;
835
+
836
+ const totalFaces = ( geometry.index !== null
837
+ ? geometry.index.count
838
+ : attributes.position.count ) / 3;
839
+
840
+ for ( let i = 0; i < groups.length; i ++ ) {
841
+
842
+ const group = groups[ i ];
843
+ const material = materials[ group.materialIndex ];
844
+
845
+ if ( material === undefined ) continue;
846
+
847
+ const startFace = Math.floor( group.start / 3 );
848
+ const endFace = Math.min( startFace + Math.floor( group.count / 3 ), totalFaces );
849
+
850
+ const indices = [];
851
+ for ( let j = startFace; j < endFace; j ++ ) indices.push( j );
852
+
853
+ const subsetNode = new USDNode( `subset_${i}`, 'GeomSubset' );
854
+ subsetNode.addMetadata( 'prepend apiSchemas', '["MaterialBindingAPI"]' );
855
+ subsetNode.addProperty( 'uniform token elementType = "face"' );
856
+ subsetNode.addProperty( 'uniform token familyName = "materialBind"' );
857
+ subsetNode.addProperty( `int[] indices = [${indices.join( ', ' )}]` );
858
+ subsetNode.addProperty(
859
+ `rel material:binding = </Materials/Material_${material.id}>`
860
+ );
861
+ node.addChild( subsetNode );
862
+
863
+ }
864
+
865
+ }
866
+
645
867
  return node;
646
868
 
647
869
  }
@@ -839,21 +1061,27 @@ function buildMaterial( material, textures, quickLookCompatible = false ) {
839
1061
  'Shader'
840
1062
  );
841
1063
  textureNode.addProperty( 'uniform token info:id = "UsdUVTexture"' );
842
- textureNode.addProperty( `asset inputs:file = @textures/Texture_${id}.png@` );
1064
+ textureNode.addProperty( `asset inputs:file = @textures/Texture_${id}.${getTextureExtension( texture )}@` );
843
1065
  textureNode.addProperty(
844
1066
  `float2 inputs:st.connect = </Materials/Material_${material.id}/Transform2d_${mapType}.outputs:result>`
845
1067
  );
846
1068
 
847
1069
  if ( color !== undefined ) {
848
1070
 
849
- textureNode.addProperty( `float4 inputs:scale = ${buildColor4( color )}` );
1071
+ const alpha = ( mapType === 'diffuse' ) ? material.opacity : 1;
1072
+ textureNode.addProperty( `float4 inputs:scale = ${buildColor4( color, alpha )}` );
850
1073
 
851
1074
  }
852
1075
 
853
1076
  if ( mapType === 'normal' ) {
854
1077
 
855
- textureNode.addProperty( 'float4 inputs:scale = (2, 2, 2, 1)' );
856
- textureNode.addProperty( 'float4 inputs:bias = (-1, -1, -1, 0)' );
1078
+ // Similar to GLTFExporter, only the x component is used so the y-negation that
1079
+ // GLTFLoader applies to tangent-less glTF assets is not baked into the export.
1080
+
1081
+ const scale = material.normalScale.x;
1082
+
1083
+ textureNode.addProperty( `float4 inputs:scale = (${ 2 * scale }, ${ 2 * scale }, 2, 1)` );
1084
+ textureNode.addProperty( `float4 inputs:bias = (${ - scale }, ${ - scale }, -1, 0)` );
857
1085
 
858
1086
  }
859
1087
 
@@ -933,33 +1161,39 @@ function buildMaterial( material, textures, quickLookCompatible = false ) {
933
1161
 
934
1162
  }
935
1163
 
936
- if ( material.emissiveMap !== null ) {
1164
+ if ( material.emissive ) {
937
1165
 
938
- previewSurfaceNode.addProperty(
939
- `color3f inputs:emissiveColor.connect = </Materials/Material_${material.id}/Texture_${material.emissiveMap.id}_emissive.outputs:rgb>`
940
- );
1166
+ const emissiveIntensity = material.emissiveIntensity ?? 1;
941
1167
 
942
- const emissiveColor = new Color(
943
- material.emissive.r * material.emissiveIntensity,
944
- material.emissive.g * material.emissiveIntensity,
945
- material.emissive.b * material.emissiveIntensity
946
- );
947
- const textureNodes = buildTextureNodes(
948
- material.emissiveMap,
949
- 'emissive',
950
- emissiveColor
951
- );
952
- textureNodes.forEach( ( node ) => materialNode.addChild( node ) );
1168
+ if ( material.emissiveMap ) {
953
1169
 
954
- } else if ( material.emissive.getHex() > 0 ) {
1170
+ previewSurfaceNode.addProperty(
1171
+ `color3f inputs:emissiveColor.connect = </Materials/Material_${material.id}/Texture_${material.emissiveMap.id}_emissive.outputs:rgb>`
1172
+ );
955
1173
 
956
- previewSurfaceNode.addProperty(
957
- `color3f inputs:emissiveColor = ${buildColor( material.emissive )}`
958
- );
1174
+ const emissiveColor = new Color(
1175
+ material.emissive.r * emissiveIntensity,
1176
+ material.emissive.g * emissiveIntensity,
1177
+ material.emissive.b * emissiveIntensity
1178
+ );
1179
+ const textureNodes = buildTextureNodes(
1180
+ material.emissiveMap,
1181
+ 'emissive',
1182
+ emissiveColor
1183
+ );
1184
+ textureNodes.forEach( ( node ) => materialNode.addChild( node ) );
1185
+
1186
+ } else if ( material.emissive.getHex() > 0 ) {
1187
+
1188
+ previewSurfaceNode.addProperty(
1189
+ `color3f inputs:emissiveColor = ${buildColor( material.emissive )}`
1190
+ );
1191
+
1192
+ }
959
1193
 
960
1194
  }
961
1195
 
962
- if ( material.normalMap !== null ) {
1196
+ if ( material.normalMap ) {
963
1197
 
964
1198
  previewSurfaceNode.addProperty(
965
1199
  `normal3f inputs:normal.connect = </Materials/Material_${material.id}/Texture_${material.normalMap.id}_normal.outputs:rgb>`
@@ -970,16 +1204,17 @@ function buildMaterial( material, textures, quickLookCompatible = false ) {
970
1204
 
971
1205
  }
972
1206
 
973
- if ( material.aoMap !== null ) {
1207
+ if ( material.aoMap ) {
974
1208
 
975
1209
  previewSurfaceNode.addProperty(
976
1210
  `float inputs:occlusion.connect = </Materials/Material_${material.id}/Texture_${material.aoMap.id}_occlusion.outputs:r>`
977
1211
  );
978
1212
 
1213
+ const aoMapIntensity = material.aoMapIntensity ?? 1;
979
1214
  const aoColor = new Color(
980
- material.aoMapIntensity,
981
- material.aoMapIntensity,
982
- material.aoMapIntensity
1215
+ aoMapIntensity,
1216
+ aoMapIntensity,
1217
+ aoMapIntensity
983
1218
  );
984
1219
  const textureNodes = buildTextureNodes(
985
1220
  material.aoMap,
@@ -990,7 +1225,7 @@ function buildMaterial( material, textures, quickLookCompatible = false ) {
990
1225
 
991
1226
  }
992
1227
 
993
- if ( material.roughnessMap !== null ) {
1228
+ if ( material.roughnessMap ) {
994
1229
 
995
1230
  previewSurfaceNode.addProperty(
996
1231
  `float inputs:roughness.connect = </Materials/Material_${material.id}/Texture_${material.roughnessMap.id}_roughness.outputs:g>`
@@ -1011,12 +1246,12 @@ function buildMaterial( material, textures, quickLookCompatible = false ) {
1011
1246
  } else {
1012
1247
 
1013
1248
  previewSurfaceNode.addProperty(
1014
- `float inputs:roughness = ${material.roughness}`
1249
+ `float inputs:roughness = ${material.roughness ?? 1}`
1015
1250
  );
1016
1251
 
1017
1252
  }
1018
1253
 
1019
- if ( material.metalnessMap !== null ) {
1254
+ if ( material.metalnessMap ) {
1020
1255
 
1021
1256
  previewSurfaceNode.addProperty(
1022
1257
  `float inputs:metallic.connect = </Materials/Material_${material.id}/Texture_${material.metalnessMap.id}_metallic.outputs:b>`
@@ -1037,12 +1272,12 @@ function buildMaterial( material, textures, quickLookCompatible = false ) {
1037
1272
  } else {
1038
1273
 
1039
1274
  previewSurfaceNode.addProperty(
1040
- `float inputs:metallic = ${material.metalness}`
1275
+ `float inputs:metallic = ${material.metalness ?? 0}`
1041
1276
  );
1042
1277
 
1043
1278
  }
1044
1279
 
1045
- if ( material.alphaMap !== null ) {
1280
+ if ( material.alphaMap ) {
1046
1281
 
1047
1282
  previewSurfaceNode.addProperty(
1048
1283
  `float inputs:opacity.connect = </Materials/Material_${material.id}/Texture_${material.alphaMap.id}_opacity.outputs:r>`
@@ -1137,9 +1372,9 @@ function buildColor( color ) {
1137
1372
 
1138
1373
  }
1139
1374
 
1140
- function buildColor4( color ) {
1375
+ function buildColor4( color, alpha = 1 ) {
1141
1376
 
1142
- return `(${color.r}, ${color.g}, ${color.b}, 1.0)`;
1377
+ return `(${color.r}, ${color.g}, ${color.b}, ${alpha})`;
1143
1378
 
1144
1379
  }
1145
1380
 
@@ -1149,12 +1384,10 @@ function buildVector2( vector ) {
1149
1384
 
1150
1385
  }
1151
1386
 
1152
- function buildCamera( camera, usedNames ) {
1387
+ function buildCamera( camera, usedNames, options ) {
1153
1388
 
1154
1389
  const name = getName( camera, usedNames );
1155
1390
 
1156
- const transform = buildMatrix( camera.matrix );
1157
-
1158
1391
  if ( camera.matrix.determinant() < 0 ) {
1159
1392
 
1160
1393
  console.warn(
@@ -1165,8 +1398,7 @@ function buildCamera( camera, usedNames ) {
1165
1398
  }
1166
1399
 
1167
1400
  const node = new USDNode( name, 'Camera' );
1168
- node.addProperty( `matrix4d xformOp:transform = ${transform}` );
1169
- node.addProperty( 'uniform token[] xformOpOrder = ["xformOp:transform"]' );
1401
+ addTransformProperties( node, camera, options );
1170
1402
 
1171
1403
  const projection = camera.isOrthographicCamera
1172
1404
  ? 'orthographic'
@@ -1235,6 +1467,9 @@ function buildCamera( camera, usedNames ) {
1235
1467
  * can be configured via `ar.anchoring.type` and `ar.planeAnchoring.alignment`.
1236
1468
  * @property {boolean} [quickLookCompatible=false] - Whether to make the exported USDZ compatible to QuickLook
1237
1469
  * which means the asset is modified to accommodate the bugs FB10036297 and FB11442287 (Apple Feedback).
1470
+ * @property {Array<AnimationClip>} [animations=[]] - Animation clips to bake into `xformOp` time samples on the
1471
+ * targeted objects. Only `position`, `quaternion`, and `scale` tracks are exported.
1472
+ * @property {number} [animationFrameRate=60] - Time codes per second used when writing animation samples.
1238
1473
  **/
1239
1474
 
1240
1475
  /**