@plastic-software/three 0.182.0 → 0.183.1

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 (299) hide show
  1. package/LICENSE +1 -1
  2. package/build/three.cjs +11521 -10878
  3. package/build/three.core.js +11732 -11340
  4. package/build/three.core.min.js +2 -2
  5. package/build/three.module.js +510 -263
  6. package/build/three.module.min.js +2 -2
  7. package/build/three.tsl.js +7 -11
  8. package/build/three.tsl.min.js +2 -2
  9. package/build/three.webgpu.js +3072 -2607
  10. package/build/three.webgpu.min.js +2 -2
  11. package/build/three.webgpu.nodes.js +3071 -2607
  12. package/build/three.webgpu.nodes.min.js +2 -2
  13. package/examples/jsm/Addons.js +0 -3
  14. package/examples/jsm/animation/CCDIKSolver.js +2 -2
  15. package/examples/jsm/controls/ArcballControls.js +3 -3
  16. package/examples/jsm/controls/OrbitControls.js +103 -0
  17. package/examples/jsm/effects/AnaglyphEffect.js +102 -7
  18. package/examples/jsm/environments/ColorEnvironment.js +59 -0
  19. package/examples/jsm/environments/RoomEnvironment.js +1 -0
  20. package/examples/jsm/exporters/EXRExporter.js +1 -1
  21. package/examples/jsm/exporters/GLTFExporter.js +131 -4
  22. package/examples/jsm/exporters/USDZExporter.js +22 -3
  23. package/examples/jsm/helpers/AnimationPathHelper.js +302 -0
  24. package/examples/jsm/helpers/ViewHelper.js +67 -8
  25. package/examples/jsm/inspector/Inspector.js +21 -5
  26. package/examples/jsm/inspector/tabs/Console.js +39 -5
  27. package/examples/jsm/inspector/tabs/Parameters.js +16 -0
  28. package/examples/jsm/inspector/ui/Style.js +25 -1
  29. package/examples/jsm/libs/meshopt_decoder.module.js +6 -5
  30. package/examples/jsm/lines/LineMaterial.js +6 -0
  31. package/examples/jsm/loaders/3MFLoader.js +2 -2
  32. package/examples/jsm/loaders/AMFLoader.js +2 -2
  33. package/examples/jsm/loaders/ColladaLoader.js +24 -4026
  34. package/examples/jsm/loaders/EXRLoader.js +5 -5
  35. package/examples/jsm/loaders/FBXLoader.js +2 -2
  36. package/examples/jsm/loaders/GCodeLoader.js +34 -8
  37. package/examples/jsm/loaders/GLTFLoader.js +122 -171
  38. package/examples/jsm/loaders/KMZLoader.js +5 -5
  39. package/examples/jsm/loaders/KTX2Loader.js +5 -5
  40. package/examples/jsm/loaders/LWOLoader.js +7 -39
  41. package/examples/jsm/loaders/NRRDLoader.js +2 -2
  42. package/examples/jsm/loaders/PCDLoader.js +3 -2
  43. package/examples/jsm/loaders/USDLoader.js +100 -40
  44. package/examples/jsm/loaders/UltraHDRLoader.js +182 -30
  45. package/examples/jsm/loaders/VRMLLoader.js +77 -0
  46. package/examples/jsm/loaders/VTKLoader.js +37 -24
  47. package/examples/jsm/loaders/collada/ColladaComposer.js +2950 -0
  48. package/examples/jsm/loaders/collada/ColladaParser.js +1962 -0
  49. package/examples/jsm/loaders/usd/USDAParser.js +447 -366
  50. package/examples/jsm/loaders/usd/USDCParser.js +1841 -6
  51. package/examples/jsm/loaders/usd/USDComposer.js +4041 -0
  52. package/examples/jsm/materials/LDrawConditionalLineNodeMaterial.js +2 -2
  53. package/examples/jsm/objects/LensflareMesh.js +1 -1
  54. package/examples/jsm/objects/Sky.js +76 -4
  55. package/examples/jsm/objects/SkyMesh.js +114 -7
  56. package/examples/jsm/objects/Water.js +4 -3
  57. package/examples/jsm/objects/Water2.js +5 -3
  58. package/examples/jsm/objects/WaterMesh.js +5 -7
  59. package/examples/jsm/physics/JoltPhysics.js +7 -5
  60. package/examples/jsm/physics/RapierPhysics.js +6 -4
  61. package/examples/jsm/postprocessing/EffectComposer.js +7 -5
  62. package/examples/jsm/postprocessing/RenderTransitionPass.js +1 -1
  63. package/examples/jsm/renderers/CSS3DRenderer.js +1 -1
  64. package/examples/jsm/renderers/SVGRenderer.js +2 -2
  65. package/examples/jsm/shaders/GTAOShader.js +19 -6
  66. package/examples/jsm/shaders/HalftoneShader.js +12 -1
  67. package/examples/jsm/shaders/PoissonDenoiseShader.js +6 -2
  68. package/examples/jsm/shaders/SAOShader.js +17 -4
  69. package/examples/jsm/shaders/SSAOShader.js +11 -1
  70. package/examples/jsm/shaders/SSRShader.js +6 -5
  71. package/examples/jsm/shaders/VignetteShader.js +1 -1
  72. package/examples/jsm/tsl/display/AfterImageNode.js +1 -1
  73. package/examples/jsm/tsl/display/AnaglyphPassNode.js +456 -16
  74. package/examples/jsm/tsl/display/AnamorphicNode.js +1 -1
  75. package/examples/jsm/tsl/display/BilateralBlurNode.js +364 -0
  76. package/examples/jsm/tsl/display/BloomNode.js +5 -5
  77. package/examples/jsm/tsl/display/CRT.js +150 -0
  78. package/examples/jsm/tsl/display/DenoiseNode.js +1 -1
  79. package/examples/jsm/tsl/display/DepthOfFieldNode.js +1 -1
  80. package/examples/jsm/tsl/display/DotScreenNode.js +1 -1
  81. package/examples/jsm/tsl/display/FXAANode.js +2 -2
  82. package/examples/jsm/tsl/display/GTAONode.js +2 -2
  83. package/examples/jsm/tsl/display/GaussianBlurNode.js +11 -2
  84. package/examples/jsm/tsl/display/GodraysNode.js +624 -0
  85. package/examples/jsm/tsl/display/LensflareNode.js +1 -1
  86. package/examples/jsm/tsl/display/Lut3DNode.js +1 -1
  87. package/examples/jsm/tsl/display/OutlineNode.js +3 -3
  88. package/examples/jsm/tsl/display/ParallaxBarrierPassNode.js +2 -2
  89. package/examples/jsm/tsl/display/PixelationPassNode.js +5 -5
  90. package/examples/jsm/tsl/display/RGBShiftNode.js +2 -2
  91. package/examples/jsm/tsl/display/RetroPassNode.js +263 -0
  92. package/examples/jsm/tsl/display/SMAANode.js +2 -2
  93. package/examples/jsm/tsl/display/SSAAPassNode.js +2 -2
  94. package/examples/jsm/tsl/display/SSGINode.js +2 -2
  95. package/examples/jsm/tsl/display/SSRNode.js +7 -7
  96. package/examples/jsm/tsl/display/SSSNode.js +2 -2
  97. package/examples/jsm/tsl/display/Shape.js +29 -0
  98. package/examples/jsm/tsl/display/SobelOperatorNode.js +2 -2
  99. package/examples/jsm/tsl/display/StereoPassNode.js +1 -2
  100. package/examples/jsm/tsl/display/TRAANode.js +9 -12
  101. package/examples/jsm/tsl/display/TransitionNode.js +1 -1
  102. package/examples/jsm/tsl/display/depthAwareBlend.js +80 -0
  103. package/examples/jsm/tsl/math/Bayer.js +40 -1
  104. package/examples/jsm/utils/LDrawUtils.js +1 -1
  105. package/package.json +11 -19
  106. package/src/Three.Core.js +1 -1
  107. package/src/Three.TSL.js +5 -9
  108. package/src/Three.WebGPU.Nodes.js +2 -0
  109. package/src/Three.WebGPU.js +3 -0
  110. package/src/Three.js +1 -0
  111. package/src/animation/AnimationAction.js +1 -1
  112. package/src/animation/AnimationClip.js +1 -1
  113. package/src/animation/AnimationMixer.js +6 -0
  114. package/src/animation/KeyframeTrack.js +46 -7
  115. package/src/animation/PropertyMixer.js +4 -4
  116. package/src/audio/Audio.js +1 -1
  117. package/src/audio/AudioListener.js +5 -3
  118. package/src/cameras/Camera.js +32 -2
  119. package/src/cameras/CubeCamera.js +20 -0
  120. package/src/constants.js +30 -1
  121. package/src/core/Clock.js +7 -0
  122. package/src/core/Object3D.js +56 -4
  123. package/src/core/RenderTarget.js +3 -4
  124. package/src/extras/PMREMGenerator.js +4 -8
  125. package/src/geometries/TorusGeometry.js +8 -3
  126. package/src/helpers/CameraHelper.js +3 -0
  127. package/src/helpers/DirectionalLightHelper.js +4 -1
  128. package/src/helpers/HemisphereLightHelper.js +3 -0
  129. package/src/helpers/PointLightHelper.js +0 -24
  130. package/src/helpers/SpotLightHelper.js +3 -0
  131. package/src/lights/LightShadow.js +15 -3
  132. package/src/lights/webgpu/IESSpotLight.js +2 -1
  133. package/src/loaders/Cache.js +28 -0
  134. package/src/loaders/FileLoader.js +1 -1
  135. package/src/loaders/ImageBitmapLoader.js +8 -3
  136. package/src/loaders/Loader.js +6 -0
  137. package/src/loaders/ObjectLoader.js +18 -1
  138. package/src/materials/MeshLambertMaterial.js +9 -0
  139. package/src/materials/MeshPhongMaterial.js +9 -0
  140. package/src/materials/nodes/Line2NodeMaterial.js +5 -5
  141. package/src/materials/nodes/MeshPhysicalNodeMaterial.js +2 -0
  142. package/src/materials/nodes/NodeMaterial.js +15 -24
  143. package/src/materials/nodes/manager/NodeMaterialObserver.js +9 -3
  144. package/src/math/Line3.js +3 -5
  145. package/src/math/MathUtils.js +10 -10
  146. package/src/math/Matrix4.js +35 -26
  147. package/src/math/Quaternion.js +3 -29
  148. package/src/math/Vector3.js +3 -3
  149. package/src/math/interpolants/BezierInterpolant.js +108 -0
  150. package/src/nodes/Nodes.js +87 -68
  151. package/src/nodes/TSL.js +2 -5
  152. package/src/nodes/accessors/Arrays.js +1 -1
  153. package/src/nodes/accessors/Bitangent.js +5 -5
  154. package/src/nodes/accessors/BufferAttributeNode.js +1 -1
  155. package/src/nodes/accessors/Camera.js +149 -28
  156. package/src/nodes/accessors/InstanceNode.js +105 -40
  157. package/src/nodes/accessors/Normal.js +9 -9
  158. package/src/nodes/accessors/Position.js +34 -2
  159. package/src/nodes/accessors/SceneProperties.js +53 -0
  160. package/src/nodes/accessors/SkinningNode.js +12 -24
  161. package/src/nodes/accessors/StorageBufferNode.js +0 -19
  162. package/src/nodes/accessors/StorageTextureNode.js +37 -1
  163. package/src/nodes/accessors/Tangent.js +3 -3
  164. package/src/nodes/accessors/Texture3DNode.js +6 -34
  165. package/src/nodes/accessors/TextureNode.js +58 -22
  166. package/src/nodes/accessors/UniformArrayNode.js +2 -0
  167. package/src/nodes/core/MRTNode.js +48 -2
  168. package/src/nodes/core/Node.js +29 -3
  169. package/src/nodes/core/NodeBuilder.js +115 -40
  170. package/src/nodes/core/NodeError.js +28 -0
  171. package/src/nodes/core/NodeUtils.js +5 -3
  172. package/src/nodes/core/OutputStructNode.js +12 -10
  173. package/src/nodes/core/ParameterNode.js +2 -1
  174. package/src/nodes/core/StackNode.js +9 -8
  175. package/src/nodes/core/StackTrace.js +139 -0
  176. package/src/nodes/core/StructNode.js +15 -0
  177. package/src/nodes/core/SubBuildNode.js +1 -1
  178. package/src/nodes/core/UniformNode.js +2 -1
  179. package/src/nodes/core/VarNode.js +1 -1
  180. package/src/nodes/core/VaryingNode.js +1 -18
  181. package/src/nodes/display/BlendModes.js +0 -64
  182. package/src/nodes/display/ColorAdjustment.js +17 -0
  183. package/src/nodes/display/ColorSpaceNode.js +3 -3
  184. package/src/nodes/display/NormalMapNode.js +2 -2
  185. package/src/nodes/display/PassNode.js +21 -2
  186. package/src/nodes/display/RenderOutputNode.js +3 -3
  187. package/src/nodes/display/ScreenNode.js +2 -1
  188. package/src/nodes/display/ToneMappingNode.js +1 -1
  189. package/src/nodes/display/ToonOutlinePassNode.js +2 -2
  190. package/src/nodes/display/ViewportDepthNode.js +52 -4
  191. package/src/nodes/display/ViewportTextureNode.js +21 -4
  192. package/src/nodes/fog/Fog.js +18 -35
  193. package/src/nodes/functions/PhysicalLightingModel.js +25 -3
  194. package/src/nodes/geometry/RangeNode.js +4 -2
  195. package/src/nodes/gpgpu/ComputeNode.js +5 -4
  196. package/src/nodes/gpgpu/WorkgroupInfoNode.js +2 -1
  197. package/src/nodes/lighting/EnvironmentNode.js +28 -3
  198. package/src/nodes/lighting/PointShadowNode.js +24 -12
  199. package/src/nodes/lighting/ShadowFilterNode.js +15 -43
  200. package/src/nodes/lighting/ShadowNode.js +54 -32
  201. package/src/nodes/math/ConditionalNode.js +2 -2
  202. package/src/nodes/math/MathNode.js +3 -40
  203. package/src/nodes/math/OperatorNode.js +2 -1
  204. package/src/nodes/pmrem/PMREMUtils.js +9 -15
  205. package/src/nodes/tsl/TSLCore.js +13 -10
  206. package/src/nodes/utils/DebugNode.js +11 -11
  207. package/src/nodes/utils/JoinNode.js +2 -2
  208. package/src/nodes/utils/LoopNode.js +1 -1
  209. package/src/nodes/utils/MemberNode.js +1 -1
  210. package/src/nodes/utils/RTTNode.js +1 -1
  211. package/src/nodes/utils/ReflectorNode.js +2 -3
  212. package/src/nodes/utils/SpriteSheetUV.js +35 -0
  213. package/src/nodes/utils/UVUtils.js +4 -2
  214. package/src/objects/BatchedMesh.js +22 -12
  215. package/src/objects/InstancedMesh.js +11 -0
  216. package/src/renderers/WebGLRenderer.js +34 -60
  217. package/src/renderers/common/Backend.js +21 -0
  218. package/src/renderers/common/Background.js +7 -4
  219. package/src/renderers/common/BindGroup.js +1 -9
  220. package/src/renderers/common/Bindings.js +20 -5
  221. package/src/renderers/common/BlendMode.js +143 -0
  222. package/src/renderers/common/BundleGroup.js +1 -1
  223. package/src/renderers/common/CubeRenderTarget.js +50 -6
  224. package/src/renderers/common/Geometries.js +17 -3
  225. package/src/renderers/common/Lighting.js +5 -21
  226. package/src/renderers/common/Pipelines.js +4 -4
  227. package/src/renderers/common/PostProcessing.js +8 -206
  228. package/src/renderers/common/RenderBundles.js +2 -1
  229. package/src/renderers/common/RenderContext.js +16 -0
  230. package/src/renderers/common/RenderContexts.js +33 -56
  231. package/src/renderers/common/RenderLists.js +2 -1
  232. package/src/renderers/common/RenderObject.js +2 -3
  233. package/src/renderers/common/RenderObjectPipeline.js +40 -0
  234. package/src/renderers/common/RenderObjects.js +18 -2
  235. package/src/renderers/common/RenderPipeline.js +203 -17
  236. package/src/renderers/common/Renderer.js +207 -40
  237. package/src/renderers/common/Sampler.js +4 -4
  238. package/src/renderers/common/StorageBuffer.js +13 -1
  239. package/src/renderers/common/Textures.js +16 -0
  240. package/src/renderers/common/TimestampQueryPool.js +5 -3
  241. package/src/renderers/common/Uniform.js +8 -0
  242. package/src/renderers/common/UniformsGroup.js +60 -0
  243. package/src/renderers/common/XRManager.js +2 -2
  244. package/src/renderers/common/nodes/NodeBuilderState.js +1 -1
  245. package/src/renderers/common/nodes/{Nodes.js → NodeManager.js} +18 -6
  246. package/src/renderers/common/nodes/NodeStorageBuffer.js +13 -2
  247. package/src/renderers/shaders/ShaderChunk/batching_pars_vertex.glsl.js +2 -2
  248. package/src/renderers/shaders/ShaderChunk/color_fragment.glsl.js +1 -5
  249. package/src/renderers/shaders/ShaderChunk/color_pars_fragment.glsl.js +1 -5
  250. package/src/renderers/shaders/ShaderChunk/color_pars_vertex.glsl.js +1 -5
  251. package/src/renderers/shaders/ShaderChunk/color_vertex.glsl.js +8 -10
  252. package/src/renderers/shaders/ShaderChunk/cube_uv_reflection_fragment.glsl.js +4 -4
  253. package/src/renderers/shaders/ShaderChunk/envmap_fragment.glsl.js +7 -11
  254. package/src/renderers/shaders/ShaderChunk/lights_fragment_end.glsl.js +6 -0
  255. package/src/renderers/shaders/ShaderChunk/lights_fragment_maps.glsl.js +6 -2
  256. package/src/renderers/shaders/ShaderChunk/lights_physical_pars_fragment.glsl.js +23 -1
  257. package/src/renderers/shaders/ShaderChunk/packing.glsl.js +20 -4
  258. package/src/renderers/shaders/ShaderChunk/shadowmap_pars_fragment.glsl.js +55 -24
  259. package/src/renderers/shaders/ShaderLib/meshlambert.glsl.js +2 -0
  260. package/src/renderers/shaders/ShaderLib/meshphong.glsl.js +2 -0
  261. package/src/renderers/shaders/ShaderLib/shadow.glsl.js +1 -0
  262. package/src/renderers/shaders/ShaderLib.js +4 -2
  263. package/src/renderers/shaders/UniformsLib.js +0 -3
  264. package/src/renderers/webgl/WebGLBackground.js +2 -2
  265. package/src/renderers/webgl/WebGLBindingStates.js +99 -27
  266. package/src/renderers/webgl/WebGLEnvironments.js +228 -0
  267. package/src/renderers/webgl/WebGLGeometries.js +10 -7
  268. package/src/renderers/webgl/WebGLMaterials.js +12 -0
  269. package/src/renderers/webgl/WebGLObjects.js +3 -1
  270. package/src/renderers/webgl/WebGLProgram.js +2 -2
  271. package/src/renderers/webgl/WebGLPrograms.js +10 -4
  272. package/src/renderers/webgl/WebGLRenderLists.js +15 -0
  273. package/src/renderers/webgl/WebGLShadowMap.js +5 -4
  274. package/src/renderers/webgl/WebGLState.js +12 -17
  275. package/src/renderers/webgl-fallback/WebGLBackend.js +71 -7
  276. package/src/renderers/webgl-fallback/nodes/GLSLNodeBuilder.js +98 -29
  277. package/src/renderers/webgl-fallback/utils/WebGLState.js +168 -7
  278. package/src/renderers/webgpu/WebGPUBackend.js +58 -9
  279. package/src/renderers/webgpu/WebGPURenderer.js +1 -0
  280. package/src/renderers/webgpu/nodes/WGSLNodeBuilder.js +257 -45
  281. package/src/renderers/webgpu/utils/WebGPUBindingUtils.js +8 -19
  282. package/src/renderers/webgpu/utils/WebGPUConstants.js +1 -1
  283. package/src/renderers/webgpu/utils/WebGPUPipelineUtils.js +56 -31
  284. package/src/renderers/webgpu/utils/WebGPUTexturePassUtils.js +152 -200
  285. package/src/renderers/webgpu/utils/WebGPUTextureUtils.js +25 -25
  286. package/src/renderers/webgpu/utils/WebGPUUtils.js +10 -6
  287. package/src/renderers/webxr/WebXRManager.js +2 -2
  288. package/src/textures/Texture.js +2 -2
  289. package/src/utils.js +246 -3
  290. package/examples/jsm/materials/MeshGouraudMaterial.js +0 -433
  291. package/examples/jsm/materials/MeshPostProcessingMaterial.js +0 -167
  292. package/examples/jsm/shaders/GodRaysShader.js +0 -333
  293. package/src/nodes/accessors/SceneNode.js +0 -145
  294. package/src/nodes/code/ScriptableNode.js +0 -726
  295. package/src/nodes/code/ScriptableValueNode.js +0 -253
  296. package/src/nodes/display/PosterizeNode.js +0 -65
  297. package/src/nodes/utils/SpriteSheetUVNode.js +0 -90
  298. package/src/renderers/webgl/WebGLCubeMaps.js +0 -99
  299. package/src/renderers/webgl/WebGLCubeUVMaps.js +0 -134
@@ -0,0 +1,302 @@
1
+ import {
2
+ BufferGeometry,
3
+ Float32BufferAttribute,
4
+ Line,
5
+ LineBasicMaterial,
6
+ Object3D,
7
+ Points,
8
+ PointsMaterial
9
+ } from 'three';
10
+
11
+ /**
12
+ * Visualizes the motion path of an animated object based on position keyframes
13
+ * from an AnimationClip.
14
+ *
15
+ * ```js
16
+ * const clip = model.animations[ 0 ];
17
+ * const helper = new AnimationPathHelper( model, clip, object );
18
+ * scene.add( helper );
19
+ * ```
20
+ *
21
+ * @augments Object3D
22
+ * @three_import import { AnimationPathHelper } from 'three/addons/helpers/AnimationPathHelper.js';
23
+ */
24
+ class AnimationPathHelper extends Object3D {
25
+
26
+ /**
27
+ * Constructs a new animation path helper.
28
+ *
29
+ * @param {Object3D} root - The root object containing the animation clips.
30
+ * @param {AnimationClip} clip - The animation clip containing position keyframes.
31
+ * @param {Object3D} object - The specific object to show the path for.
32
+ * @param {Object} [options={}] - Configuration options.
33
+ * @param {number|Color|string} [options.color=0x00ff00] - The path line color.
34
+ * @param {number|Color|string} [options.markerColor=0xff0000] - The keyframe marker color.
35
+ * @param {number} [options.divisions=100] - Number of samples for smooth path interpolation.
36
+ * @param {boolean} [options.showMarkers=true] - Whether to show markers at keyframe positions.
37
+ * @param {number} [options.markerSize=5] - Size of keyframe markers in pixels.
38
+ */
39
+ constructor( root, clip, object, options = {} ) {
40
+
41
+ super();
42
+
43
+ const {
44
+ color = 0x00ff00,
45
+ markerColor = 0xff0000,
46
+ divisions = 100,
47
+ showMarkers = true,
48
+ markerSize = 5
49
+ } = options;
50
+
51
+ /**
52
+ * This flag can be used for type testing.
53
+ *
54
+ * @type {boolean}
55
+ * @readonly
56
+ * @default true
57
+ */
58
+ this.isAnimationPathHelper = true;
59
+
60
+ this.type = 'AnimationPathHelper';
61
+
62
+ /**
63
+ * The root object containing the animation clips.
64
+ *
65
+ * @type {Object3D}
66
+ */
67
+ this.root = root;
68
+
69
+ /**
70
+ * The animation clip containing position keyframes.
71
+ *
72
+ * @type {AnimationClip}
73
+ */
74
+ this.clip = clip;
75
+
76
+ /**
77
+ * The object whose path is being visualized.
78
+ *
79
+ * @type {Object3D}
80
+ */
81
+ this.object = object;
82
+
83
+ /**
84
+ * Number of samples for smooth path interpolation.
85
+ *
86
+ * @type {number}
87
+ * @default 100
88
+ */
89
+ this.divisions = divisions;
90
+
91
+ /**
92
+ * The position track for the object.
93
+ *
94
+ * @type {KeyframeTrack|null}
95
+ * @private
96
+ */
97
+ this._track = this._findTrackForObject( object );
98
+
99
+ if ( this._track === null ) {
100
+
101
+ console.warn( 'AnimationPathHelper: No position track found for object', object.name );
102
+ return;
103
+
104
+ }
105
+
106
+ // Create line for path
107
+ const lineGeometry = new BufferGeometry();
108
+ const lineMaterial = new LineBasicMaterial( {
109
+ color: color,
110
+ toneMapped: false
111
+ } );
112
+
113
+ /**
114
+ * The line representing the animation path.
115
+ *
116
+ * @type {Line}
117
+ */
118
+ this.line = new Line( lineGeometry, lineMaterial );
119
+ this.add( this.line );
120
+
121
+ // Create points for keyframe markers
122
+ if ( showMarkers ) {
123
+
124
+ const pointsGeometry = new BufferGeometry();
125
+ const pointsMaterial = new PointsMaterial( {
126
+ color: markerColor,
127
+ size: markerSize,
128
+ sizeAttenuation: false,
129
+ toneMapped: false
130
+ } );
131
+
132
+ /**
133
+ * Points marking keyframe positions.
134
+ *
135
+ * @type {Points|null}
136
+ */
137
+ this.points = new Points( pointsGeometry, pointsMaterial );
138
+ this.add( this.points );
139
+
140
+ } else {
141
+
142
+ this.points = null;
143
+
144
+ }
145
+
146
+ // Sync matrix with object's parent
147
+ this.matrixAutoUpdate = false;
148
+
149
+ this._updateGeometry();
150
+
151
+ }
152
+
153
+ /**
154
+ * Finds the position track for the given object.
155
+ *
156
+ * @private
157
+ * @param {Object3D} object - The object to find the track for.
158
+ * @returns {KeyframeTrack|null} The position track, or null if not found.
159
+ */
160
+ _findTrackForObject( object ) {
161
+
162
+ const targetName = object.uuid + '.position';
163
+
164
+ for ( const track of this.clip.tracks ) {
165
+
166
+ if ( track.name === targetName && track.getValueSize() === 3 ) {
167
+
168
+ return track;
169
+
170
+ }
171
+
172
+ }
173
+
174
+ return null;
175
+
176
+ }
177
+
178
+ /**
179
+ * Samples the track at regular intervals.
180
+ *
181
+ * @private
182
+ * @returns {Float32Array} Array of sampled positions.
183
+ */
184
+ _sampleTrack() {
185
+
186
+ const track = this._track;
187
+ const interpolant = track.createInterpolant();
188
+ const duration = this.clip.duration;
189
+ const positions = [];
190
+
191
+ for ( let i = 0; i <= this.divisions; i ++ ) {
192
+
193
+ const t = ( i / this.divisions ) * duration;
194
+ const result = interpolant.evaluate( t );
195
+ positions.push( result[ 0 ], result[ 1 ], result[ 2 ] );
196
+
197
+ }
198
+
199
+ return new Float32Array( positions );
200
+
201
+ }
202
+
203
+ /**
204
+ * Updates the geometry with sampled path data.
205
+ *
206
+ * @private
207
+ */
208
+ _updateGeometry() {
209
+
210
+ if ( this._track === null ) return;
211
+
212
+ // Update line geometry
213
+ const sampledPositions = this._sampleTrack();
214
+ this.line.geometry.setAttribute( 'position', new Float32BufferAttribute( sampledPositions, 3 ) );
215
+ this.line.geometry.computeBoundingSphere();
216
+
217
+ // Update keyframe markers
218
+ if ( this.points !== null ) {
219
+
220
+ this.points.geometry.setAttribute( 'position', new Float32BufferAttribute( new Float32Array( this._track.values ), 3 ) );
221
+ this.points.geometry.computeBoundingSphere();
222
+
223
+ }
224
+
225
+ }
226
+
227
+ /**
228
+ * Updates the helper's transform to match the object's parent.
229
+ *
230
+ * @param {boolean} force - Force matrix update.
231
+ */
232
+ updateMatrixWorld( force ) {
233
+
234
+ // Position the helper at the object's parent so the path appears in correct local space
235
+ if ( this.object && this.object.parent ) {
236
+
237
+ this.object.parent.updateWorldMatrix( true, false );
238
+ this.matrix.copy( this.object.parent.matrixWorld );
239
+
240
+ } else {
241
+
242
+ this.matrix.identity();
243
+
244
+ }
245
+
246
+ this.matrixWorld.copy( this.matrix );
247
+
248
+ // Update children
249
+ for ( let i = 0; i < this.children.length; i ++ ) {
250
+
251
+ this.children[ i ].updateMatrixWorld( force );
252
+
253
+ }
254
+
255
+ }
256
+
257
+ /**
258
+ * Sets the path line color.
259
+ *
260
+ * @param {number|Color|string} color - The new color.
261
+ */
262
+ setColor( color ) {
263
+
264
+ if ( this.line ) this.line.material.color.set( color );
265
+
266
+ }
267
+
268
+ /**
269
+ * Sets the keyframe marker color.
270
+ *
271
+ * @param {number|Color|string} color - The new color.
272
+ */
273
+ setMarkerColor( color ) {
274
+
275
+ if ( this.points ) this.points.material.color.set( color );
276
+
277
+ }
278
+
279
+ /**
280
+ * Frees the GPU-related resources allocated by this instance.
281
+ */
282
+ dispose() {
283
+
284
+ if ( this.line ) {
285
+
286
+ this.line.geometry.dispose();
287
+ this.line.material.dispose();
288
+
289
+ }
290
+
291
+ if ( this.points ) {
292
+
293
+ this.points.geometry.dispose();
294
+ this.points.material.dispose();
295
+
296
+ }
297
+
298
+ }
299
+
300
+ }
301
+
302
+ export { AnimationPathHelper };
@@ -65,6 +65,20 @@ class ViewHelper extends Object3D {
65
65
  */
66
66
  this.center = new Vector3();
67
67
 
68
+ /**
69
+ * Controls the position of the helper in the viewport.
70
+ * Use `top`/`bottom` for vertical positioning and `left`/`right` for horizontal.
71
+ * If `left` is `null`, `right` is used. If `top` is `null`, `bottom` is used.
72
+ *
73
+ * @type {{top: number|null, right: number, bottom: number, left: number|null}}
74
+ */
75
+ this.location = {
76
+ top: null,
77
+ right: 0,
78
+ bottom: 0,
79
+ left: null
80
+ };
81
+
68
82
  const color1 = new Color( '#ff4466' );
69
83
  const color2 = new Color( '#88ff44' );
70
84
  const color3 = new Color( '#4488ff' );
@@ -142,8 +156,8 @@ class ViewHelper extends Object3D {
142
156
  const turnRate = 2 * Math.PI; // turn rate in angles per second
143
157
 
144
158
  /**
145
- * Renders the helper in a separate view in the bottom-right corner
146
- * of the viewport.
159
+ * Renders the helper in a separate view in the viewport.
160
+ * Position is controlled by the `location` property.
147
161
  *
148
162
  * @param {WebGLRenderer|WebGPURenderer} renderer - The renderer.
149
163
  */
@@ -157,8 +171,31 @@ class ViewHelper extends Object3D {
157
171
 
158
172
  //
159
173
 
160
- const x = domElement.offsetWidth - dim;
161
- const y = renderer.isWebGPURenderer ? domElement.offsetHeight - dim : 0;
174
+ const location = this.location;
175
+
176
+ let x, y;
177
+
178
+ if ( location.left !== null ) {
179
+
180
+ x = location.left;
181
+
182
+ } else {
183
+
184
+ x = domElement.offsetWidth - dim - location.right;
185
+
186
+ }
187
+
188
+ if ( location.top !== null ) {
189
+
190
+ // Position from top
191
+ y = renderer.isWebGPURenderer ? location.top : domElement.offsetHeight - dim - location.top;
192
+
193
+ } else {
194
+
195
+ // Position from bottom
196
+ y = renderer.isWebGPURenderer ? domElement.offsetHeight - dim - location.bottom : location.bottom;
197
+
198
+ }
162
199
 
163
200
  renderer.clearDepth();
164
201
 
@@ -191,10 +228,32 @@ class ViewHelper extends Object3D {
191
228
  if ( this.animating === true ) return false;
192
229
 
193
230
  const rect = domElement.getBoundingClientRect();
194
- const offsetX = rect.left + ( domElement.offsetWidth - dim );
195
- const offsetY = rect.top + ( domElement.offsetHeight - dim );
196
- mouse.x = ( ( event.clientX - offsetX ) / ( rect.right - offsetX ) ) * 2 - 1;
197
- mouse.y = - ( ( event.clientY - offsetY ) / ( rect.bottom - offsetY ) ) * 2 + 1;
231
+ const location = this.location;
232
+
233
+ let offsetX, offsetY;
234
+
235
+ if ( location.left !== null ) {
236
+
237
+ offsetX = rect.left + location.left;
238
+
239
+ } else {
240
+
241
+ offsetX = rect.left + domElement.offsetWidth - dim - location.right;
242
+
243
+ }
244
+
245
+ if ( location.top !== null ) {
246
+
247
+ offsetY = rect.top + location.top;
248
+
249
+ } else {
250
+
251
+ offsetY = rect.top + domElement.offsetHeight - dim - location.bottom;
252
+
253
+ }
254
+
255
+ mouse.x = ( ( event.clientX - offsetX ) / dim ) * 2 - 1;
256
+ mouse.y = - ( ( event.clientY - offsetY ) / dim ) * 2 + 1;
198
257
 
199
258
  raycaster.setFromCamera( mouse, orthoCamera );
200
259
 
@@ -110,7 +110,7 @@ class Inspector extends RendererInspector {
110
110
 
111
111
  }
112
112
 
113
- resolveConsole( type, message ) {
113
+ resolveConsole( type, message, stackTrace = null ) {
114
114
 
115
115
  switch ( type ) {
116
116
 
@@ -126,7 +126,15 @@ class Inspector extends RendererInspector {
126
126
 
127
127
  this.console.addMessage( 'warn', message );
128
128
 
129
- console.warn( message );
129
+ if ( stackTrace && stackTrace.isStackTrace ) {
130
+
131
+ console.warn( stackTrace.getError( message ) );
132
+
133
+ } else {
134
+
135
+ console.warn( message );
136
+
137
+ }
130
138
 
131
139
  break;
132
140
 
@@ -134,7 +142,15 @@ class Inspector extends RendererInspector {
134
142
 
135
143
  this.console.addMessage( 'error', message );
136
144
 
137
- console.error( message );
145
+ if ( stackTrace && stackTrace.isStackTrace ) {
146
+
147
+ console.error( stackTrace.getError( message ) );
148
+
149
+ } else {
150
+
151
+ console.error( message );
152
+
153
+ }
138
154
 
139
155
  break;
140
156
 
@@ -182,10 +198,10 @@ class Inspector extends RendererInspector {
182
198
 
183
199
  if ( this.isAvailable ) {
184
200
 
185
- renderer.backend.trackTimestamp = true;
186
-
187
201
  renderer.init().then( () => {
188
202
 
203
+ renderer.backend.trackTimestamp = true;
204
+
189
205
  if ( renderer.hasFeature( 'timestamp-query' ) !== true ) {
190
206
 
191
207
  this.console.addMessage( 'error', 'THREE.Inspector: GPU Timestamp Queries not available.' );
@@ -33,8 +33,14 @@ class Console extends Tab {
33
33
 
34
34
  } );
35
35
 
36
- const filtersGroup = document.createElement( 'div' );
37
- filtersGroup.className = 'console-filters-group';
36
+ const copyButton = document.createElement( 'button' );
37
+ copyButton.className = 'console-copy-button';
38
+ copyButton.title = 'Copy all';
39
+ copyButton.innerHTML = '<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path></svg>';
40
+ copyButton.addEventListener( 'click', () => this.copyAll( copyButton ) );
41
+
42
+ const buttonsGroup = document.createElement( 'div' );
43
+ buttonsGroup.className = 'console-buttons-group';
38
44
 
39
45
  Object.keys( this.filters ).forEach( type => {
40
46
 
@@ -53,11 +59,11 @@ class Console extends Tab {
53
59
  label.appendChild( checkbox );
54
60
  label.appendChild( checkmark );
55
61
  label.append( type.charAt( 0 ).toUpperCase() + type.slice( 1 ) );
56
- filtersGroup.appendChild( label );
62
+ buttonsGroup.appendChild( label );
57
63
 
58
64
  } );
59
65
 
60
- filtersGroup.addEventListener( 'change', ( e ) => {
66
+ buttonsGroup.addEventListener( 'change', ( e ) => {
61
67
 
62
68
  const type = e.target.dataset.type;
63
69
  if ( type in this.filters ) {
@@ -69,8 +75,10 @@ class Console extends Tab {
69
75
 
70
76
  } );
71
77
 
78
+ buttonsGroup.appendChild( copyButton );
79
+
72
80
  header.appendChild( filterInput );
73
- header.appendChild( filtersGroup );
81
+ header.appendChild( buttonsGroup );
74
82
  this.content.appendChild( header );
75
83
 
76
84
  }
@@ -92,6 +100,32 @@ class Console extends Tab {
92
100
 
93
101
  }
94
102
 
103
+ copyAll( button ) {
104
+
105
+ const win = this.logContainer.ownerDocument.defaultView;
106
+ const selection = win.getSelection();
107
+ const selectedText = selection.toString();
108
+ const textInConsole = selectedText && this.logContainer.contains( selection.anchorNode );
109
+
110
+ let text;
111
+ if ( textInConsole ) {
112
+
113
+ text = selectedText;
114
+
115
+ } else {
116
+
117
+ const messages = this.logContainer.querySelectorAll( '.log-message:not(.hidden)' );
118
+ text = Array.from( messages ).map( msg => msg.dataset.rawText ).join( '\n' );
119
+
120
+ }
121
+
122
+ navigator.clipboard.writeText( text );
123
+
124
+ button.classList.add( 'copied' );
125
+ setTimeout( () => button.classList.remove( 'copied' ), 350 );
126
+
127
+ }
128
+
95
129
  _getIcon( type, subType ) {
96
130
 
97
131
  let icon;
@@ -13,6 +13,8 @@ class ParametersGroup {
13
13
 
14
14
  this.paramList = new Item( name );
15
15
 
16
+ this.objects = [];
17
+
16
18
  }
17
19
 
18
20
  close() {
@@ -93,6 +95,15 @@ class ParametersGroup {
93
95
 
94
96
  };
95
97
 
98
+
99
+ this._registerParameter( object, property, editor, subItem );
100
+
101
+ }
102
+
103
+ _registerParameter( object, property, editor, subItem ) {
104
+
105
+ this.objects.push( { object: object, key: property, editor: editor, subItem: subItem } );
106
+
96
107
  }
97
108
 
98
109
  addFolder( name ) {
@@ -291,6 +302,8 @@ class ParametersGroup {
291
302
 
292
303
  };
293
304
 
305
+ this._registerParameter( object, property, editor, subItem );
306
+
294
307
  return editor;
295
308
 
296
309
  }
@@ -315,6 +328,8 @@ class Parameters extends Tab {
315
328
 
316
329
  this.paramList = paramList;
317
330
 
331
+ this.groups = [];
332
+
318
333
  }
319
334
 
320
335
  createGroup( name ) {
@@ -322,6 +337,7 @@ class Parameters extends Tab {
322
337
  const group = new ParametersGroup( this, name );
323
338
 
324
339
  this.paramList.add( group.paramList );
340
+ this.groups.push( group );
325
341
 
326
342
  return group;
327
343
 
@@ -1057,7 +1057,7 @@ export class Style {
1057
1057
  justify-content: space-between;
1058
1058
  }
1059
1059
 
1060
- .console-filters-group {
1060
+ .console-buttons-group {
1061
1061
  display: flex;
1062
1062
  gap: 20px;
1063
1063
  }
@@ -1074,6 +1074,28 @@ export class Style {
1074
1074
  border-radius: 15px;
1075
1075
  }
1076
1076
 
1077
+ .console-copy-button {
1078
+ background: transparent;
1079
+ border: none;
1080
+ color: var(--text-secondary);
1081
+ cursor: pointer;
1082
+ padding: 4px;
1083
+ display: flex;
1084
+ align-items: center;
1085
+ justify-content: center;
1086
+ border-radius: 4px;
1087
+ transition: color 0.2s, background-color 0.2s;
1088
+ }
1089
+
1090
+ .console-copy-button:hover {
1091
+ color: var(--text-primary);
1092
+ background-color: var(--profiler-hover);
1093
+ }
1094
+
1095
+ .console-copy-button.copied {
1096
+ color: var(--color-green);
1097
+ }
1098
+
1077
1099
  #console-log {
1078
1100
  display: flex;
1079
1101
  flex-direction: column;
@@ -1081,6 +1103,8 @@ export class Style {
1081
1103
  padding: 10px;
1082
1104
  overflow-y: auto;
1083
1105
  flex-grow: 1;
1106
+ user-select: text;
1107
+ -webkit-user-select: text;
1084
1108
  }
1085
1109
 
1086
1110
  .log-message {