Mr.doob 1 year ago
parent
commit
de2a2da880
100 changed files with 1029 additions and 1362 deletions
  1. 144 236
      build/three.cjs
  2. 144 236
      build/three.module.js
  3. 0 0
      build/three.module.min.js
  4. 5 1
      docs/api/ar/constants/Renderer.html
  5. 45 39
      docs/api/ar/core/Raycaster.html
  6. 0 1
      docs/api/ar/core/bufferAttributeTypes/BufferAttributeTypes.html
  7. 1 1
      docs/api/ar/helpers/GridHelper.html
  8. 1 1
      docs/api/ar/helpers/PolarGridHelper.html
  9. 0 75
      docs/api/ar/renderers/WebGLMultipleRenderTargets.html
  10. 7 4
      docs/api/en/constants/Renderer.html
  11. 6 8
      docs/api/en/core/BufferGeometry.html
  12. 22 0
      docs/api/en/core/Object3D.html
  13. 10 4
      docs/api/en/core/Raycaster.html
  14. 0 1
      docs/api/en/core/bufferAttributeTypes/BufferAttributeTypes.html
  15. 1 1
      docs/api/en/helpers/GridHelper.html
  16. 1 1
      docs/api/en/helpers/PolarGridHelper.html
  17. 5 0
      docs/api/en/materials/MeshBasicMaterial.html
  18. 5 0
      docs/api/en/materials/MeshLambertMaterial.html
  19. 5 0
      docs/api/en/materials/MeshPhongMaterial.html
  20. 30 0
      docs/api/en/materials/MeshPhysicalMaterial.html
  21. 5 0
      docs/api/en/materials/MeshStandardMaterial.html
  22. 42 7
      docs/api/en/objects/InstancedMesh.html
  23. 6 10
      docs/api/en/objects/SkinnedMesh.html
  24. 0 75
      docs/api/en/renderers/WebGLMultipleRenderTargets.html
  25. 8 1
      docs/api/en/renderers/WebGLRenderTarget.html
  26. 12 0
      docs/api/en/scenes/Scene.html
  27. 5 2
      docs/api/fr/constants/Renderer.html
  28. 5 1
      docs/api/it/constants/Renderer.html
  29. 13 7
      docs/api/it/core/Raycaster.html
  30. 0 1
      docs/api/it/core/bufferAttributeTypes/BufferAttributeTypes.html
  31. 1 1
      docs/api/it/helpers/GridHelper.html
  32. 1 1
      docs/api/it/helpers/PolarGridHelper.html
  33. 0 67
      docs/api/it/renderers/WebGLMultipleRenderTargets.html
  34. 8 1
      docs/api/it/renderers/WebGLRenderTarget.html
  35. 4 1
      docs/api/ko/constants/Renderer.html
  36. 6 0
      docs/api/ko/core/Raycaster.html
  37. 0 1
      docs/api/ko/core/bufferAttributeTypes/BufferAttributeTypes.html
  38. 5 1
      docs/api/pt-br/constants/Renderer.html
  39. 4 0
      docs/api/zh/constants/CustomBlendingEquations.html
  40. 4 1
      docs/api/zh/constants/Renderer.html
  41. 6 0
      docs/api/zh/core/Raycaster.html
  42. 0 1
      docs/api/zh/core/bufferAttributeTypes/BufferAttributeTypes.html
  43. 1 1
      docs/api/zh/helpers/GridHelper.html
  44. 1 1
      docs/api/zh/helpers/PolarGridHelper.html
  45. 12 5
      docs/api/zh/materials/Material.html
  46. 0 61
      docs/api/zh/renderers/WebGLMultipleRenderTargets.html
  47. 8 1
      docs/api/zh/renderers/WebGLRenderTarget.html
  48. 15 0
      docs/examples/en/controls/DragControls.html
  49. 6 6
      docs/examples/en/loaders/3DMLoader.html
  50. 3 3
      docs/examples/en/loaders/GLTFLoader.html
  51. 10 0
      docs/examples/ko/controls/DragControls.html
  52. 2 3
      docs/examples/zh/animations/CCDIKSolver.html
  53. 2 3
      docs/examples/zh/animations/MMDAnimationHelper.html
  54. 2 3
      docs/examples/zh/animations/MMDPhysics.html
  55. 2 3
      docs/examples/zh/controls/ArcballControls.html
  56. 10 0
      docs/examples/zh/controls/DragControls.html
  57. 2 3
      docs/examples/zh/controls/MapControls.html
  58. 2 3
      docs/examples/zh/exporters/DRACOExporter.html
  59. 2 3
      docs/examples/zh/exporters/EXRExporter.html
  60. 2 3
      docs/examples/zh/exporters/GLTFExporter.html
  61. 2 3
      docs/examples/zh/exporters/OBJExporter.html
  62. 2 3
      docs/examples/zh/exporters/PLYExporter.html
  63. 2 3
      docs/examples/zh/exporters/STLExporter.html
  64. 2 3
      docs/examples/zh/geometries/SDFGeometryGenerator.html
  65. 2 3
      docs/examples/zh/helpers/VertexTangentsHelper.html
  66. 2 3
      docs/examples/zh/loaders/3DMLoader.html
  67. 4 14
      docs/examples/zh/loaders/GLTFLoader.html
  68. 2 3
      docs/examples/zh/loaders/KTX2Loader.html
  69. 2 3
      docs/examples/zh/loaders/LDrawLoader.html
  70. 2 3
      docs/examples/zh/loaders/PDBLoader.html
  71. 2 3
      docs/examples/zh/math/MeshSurfaceSampler.html
  72. 2 3
      docs/examples/zh/math/convexhull/ConvexHull.html
  73. 2 3
      docs/examples/zh/math/convexhull/Face.html
  74. 2 3
      docs/examples/zh/math/convexhull/HalfEdge.html
  75. 2 3
      docs/examples/zh/math/convexhull/VertexList.html
  76. 2 3
      docs/examples/zh/math/convexhull/VertexNode.html
  77. 2 3
      docs/examples/zh/utils/CameraUtils.html
  78. 2 3
      docs/examples/zh/webxr/XREstimatedLight.html
  79. 0 5
      docs/list.json
  80. 30 1
      docs/manual/en/introduction/How-to-update-things.html
  81. 3 0
      docs/manual/en/introduction/Matrix-transformations.html
  82. 15 9
      editor/css/main.css
  83. 2 4
      editor/index.html
  84. 43 6
      editor/js/Editor.js
  85. 125 44
      editor/js/EditorControls.js
  86. 1 18
      editor/js/Menubar.Edit.js
  87. 3 224
      editor/js/Menubar.File.js
  88. 0 39
      editor/js/Menubar.Play.js
  89. 42 12
      editor/js/Menubar.View.js
  90. 0 2
      editor/js/Menubar.js
  91. 35 0
      editor/js/Selector.js
  92. 9 9
      editor/js/Sidebar.Geometry.BoxGeometry.js
  93. 3 3
      editor/js/Sidebar.Geometry.BufferGeometry.js
  94. 4 4
      editor/js/Sidebar.Geometry.CapsuleGeometry.js
  95. 4 4
      editor/js/Sidebar.Geometry.CircleGeometry.js
  96. 6 6
      editor/js/Sidebar.Geometry.CylinderGeometry.js
  97. 2 2
      editor/js/Sidebar.Geometry.DodecahedronGeometry.js
  98. 9 9
      editor/js/Sidebar.Geometry.ExtrudeGeometry.js
  99. 2 2
      editor/js/Sidebar.Geometry.IcosahedronGeometry.js
  100. 4 4
      editor/js/Sidebar.Geometry.LatheGeometry.js

File diff suppressed because it is too large
+ 144 - 236
build/three.cjs


File diff suppressed because it is too large
+ 144 - 236
build/three.module.js


File diff suppressed because it is too large
+ 0 - 0
build/three.module.min.js


+ 5 - 1
docs/api/ar/constants/Renderer.html

@@ -51,13 +51,17 @@
 		THREE.CineonToneMapping 
 		THREE.CineonToneMapping 
 		THREE.ACESFilmicToneMapping
 		THREE.ACESFilmicToneMapping
 		THREE.AgXToneMapping
 		THREE.AgXToneMapping
+		THREE.NeutralToneMapping
 		THREE.CustomToneMapping
 		THREE.CustomToneMapping
 		</code>
 		</code>
 		<p>
 		<p>
 			هذه الخيارات تحدد خاصية [page:WebGLRenderer.toneMapping toneMapping] في WebGLRenderer. يتم استخدام هذا لتقريب مظهر نطاق الإضاءة العالي (HDR) على الوسط الذي يحتوي على نطاق إضاءة منخفض على شاشة الكمبيوتر القياسية أو شاشة الجوال.
 			هذه الخيارات تحدد خاصية [page:WebGLRenderer.toneMapping toneMapping] في WebGLRenderer. يتم استخدام هذا لتقريب مظهر نطاق الإضاءة العالي (HDR) على الوسط الذي يحتوي على نطاق إضاءة منخفض على شاشة الكمبيوتر القياسية أو شاشة الجوال.
 		</p>
 		</p>
 		<p>
 		<p>
-			THREE.LinearToneMapping، THREE.ReinhardToneMapping، THREE.CineonToneMapping، THREE.ACESFilmicToneMapping و THREE.AgXToneMapping هي تنفيذات مدمجة لتقريب مظهر نطاق الإضاءة العالي (HDR). يتوقع THREE.CustomToneMapping تنفيذًا مخصصًا عن طريق تعديل شفرة GLSL لبرنامج تظليل مقطع المواد. راجع [example:webgl_tonemapping WebGL / tonemapping] مثالًا. 
+			THREE.LinearToneMapping، THREE.ReinhardToneMapping، THREE.CineonToneMapping، THREE.ACESFilmicToneMapping، THREE.AgXToneMapping و THREE.NeutralToneMapping هي تنفيذات مدمجة لتقريب مظهر نطاق الإضاءة العالي (HDR). يتوقع THREE.CustomToneMapping تنفيذًا مخصصًا عن طريق تعديل شفرة GLSL لبرنامج تظليل مقطع المواد. راجع [example:webgl_tonemapping WebGL / tonemapping] مثالًا. 
+		</p>
+		<p>
+			THREE.NeutralToneMapping is an implementation based on the Khronos 3D Commerce Group standard tone mapping.
 		</p>
 		</p>
 
 
 		<h2>المصدر (Source)</h2>
 		<h2>المصدر (Source)</h2>

+ 45 - 39
docs/api/ar/core/Raycaster.html

@@ -8,55 +8,55 @@
 	</head>
 	</head>
 	<body class="rtl">
 	<body class="rtl">
 		<h1>[name]</h1>
 		<h1>[name]</h1>
-	 
+
 		<p class="desc">
 		<p class="desc">
 			تم تصميم هذه الفئة للمساعدة في
 			تم تصميم هذه الفئة للمساعدة في
 			[link:https://en.wikipedia.org/wiki/Ray_casting raycasting]. يتم استخدام Raycasting
 			[link:https://en.wikipedia.org/wiki/Ray_casting raycasting]. يتم استخدام Raycasting
 			لاختيار الماوس (العمل على معرفة الكائنات في المساحة ثلاثية الأبعاد التي يكون عليها الماوس
 			لاختيار الماوس (العمل على معرفة الكائنات في المساحة ثلاثية الأبعاد التي يكون عليها الماوس
 			فوق) من بين أشياء أخرى.
 			فوق) من بين أشياء أخرى.
 		</p>
 		</p>
-	 
+
 		<h2>مثال الكود</h2>
 		<h2>مثال الكود</h2>
 		<code>
 		<code>
 		const raycaster = new THREE.Raycaster();
 		const raycaster = new THREE.Raycaster();
 		const pointer = new THREE.Vector2();
 		const pointer = new THREE.Vector2();
-	 
+
 		function onPointerMove( event ) {
 		function onPointerMove( event ) {
-	 
+
 		// حساب موضع المؤشر في إحداثيات الجهاز المعتدلة
 		// حساب موضع المؤشر في إحداثيات الجهاز المعتدلة
 		// (-1 إلى +1) لكلا المكونين
 		// (-1 إلى +1) لكلا المكونين
-	 
+
 		pointer.x = ( event.clientX / window.innerWidth ) * 2 - 1;
 		pointer.x = ( event.clientX / window.innerWidth ) * 2 - 1;
 		pointer.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
 		pointer.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
-	 
+
 		}
 		}
-	 
+
 		function render() {
 		function render() {
-	 
+
 		// تحديث شعاع التقاط مع الكاميرا وموضع المؤشر
 		// تحديث شعاع التقاط مع الكاميرا وموضع المؤشر
 		raycaster.setFromCamera( pointer, camera );
 		raycaster.setFromCamera( pointer, camera );
-	 
+
 		// حساب الكائنات المتقاطعة مع شعاع التقاط
 		// حساب الكائنات المتقاطعة مع شعاع التقاط
 		const intersects = raycaster.intersectObjects( scene.children );
 		const intersects = raycaster.intersectObjects( scene.children );
-	 
+
 		for ( let i = 0; i < intersects.length; i ++ ) {
 		for ( let i = 0; i < intersects.length; i ++ ) {
-	 
+
 		intersects[ i ].object.material.color.set( 0xff0000 );
 		intersects[ i ].object.material.color.set( 0xff0000 );
-	 
+
 		}
 		}
-	 
+
 		renderer.render( scene, camera );
 		renderer.render( scene, camera );
-	 
+
 		}
 		}
-	 
+
 		window.addEventListener( 'pointermove', onPointerMove );
 		window.addEventListener( 'pointermove', onPointerMove );
-	 
+
 		window.requestAnimationFrame(render);
 		window.requestAnimationFrame(render);
-	 
+
 		</code>
 		</code>
-	 
+
 		<h2>أمثلة (Examples)</h2>
 		<h2>أمثلة (Examples)</h2>
-	 
+
 		<p>
 		<p>
 			[example:webgl_interactive_cubes Raycasting to a Mesh]<br />
 			[example:webgl_interactive_cubes Raycasting to a Mesh]<br />
 			[example:webgl_interactive_cubes_ortho Raycasting to a Mesh in using an OrthographicCamera]<br />
 			[example:webgl_interactive_cubes_ortho Raycasting to a Mesh in using an OrthographicCamera]<br />
@@ -68,9 +68,9 @@
 			[example:webgl_interactive_voxelpainter Raycasting to paint voxels]<br />
 			[example:webgl_interactive_voxelpainter Raycasting to paint voxels]<br />
 			[example:webgl_raycaster_texture Raycast to a Texture]
 			[example:webgl_raycaster_texture Raycast to a Texture]
 		</p>
 		</p>
-	 
+
 		<h2>المنشئ (Constructor)</h2>
 		<h2>المنشئ (Constructor)</h2>
-	 
+
 		<h3>[name]( [param:Vector3 origin], [param:Vector3 direction], [param:Float near], [param:Float far] )</h3>
 		<h3>[name]( [param:Vector3 origin], [param:Vector3 direction], [param:Float near], [param:Float far] )</h3>
 		<p>
 		<p>
 			[page:Vector3 origin] — متجه المنشأ الذي يلقي منه الشعاع.<br />
 			[page:Vector3 origin] — متجه المنشأ الذي يلقي منه الشعاع.<br />
@@ -82,64 +82,64 @@
 			أقل من قريب. القيمة الافتراضية هي Infinity.
 			أقل من قريب. القيمة الافتراضية هي Infinity.
 		</p>
 		</p>
 		<p>هذا يخلق كائن raycaster جديد.<br /></p>
 		<p>هذا يخلق كائن raycaster جديد.<br /></p>
-		 
+
 		<h2>الخصائص (Properties)</h2>
 		<h2>الخصائص (Properties)</h2>
-		 
+
 		<h3>[property:Float far]</h3>
 		<h3>[property:Float far]</h3>
 		<p>
 		<p>
 			عامل بعيد للraycaster. هذه القيمة تشير إلى الكائنات التي يمكن
 			عامل بعيد للraycaster. هذه القيمة تشير إلى الكائنات التي يمكن
 			تجاهلها بناءً على المسافة. هذه القيمة لا يجب أن تكون سلبية و
 			تجاهلها بناءً على المسافة. هذه القيمة لا يجب أن تكون سلبية و
 			يجب أن تكون أكبر من خاصية قريب.
 			يجب أن تكون أكبر من خاصية قريب.
 		</p>
 		</p>
-		 
+
 		<h3>[property:Float near]</h3>
 		<h3>[property:Float near]</h3>
 		<p>
 		<p>
 			عامل قريب للraycaster. هذه القيمة تشير إلى الكائنات التي يمكن
 			عامل قريب للraycaster. هذه القيمة تشير إلى الكائنات التي يمكن
 			تجاهلها بناءً على المسافة. هذه القيمة لا يجب أن تكون سلبية و
 			تجاهلها بناءً على المسافة. هذه القيمة لا يجب أن تكون سلبية و
 			يجب أن تكون أصغر من خاصية بعيد.
 			يجب أن تكون أصغر من خاصية بعيد.
 		</p>
 		</p>
-		 
+
 		<h3>[property:Camera camera]</h3>
 		<h3>[property:Camera camera]</h3>
 		<p>
 		<p>
 			الكاميرا المستخدمة عند التصوير بالأشعة ضد كائنات تعتمد على المشهد مثل
 			الكاميرا المستخدمة عند التصوير بالأشعة ضد كائنات تعتمد على المشهد مثل
 			كائنات billboarded مثل [page:Sprites]. يمكن تعيين هذا الحقل يدويًا أو
 			كائنات billboarded مثل [page:Sprites]. يمكن تعيين هذا الحقل يدويًا أو
 			يتم تعيينه عند استدعاء "setFromCamera". افتراضات إلى null.
 			يتم تعيينه عند استدعاء "setFromCamera". افتراضات إلى null.
 		</p>
 		</p>
-		 
+
 		<h3>[property:Layers layers]</h3>
 		<h3>[property:Layers layers]</h3>
 		<p>
 		<p>
 			يستخدم من قبل [name] لتجاهل كائنات 3D بشكل اختياري عند إجراء
 			يستخدم من قبل [name] لتجاهل كائنات 3D بشكل اختياري عند إجراء
 			اختبارات التقاطع. يضمن المثال التالي للكود أن كائنات 3D فقط على طبقة `1` ستحظى باحترام من قِبَل المثيل من [name].
 			اختبارات التقاطع. يضمن المثال التالي للكود أن كائنات 3D فقط على طبقة `1` ستحظى باحترام من قِبَل المثيل من [name].
-		 
+
 			<code>
 			<code>
-			raycaster.layers.set( 1 ); 
-			object.layers.enable( 1 ); 
+			raycaster.layers.set( 1 );
+			object.layers.enable( 1 );
 			</code>
 			</code>
 		</p>
 		</p>
-		 
+
 		<h3>[property:Object params]</h3>
 		<h3>[property:Object params]</h3>
 		<p>
 		<p>
 			 كائن به الخصائص التالية:
 			 كائن به الخصائص التالية:
-		 
+
 			<code>
 			<code>
-			{ 
+			{
 			Mesh: {},
 			Mesh: {},
 			Line: { threshold: 1 },
 			Line: { threshold: 1 },
 			LOD: {},
 			LOD: {},
 			Points: { threshold: 1 },
 			Points: { threshold: 1 },
-			Sprite: {} 
+			Sprite: {}
 			}
 			}
 			</code>
 			</code>
-		 
+
 			حيث threshold هو دقة raycaster عند التقاط
 			حيث threshold هو دقة raycaster عند التقاط
 			كائنات، في وحدات العالم.
 			كائنات، في وحدات العالم.
 		</p>
 		</p>
 
 
 		<h3>[property:Ray ray]</h3>
 		<h3>[property:Ray ray]</h3>
 		<p>ال[Page:Ray] المستخدم للتصوير بالأشعة.</p>
 		<p>ال[Page:Ray] المستخدم للتصوير بالأشعة.</p>
-		 
+
 		<h2>الوظائف (Methods)</h2>
 		<h2>الوظائف (Methods)</h2>
-		 
+
 		<h3>[method:undefined set]( [param:Vector3 origin], [param:Vector3 direction])</h3>
 		<h3>[method:undefined set]( [param:Vector3 origin], [param:Vector3 direction])</h3>
 		<p>
 		<p>
 			[page:Vector3 origin] — متجه المنشأ الذي يلقي منه الشعاع.<br />
 			[page:Vector3 origin] — متجه المنشأ الذي يلقي منه الشعاع.<br />
@@ -150,7 +150,7 @@
 			يحدث الشعاع بمنشأ واتجاه جديد. يرجى ملاحظة أن هذا
 			يحدث الشعاع بمنشأ واتجاه جديد. يرجى ملاحظة أن هذا
 			الطريقة تنسخ فقط القيم من الوسائط.
 			الطريقة تنسخ فقط القيم من الوسائط.
 		</p>
 		</p>
-		 
+
 		<h3>[method:undefined setFromCamera]( [param:Vector2 coords], [param:Camera camera] )</h3>
 		<h3>[method:undefined setFromCamera]( [param:Vector2 coords], [param:Camera camera] )</h3>
 		<p>
 		<p>
 			[page:Vector2 coords] — إحداثيات 2D للماوس، في تعديل جهاز
 			[page:Vector2 coords] — إحداثيات 2D للماوس، في تعديل جهاز
@@ -158,7 +158,13 @@
 			[page:Camera camera] — الكاميرا التي يجب أن ينبثق منها الشعاع
 			[page:Camera camera] — الكاميرا التي يجب أن ينبثق منها الشعاع
 		</p>
 		</p>
 		<p>يحدث الشعاع بمنشأ واتجاه جديد.</p>
 		<p>يحدث الشعاع بمنشأ واتجاه جديد.</p>
-		 
+
+		<h3>[method:this setFromXRController]( [param:WebXRController controller] )</h3>
+		<p>
+			[page:WebXRController controller] — The controller to copy the position and direction from.
+		</p>
+		<p>Updates the ray with a new origin and direction.</p>
+
 		<h3>[method:Array intersectObject]( [param:Object3D object], [param:Boolean recursive], [param:Array optionalTarget] )</h3>
 		<h3>[method:Array intersectObject]( [param:Object3D object], [param:Boolean recursive], [param:Array optionalTarget] )</h3>
 		<p>
 		<p>
 			[page:Object3D object] — الكائن للتحقق من التقاطع مع
 			[page:Object3D object] — الكائن للتحقق من التقاطع مع
@@ -203,7 +209,7 @@
 			وجوه كائن، سترغب في تعيين خصائص [page:Mesh.material material]
 			وجوه كائن، سترغب في تعيين خصائص [page:Mesh.material material]
 			[page:Material.side side] إلى `THREE.DoubleSide`.
 			[page:Material.side side] إلى `THREE.DoubleSide`.
 		</p>
 		</p>
-		 
+
 		<h3>[method:Array intersectObjects]( [param:Array objects], [param:Boolean recursive], [param:Array optionalTarget] )</h3>
 		<h3>[method:Array intersectObjects]( [param:Array objects], [param:Boolean recursive], [param:Array optionalTarget] )</h3>
 		<p>
 		<p>
 			[page:Array objects] — الكائنات للتحقق من التقاطع مع
 			[page:Array objects] — الكائنات للتحقق من التقاطع مع

+ 0 - 1
docs/api/ar/core/bufferAttributeTypes/BufferAttributeTypes.html

@@ -17,7 +17,6 @@
 		</p>
 		</p>
 
 
 		<code>
 		<code>
-		THREE.Float64BufferAttribute 
 		THREE.Float32BufferAttribute
 		THREE.Float32BufferAttribute
 		THREE.Float16BufferAttribute 
 		THREE.Float16BufferAttribute 
 		THREE.Uint32BufferAttribute
 		THREE.Uint32BufferAttribute

+ 1 - 1
docs/api/ar/helpers/GridHelper.html

@@ -7,7 +7,7 @@
 		<link type="text/css" rel="stylesheet" href="page.css" />
 		<link type="text/css" rel="stylesheet" href="page.css" />
 	</head>
 	</head>
 	<body class="rtl">
 	<body class="rtl">
-		[page:Object3D] &rarr; [page:Line] &rarr;
+		[page:Object3D] &rarr; [page:Line] &rarr; [page:LineSegments] &rarr;
 
 
 		<h1>[name]</h1>
 		<h1>[name]</h1>
 
 

+ 1 - 1
docs/api/ar/helpers/PolarGridHelper.html

@@ -7,7 +7,7 @@
 		<link type="text/css" rel="stylesheet" href="page.css" />
 		<link type="text/css" rel="stylesheet" href="page.css" />
 	</head>
 	</head>
 	<body class="rtl">
 	<body class="rtl">
-		[page:Object3D] &rarr; [page:Line] &rarr;
+		[page:Object3D] &rarr; [page:Line] &rarr; [page:LineSegments] &rarr;
 
 
 		<h1>[name]</h1>
 		<h1>[name]</h1>
 
 

+ 0 - 75
docs/api/ar/renderers/WebGLMultipleRenderTargets.html

@@ -1,75 +0,0 @@
-<!DOCTYPE html>
-<html lang="ar">
-	<head>
-		<meta charset="utf-8" />
-		<base href="../../../" />
-		<script src="page.js"></script>
-		<link type="text/css" rel="stylesheet" href="page.css" />
-	</head>
-	<body class="rtl">
-		[page:WebGLRenderTarget] &rarr;
-
-		<h1>[name]</h1>
-
-		<p class="desc">
-		هدف عرض خاص يتيح لشادر الجزء الكتابة إلى عدة
-		قوام. هذا النهج مفيد لتقنيات العرض المتقدمة مثل
-		معالجة ما بعد الإنتاج أو العرض المؤجل. انتبه: [name] يمكن استخدامه فقط
-		مع سياق عرض WebGL 2.
-		</p>
-		 
-		<h2>أمثلة (Examples)</h2>
-		 
-		<p>
-		[example:webgl2_multiple_rendertargets webgl2 / multiple / rendertargets ]
-		</p>
-		 
-		<h2>المنشئ (Constructor)</h2>
-		 
-		<h3>
-		[name]([param:Number width], [param:Number height], [param:Number count],
-		[param:Object options])
-		</h3>
-		 
-		<p>
-		[page:Number width] - عرض هدف العرض. الافتراضي هو `1`.<br />
-		[page:Number height] - ارتفاع هدف العرض. الافتراضي هو `1`.<br />
-		[page:Number count] - عدد أهداف العرض. الافتراضي هو `1`.<br />
-		 
-		options - (كائن اختياري يحمل معلمات القوام لـ
-		قوام الهدف المُنشأ تلقائيًا وعمق المخزن/مخططات المخزن booleans. لـ
-		شرح معلمات القوام انظر [page:Texture Texture]. لـ
-		قائمة بالخيارات الصالحة ، انظر [page:WebGLRenderTarget WebGLRenderTarget]).<br /><br />
-		</p>
-		 
-		<h2>الخصائص (Properties)</h2>
-		 
-		<h3>[property:Boolean isWebGLMultipleRenderTargets]</h3>
-		<p>علامة للقراءة فقط للتحقق مما إذا كان كائنًا معينًا من نوع [name].</p>
-		 
-		<h3>[property:Array texture]</h3>
-		<p>
-		يتم استبدال خاصية القوام في [name] واستبدالها بمصفوفة.
-		تحتوي هذه المصفوفة على مراجع [page:WebGLRenderTarget.texture texture]
-		من أهداف العرض المعنية.
-		</p>
-		 
-		<p>
-		خصائص [page:WebGLRenderTarget WebGLRenderTarget] متوفرة على
-		هذه الفئة.
-		</p>
-		 
-		<h2>الطرق (Methods)</h2>
-		 
-		<p>
-		طرق [page:WebGLRenderTarget WebGLRenderTarget] متوفرة على هذه
-		فئة.
-		</p>
-
-		<h2>المصدر (Source)</h2>
-
-		<p>
-			[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
-		</p>
-	</body>
-</html>

+ 7 - 4
docs/api/en/constants/Renderer.html

@@ -53,6 +53,7 @@
 		THREE.CineonToneMapping 
 		THREE.CineonToneMapping 
 		THREE.ACESFilmicToneMapping
 		THREE.ACESFilmicToneMapping
 		THREE.AgXToneMapping
 		THREE.AgXToneMapping
+		THREE.NeutralToneMapping
 		THREE.CustomToneMapping
 		THREE.CustomToneMapping
 		</code>
 		</code>
 		<p>
 		<p>
@@ -61,12 +62,14 @@
 			monitor or mobile device's screen.
 			monitor or mobile device's screen.
 		</p>
 		</p>
 		<p>
 		<p>
-			THREE.LinearToneMapping, THREE.ReinhardToneMapping,
-			THREE.CineonToneMapping, THREE.ACESFilmicToneMapping, and THREE.AgXToneMapping are built-in
-			implementations of tone mapping. THREE.CustomToneMapping expects a custom
-			implementation by modyfing GLSL code of the material's fragment shader.
+			THREE.LinearToneMapping, THREE.ReinhardToneMapping, THREE.CineonToneMapping, THREE.ACESFilmicToneMapping, 
+			THREE.AgXToneMapping and THREE.NeutralToneMapping are built-inimplementations of tone mapping. 
+			THREE.CustomToneMapping expects a custom implementation by modyfing GLSL code of the material's fragment shader.
 			See the [example:webgl_tonemapping WebGL / tonemapping] example.
 			See the [example:webgl_tonemapping WebGL / tonemapping] example.
 		</p>
 		</p>
+		<p>
+			THREE.NeutralToneMapping is an implementation based on the Khronos 3D Commerce Group standard tone mapping.
+		</p>
 
 
 		<h2>Source</h2>
 		<h2>Source</h2>
 		<p>
 		<p>

+ 6 - 8
docs/api/en/core/BufferGeometry.html

@@ -231,18 +231,16 @@
 
 
 		<h3>[method:undefined computeBoundingBox]()</h3>
 		<h3>[method:undefined computeBoundingBox]()</h3>
 		<p>
 		<p>
-			Computes bounding box of the geometry, updating [page:.boundingBox]
-			attribute.<br />
-			Bounding boxes aren't computed by default. They need to be explicitly
-			computed, otherwise they are `null`.
+			Computes the bounding box of the geometry, and updates the [page:.boundingBox] attribute.
+			The bounding box is not computed by the engine; it must be computed by your app.
+			You may need to recompute the bounding box if the geometry vertices are modified.
 		</p>
 		</p>
 
 
 		<h3>[method:undefined computeBoundingSphere]()</h3>
 		<h3>[method:undefined computeBoundingSphere]()</h3>
 		<p>
 		<p>
-			Computes bounding sphere of the geometry, updating [page:.boundingSphere]
-			attribute.<br />
-			Bounding spheres aren't computed by default. They need to be explicitly
-			computed, otherwise they are `null`.
+			Computes the bounding sphere of the geometry, and updates the [page:.boundingSphere] attribute.
+			The engine automatically computes the bounding sphere when it is needed, e.g., for ray casting or view frustum culling.
+			You may need to recompute the bounding sphere if the geometry vertices are modified.
 		</p>
 		</p>
 
 
 		<h3>[method:undefined computeTangents]()</h3>
 		<h3>[method:undefined computeTangents]()</h3>

+ 22 - 0
docs/api/en/core/Object3D.html

@@ -604,6 +604,28 @@
 			Converts the vector from world space to this object's local space.
 			Converts the vector from world space to this object's local space.
 		</p>
 		</p>
 
 
+		<h2>Events</h2>
+
+		<h3>added</h3>
+		<p>
+			Fires when the object has been added to its parent object.
+		</p>
+
+		<h3>removed</h3>
+		<p>
+			Fires when the object has been removed from its parent object.
+		</p>
+
+		<h3>childadded</h3>
+		<p>
+			Fires when a new child object has been added.
+		</p>
+
+		<h3>childremoved</h3>
+		<p>
+			Fires when a new child object has been removed.
+		</p>
+
 		<h2>Source</h2>
 		<h2>Source</h2>
 
 
 		<p>
 		<p>

+ 10 - 4
docs/api/en/core/Raycaster.html

@@ -113,8 +113,8 @@
 			objects on layer `1` will be honored by the instance of [name].
 			objects on layer `1` will be honored by the instance of [name].
 
 
 			<code>
 			<code>
-raycaster.layers.set( 1 ); 
-object.layers.enable( 1 ); 
+raycaster.layers.set( 1 );
+object.layers.enable( 1 );
 			</code>
 			</code>
 		</p>
 		</p>
 
 
@@ -123,12 +123,12 @@ object.layers.enable( 1 );
 			An object with the following properties:
 			An object with the following properties:
 
 
 			<code>
 			<code>
-{ 
+{
 	Mesh: {},
 	Mesh: {},
 	Line: { threshold: 1 },
 	Line: { threshold: 1 },
 	LOD: {},
 	LOD: {},
 	Points: { threshold: 1 },
 	Points: { threshold: 1 },
-	Sprite: {} 
+	Sprite: {}
 }
 }
 			</code>
 			</code>
 
 
@@ -160,6 +160,12 @@ object.layers.enable( 1 );
 		</p>
 		</p>
 		<p>Updates the ray with a new origin and direction.</p>
 		<p>Updates the ray with a new origin and direction.</p>
 
 
+		<h3>[method:this setFromXRController]( [param:WebXRController controller] )</h3>
+		<p>
+			[page:WebXRController controller] — The controller to copy the position and direction from.
+		</p>
+		<p>Updates the ray with a new origin and direction.</p>
+
 		<h3>[method:Array intersectObject]( [param:Object3D object], [param:Boolean recursive], [param:Array optionalTarget] )</h3>
 		<h3>[method:Array intersectObject]( [param:Object3D object], [param:Boolean recursive], [param:Array optionalTarget] )</h3>
 		<p>
 		<p>
 			[page:Object3D object] — The object to check for intersection with the
 			[page:Object3D object] — The object to check for intersection with the

+ 0 - 1
docs/api/en/core/bufferAttributeTypes/BufferAttributeTypes.html

@@ -18,7 +18,6 @@
 		</p>
 		</p>
 
 
 		<code>
 		<code>
-		THREE.Float64BufferAttribute 
 		THREE.Float32BufferAttribute
 		THREE.Float32BufferAttribute
 		THREE.Float16BufferAttribute 
 		THREE.Float16BufferAttribute 
 		THREE.Uint32BufferAttribute
 		THREE.Uint32BufferAttribute

+ 1 - 1
docs/api/en/helpers/GridHelper.html

@@ -7,7 +7,7 @@
 		<link type="text/css" rel="stylesheet" href="page.css" />
 		<link type="text/css" rel="stylesheet" href="page.css" />
 	</head>
 	</head>
 	<body>
 	<body>
-		[page:Object3D] &rarr; [page:Line] &rarr;
+		[page:Object3D] &rarr; [page:Line] &rarr; [page:LineSegments] &rarr;
 
 
 		<h1>[name]</h1>
 		<h1>[name]</h1>
 
 

+ 1 - 1
docs/api/en/helpers/PolarGridHelper.html

@@ -7,7 +7,7 @@
 		<link type="text/css" rel="stylesheet" href="page.css" />
 		<link type="text/css" rel="stylesheet" href="page.css" />
 	</head>
 	</head>
 	<body>
 	<body>
-		[page:Object3D] &rarr; [page:Line] &rarr;
+		[page:Object3D] &rarr; [page:Line] &rarr; [page:LineSegments] &rarr;
 
 
 		<h1>[name]</h1>
 		<h1>[name]</h1>
 
 

+ 5 - 0
docs/api/en/materials/MeshBasicMaterial.html

@@ -99,6 +99,11 @@
 		<h3>[property:Texture envMap]</h3>
 		<h3>[property:Texture envMap]</h3>
 		<p>The environment map. Default is null.</p>
 		<p>The environment map. Default is null.</p>
 
 
+		<h3>[property:Euler envMapRotation]</h3>
+		<p>
+			The rotation of the environment map in radians. Default is `(0,0,0)`.
+		</p>
+
 		<h3>[property:Boolean fog]</h3>
 		<h3>[property:Boolean fog]</h3>
 		<p>Whether the material is affected by fog. Default is `true`.</p>
 		<p>Whether the material is affected by fog. Default is `true`.</p>
 
 

+ 5 - 0
docs/api/en/materials/MeshLambertMaterial.html

@@ -165,6 +165,11 @@
 		<h3>[property:Texture envMap]</h3>
 		<h3>[property:Texture envMap]</h3>
 		<p>The environment map. Default is null.</p>
 		<p>The environment map. Default is null.</p>
 
 
+		<h3>[property:Euler envMapRotation]</h3>
+		<p>
+			The rotation of the environment map in radians. Default is `(0,0,0)`.
+		</p>
+
 		<h3>[property:Boolean flatShading]</h3>
 		<h3>[property:Boolean flatShading]</h3>
 		<p>
 		<p>
 			Define whether the material is rendered with flat shading. Default is
 			Define whether the material is rendered with flat shading. Default is

+ 5 - 0
docs/api/en/materials/MeshPhongMaterial.html

@@ -163,6 +163,11 @@
 		<h3>[property:Texture envMap]</h3>
 		<h3>[property:Texture envMap]</h3>
 		<p>The environment map. Default is null.</p>
 		<p>The environment map. Default is null.</p>
 
 
+		<h3>[property:Euler envMapRotation]</h3>
+		<p>
+			The rotation of the environment map in radians. Default is `(0,0,0)`.
+		</p>
+
 		<h3>[property:Boolean flatShading]</h3>
 		<h3>[property:Boolean flatShading]</h3>
 		<p>
 		<p>
 			Define whether the material is rendered with flat shading. Default is
 			Define whether the material is rendered with flat shading. Default is

+ 30 - 0
docs/api/en/materials/MeshPhysicalMaterial.html

@@ -17,12 +17,21 @@
 		</p>
 		</p>
 
 
 		<ul>
 		<ul>
+			<li>
+				<b>Anisotropy:</b> Ability to represent the anisotropic property of materials 
+				as observable with brushed metals.
+			</li>
 			<li>
 			<li>
 				<b>Clearcoat:</b> Some materials — like car paints, carbon fiber, and
 				<b>Clearcoat:</b> Some materials — like car paints, carbon fiber, and
 				wet surfaces — require a clear, reflective layer on top of another layer
 				wet surfaces — require a clear, reflective layer on top of another layer
 				that may be irregular or rough. Clearcoat approximates this effect,
 				that may be irregular or rough. Clearcoat approximates this effect,
 				without the need for a separate transparent surface.
 				without the need for a separate transparent surface.
 			</li>
 			</li>
+			<li>
+				<b>Iridescence:</b> Allows to render the effect where hue varies 
+				depending on the viewing angle and illumination angle. This can be seen on
+				soap bubbles, oil films, or on the wings of many insects.
+			</li>
 			<li>
 			<li>
 				<b>Physically-based transparency:</b> One limitation of
 				<b>Physically-based transparency:</b> One limitation of
 				[page:Material.opacity .opacity] is that highly transparent materials
 				[page:Material.opacity .opacity] is that highly transparent materials
@@ -69,7 +78,9 @@
 
 
 		<h2>Examples</h2>
 		<h2>Examples</h2>
 		<p>
 		<p>
+			[example:webgl_loader_gltf_anisotropy loader / gltf / anisotropy]<br />
 			[example:webgl_materials_physical_clearcoat materials / physical / clearcoat]<br />
 			[example:webgl_materials_physical_clearcoat materials / physical / clearcoat]<br />
+			[example:webgl_loader_gltf_iridescence loader / gltf / iridescence]<br />
 			[example:webgl_loader_gltf_sheen loader / gltf / sheen]<br />
 			[example:webgl_loader_gltf_sheen loader / gltf / sheen]<br />
 			[example:webgl_materials_physical_transmission materials / physical / transmission]
 			[example:webgl_materials_physical_transmission materials / physical / transmission]
 		</p>
 		</p>
@@ -94,6 +105,25 @@
 			common properties.
 			common properties.
 		</p>
 		</p>
 
 
+		<h3>[property:Float anisotropy]</h3>
+		<p>
+			The anisotropy strength. Default is `0.0`.
+		</p>
+
+		<h3>[property:Texture anisotropyMap]</h3>
+		<p>
+			Red and green channels represent the anisotropy direction in `[-1, 1]` tangent,
+			bitangent space, to be rotated by [page:.anisotropyRotation]. The blue channel
+			contains strength as `[0, 1]` to be multiplied by [page:.anisotropy]. Default is `null`.
+		</p>
+
+		<h3>[property:Float anisotropyRotation]</h3>
+		<p>
+			The rotation of the anisotropy in tangent, bitangent space, measured in radians
+			counter-clockwise from the tangent. When [page:.anisotropyMap] is present, this
+			property provides additional rotation to the vectors in the texture. Default is `0.0`.
+		</p>
+
 		<h3>[property:Color attenuationColor]</h3>
 		<h3>[property:Color attenuationColor]</h3>
 		<p>
 		<p>
 			The color that white light turns into due to absorption when reaching the
 			The color that white light turns into due to absorption when reaching the

+ 5 - 0
docs/api/en/materials/MeshStandardMaterial.html

@@ -193,6 +193,11 @@
 			[page:PMREMGenerator]. Default is null.
 			[page:PMREMGenerator]. Default is null.
 		</p>
 		</p>
 
 
+		<h3>[property:Euler envMapRotation]</h3>
+		<p>
+			The rotation of the environment map in radians. Default is `(0,0,0)`.
+		</p>
+
 		<h3>[property:Float envMapIntensity]</h3>
 		<h3>[property:Float envMapIntensity]</h3>
 		<p>Scales the effect of the environment map by multiplying its color.</p>
 		<p>Scales the effect of the environment map by multiplying its color.</p>
 
 

+ 42 - 7
docs/api/en/objects/InstancedMesh.html

@@ -79,6 +79,13 @@
 			instanced data via [page:.setMatrixAt]().
 			instanced data via [page:.setMatrixAt]().
 		</p>
 		</p>
 
 
+		<h3>[property:DataTexture morphTexture]</h3>
+		<p>
+			Represents the morph target weights of all instances. You have to set its
+			[page:Texture.needsUpdate needsUpdate] flag to true if you modify
+			instanced data via [page:.setMorphAt]().
+		</p>
+
 		<h3>[property:Boolean isInstancedMesh]</h3>
 		<h3>[property:Boolean isInstancedMesh]</h3>
 		<p>Read-only flag to check if a given object is of type [name].</p>
 		<p>Read-only flag to check if a given object is of type [name].</p>
 
 
@@ -87,17 +94,16 @@
 
 
 		<h3>[method:undefined computeBoundingBox]()</h3>
 		<h3>[method:undefined computeBoundingBox]()</h3>
 		<p>
 		<p>
-			Computes the bounding box, updating [page:.boundingBox] attribute.<br />
-			Bounding boxes aren't computed by default. They need to be explicitly
-			computed, otherwise they are `null`.
+			Computes the bounding box of the instanced mesh, and updates the [page:.boundingBox] attribute.
+			The bounding box is not computed by the engine; it must be computed by your app.
+			You may need to recompute the bounding box if an instance is transformed via [page:.setMatrixAt]().
 		</p>
 		</p>
 
 
 		<h3>[method:undefined computeBoundingSphere]()</h3>
 		<h3>[method:undefined computeBoundingSphere]()</h3>
 		<p>
 		<p>
-			Computes the bounding sphere, updating [page:.boundingSphere]
-			attribute.<br />
-			Bounding spheres aren't computed by default. They need to be explicitly
-			computed, otherwise they are `null`.
+			Computes the bounding sphere of the instanced mesh, and updates the [page:.boundingSphere] attribute.
+			The engine automatically computes the bounding sphere when it is needed, e.g., for ray casting or view frustum culling.
+			You may need to recompute the bounding sphere if an instance is transformed via [page:.setMatrixAt]().
 		</p>
 		</p>
 
 
 		<h3>[method:undefined dispose]()</h3>
 		<h3>[method:undefined dispose]()</h3>
@@ -132,6 +138,18 @@
 		</p>
 		</p>
 		<p>Get the local transformation matrix of the defined instance.</p>
 		<p>Get the local transformation matrix of the defined instance.</p>
 
 
+		<h3>
+			[method:undefined getMorphAt]( [param:Integer index], [param:Mesh mesh] )
+		</h3>
+		<p>
+			[page:Integer index]: The index of an instance. Values have to be in the
+			range [0, count].
+		</p>
+		<p>
+			[page:Mesh mesh]: The [page:Mesh.morphTargetInfluences .morphTargetInfluences] property of this mesh will be filled with the morph target weights of the defined instance.
+		</p>
+		<p>Get the morph target weights of the defined instance.</p>
+
 		<h3>
 		<h3>
 			[method:undefined setColorAt]( [param:Integer index], [param:Color color] )
 			[method:undefined setColorAt]( [param:Integer index], [param:Color color] )
 		</h3>
 		</h3>
@@ -163,6 +181,23 @@
 			to true after updating all the matrices.
 			to true after updating all the matrices.
 		</p>
 		</p>
 
 
+		<h3>
+			[method:undefined setMorphAt]( [param:Integer index], [param:Mesh mesh] )
+		</h3>
+		<p>
+			[page:Integer index]: The index of an instance. Values have to be in the
+			range [0, count].
+		</p>
+		<p>
+			[page:Matrix4 matrix]: A mesh with [page:Mesh.morphTargetInfluences .morphTargetInfluences] property containing the morph target weights
+			of a single instance.
+		</p>
+		<p>
+			Sets the morph target weights to the defined instance. Make
+			sure you set [page:.morphTexture][page:Texture.needsUpdate .needsUpdate] 
+			to true after updating all the influences.
+		</p>
+
 		<h2>Source</h2>
 		<h2>Source</h2>
 
 
 		<p>
 		<p>

+ 6 - 10
docs/api/en/objects/SkinnedMesh.html

@@ -151,20 +151,16 @@
 
 
 		<h3>[method:undefined computeBoundingBox]()</h3>
 		<h3>[method:undefined computeBoundingBox]()</h3>
 		<p>
 		<p>
-			Computes the bounding box, updating [page:.boundingBox] attribute.<br />
-			Bounding boxes aren't computed by default. They need to be explicitly
-			computed, otherwise they are `null`. If an instance of [name] is animated,
-			this method should be called per frame to compute a correct bounding box.
+			Computes the bounding box of the skinned mesh, and updates the [page:.boundingBox] attribute.
+			The bounding box is not computed by the engine; it must be computed by your app.
+			If the skinned mesh is animated, the bounding box should be recomputed per frame.
 		</p>
 		</p>
 
 
 		<h3>[method:undefined computeBoundingSphere]()</h3>
 		<h3>[method:undefined computeBoundingSphere]()</h3>
 		<p>
 		<p>
-			Computes the bounding sphere, updating [page:.boundingSphere]
-			attribute.<br />
-			Bounding spheres aren't computed by default. They need to be explicitly
-			computed, otherwise they are `null`. If an instance of [name] is animated,
-			this method should be called per frame to compute a correct bounding
-			sphere.
+			Computes the bounding sphere of the skinned mesh, and updates the [page:.boundingSphere] attribute.
+			The bounding sphere is automatically computed by the engine when it is needed, e.g., for ray casting and view frustum culling.
+			If the skinned mesh is animated, the bounding sphere should be recomputed per frame.
 		</p>
 		</p>
 
 
 		<h3>[method:undefined normalizeSkinWeights]()</h3>
 		<h3>[method:undefined normalizeSkinWeights]()</h3>

+ 0 - 75
docs/api/en/renderers/WebGLMultipleRenderTargets.html

@@ -1,75 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-	<head>
-		<meta charset="utf-8" />
-		<base href="../../../" />
-		<script src="page.js"></script>
-		<link type="text/css" rel="stylesheet" href="page.css" />
-	</head>
-	<body>
-		[page:WebGLRenderTarget] &rarr;
-
-		<h1>[name]</h1>
-
-		<p class="desc">
-			A special render target that enables a fragment shader to write to several
-			textures. This approach is useful for advanced rendering techniques like
-			post-processing or deferred rendering. Heads up: [name] can only be used
-			with a WebGL 2 rendering context.
-		</p>
-
-		<h2>Examples</h2>
-
-		<p>
-			[example:webgl2_multiple_rendertargets webgl2 / multiple / rendertargets ]
-		</p>
-
-		<h2>Constructor</h2>
-
-		<h3>
-			[name]([param:Number width], [param:Number height], [param:Number count],
-			[param:Object options])
-		</h3>
-
-		<p>
-			[page:Number width] - The width of the render target. Default is `1`.<br />
-			[page:Number height] - The height of the render target. Default is `1`.<br />
-			[page:Number count] - The number of render targets. Default is `1`.<br />
-
-			options - (optional object that holds texture parameters for an
-			auto-generated target texture and depthBuffer/stencilBuffer booleans. For
-			an explanation of the texture parameters see [page:Texture Texture]. For a
-			list of valid options, see [page:WebGLRenderTarget WebGLRenderTarget]).<br /><br />
-		</p>
-
-		<h2>Properties</h2>
-
-		<h3>[property:Boolean isWebGLMultipleRenderTargets]</h3>
-		<p>Read-only flag to check if a given object is of type [name].</p>
-
-		<h3>[property:Array texture]</h3>
-		<p>
-			The texture property is overwritten in [name] and replaced with an array.
-			This array holds the [page:WebGLRenderTarget.texture texture] references
-			of the respective render targets.
-		</p>
-
-		<p>
-			[page:WebGLRenderTarget WebGLRenderTarget] properties are available on
-			this class.
-		</p>
-
-		<h2>Methods</h2>
-
-		<p>
-			[page:WebGLRenderTarget WebGLRenderTarget] methods are available on this
-			class.
-		</p>
-
-		<h2>Source</h2>
-
-		<p>
-			[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
-		</p>
-	</body>
-</html>

+ 8 - 1
docs/api/en/renderers/WebGLRenderTarget.html

@@ -49,7 +49,8 @@
 			<br />
 			<br />
 			[page:Boolean depthBuffer] - default is `true`. <br />
 			[page:Boolean depthBuffer] - default is `true`. <br />
 			[page:Boolean stencilBuffer] - default is `false`.<br />
 			[page:Boolean stencilBuffer] - default is `false`.<br />
-			[page:Number samples] - default is `0`.<br /><br />
+			[page:Number samples] - default is `0`.<br />
+			[page:Number count] - default is `1`.<br /><br />
 
 
 			Creates a new [name]
 			Creates a new [name]
 		</p>
 		</p>
@@ -83,6 +84,12 @@
 			further processing.
 			further processing.
 		</p>
 		</p>
 
 
+		<h3>[property:Texture textures]</h3>
+		<p>
+			An array holding the [page:WebGLRenderTarget.texture texture] references
+			of multiple render targets configured with the [page:Number count] option.
+		</p>
+
 		<h3>[property:Boolean depthBuffer]</h3>
 		<h3>[property:Boolean depthBuffer]</h3>
 		<p>Renders to the depth buffer. Default is true.</p>
 		<p>Renders to the depth buffer. Default is true.</p>
 
 

+ 12 - 0
docs/api/en/scenes/Scene.html

@@ -49,6 +49,12 @@
 			textures. Default is `1`.
 			textures. Default is `1`.
 		</p>
 		</p>
 
 
+		<h3>[property:Euler backgroundRotation]</h3>
+		<p>
+			The rotation of the background in radians. Only influences environment maps
+			assigned to [page:Scene.background]. Default is `(0,0,0)`.
+		</p>
+
 		<h3>[property:Texture environment]</h3>
 		<h3>[property:Texture environment]</h3>
 		<p>
 		<p>
 			Sets the environment map for all physical materials in the scene. However,
 			Sets the environment map for all physical materials in the scene. However,
@@ -56,6 +62,12 @@
 			[page:MeshStandardMaterial.envMap]. Default is `null`.
 			[page:MeshStandardMaterial.envMap]. Default is `null`.
 		</p>
 		</p>
 
 
+		<h3>[property:Euler environmentRotation]</h3>
+		<p>
+			The rotation of the environment map in radians. Only influences physical materials 
+			in the scene when [page:.environment] is used. Default is `(0,0,0)`.
+		</p>
+
 		<h3>[property:Fog fog]</h3>
 		<h3>[property:Fog fog]</h3>
 
 
 		<p>
 		<p>

+ 5 - 2
docs/api/fr/constants/Renderer.html

@@ -47,6 +47,7 @@
 		THREE.CineonToneMapping
 		THREE.CineonToneMapping
 		THREE.ACESFilmicToneMapping
 		THREE.ACESFilmicToneMapping
 		THREE.AgXToneMapping
 		THREE.AgXToneMapping
+		THREE.NeutralToneMapping
 		THREE.CustomToneMapping
 		THREE.CustomToneMapping
 		</code>
 		</code>
 		<p>
 		<p>
@@ -55,11 +56,13 @@
 		milieu de plage dynamique faible d'un écran d'ordinateur standard ou d'un écran d'appareil mobile.
 		milieu de plage dynamique faible d'un écran d'ordinateur standard ou d'un écran d'appareil mobile.
 		</p>
 		</p>
 		<p>
 		<p>
-		THREE.LinearToneMapping, THREE.ReinhardToneMapping, THREE.CineonToneMapping, THREE.ACESFilmicToneMapping et THREE.AgXToneMapping sont des implémentations intégrées à la cartographie des tons.
+		THREE.LinearToneMapping, THREE.ReinhardToneMapping, THREE.CineonToneMapping, THREE.ACESFilmicToneMapping, THREE.AgXToneMapping et THREE.NeutralToneMapping sont des implémentations intégrées à la cartographie des tons.
 		THREE.CustomToneMapping attend une implémentation personnalisée en modifiant le code GLSL du fragment shader du matériau.
 		THREE.CustomToneMapping attend une implémentation personnalisée en modifiant le code GLSL du fragment shader du matériau.
 		Voir l'exemple [example:webgl_tonemapping WebGL / tonemapping].
 		Voir l'exemple [example:webgl_tonemapping WebGL / tonemapping].
 		</p>
 		</p>
-
+		<p>
+			THREE.NeutralToneMapping is an implementation based on the Khronos 3D Commerce Group standard tone mapping.
+		</p>
 
 
 		<h2>Source</h2>
 		<h2>Source</h2>
 
 

+ 5 - 1
docs/api/it/constants/Renderer.html

@@ -49,6 +49,7 @@
 		THREE.CineonToneMapping
 		THREE.CineonToneMapping
 		THREE.ACESFilmicToneMapping
 		THREE.ACESFilmicToneMapping
 		THREE.AgXToneMapping
 		THREE.AgXToneMapping
+		THREE.NeutralToneMapping
 		THREE.CustomToneMapping
 		THREE.CustomToneMapping
 		</code>
 		</code>
 		<p>
 		<p>
@@ -57,11 +58,14 @@
       gamma dinamica bassa del monitor di un computer o dello schermo di un dispositivo mobile.
       gamma dinamica bassa del monitor di un computer o dello schermo di un dispositivo mobile.
 		</p>
 		</p>
 		<p>
 		<p>
-      THREE.LinearToneMapping, THREE.ReinhardToneMapping, THREE.CineonToneMapping, THREE.ACESFilmicToneMapping e THREE.AgXToneMapping sono implementazioni 
+      THREE.LinearToneMapping, THREE.ReinhardToneMapping, THREE.CineonToneMapping, THREE.ACESFilmicToneMapping THREE.AgXToneMapping e THREE.NeutralToneMapping sono implementazioni 
       integrate della mappatura dei toni.
       integrate della mappatura dei toni.
       THREE.CustomToneMapping prevede un'implementazione personalizzata modificando il codice GLSL dello shader di frammenti del materiale.
       THREE.CustomToneMapping prevede un'implementazione personalizzata modificando il codice GLSL dello shader di frammenti del materiale.
       Vedi l'esempio [example:webgl_tonemapping WebGL / tonemapping].
       Vedi l'esempio [example:webgl_tonemapping WebGL / tonemapping].
 		</p>
 		</p>
+		<p>
+			THREE.NeutralToneMapping is an implementation based on the Khronos 3D Commerce Group standard tone mapping.
+		</p>
 
 
 
 
 		<h2>Source</h2>
 		<h2>Source</h2>

+ 13 - 7
docs/api/it/core/Raycaster.html

@@ -97,7 +97,7 @@
 
 
 		<h3>[property:Camera camera]</h3>
 		<h3>[property:Camera camera]</h3>
 		<p>
 		<p>
-      La telecamera da utilizzare durante il raycast contro oggetti dipendenti dalla vista, come oggetti su cartelloni pubblicitari 
+      La telecamera da utilizzare durante il raycast contro oggetti dipendenti dalla vista, come oggetti su cartelloni pubblicitari
       come [page:Sprites]. Questo campo può essere settato manualmente o viene impostato quando si chiama il metodo "setFromCamera".
       come [page:Sprites]. Questo campo può essere settato manualmente o viene impostato quando si chiama il metodo "setFromCamera".
 
 
       L'impostazione predefinita è null.
       L'impostazione predefinita è null.
@@ -156,12 +156,18 @@
 		  Aggiorna il raggio con una nuova origine e direzione.
 		  Aggiorna il raggio con una nuova origine e direzione.
 		</p>
 		</p>
 
 
+		<h3>[method:this setFromXRController]( [param:WebXRController controller] )</h3>
+		<p>
+			[page:WebXRController controller] — The controller to copy the position and direction from.
+		</p>
+		<p>Updates the ray with a new origin and direction.</p>
+
 		<h3>[method:Array intersectObject]( [param:Object3D object], [param:Boolean recursive], [param:Array optionalTarget] )</h3>
 		<h3>[method:Array intersectObject]( [param:Object3D object], [param:Boolean recursive], [param:Array optionalTarget] )</h3>
 		<p>
 		<p>
 		[page:Object3D object] — L'oggetto da verificare per l'intersezione con il raggio.<br />
 		[page:Object3D object] — L'oggetto da verificare per l'intersezione con il raggio.<br />
-		[page:Boolean recursive] — Se true, controlla anche tutti i discendenti. Altrimenti controlla soltanto 
+		[page:Boolean recursive] — Se true, controlla anche tutti i discendenti. Altrimenti controlla soltanto
     l'intersezione con l'oggetto. Il valore predefinito è true.<br />
     l'intersezione con l'oggetto. Il valore predefinito è true.<br />
-		[page:Array optionalTarget] — (opzionale) obiettivo per impostare il risultato. 
+		[page:Array optionalTarget] — (opzionale) obiettivo per impostare il risultato.
     Altrimenti viene istanziato un nuovo [page:Array]. Se impostato, è necessario cancellare questo array prima di ogni chiamata (ad esempio, array.length = 0;).
     Altrimenti viene istanziato un nuovo [page:Array]. Se impostato, è necessario cancellare questo array prima di ogni chiamata (ad esempio, array.length = 0;).
 		</p>
 		</p>
 		<p>
 		<p>
@@ -183,8 +189,8 @@
 			[page:Integer instanceId] – Il numero di indice dell'istanza in cui il raggio interseca la InstancedMesh.
 			[page:Integer instanceId] – Il numero di indice dell'istanza in cui il raggio interseca la InstancedMesh.
 		</p>
 		</p>
 		<p>
 		<p>
-      `Raycaster` delega al metodo [page:Object3D.raycast raycast] dell'oggetto passato, 
-      quando valuta se il raggio interseca l'oggetto o no. Ciò permette alle mesh di rispondere 
+      `Raycaster` delega al metodo [page:Object3D.raycast raycast] dell'oggetto passato,
+      quando valuta se il raggio interseca l'oggetto o no. Ciò permette alle mesh di rispondere
       in modo diverso al raycasting rispetto alle linee e alle nuvole di punti.
       in modo diverso al raycasting rispetto alle linee e alle nuvole di punti.
 		</p>
 		</p>
 		<p>
 		<p>
@@ -197,14 +203,14 @@
 		<h3>[method:Array intersectObjects]( [param:Array objects], [param:Boolean recursive], [param:Array optionalTarget] )</h3>
 		<h3>[method:Array intersectObjects]( [param:Array objects], [param:Boolean recursive], [param:Array optionalTarget] )</h3>
 		<p>
 		<p>
       [page:Array objects] — Gli oggetti da controllare per l'intersezione con il raggio.<br />
       [page:Array objects] — Gli oggetti da controllare per l'intersezione con il raggio.<br />
-      [page:Boolean recursive] — Se true, controlla anche i discendenti degli oggetti. Altrimenti controlla soltanto 
+      [page:Boolean recursive] — Se true, controlla anche i discendenti degli oggetti. Altrimenti controlla soltanto
       l'intersezione con gli oggetti. Il valore predefinito è true.<br />
       l'intersezione con gli oggetti. Il valore predefinito è true.<br />
       [page:Array optionalTarget] — (opzionale) obiettivo per impostare il risultato.
       [page:Array optionalTarget] — (opzionale) obiettivo per impostare il risultato.
       Altrimenti viene istanziato un nuovo [page:Array]. Se impostato, è necessario cancellare questo array prima di ogni chiamata (ad esempio, array.length = 0;).
       Altrimenti viene istanziato un nuovo [page:Array]. Se impostato, è necessario cancellare questo array prima di ogni chiamata (ad esempio, array.length = 0;).
 		</p>
 		</p>
 		<p>
 		<p>
       Controlla tutte le intersezioni tra il raggio e gli oggetti con o senza i discendenti.
       Controlla tutte le intersezioni tra il raggio e gli oggetti con o senza i discendenti.
-      Le intersezioni sono restituite ordinate per distanza, prima le più vicine. Le intersezioni 
+      Le intersezioni sono restituite ordinate per distanza, prima le più vicine. Le intersezioni
       hanno la stessa forma di quelle restituite da [page:.intersectObject].
       hanno la stessa forma di quelle restituite da [page:.intersectObject].
 		</p>
 		</p>
 
 

+ 0 - 1
docs/api/it/core/bufferAttributeTypes/BufferAttributeTypes.html

@@ -17,7 +17,6 @@
 		</p>
 		</p>
 
 
 		<code>
 		<code>
-		THREE.Float64BufferAttribute
 		THREE.Float32BufferAttribute
 		THREE.Float32BufferAttribute
 		THREE.Float16BufferAttribute
 		THREE.Float16BufferAttribute
 		THREE.Uint32BufferAttribute
 		THREE.Uint32BufferAttribute

+ 1 - 1
docs/api/it/helpers/GridHelper.html

@@ -7,7 +7,7 @@
 		<link type="text/css" rel="stylesheet" href="page.css" />
 		<link type="text/css" rel="stylesheet" href="page.css" />
 	</head>
 	</head>
 	<body>
 	<body>
-		[page:Object3D] &rarr; [page:Line] &rarr;
+		[page:Object3D] &rarr; [page:Line] &rarr; [page:LineSegments] &rarr;
 
 
 		<h1>[name]</h1>
 		<h1>[name]</h1>
 
 

+ 1 - 1
docs/api/it/helpers/PolarGridHelper.html

@@ -7,7 +7,7 @@
 		<link type="text/css" rel="stylesheet" href="page.css" />
 		<link type="text/css" rel="stylesheet" href="page.css" />
 	</head>
 	</head>
 	<body>
 	<body>
-		[page:Object3D] &rarr; [page:Line] &rarr;
+		[page:Object3D] &rarr; [page:Line] &rarr; [page:LineSegments] &rarr;
 
 
 		<h1>[name]</h1>
 		<h1>[name]</h1>
 
 

+ 0 - 67
docs/api/it/renderers/WebGLMultipleRenderTargets.html

@@ -1,67 +0,0 @@
-<!DOCTYPE html>
-<html lang="it">
-	<head>
-		<meta charset="utf-8" />
-		<base href="../../../" />
-		<script src="page.js"></script>
-		<link type="text/css" rel="stylesheet" href="page.css" />
-	</head>
-	<body>
-		[page:WebGLRenderTarget] &rarr;
-
-		<h1>[name]</h1>
-
-		<p class="desc">
-			Un target di rendering speciale che consente a un fragment shader di scrivere su più texture.
-			Questo approccio è utile per le tecniche di rendering avanzate come la post-eleborazione o il rendering differito.
-
-			Attenzione: [name] può solo essere utilizzato in un contesto di rendering WebGL 2.
-		</p>
-
-		<h2>Esempi</h2>
-
-		<p>
-			[example:webgl2_multiple_rendertargets webgl2 / multiple / rendertargets ]
-		</p>
-
-		<h2>Costruttore</h2>
-
-
-		<h3>[name]([param:Number width], [param:Number height], [param:Number count], [param:Object options])</h3>
-
-		<p>
-		[page:Number width] - La larghezza del target di rendering. Il valore predefinito è `1`.<br />
-		[page:Number height] - L'altezza del target di rendering. Il valore predefinito è `1`.<br />
-		[page:Number count] - Il numero di target di rendering. Il valore predefinito è `1`.<br />
-
-		options - (oggetto opzionale che contiene i parametri della texture per una texture target auto generata
-		e i booleani depthBuffer/stencilBuffer. Per una spiegazione dei parametri della texture consultare [page:Texture Texture].
-		Per un elenco di opzioni valide, consultare [page:WebGLRenderTarget WebGLRenderTarget].)<br /><br />
-		</p>
-
-		<h2>Proprietà</h2>
-
-		<h3>[property:Boolean isWebGLMultipleRenderTargets]</h3>
-		<p>
-			Flag di sola lettura per verificare se l'oggetto dato è di tipo [name].
-		</p>
-
-		<h3>[property:Array texture]</h3>
-		<p>
-			La proprietà texture viene sovrascritta in [name] e sostituita con un array. Questo array contiene i
-			riferimenti alla [page:WebGLRenderTarget.texture texture] dei rispettivi target di rendering.
-		</p>
-
-		<p>Le proprietà [page:WebGLRenderTarget WebGLRenderTarget] sono disponibili su questa classe.</p>
-
-		<h2>Metodi</h2>
-
-		<p>I metodi [page:WebGLRenderTarget WebGLRenderTarget] sono disponibili su questa classe.</p>
-
-		<h2>Source</h2>
-
-		<p>
-			[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
-		</p>
-	</body>
-</html>

+ 8 - 1
docs/api/it/renderers/WebGLRenderTarget.html

@@ -42,7 +42,8 @@
 		[page:Constant colorSpace] - il valore predefinito è [page:Textures NoColorSpace]. <br />
 		[page:Constant colorSpace] - il valore predefinito è [page:Textures NoColorSpace]. <br />
 		[page:Boolean depthBuffer] - il valore predefinito è `true`. <br />
 		[page:Boolean depthBuffer] - il valore predefinito è `true`. <br />
 		[page:Boolean stencilBuffer] - il valore predefinito è `false`.<br />
 		[page:Boolean stencilBuffer] - il valore predefinito è `false`.<br />
-		[page:Number samples] - il valore predefinito è 0.<br /><br />
+		[page:Number samples] - il valore predefinito è 0.<br />
+		[page:Number count] - default is `1`.<br /><br />
 
 
 		Crea un nuovo [name]
 		Crea un nuovo [name]
 		</p>
 		</p>
@@ -84,6 +85,12 @@
 			Questa istanza della texture contiene i pixel renderizzati. Utilizzalo come input per ulteriori informazioni.
 			Questa istanza della texture contiene i pixel renderizzati. Utilizzalo come input per ulteriori informazioni.
 		</p>
 		</p>
 
 
+		<h3>[property:Texture textures]</h3>
+		<p>
+			An array holding the [page:WebGLRenderTarget.texture texture] references
+			of multiple render targets configured with the [page:Number count] option.
+		</p>
+
 		<h3>[property:Boolean depthBuffer]</h3>
 		<h3>[property:Boolean depthBuffer]</h3>
 		<p>
 		<p>
 			Effettua il rendering al buffer di profondità. L'impostazione predefinita è `true`.
 			Effettua il rendering al buffer di profondità. L'impostazione predefinita è `true`.

+ 4 - 1
docs/api/ko/constants/Renderer.html

@@ -47,6 +47,7 @@
 		THREE.CineonToneMapping
 		THREE.CineonToneMapping
 		THREE.ACESFilmicToneMapping
 		THREE.ACESFilmicToneMapping
 		THREE.AgXToneMapping
 		THREE.AgXToneMapping
+		THREE.NeutralToneMapping
 		THREE.CustomToneMapping
 		THREE.CustomToneMapping
 		</code>
 		</code>
 		<p>
 		<p>
@@ -56,7 +57,9 @@
 		[example:webgl_tonemapping WebGL / tonemapping] 예제를 참고하세요.
 		[example:webgl_tonemapping WebGL / tonemapping] 예제를 참고하세요.
 
 
 		</p>
 		</p>
-
+		<p>
+			THREE.NeutralToneMapping is an implementation based on the Khronos 3D Commerce Group standard tone mapping.
+		</p>
 
 
 		<h2>소스 코드</h2>
 		<h2>소스 코드</h2>
 
 

+ 6 - 0
docs/api/ko/core/Raycaster.html

@@ -155,6 +155,12 @@
 		레이의 새 시점과 방향을 업데이트합니다.
 		레이의 새 시점과 방향을 업데이트합니다.
 		</p>
 		</p>
 
 
+		<h3>[method:this setFromXRController]( [param:WebXRController controller] )</h3>
+		<p>
+			[page:WebXRController controller] — The controller to copy the position and direction from.
+		</p>
+		<p>Updates the ray with a new origin and direction.</p>
+
 		<h3>[method:Array intersectObject]( [param:Object3D object], [param:Boolean recursive], [param:Array optionalTarget] )</h3>
 		<h3>[method:Array intersectObject]( [param:Object3D object], [param:Boolean recursive], [param:Array optionalTarget] )</h3>
 		<p>
 		<p>
 		[page:Object3D object] — 레이와의 교차 체크를 하는 객체입니다.<br />
 		[page:Object3D object] — 레이와의 교차 체크를 하는 객체입니다.<br />

+ 0 - 1
docs/api/ko/core/bufferAttributeTypes/BufferAttributeTypes.html

@@ -17,7 +17,6 @@
 		</p>
 		</p>
 
 
 		<code>
 		<code>
-		THREE.Float64BufferAttribute
 		THREE.Float32BufferAttribute
 		THREE.Float32BufferAttribute
 		THREE.Float16BufferAttribute
 		THREE.Float16BufferAttribute
 		THREE.Uint32BufferAttribute
 		THREE.Uint32BufferAttribute

+ 5 - 1
docs/api/pt-br/constants/Renderer.html

@@ -47,6 +47,7 @@
 		THREE.CineonToneMapping
 		THREE.CineonToneMapping
 		THREE.ACESFilmicToneMapping
 		THREE.ACESFilmicToneMapping
 		THREE.AgXToneMapping
 		THREE.AgXToneMapping
+		THREE.NeutralToneMapping
 		THREE.CustomToneMapping
 		THREE.CustomToneMapping
 		</code>
 		</code>
 		<p>
 		<p>
@@ -55,10 +56,13 @@
 		médio da faixa dinâmica baixa de um monitor de computador padrão ou tela de dispositivo móvel.
 		médio da faixa dinâmica baixa de um monitor de computador padrão ou tela de dispositivo móvel.
 		</p>
 		</p>
 		<p>
 		<p>
-		THREE.LinearToneMapping, THREE.ReinhardToneMapping, THREE.CineonToneMapping, THREE.ACESFilmicToneMapping e THREE.AgXToneMapping são implementações internas de mapeamento de tom.
+		THREE.LinearToneMapping, THREE.ReinhardToneMapping, THREE.CineonToneMapping, THREE.ACESFilmicToneMapping, THREE.AgXToneMapping e THREE.NeutralToneMapping são implementações internas de mapeamento de tom.
 		THREE.CustomToneMapping espera uma implementação personalizada modificando o código GLSL do sombreador de fragmento do material.  
 		THREE.CustomToneMapping espera uma implementação personalizada modificando o código GLSL do sombreador de fragmento do material.  
 		Vejo o exemplo [example:webgl_tonemapping WebGL / tonemapping].
 		Vejo o exemplo [example:webgl_tonemapping WebGL / tonemapping].
 		</p>
 		</p>
+		<p>
+			THREE.NeutralToneMapping is an implementation based on the Khronos 3D Commerce Group standard tone mapping.
+		</p>
 
 
 		<h2>Source</h2>
 		<h2>Source</h2>
 
 

+ 4 - 0
docs/api/zh/constants/CustomBlendingEquations.html

@@ -48,6 +48,10 @@
 		THREE.DstColorFactor
 		THREE.DstColorFactor
 		THREE.OneMinusDstColorFactor
 		THREE.OneMinusDstColorFactor
 		THREE.SrcAlphaSaturateFactor
 		THREE.SrcAlphaSaturateFactor
+		THREE.ConstantColorFactor
+		THREE.OneMinusConstantColorFactor
+		THREE.ConstantAlphaFactor
+		THREE.OneMinusConstantAlphaFactor
 		</code>
 		</code>
 
 
 		<h2>目标因子</h2>
 		<h2>目标因子</h2>

+ 4 - 1
docs/api/zh/constants/Renderer.html

@@ -47,6 +47,7 @@
 		THREE.CineonToneMapping
 		THREE.CineonToneMapping
 		THREE.ACESFilmicToneMapping
 		THREE.ACESFilmicToneMapping
 		THREE.AgXToneMapping
 		THREE.AgXToneMapping
+		THREE.NeutralToneMapping
 		THREE.CustomToneMapping
 		THREE.CustomToneMapping
 		</code>
 		</code>
 		<p>
 		<p>
@@ -57,7 +58,9 @@
 		请查看示例:[example:webgl_tonemapping WebGL / tonemapping]。
 		请查看示例:[example:webgl_tonemapping WebGL / tonemapping]。
 
 
 		</p>
 		</p>
-
+		<p>
+			THREE.NeutralToneMapping is an implementation based on the Khronos 3D Commerce Group standard tone mapping.
+		</p>
 
 
 		<h2>源代码</h2>
 		<h2>源代码</h2>
 
 

+ 6 - 0
docs/api/zh/core/Raycaster.html

@@ -159,6 +159,12 @@
 			使用一个新的原点和方向来更新射线。
 			使用一个新的原点和方向来更新射线。
 		</p>
 		</p>
 
 
+		<h3>[method:this setFromXRController]( [param:WebXRController controller] )</h3>
+		<p>
+			[page:WebXRController controller] — The controller to copy the position and direction from.
+		</p>
+		<p>Updates the ray with a new origin and direction.</p>
+
 		<h3>[method:Array intersectObject]( [param:Object3D object], [param:Boolean recursive], [param:Array optionalTarget] )</h3>
 		<h3>[method:Array intersectObject]( [param:Object3D object], [param:Boolean recursive], [param:Array optionalTarget] )</h3>
 		<p>
 		<p>
 		[page:Object3D object] —— 检查与射线相交的物体。<br />
 		[page:Object3D object] —— 检查与射线相交的物体。<br />

+ 0 - 1
docs/api/zh/core/bufferAttributeTypes/BufferAttributeTypes.html

@@ -17,7 +17,6 @@
 		</p>
 		</p>
 
 
 		<code>
 		<code>
-		THREE.Float64BufferAttribute
 		THREE.Float32BufferAttribute
 		THREE.Float32BufferAttribute
 		THREE.Float16BufferAttribute
 		THREE.Float16BufferAttribute
 		THREE.Uint32BufferAttribute
 		THREE.Uint32BufferAttribute

+ 1 - 1
docs/api/zh/helpers/GridHelper.html

@@ -7,7 +7,7 @@
 		<link type="text/css" rel="stylesheet" href="page.css" />
 		<link type="text/css" rel="stylesheet" href="page.css" />
 	</head>
 	</head>
 	<body>
 	<body>
-		[page:Object3D] &rarr; [page:Line] &rarr;
+		[page:Object3D] &rarr; [page:Line] &rarr; [page:LineSegments] &rarr;
 
 
 		<h1>[name]</h1>
 		<h1>[name]</h1>
 
 

+ 1 - 1
docs/api/zh/helpers/PolarGridHelper.html

@@ -7,7 +7,7 @@
 		<link type="text/css" rel="stylesheet" href="page.css" />
 		<link type="text/css" rel="stylesheet" href="page.css" />
 	</head>
 	</head>
 	<body>
 	<body>
-		[page:Object3D] &rarr; [page:Line] &rarr;
+		[page:Object3D] &rarr; [page:Line] &rarr; [page:LineSegments] &rarr;
 
 
 		<h1>[name]</h1>
 		<h1>[name]</h1>
 
 

+ 12 - 5
docs/api/zh/materials/Material.html

@@ -34,11 +34,18 @@
 </p>
 </p>
 
 
 <h3>[property:Boolean alphaToCoverage]</h3>
 <h3>[property:Boolean alphaToCoverage]</h3>
-<p>
-	Enables alpha to coverage. Can only be used with MSAA-enabled contexts
-	(meaning when the renderer was created with *antialias* parameter set to
-	`true`). Enabling this will smooth aliasing on clip plane edges and alphaTest-clipped edges.
-	Default is `false`.
+<p>启用 alpha 覆盖。 只能与启用 MSAA 的上下文一起使用(意味着在创建渲染器时将抗锯齿参数 *antialias* 设置为 `true`)。
+	启用此选项将平滑剪裁平面边缘和 alphaTest 剪辑边缘上的锯齿。 默认值为 `false`。
+</p>
+
+<h3>[property:Float blendAlpha]</h3>
+<p>表示恒定混合颜色的 alpha 值。 默认值为 `0`。<br />
+	此属性仅在使用 [page:CustomBlendingEquation ConstantAlpha] 或 [page:CustomBlendingEquation OneMinusConstantAlpha] 自定义混合时有效。
+</p>
+
+<h3>[property:Color blendColor]</h3>
+<p>表示恒定混合颜色的 RGB 值。 默认值为 `0x000000`。<br />
+	此属性仅在使用 [page:CustomBlendingEquation ConstantColor] 或 [page:CustomBlendingEquation OneMinusConstantColor] 自定义混合时有效。
 </p>
 </p>
 
 
 <h3>[property:Integer blendDst]</h3>
 <h3>[property:Integer blendDst]</h3>

+ 0 - 61
docs/api/zh/renderers/WebGLMultipleRenderTargets.html

@@ -1,61 +0,0 @@
-<!DOCTYPE html>
-<html lang="zh">
-	<head>
-		<meta charset="utf-8" />
-		<base href="../../../" />
-		<script src="page.js"></script>
-		<link type="text/css" rel="stylesheet" href="page.css" />
-	</head>
-	<body>
-		[page:WebGLRenderTarget] &rarr;
-
-		<h1>[name]</h1>
-
-		<p class="desc">
-			一个特殊的渲染目标,使片段着色器能够写入多个纹理。这种方法对于高级渲染技术很有用,例如后处理或延迟渲染。
-			
-			注意:[name]只能与 WebGL 2 渲染上下文一起使用。
-		</p>
-
-		<h2>例子(Examples)</h2>
-
-		<p>
-			[example:webgl2_multiple_rendertargets webgl2 / multiple / rendertargets ]
-		</p>
-
-		<h2>构造器(Constructor)</h2>
-
-
-		<h3>[name]([param:Number width], [param:Number height], [param:Number count])</h3>
-
-		<p>
-		[page:Number width] - 渲染目标的宽度。默认为`1`。<br />
-		[page:Number height] - 渲染目标的高度。默认为`1`。<br />
-		[page:Number count] - 渲染目标的数量。默认为`1`。
-		</p>
-
-		<h2>特性(Properties)</h2>
-
-		<h3>[property:Boolean isWebGLMultipleRenderTargets]</h3>
-		<p>
-			只读标志,用于检查给定对象是否属于[name]类型。
-		</p>
-
-		<h3>[property:Array texture]</h3>
-		<p>
-			纹理属性在[name]中被覆盖并替换为数组。该数组包含各个渲染目标的[page:WebGLRenderTarget.texture 纹理]引用。
-		</p>
-
-		<p>[page:WebGLRenderTarget WebGLRenderTarget]属性在此类上可用。</p>
-
-		<h2>方法(Methods)</h2>
-
-		<p>[page:WebGLRenderTarget WebGLRenderTarget]方法在此类上可用。</p>
-
-		<h2>源代码(Source)</h2>
-
-		<p>
-			[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
-		</p>
-	</body>
-</html>

+ 8 - 1
docs/api/zh/renderers/WebGLRenderTarget.html

@@ -38,7 +38,8 @@
 		[page:Constant colorSpace] - 默认是[page:Textures NoColorSpace]. <br />
 		[page:Constant colorSpace] - 默认是[page:Textures NoColorSpace]. <br />
 		[page:Boolean depthBuffer] - 默认是`true`.<br />
 		[page:Boolean depthBuffer] - 默认是`true`.<br />
 		[page:Boolean stencilBuffer] - 默认是`false`.<br />
 		[page:Boolean stencilBuffer] - 默认是`false`.<br />
-		[page:Number samples] - 默认是`0`.<br /><br />
+		[page:Number samples] - 默认是`0`.<br />
+		[page:Number count] - default is `1`.<br /><br />
 
 
 		创建一个新[name]
 		创建一个新[name]
 		</p>
 		</p>
@@ -80,6 +81,12 @@
 		纹理实例保存这渲染的像素,用作进一步处理的输入值
 		纹理实例保存这渲染的像素,用作进一步处理的输入值
 		</p>
 		</p>
 
 
+		<h3>[property:Texture textures]</h3>
+		<p>
+			An array holding the [page:WebGLRenderTarget.texture texture] references
+			of multiple render targets configured with the [page:Number count] option.
+		</p>
+
 		<h3>[property:Boolean depthBuffer]</h3>
 		<h3>[property:Boolean depthBuffer]</h3>
 		<p>
 		<p>
 		渲染到深度缓冲区。默认true.
 		渲染到深度缓冲区。默认true.

+ 15 - 0
docs/examples/en/controls/DragControls.html

@@ -111,6 +111,16 @@
 			If set to `true`, [name] does not transform individual objects but the entire group. Default is `false`.
 			If set to `true`, [name] does not transform individual objects but the entire group. Default is `false`.
 		</p>
 		</p>
 
 
+		<h3>[property:String mode]</h3>
+		<p>
+			The current transformation mode. Possible values are `translate`, and `rotate`. Default is `translate`.
+		</p>
+
+		<h3>[property:Float rotateSpeed]</h3>
+		<p>
+			The speed at which the object will rotate when dragged in `rotate` mode. The higher the number the faster the rotation. Default is `1`.
+		</p>
+
 		<h2>Methods</h2>
 		<h2>Methods</h2>
 
 
 		<p>See the base [page:EventDispatcher] class for common methods.</p>
 		<p>See the base [page:EventDispatcher] class for common methods.</p>
@@ -140,6 +150,11 @@
 			Returns the internal [page:Raycaster] instance that is used for intersection tests.
 			Returns the internal [page:Raycaster] instance that is used for intersection tests.
 		</p>
 		</p>
 
 
+		<h3>[method:undefined setObjects] ( [param:Array objects] )</h3>
+		<p>
+			Sets an array of draggable objects by overwriting the existing one.
+		</p>
+
 		<h2>Source</h2>
 		<h2>Source</h2>
 
 
 		<p>
 		<p>

+ 6 - 6
docs/examples/en/loaders/3DMLoader.html

@@ -14,7 +14,7 @@
 			A loader for Rhinoceros 3d files and objects. <br /><br />
 			A loader for Rhinoceros 3d files and objects. <br /><br />
 			Rhinoceros is a 3D modeler used to create, edit, analyze, document, render, animate, and translate NURBS curves, surfaces, breps, extrusions, point clouds, as well as polygon meshes and SubD objects.
 			Rhinoceros is a 3D modeler used to create, edit, analyze, document, render, animate, and translate NURBS curves, surfaces, breps, extrusions, point clouds, as well as polygon meshes and SubD objects.
 			[link:https://github.com/mcneel/rhino3dm rhino3dm.js] is compiled to WebAssembly from the open source geometry library [link:https://github.com/mcneel/opennurbs openNURBS].
 			[link:https://github.com/mcneel/rhino3dm rhino3dm.js] is compiled to WebAssembly from the open source geometry library [link:https://github.com/mcneel/opennurbs openNURBS].
-			The loader currently uses [link:https://www.npmjs.com/package/rhino3dm/v/8.0.1 rhino3dm.js 8.0.1.]
+			The loader currently uses [link:https://www.npmjs.com/package/rhino3dm/v/8.4.0 rhino3dm.js 8.4.0.]
 		</p>
 		</p>
 
 
 		<h2>Import</h2>
 		<h2>Import</h2>
@@ -166,7 +166,7 @@
 			// Specify path to a folder containing WASM/JS libraries or a CDN.
 			// Specify path to a folder containing WASM/JS libraries or a CDN.
 			// For example, /jsm/libs/rhino3dm/ is the location of the library inside the three.js repository
 			// For example, /jsm/libs/rhino3dm/ is the location of the library inside the three.js repository
 			// loader.setLibraryPath( '/path_to_library/rhino3dm/' );
 			// loader.setLibraryPath( '/path_to_library/rhino3dm/' );
-			loader.setLibraryPath( 'https://unpkg.com/rhino3dm@8.0.1/' );
+			loader.setLibraryPath( 'https://unpkg.com/rhino3dm@8.4.0/' );
 	
 	
 			// Load a 3DM file
 			// Load a 3DM file
 			loader.load(
 			loader.load(
@@ -201,17 +201,17 @@
 		</p>
 		</p>
 		<p>
 		<p>
 		Parse a File3dm ArrayBuffer and call the `onLoad` function with the resulting Object3d.
 		Parse a File3dm ArrayBuffer and call the `onLoad` function with the resulting Object3d.
-		See [link:https://github.com/mcneel/rhino-developer-samples/tree/7/rhino3dm/js/SampleParse3dmObjects this example] for further reference.
+		See [link:https://github.com/mcneel/rhino-developer-samples/tree/8/rhino3dm/js/SampleParse3dmObjects this example] for further reference.
 		</p>
 		</p>
 
 
 		<code>
 		<code>
-		import rhino3dm from 'https://unpkg.com/rhino3dm@8.0.1'
+		import rhino3dm from 'https://unpkg.com/rhino3dm@8.4.0'
 
 
 		// Instantiate a loader
 		// Instantiate a loader
 		const loader = new Rhino3dmLoader();
 		const loader = new Rhino3dmLoader();
 
 
 		// Specify path to a folder containing WASM/JS libraries or a CDN.
 		// Specify path to a folder containing WASM/JS libraries or a CDN.
-		loader.setLibraryPath( 'https://unpkg.com/rhino3dm@8.0.1' );
+		loader.setLibraryPath( 'https://unpkg.com/rhino3dm@8.4.0' );
 
 
 		const rhino = await rhino3dm();
 		const rhino = await rhino3dm();
 		console.log('Loaded rhino3dm.');
 		console.log('Loaded rhino3dm.');
@@ -244,7 +244,7 @@
 		// Specify path to a folder containing the WASM/JS library:
 		// Specify path to a folder containing the WASM/JS library:
 		loader.setLibraryPath( '/path_to_library/rhino3dm/' );
 		loader.setLibraryPath( '/path_to_library/rhino3dm/' );
 		// or from a CDN:
 		// or from a CDN:
-		loader.setLibraryPath( 'https://unpkg.com/rhino3dm@8.0.1' );
+		loader.setLibraryPath( 'https://unpkg.com/rhino3dm@8.4.0' );
 		</code>
 		</code>
 
 
 		<h3>[method:this setWorkerLimit]( [param:Number workerLimit] )</h3>
 		<h3>[method:this setWorkerLimit]( [param:Number workerLimit] )</h3>

+ 3 - 3
docs/examples/en/loaders/GLTFLoader.html

@@ -53,7 +53,7 @@
 			<li>KHR_materials_unlit</li>
 			<li>KHR_materials_unlit</li>
 			<li>KHR_materials_volume</li>
 			<li>KHR_materials_volume</li>
 			<li>KHR_mesh_quantization</li>
 			<li>KHR_mesh_quantization</li>
-			<li>KHR_lights_punctual<sup>1</sup></li>
+			<li>KHR_lights_punctual</li>
 			<li>KHR_texture_basisu</li>
 			<li>KHR_texture_basisu</li>
 			<li>KHR_texture_transform</li>
 			<li>KHR_texture_transform</li>
 			<li>EXT_texture_webp</li>
 			<li>EXT_texture_webp</li>
@@ -66,12 +66,12 @@
 		</p>
 		</p>
 
 
 		<ul>
 		<ul>
-			<li>[link:https://github.com/takahirox/three-gltf-extensions KHR_materials_variants]<sup>2</sup></li>
+			<li>[link:https://github.com/takahirox/three-gltf-extensions KHR_materials_variants]<sup>1</sup></li>
 			<li>[link:https://github.com/takahirox/three-gltf-extensions MSFT_texture_dds]</li>
 			<li>[link:https://github.com/takahirox/three-gltf-extensions MSFT_texture_dds]</li>
 		</ul>
 		</ul>
 
 
 		<p><i>
 		<p><i>
-			<sup>2</sup>You can also manually process the extension after loading in your application. See [link:https://threejs.org/examples/#webgl_loader_gltf_variants Three.js glTF materials variants example].
+			<sup>1</sup>You can also manually process the extension after loading in your application. See [link:https://threejs.org/examples/#webgl_loader_gltf_variants Three.js glTF materials variants example].
 		</i></p>
 		</i></p>
 
 
 		<h2>Code Example</h2>
 		<h2>Code Example</h2>

+ 10 - 0
docs/examples/ko/controls/DragControls.html

@@ -109,6 +109,11 @@
 			*true* 값으로 설정 되어있다면, [name]은 개별 객체가 아닌 전체 그룹은 드래그 합니다. 기본 값은 *false* 입니다.
 			*true* 값으로 설정 되어있다면, [name]은 개별 객체가 아닌 전체 그룹은 드래그 합니다. 기본 값은 *false* 입니다.
 		</p>
 		</p>
 
 
+		<h3>[property:String mode]</h3>
+		<p>
+			The current transformation mode. Possible values are `translate`, and `rotate`. Default is `translate`.
+		</p>
+
 		<h2>메소드</h2>
 		<h2>메소드</h2>
 
 
 		<p>일반적인 메소드는 [page:EventDispatcher] 클래스를 참조하세요.</p>
 		<p>일반적인 메소드는 [page:EventDispatcher] 클래스를 참조하세요.</p>
@@ -138,6 +143,11 @@
 			Returns the internal [page:Raycaster] instance that is used for intersection tests.
 			Returns the internal [page:Raycaster] instance that is used for intersection tests.
 		</p>
 		</p>
 
 
+		<h3>[method:undefined setObjects] ( [param:Array objects] )</h3>
+		<p>
+			Sets an array of draggable objects by overwriting the existing one.
+		</p>
+
 		<h2>Source</h2>
 		<h2>Source</h2>
 
 
 		<p>
 		<p>

+ 2 - 3
docs/examples/zh/animations/CCDIKSolver.html

@@ -180,9 +180,8 @@
 	<h2>源代码</h2>
 	<h2>源代码</h2>
 
 
 	<p>
 	<p>
-		[link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/animation/CCDIKSolver.js
-		examples/jsm/animation/CCDIKSolver.js]
+		[link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/animation/CCDIKSolver.js examples/jsm/animation/CCDIKSolver.js]
 	</p>
 	</p>
 </body>
 </body>
 
 
-</html>
+</html>

+ 2 - 3
docs/examples/zh/animations/MMDAnimationHelper.html

@@ -178,9 +178,8 @@
 	<h2>源代码</h2>
 	<h2>源代码</h2>
 
 
 	<p>
 	<p>
-		[link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/animation/MMDAnimationHelper.js
-		examples/jsm/animation/MMDAnimationHelper.js]
+		[link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/animation/MMDAnimationHelper.js examples/jsm/animation/MMDAnimationHelper.js]
 	</p>
 	</p>
 </body>
 </body>
 
 
-</html>
+</html>

+ 2 - 3
docs/examples/zh/animations/MMDPhysics.html

@@ -122,9 +122,8 @@
 	<h2>源代码</h2>
 	<h2>源代码</h2>
 
 
 	<p>
 	<p>
-		[link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/animation/MMDPhysics.js
-		examples/jsm/animation/MMDPhysics.js]
+		[link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/animation/MMDPhysics.js examples/jsm/animation/MMDPhysics.js]
 	</p>
 	</p>
 </body>
 </body>
 
 
-</html>
+</html>

+ 2 - 3
docs/examples/zh/controls/ArcballControls.html

@@ -279,9 +279,8 @@
 	<h2>源代码</h2>
 	<h2>源代码</h2>
 
 
 	<p>
 	<p>
-		[link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/controls/ArcballControls.js
-		examples/jsm/controls/ArcballControls.js]
+		[link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/controls/ArcballControls.js examples/jsm/controls/ArcballControls.js]
 	</p>
 	</p>
 </body>
 </body>
 
 
-</html>
+</html>

+ 10 - 0
docs/examples/zh/controls/DragControls.html

@@ -107,6 +107,11 @@
 			当[page:DragControls.objects]数组包含一个单个可拖拽的组对象时该选项生效。如果设置为`true`,[name]会转换整个组对象,而不对单个对象做转换。默认值为`false`。
 			当[page:DragControls.objects]数组包含一个单个可拖拽的组对象时该选项生效。如果设置为`true`,[name]会转换整个组对象,而不对单个对象做转换。默认值为`false`。
 		</p>
 		</p>
 
 
+		<h3>[property:String mode]</h3>
+		<p>
+			The current transformation mode. Possible values are `translate`, and `rotate`. Default is `translate`.
+		</p>
+
 		<h2>方法</h2>
 		<h2>方法</h2>
 
 
 		<p>共有方法请参见其基类[page:EventDispatcher]。</p>
 		<p>共有方法请参见其基类[page:EventDispatcher]。</p>
@@ -136,6 +141,11 @@
 			返回用于相交测试的内部[page:Raycaster]实例。
 			返回用于相交测试的内部[page:Raycaster]实例。
 		</p>
 		</p>
 
 
+		<h3>[method:undefined setObjects] ( [param:Array objects] )</h3>
+		<p>
+			Sets an array of draggable objects by overwriting the existing one.
+		</p>
+
 		<h2>Source</h2>
 		<h2>Source</h2>
 
 
 		<p>
 		<p>

+ 2 - 3
docs/examples/zh/controls/MapControls.html

@@ -111,9 +111,8 @@ controls.touches = {
 	<h2>源代码</h2>
 	<h2>源代码</h2>
 
 
 	<p>
 	<p>
-		[link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/controls/MapControls.js
-		examples/jsm/controls/MapControls.js]
+		[link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/controls/MapControls.js examples/jsm/controls/MapControls.js]
 	</p>
 	</p>
 </body>
 </body>
 
 
-</html>
+</html>

+ 2 - 3
docs/examples/zh/exporters/DRACOExporter.html

@@ -78,9 +78,8 @@
 	<h2>源代码</h2>
 	<h2>源代码</h2>
 
 
 	<p>
 	<p>
-		[link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/exporters/DRACOExporter.js
-		examples/jsm/exporters/DRACOExporter.js]
+		[link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/exporters/DRACOExporter.js examples/jsm/exporters/DRACOExporter.js]
 	</p>
 	</p>
 </body>
 </body>
 
 
-</html>
+</html>

+ 2 - 3
docs/examples/zh/exporters/EXRExporter.html

@@ -88,9 +88,8 @@ ZIPS_COMPRESSION
 	<h2>源代码</h2>
 	<h2>源代码</h2>
 
 
 	<p>
 	<p>
-		[link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/exporters/EXRExporter.js
-		examples/jsm/exporters/EXRExporter.js]
+		[link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/exporters/EXRExporter.js examples/jsm/exporters/EXRExporter.js]
 	</p>
 	</p>
 </body>
 </body>
 
 
-</html>
+</html>

+ 2 - 3
docs/examples/zh/exporters/GLTFExporter.html

@@ -149,9 +149,8 @@
 	<h2>源代码</h2>
 	<h2>源代码</h2>
 
 
 	<p>
 	<p>
-		[link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/exporters/GLTFExporter.js
-		examples/jsm/exporters/GLTFExporter.js]
+		[link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/exporters/GLTFExporter.js examples/jsm/exporters/GLTFExporter.js]
 	</p>
 	</p>
 </body>
 </body>
 
 
-</html>
+</html>

+ 2 - 3
docs/examples/zh/exporters/OBJExporter.html

@@ -60,9 +60,8 @@
 	<h2>源代码</h2>
 	<h2>源代码</h2>
 
 
 	<p>
 	<p>
-		[link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/exporters/OBJExporter.js
-		examples/jsm/exporters/OBJExporter.js]
+		[link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/exporters/OBJExporter.js examples/jsm/exporters/OBJExporter.js]
 	</p>
 	</p>
 </body>
 </body>
 
 
-</html>
+</html>

+ 2 - 3
docs/examples/zh/exporters/PLYExporter.html

@@ -68,9 +68,8 @@
 	<h2>源代码</h2>
 	<h2>源代码</h2>
 
 
 	<p>
 	<p>
-		[link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/exporters/PLYExporter.js
-		examples/jsm/exporters/PLYExporter.js]
+		[link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/exporters/PLYExporter.js examples/jsm/exporters/PLYExporter.js]
 	</p>
 	</p>
 </body>
 </body>
 
 
-</html>
+</html>

+ 2 - 3
docs/examples/zh/exporters/STLExporter.html

@@ -68,9 +68,8 @@
 	<h2>源代码</h2>
 	<h2>源代码</h2>
 
 
 	<p>
 	<p>
-		[link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/exporters/STLExporter.js
-		examples/jsm/exporters/STLExporter.js]
+		[link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/exporters/STLExporter.js examples/jsm/exporters/STLExporter.js]
 	</p>
 	</p>
 </body>
 </body>
 
 
-</html>
+</html>

+ 2 - 3
docs/examples/zh/geometries/SDFGeometryGenerator.html

@@ -65,9 +65,8 @@
 	<h2>源代码</h2>
 	<h2>源代码</h2>
 
 
 	<p>
 	<p>
-		[link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/geometries/SDFGeometry.js
-		examples/jsm/geometries/SDFGeometryGenerator.js]
+		[link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/geometries/SDFGeometry.js examples/jsm/geometries/SDFGeometryGenerator.js]
 	</p>
 	</p>
 </body>
 </body>
 
 
-</html>
+</html>

+ 2 - 3
docs/examples/zh/helpers/VertexTangentsHelper.html

@@ -87,9 +87,8 @@
 	<h2>源代码</h2>
 	<h2>源代码</h2>
 
 
 	<p>
 	<p>
-		[link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/helpers/VertexTangentsHelper.js
-		examples/jsm/helpers/VertexTangentsHelper.js]
+		[link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/helpers/VertexTangentsHelper.js examples/jsm/helpers/VertexTangentsHelper.js]
 	</p>
 	</p>
 </body>
 </body>
 
 
-</html>
+</html>

+ 2 - 3
docs/examples/zh/loaders/3DMLoader.html

@@ -271,9 +271,8 @@
 	<h2>源代码</h2>
 	<h2>源代码</h2>
 
 
 	<p>
 	<p>
-		[link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/loaders/3DMLoader.js
-		examples/jsm/loaders/3DMLoader.js]
+		[link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/loaders/3DMLoader.js examples/jsm/loaders/3DMLoader.js]
 	</p>
 	</p>
 </body>
 </body>
 
 
-</html>
+</html>

+ 4 - 14
docs/examples/zh/loaders/GLTFLoader.html

@@ -52,9 +52,9 @@
 			<li>KHR_materials_unlit</li>
 			<li>KHR_materials_unlit</li>
 			<li>KHR_materials_volume</li>
 			<li>KHR_materials_volume</li>
 			<li>KHR_mesh_quantization</li>
 			<li>KHR_mesh_quantization</li>
-			<li>KHR_lights_punctual<sup>1</sup></li>
+			<li>KHR_lights_punctual</li>
 			<li>KHR_texture_basisu</li>
 			<li>KHR_texture_basisu</li>
-			<li>KHR_texture_transform<sup>2</sup></li>
+			<li>KHR_texture_transform</li>
 			<li>EXT_texture_webp</li>
 			<li>EXT_texture_webp</li>
 			<li>EXT_meshopt_compression</li>
 			<li>EXT_meshopt_compression</li>
 			<li>EXT_mesh_gpu_instancing</li>
 			<li>EXT_mesh_gpu_instancing</li>
@@ -65,22 +65,12 @@
 		</p>
 		</p>
 
 
 		<ul>
 		<ul>
-			<li>[link:https://github.com/takahirox/three-gltf-extensions KHR_materials_variants]<sup>3</sup></li>
+			<li>[link:https://github.com/takahirox/three-gltf-extensions KHR_materials_variants]<sup>1</sup></li>
 			<li>[link:https://github.com/takahirox/three-gltf-extensions MSFT_texture_dds]</li>
 			<li>[link:https://github.com/takahirox/three-gltf-extensions MSFT_texture_dds]</li>
 		</ul>
 		</ul>
 
 
 		<p><i>
 		<p><i>
-			<sup>2</sup>支持UV变换,但存在一些重要的限制。
-			Transforms applied to
-			a texture using the first UV slot (all textures except aoMap and lightMap) must share the same
-			transform, or no transform at all.
-			aoMap 和 lightMap 纹理不能被变换。每个材质最多只能使用一次变换。
-			请参阅#[link:https://github.com/mrdoob/three.js/pull/13831 13831] 和
-			#[link:https://github.com/mrdoob/three.js/issues/12788 12788]。
-		</i></p>
-
-		<p><i>
-			<sup>3</sup>You can also manually process the extension after loading in your application. See [link:https://threejs.org/examples/#webgl_loader_gltf_variants Three.js glTF materials variants example].
+			<sup>1</sup>You can also manually process the extension after loading in your application. See [link:https://threejs.org/examples/#webgl_loader_gltf_variants Three.js glTF materials variants example].
 		</i></p>
 		</i></p>
 
 
 		<h2>代码示例</h2>
 		<h2>代码示例</h2>

+ 2 - 3
docs/examples/zh/loaders/KTX2Loader.html

@@ -134,9 +134,8 @@
 	<h2>源代码</h2>
 	<h2>源代码</h2>
 
 
 	<p>
 	<p>
-		[link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/loaders/KTX2Loader.js
-		examples/jsm/loaders/KTX2Loader.js]
+		[link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/loaders/KTX2Loader.js examples/jsm/loaders/KTX2Loader.js]
 	</p>
 	</p>
 </body>
 </body>
 
 
-</html>
+</html>

+ 2 - 3
docs/examples/zh/loaders/LDrawLoader.html

@@ -211,9 +211,8 @@
 	<h2>源代码</h2>
 	<h2>源代码</h2>
 
 
 	<p>
 	<p>
-		[link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/loaders/LDrawLoader.js
-		examples/jsm/loaders/LDrawLoader.js]
+		[link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/loaders/LDrawLoader.js examples/jsm/loaders/LDrawLoader.js]
 	</p>
 	</p>
 </body>
 </body>
 
 
-</html>
+</html>

+ 2 - 3
docs/examples/zh/loaders/PDBLoader.html

@@ -109,9 +109,8 @@
 	<h2>源代码</h2>
 	<h2>源代码</h2>
 
 
 	<p>
 	<p>
-		[link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/loaders/PDBLoader.js
-		examples/jsm/loaders/PDBLoader.js]
+		[link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/loaders/PDBLoader.js examples/jsm/loaders/PDBLoader.js]
 	</p>
 	</p>
 </body>
 </body>
 
 
-</html>
+</html>

+ 2 - 3
docs/examples/zh/math/MeshSurfaceSampler.html

@@ -90,9 +90,8 @@
 	<h2>源代码</h2>
 	<h2>源代码</h2>
 
 
 	<p>
 	<p>
-		[link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/math/MeshSurfaceSampler.js
-		examples/jsm/math/MeshSurfaceSampler.js]
+		[link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/math/MeshSurfaceSampler.js examples/jsm/math/MeshSurfaceSampler.js]
 	</p>
 	</p>
 </body>
 </body>
 
 
-</html>
+</html>

+ 2 - 3
docs/examples/zh/math/convexhull/ConvexHull.html

@@ -230,9 +230,8 @@
 	<h2>源代码</h2>
 	<h2>源代码</h2>
 
 
 	<p>
 	<p>
-		[link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/math/ConvexHull.js
-		examples/jsm/math/ConvexHull.js]
+		[link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/math/ConvexHull.js examples/jsm/math/ConvexHull.js]
 	</p>
 	</p>
 </body>
 </body>
 
 
-</html>
+</html>

+ 2 - 3
docs/examples/zh/math/convexhull/Face.html

@@ -103,9 +103,8 @@
 	<h2>源代码</h2>
 	<h2>源代码</h2>
 
 
 	<p>
 	<p>
-		[link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/math/ConvexHull.js
-		examples/jsm/math/ConvexHull.js]
+		[link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/math/ConvexHull.js examples/jsm/math/ConvexHull.js]
 	</p>
 	</p>
 </body>
 </body>
 
 
-</html>
+</html>

+ 2 - 3
docs/examples/zh/math/convexhull/HalfEdge.html

@@ -90,9 +90,8 @@
 	<h2>源代码</h2>
 	<h2>源代码</h2>
 
 
 	<p>
 	<p>
-		[link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/math/ConvexHull.js
-		examples/jsm/math/ConvexHull.js]
+		[link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/math/ConvexHull.js examples/jsm/math/ConvexHull.js]
 	</p>
 	</p>
 </body>
 </body>
 
 
-</html>
+</html>

+ 2 - 3
docs/examples/zh/math/convexhull/VertexList.html

@@ -109,9 +109,8 @@
 	<h2>源代码</h2>
 	<h2>源代码</h2>
 
 
 	<p>
 	<p>
-		[link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/math/ConvexHull.js
-		examples/jsm/math/ConvexHull.js]
+		[link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/math/ConvexHull.js examples/jsm/math/ConvexHull.js]
 	<p>
 	<p>
 </body>
 </body>
 
 
-</html>
+</html>

+ 2 - 3
docs/examples/zh/math/convexhull/VertexNode.html

@@ -61,9 +61,8 @@
 	<h2>源代码</h2>
 	<h2>源代码</h2>
 
 
 	<p>
 	<p>
-		[link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/math/ConvexHull.js
-		examples/jsm/math/ConvexHull.js]
+		[link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/math/ConvexHull.js examples/jsm/math/ConvexHull.js]
 	<p>
 	<p>
 </body>
 </body>
 
 
-</html>
+</html>

+ 2 - 3
docs/examples/zh/utils/CameraUtils.html

@@ -38,9 +38,8 @@
 	<h2>源代码</h2>
 	<h2>源代码</h2>
 
 
 	<p>
 	<p>
-		[link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/utils/CameraUtils.js
-		examples/jsm/utils/CameraUtils.js]
+		[link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/utils/CameraUtils.js examples/jsm/utils/CameraUtils.js]
 	</p>
 	</p>
 </body>
 </body>
 
 
-</html>
+</html>

+ 2 - 3
docs/examples/zh/webxr/XREstimatedLight.html

@@ -109,9 +109,8 @@
 	<h2>源代码</h2>
 	<h2>源代码</h2>
 
 
 	<p>
 	<p>
-		[link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/webxr/XREstimatedLight.js
-		examples/jsm/webxr/XREstimatedLight.js]
+		[link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/webxr/XREstimatedLight.js examples/jsm/webxr/XREstimatedLight.js]
 	</p>
 	</p>
 </body>
 </body>
 
 
-</html>
+</html>

+ 0 - 5
docs/list.json

@@ -278,7 +278,6 @@
 			},
 			},
 
 
 			"Renderers": {
 			"Renderers": {
-				"WebGLMultipleRenderTargets": "api/en/renderers/WebGLMultipleRenderTargets",
 				"WebGLRenderer": "api/en/renderers/WebGLRenderer",
 				"WebGLRenderer": "api/en/renderers/WebGLRenderer",
 				"WebGL1Renderer": "api/en/renderers/WebGL1Renderer",
 				"WebGL1Renderer": "api/en/renderers/WebGL1Renderer",
 				"WebGLRenderTarget": "api/en/renderers/WebGLRenderTarget",
 				"WebGLRenderTarget": "api/en/renderers/WebGLRenderTarget",
@@ -720,7 +719,6 @@
 			},
 			},
 
 
 			"Renderers": {
 			"Renderers": {
-				"WebGLMultipleRenderTargets": "api/ar/renderers/WebGLMultipleRenderTargets",
 				"WebGLRenderer": "api/ar/renderers/WebGLRenderer",
 				"WebGLRenderer": "api/ar/renderers/WebGLRenderer",
 				"WebGL1Renderer": "api/ar/renderers/WebGL1Renderer",
 				"WebGL1Renderer": "api/ar/renderers/WebGL1Renderer",
 				"WebGLRenderTarget": "api/ar/renderers/WebGLRenderTarget",
 				"WebGLRenderTarget": "api/ar/renderers/WebGLRenderTarget",
@@ -1028,7 +1026,6 @@
 			},
 			},
 
 
 			"渲染器": {
 			"渲染器": {
-				"WebGLMultipleRenderTargets": "api/zh/renderers/WebGLMultipleRenderTargets",
 				"WebGLRenderer": "api/zh/renderers/WebGLRenderer",
 				"WebGLRenderer": "api/zh/renderers/WebGLRenderer",
 				"WebGL1Renderer": "api/zh/renderers/WebGL1Renderer",
 				"WebGL1Renderer": "api/zh/renderers/WebGL1Renderer",
 				"WebGLRenderTarget": "api/zh/renderers/WebGLRenderTarget",
 				"WebGLRenderTarget": "api/zh/renderers/WebGLRenderTarget",
@@ -1665,7 +1662,6 @@
 			},
 			},
 
 
 			"Renderers": {
 			"Renderers": {
-				"WebGLMultipleRenderTargets": "api/it/renderers/WebGLMultipleRenderTargets",
 				"WebGLRenderer": "api/it/renderers/WebGLRenderer",
 				"WebGLRenderer": "api/it/renderers/WebGLRenderer",
 				"WebGL1Renderer": "api/it/renderers/WebGL1Renderer",
 				"WebGL1Renderer": "api/it/renderers/WebGL1Renderer",
 				"WebGLRenderTarget": "api/it/renderers/WebGLRenderTarget",
 				"WebGLRenderTarget": "api/it/renderers/WebGLRenderTarget",
@@ -2193,7 +2189,6 @@
 			},
 			},
 
 
 			"Renderers": {
 			"Renderers": {
-				"WebGLMultipleRenderTargets": "api/en/renderers/WebGLMultipleRenderTargets",
 				"WebGLRenderer": "api/en/renderers/WebGLRenderer",
 				"WebGLRenderer": "api/en/renderers/WebGLRenderer",
 				"WebGL1Renderer": "api/en/renderers/WebGL1Renderer",
 				"WebGL1Renderer": "api/en/renderers/WebGL1Renderer",
 				"WebGLRenderTarget": "api/en/renderers/WebGLRenderTarget",
 				"WebGLRenderTarget": "api/en/renderers/WebGLRenderTarget",

+ 30 - 1
docs/manual/en/introduction/How-to-update-things.html

@@ -190,7 +190,6 @@ line.geometry.computeBoundingSphere();
 
 
 		</div>
 		</div>
 
 
-
 		<h2>Cameras</h2>
 		<h2>Cameras</h2>
 		<div>
 		<div>
 			<p>A camera's position and target is updated automatically. If you need to change</p>
 			<p>A camera's position and target is updated automatically. If you need to change</p>
@@ -216,5 +215,35 @@ camera.aspect = window.innerWidth / window.innerHeight;
 camera.updateProjectionMatrix();
 camera.updateProjectionMatrix();
 			</code>
 			</code>
 		</div>
 		</div>
+
+		<h2>InstancedMesh</h2>
+		<div>
+			<p>
+				`InstancedMesh` is a class for conveniently access instanced rendering in `three.js`. Certain library features like view frustum culling or
+				ray casting rely on up-to-date bounding volumes (bounding sphere and bounding box). Because of the way how `InstancedMesh` works, the class 
+				has its own [page:InstancedMesh.boundingBox boundingBox] and [page:InstancedMesh.boundingSphere boundingSphere] properties that supersede
+				the bounding volumes on geometry level.
+			</p>
+			<p>
+				Similar to geometries you have to recompute the bounding box and sphere whenever you change the underlying data. In context of `InstancedMesh`, that
+				happens when you transform instances via [page:InstancedMesh.setMatrixAt setMatrixAt](). You can use the same pattern like with geometries.
+			</p>
+			<code>
+instancedMesh.computeBoundingBox();
+instancedMesh.computeBoundingSphere();
+			</code>
+
+		</div>
+
+		<h2>SkinnedMesh</h2>
+		<div>
+			<p>
+				`SkinnedMesh` follows the same principles like `InstancedMesh` in context of bounding volumes. Meaning the class has its own version of
+				[page:SkinnedMesh.boundingBox boundingBox] and [page:SkinnedMesh.boundingSphere boundingSphere] to correctly enclose animated meshes.
+				When calling `computeBoundingBox()` and `computeBoundingSphere()`, the class computes the respective bounding volumes based on the current
+				bone tranformation (or in other words the current animation state).
+			</p>
+		</div>
+
 	</body>
 	</body>
 </html>
 </html>

+ 3 - 0
docs/manual/en/introduction/Matrix-transformations.html

@@ -54,6 +54,9 @@ object.matrixAutoUpdate = false;
 		<p>
 		<p>
 		When either the parent or the child object's transformation changes, you can request that the child object's [page:Object3D.matrixWorld matrixWorld] be updated by calling [page:Object3D.updateMatrixWorld updateMatrixWorld]().
 		When either the parent or the child object's transformation changes, you can request that the child object's [page:Object3D.matrixWorld matrixWorld] be updated by calling [page:Object3D.updateMatrixWorld updateMatrixWorld]().
 		</p>
 		</p>
+		<p>
+		An object can be transformed via [page:Object3D.applyMatrix4]. Note: Under-the-hood, this method relies on [page:Matrix4.decompose], and not all matrices are decomposable in this way. For example, if an object has a non-uniformly scaled parent, then the object's world matrix may not be decomposable, and this method may not be appropriate.
+		</p>
 
 
 		<h2>Rotation and Quaternion</h2>
 		<h2>Rotation and Quaternion</h2>
 		<p>
 		<p>

+ 15 - 9
editor/css/main.css

@@ -67,7 +67,7 @@ textarea, input { outline: none; } /* osx */
 	position: relative;
 	position: relative;
 	display: block;
 	display: block;
 	width: 100%;
 	width: 100%;
-	min-width: 260px;
+	min-width: 335px;
 }
 }
 
 
 .TabbedPanel .Tabs {
 .TabbedPanel .Tabs {
@@ -77,7 +77,7 @@ textarea, input { outline: none; } /* osx */
 }
 }
 
 
 	.TabbedPanel .Tabs .Tab {
 	.TabbedPanel .Tabs .Tab {
-		padding: 10px;
+		padding: 10px 9px;
 		text-transform: uppercase;
 		text-transform: uppercase;
 	}
 	}
 
 
@@ -93,7 +93,7 @@ textarea, input { outline: none; } /* osx */
 	background-color: #fff;
 	background-color: #fff;
 	padding: 0;
 	padding: 0;
 	width: 100%;
 	width: 100%;
-	min-height: 140px;
+	min-height: 180px;
 	font-size: 12px;
 	font-size: 12px;
 	cursor: default;
 	cursor: default;
 	overflow: auto;
 	overflow: auto;
@@ -293,7 +293,7 @@ select {
 #resizer {
 #resizer {
 	position: absolute;
 	position: absolute;
 	top: 32px;
 	top: 32px;
-	right: 295px;
+	right: 345px;
 	width: 5px;
 	width: 5px;
 	bottom: 0px;
 	bottom: 0px;
 	/* background-color: rgba(255,0,0,0.5); */
 	/* background-color: rgba(255,0,0,0.5); */
@@ -304,7 +304,7 @@ select {
 	position: absolute;
 	position: absolute;
 	top: 32px;
 	top: 32px;
 	left: 0;
 	left: 0;
-	right: 300px;
+	right: 350px;
 	bottom: 0;
 	bottom: 0;
 }
 }
 
 
@@ -317,7 +317,7 @@ select {
 	position: absolute;
 	position: absolute;
 	top: 32px;
 	top: 32px;
 	left: 0;
 	left: 0;
-	right: 300px;
+	right: 350px;
 	bottom: 0;
 	bottom: 0;
 	opacity: 0.9;
 	opacity: 0.9;
 }
 }
@@ -326,7 +326,7 @@ select {
 	position: absolute;
 	position: absolute;
 	top: 32px;
 	top: 32px;
 	left: 0;
 	left: 0;
-	right: 300px;
+	right: 350px;
 	bottom: 0;
 	bottom: 0;
 }
 }
 
 
@@ -409,7 +409,7 @@ select {
 	right: 0;
 	right: 0;
 	top: 32px;
 	top: 32px;
 	bottom: 0;
 	bottom: 0;
-	width: 300px;
+	width: 350px;
 	background: #eee;
 	background: #eee;
 	overflow: auto;
 	overflow: auto;
 }
 }
@@ -431,6 +431,12 @@ select {
 		margin-bottom: 10px;
 		margin-bottom: 10px;
 	}
 	}
 
 
+	#sidebar .Row .Label {
+
+		width: 120px;
+
+	}
+
 #tabs {
 #tabs {
 	background-color: #ddd;
 	background-color: #ddd;
 	border-top: 1px solid #ccc;
 	border-top: 1px solid #ccc;
@@ -470,7 +476,7 @@ select {
 	background-color: #fff;
 	background-color: #fff;
 	padding: 0;
 	padding: 0;
 	width: 100%;
 	width: 100%;
-	height: 140px;
+	height: 180px;
 	font-size: 12px;
 	font-size: 12px;
 	cursor: default;
 	cursor: default;
 	overflow: auto;
 	overflow: auto;

+ 2 - 4
editor/index.html

@@ -61,8 +61,8 @@
 					"three/addons/": "../examples/jsm/",
 					"three/addons/": "../examples/jsm/",
 
 
 					"three/examples/": "../examples/",
 					"three/examples/": "../examples/",
-					"three-gpu-pathtracer": "https://unpkg.com/[email protected]7/build/index.module.js",
-					"three-mesh-bvh": "https://unpkg.com/[email protected].0/build/index.module.js"
+					"three-gpu-pathtracer": "https://unpkg.com/[email protected]9/build/index.module.js",
+					"three-mesh-bvh": "https://unpkg.com/[email protected].3/build/index.module.js"
 				}
 				}
 			}
 			}
 		</script>
 		</script>
@@ -79,7 +79,6 @@
 			import { Sidebar } from './js/Sidebar.js';
 			import { Sidebar } from './js/Sidebar.js';
 			import { Menubar } from './js/Menubar.js';
 			import { Menubar } from './js/Menubar.js';
 			import { Resizer } from './js/Resizer.js';
 			import { Resizer } from './js/Resizer.js';
-			import { VRButton } from 'three/addons/webxr/VRButton.js';
 
 
 			window.URL = window.URL || window.webkitURL;
 			window.URL = window.URL || window.webkitURL;
 			window.BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder;
 			window.BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder;
@@ -96,7 +95,6 @@
 
 
 			window.editor = editor; // Expose editor to Console
 			window.editor = editor; // Expose editor to Console
 			window.THREE = THREE; // Expose THREE to APP Scripts and Console
 			window.THREE = THREE; // Expose THREE to APP Scripts and Console
-			window.VRButton = VRButton; // Expose VRButton to APP Scripts
 
 
 			const viewport = new Viewport( editor );
 			const viewport = new Viewport( editor );
 			document.body.appendChild( viewport.dom );
 			document.body.appendChild( viewport.dom );

+ 43 - 6
editor/js/Editor.js

@@ -5,7 +5,7 @@ import { Loader } from './Loader.js';
 import { History as _History } from './History.js';
 import { History as _History } from './History.js';
 import { Strings } from './Strings.js';
 import { Strings } from './Strings.js';
 import { Storage as _Storage } from './Storage.js';
 import { Storage as _Storage } from './Storage.js';
-import { Selector } from './Viewport.Selector.js';
+import { Selector } from './Selector.js';
 
 
 var _DEFAULT_CAMERA = new THREE.PerspectiveCamera( 50, 1, 0.01, 1000 );
 var _DEFAULT_CAMERA = new THREE.PerspectiveCamera( 50, 1, 0.01, 1000 );
 _DEFAULT_CAMERA.name = 'Camera';
 _DEFAULT_CAMERA.name = 'Camera';
@@ -27,10 +27,11 @@ function Editor() {
 		startPlayer: new Signal(),
 		startPlayer: new Signal(),
 		stopPlayer: new Signal(),
 		stopPlayer: new Signal(),
 
 
-		// vr
+		// xr
 
 
-		toggleVR: new Signal(),
-		exitedVR: new Signal(),
+		enterXR: new Signal(),
+		offerXR: new Signal(),
+		leaveXR: new Signal(),
 
 
 		// notifications
 		// notifications
 
 
@@ -96,9 +97,9 @@ function Editor() {
 
 
 	this.config = new Config();
 	this.config = new Config();
 	this.history = new _History( this );
 	this.history = new _History( this );
+	this.selector = new Selector( this );
 	this.storage = new _Storage();
 	this.storage = new _Storage();
 	this.strings = new Strings( this.config );
 	this.strings = new Strings( this.config );
-	this.selector = new Selector( this );
 
 
 	this.loader = new Loader( this );
 	this.loader = new Loader( this );
 
 
@@ -108,6 +109,7 @@ function Editor() {
 	this.scene.name = 'Scene';
 	this.scene.name = 'Scene';
 
 
 	this.sceneHelpers = new THREE.Scene();
 	this.sceneHelpers = new THREE.Scene();
+	this.sceneHelpers.add( new THREE.HemisphereLight( 0xffffff, 0x888888, 2 ) );
 
 
 	this.object = {};
 	this.object = {};
 	this.geometries = {};
 	this.geometries = {};
@@ -711,7 +713,6 @@ Editor.prototype = {
 			project: {
 			project: {
 				shadows: this.config.getKey( 'project/renderer/shadows' ),
 				shadows: this.config.getKey( 'project/renderer/shadows' ),
 				shadowType: this.config.getKey( 'project/renderer/shadowType' ),
 				shadowType: this.config.getKey( 'project/renderer/shadowType' ),
-				vr: this.config.getKey( 'project/vr' ),
 				toneMapping: this.config.getKey( 'project/renderer/toneMapping' ),
 				toneMapping: this.config.getKey( 'project/renderer/toneMapping' ),
 				toneMappingExposure: this.config.getKey( 'project/renderer/toneMappingExposure' )
 				toneMappingExposure: this.config.getKey( 'project/renderer/toneMappingExposure' )
 			},
 			},
@@ -747,8 +748,44 @@ Editor.prototype = {
 
 
 		this.history.redo();
 		this.history.redo();
 
 
+	},
+
+	utils: {
+
+		save: save,
+		saveArrayBuffer: saveArrayBuffer,
+		saveString: saveString
+
 	}
 	}
 
 
 };
 };
 
 
+const link = document.createElement( 'a' );
+
+function save( blob, filename ) {
+
+	if ( link.href ) {
+
+		URL.revokeObjectURL( link.href );
+
+	}
+
+	link.href = URL.createObjectURL( blob );
+	link.download = filename || 'data.json';
+	link.dispatchEvent( new MouseEvent( 'click' ) );
+
+}
+
+function saveArrayBuffer( buffer, filename ) {
+
+	save( new Blob( [ buffer ], { type: 'application/octet-stream' } ), filename );
+
+}
+
+function saveString( text, filename ) {
+
+	save( new Blob( [ text ], { type: 'text/plain' } ), filename );
+
+}
+
 export { Editor };
 export { Editor };

+ 125 - 44
editor/js/EditorControls.js

@@ -31,6 +31,9 @@ class EditorControls extends THREE.EventDispatcher {
 		var spherical = new THREE.Spherical();
 		var spherical = new THREE.Spherical();
 		var sphere = new THREE.Sphere();
 		var sphere = new THREE.Sphere();
 
 
+		var pointers = [];
+		var pointerPositions = {};
+
 		// events
 		// events
 
 
 		var changeEvent = { type: 'change' };
 		var changeEvent = { type: 'change' };
@@ -122,19 +125,32 @@ class EditorControls extends THREE.EventDispatcher {
 
 
 			if ( scope.enabled === false ) return;
 			if ( scope.enabled === false ) return;
 
 
-			switch ( event.pointerType ) {
+			if ( pointers.length === 0 ) {
 
 
-				case 'mouse':
-				case 'pen':
-					onMouseDown( event );
-					break;
+				domElement.setPointerCapture( event.pointerId );
 
 
-				// TODO touch
+				domElement.ownerDocument.addEventListener( 'pointermove', onPointerMove );
+				domElement.ownerDocument.addEventListener( 'pointerup', onPointerUp );
 
 
 			}
 			}
 
 
-			domElement.ownerDocument.addEventListener( 'pointermove', onPointerMove );
-			domElement.ownerDocument.addEventListener( 'pointerup', onPointerUp );
+			//
+
+			if ( isTrackingPointer( event ) ) return;
+
+			//
+
+			addPointer( event );
+
+			if ( event.pointerType === 'touch' ) {
+
+				onTouchStart( event );
+
+			} else {
+
+				onMouseDown( event );
+
+			}
 
 
 		}
 		}
 
 
@@ -142,14 +158,13 @@ class EditorControls extends THREE.EventDispatcher {
 
 
 			if ( scope.enabled === false ) return;
 			if ( scope.enabled === false ) return;
 
 
-			switch ( event.pointerType ) {
+			if ( event.pointerType === 'touch' ) {
 
 
-				case 'mouse':
-				case 'pen':
-					onMouseMove( event );
-					break;
+				onTouchMove( event );
 
 
-				// TODO touch
+			} else {
+
+				onMouseMove( event );
 
 
 			}
 			}
 
 
@@ -157,19 +172,30 @@ class EditorControls extends THREE.EventDispatcher {
 
 
 		function onPointerUp( event ) {
 		function onPointerUp( event ) {
 
 
-			switch ( event.pointerType ) {
+			removePointer( event );
+
+			switch ( pointers.length ) {
+
+				case 0:
+
+					domElement.releasePointerCapture( event.pointerId );
+
+					domElement.ownerDocument.removeEventListener( 'pointermove', onPointerMove );
+					domElement.ownerDocument.removeEventListener( 'pointerup', onPointerUp );
 
 
-				case 'mouse':
-				case 'pen':
-					onMouseUp();
 					break;
 					break;
 
 
-				// TODO touch
+				case 1:
 
 
-			}
+					var pointerId = pointers[ 0 ];
+					var position = pointerPositions[ pointerId ];
 
 
-			domElement.ownerDocument.removeEventListener( 'pointermove', onPointerMove );
-			domElement.ownerDocument.removeEventListener( 'pointerup', onPointerUp );
+					// minimal placeholder event - allows state correction on pointer-up
+					onTouchStart( { pointerId: pointerId, pageX: position.x, pageY: position.y } );
+
+					break;
+
+			}
 
 
 		}
 		}
 
 
@@ -251,9 +277,6 @@ class EditorControls extends THREE.EventDispatcher {
 
 
 			domElement.removeEventListener( 'pointerdown', onPointerDown );
 			domElement.removeEventListener( 'pointerdown', onPointerDown );
 
 
-			domElement.removeEventListener( 'touchstart', touchStart );
-			domElement.removeEventListener( 'touchmove', touchMove );
-
 		};
 		};
 
 
 		domElement.addEventListener( 'contextmenu', contextmenu );
 		domElement.addEventListener( 'contextmenu', contextmenu );
@@ -269,20 +292,23 @@ class EditorControls extends THREE.EventDispatcher {
 
 
 		var prevDistance = null;
 		var prevDistance = null;
 
 
-		function touchStart( event ) {
+		function onTouchStart( event ) {
 
 
-			if ( scope.enabled === false ) return;
+			trackPointer( event );
 
 
-			switch ( event.touches.length ) {
+			switch ( pointers.length ) {
 
 
 				case 1:
 				case 1:
-					touches[ 0 ].set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY, 0 ).divideScalar( window.devicePixelRatio );
-					touches[ 1 ].set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY, 0 ).divideScalar( window.devicePixelRatio );
+					touches[ 0 ].set( event.pageX, event.pageY, 0 ).divideScalar( window.devicePixelRatio );
+					touches[ 1 ].set( event.pageX, event.pageY, 0 ).divideScalar( window.devicePixelRatio );
 					break;
 					break;
 
 
 				case 2:
 				case 2:
-					touches[ 0 ].set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY, 0 ).divideScalar( window.devicePixelRatio );
-					touches[ 1 ].set( event.touches[ 1 ].pageX, event.touches[ 1 ].pageY, 0 ).divideScalar( window.devicePixelRatio );
+
+					var position = getSecondPointerPosition( event );
+
+					touches[ 0 ].set( event.pageX, event.pageY, 0 ).divideScalar( window.devicePixelRatio );
+					touches[ 1 ].set( position.x, position.y, 0 ).divideScalar( window.devicePixelRatio );
 					prevDistance = touches[ 0 ].distanceTo( touches[ 1 ] );
 					prevDistance = touches[ 0 ].distanceTo( touches[ 1 ] );
 					break;
 					break;
 
 
@@ -294,12 +320,9 @@ class EditorControls extends THREE.EventDispatcher {
 		}
 		}
 
 
 
 
-		function touchMove( event ) {
-
-			if ( scope.enabled === false ) return;
+		function onTouchMove( event ) {
 
 
-			event.preventDefault();
-			event.stopPropagation();
+			trackPointer( event );
 
 
 			function getClosest( touch, touches ) {
 			function getClosest( touch, touches ) {
 
 
@@ -315,17 +338,20 @@ class EditorControls extends THREE.EventDispatcher {
 
 
 			}
 			}
 
 
-			switch ( event.touches.length ) {
+			switch ( pointers.length ) {
 
 
 				case 1:
 				case 1:
-					touches[ 0 ].set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY, 0 ).divideScalar( window.devicePixelRatio );
-					touches[ 1 ].set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY, 0 ).divideScalar( window.devicePixelRatio );
+					touches[ 0 ].set( event.pageX, event.pageY, 0 ).divideScalar( window.devicePixelRatio );
+					touches[ 1 ].set( event.pageX, event.pageY, 0 ).divideScalar( window.devicePixelRatio );
 					scope.rotate( touches[ 0 ].sub( getClosest( touches[ 0 ], prevTouches ) ).multiplyScalar( - 1 ) );
 					scope.rotate( touches[ 0 ].sub( getClosest( touches[ 0 ], prevTouches ) ).multiplyScalar( - 1 ) );
 					break;
 					break;
 
 
 				case 2:
 				case 2:
-					touches[ 0 ].set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY, 0 ).divideScalar( window.devicePixelRatio );
-					touches[ 1 ].set( event.touches[ 1 ].pageX, event.touches[ 1 ].pageY, 0 ).divideScalar( window.devicePixelRatio );
+
+					var position = getSecondPointerPosition( event );
+
+					touches[ 0 ].set( event.pageX, event.pageY, 0 ).divideScalar( window.devicePixelRatio );
+					touches[ 1 ].set( position.x, position.y, 0 ).divideScalar( window.devicePixelRatio );
 					var distance = touches[ 0 ].distanceTo( touches[ 1 ] );
 					var distance = touches[ 0 ].distanceTo( touches[ 1 ] );
 					scope.zoom( delta.set( 0, 0, prevDistance - distance ) );
 					scope.zoom( delta.set( 0, 0, prevDistance - distance ) );
 					prevDistance = distance;
 					prevDistance = distance;
@@ -347,8 +373,63 @@ class EditorControls extends THREE.EventDispatcher {
 
 
 		}
 		}
 
 
-		domElement.addEventListener( 'touchstart', touchStart, { passive: false } );
-		domElement.addEventListener( 'touchmove', touchMove, { passive: false } );
+		function addPointer( event ) {
+
+			pointers.push( event.pointerId );
+
+		}
+
+		function removePointer( event ) {
+
+			delete pointerPositions[ event.pointerId ];
+
+			for ( var i = 0; i < pointers.length; i ++ ) {
+
+				if ( pointers[ i ] == event.pointerId ) {
+
+					pointers.splice( i, 1 );
+					return;
+
+				}
+
+			}
+
+		}
+
+		function isTrackingPointer( event ) {
+
+			for ( var i = 0; i < pointers.length; i ++ ) {
+
+				if ( pointers[ i ] == event.pointerId ) return true;
+
+			}
+
+			return false;
+
+		}
+
+		function trackPointer( event ) {
+
+			var position = pointerPositions[ event.pointerId ];
+
+			if ( position === undefined ) {
+
+				position = new THREE.Vector2();
+				pointerPositions[ event.pointerId ] = position;
+
+			}
+
+			position.set( event.pageX, event.pageY );
+
+		}
+
+		function getSecondPointerPosition( event ) {
+
+			var pointerId = ( event.pointerId === pointers[ 0 ] ) ? pointers[ 1 ] : pointers[ 0 ];
+
+			return pointerPositions[ pointerId ];
+
+		}
 
 
 	}
 	}
 
 

+ 1 - 18
editor/js/Menubar.Edit.js

@@ -47,23 +47,6 @@ function MenubarEdit( editor ) {
 	} );
 	} );
 	options.add( redo );
 	options.add( redo );
 
 
-	// Clear History
-
-	let option = new UIRow();
-	option.setClass( 'option' );
-	option.setTextContent( strings.getKey( 'menubar/edit/clear_history' ) );
-	option.onClick( function () {
-
-		if ( confirm( 'The Undo/Redo History will be cleared. Are you sure?' ) ) {
-
-			editor.history.clear();
-
-		}
-
-	} );
-	options.add( option );
-
-
 	editor.signals.historyChanged.add( function () {
 	editor.signals.historyChanged.add( function () {
 
 
 		const history = editor.history;
 		const history = editor.history;
@@ -91,7 +74,7 @@ function MenubarEdit( editor ) {
 
 
 	// Center
 	// Center
 
 
-	option = new UIRow();
+	let option = new UIRow();
 	option.setClass( 'option' );
 	option.setClass( 'option' );
 	option.setTextContent( strings.getKey( 'menubar/edit/center' ) );
 	option.setTextContent( strings.getKey( 'menubar/edit/center' ) );
 	option.onClick( function () {
 	option.onClick( function () {

+ 3 - 224
editor/js/Menubar.File.js

@@ -1,14 +1,12 @@
-import * as THREE from 'three';
-
-import { zipSync, strToU8 } from 'three/addons/libs/fflate.module.js';
-
 import { UIPanel, UIRow, UIHorizontalRule } from './libs/ui.js';
 import { UIPanel, UIRow, UIHorizontalRule } from './libs/ui.js';
 
 
 function MenubarFile( editor ) {
 function MenubarFile( editor ) {
 
 
-	const config = editor.config;
 	const strings = editor.strings;
 	const strings = editor.strings;
 
 
+	const saveArrayBuffer = editor.utils.saveArrayBuffer;
+	const saveString = editor.utils.saveString;
+
 	const container = new UIPanel();
 	const container = new UIPanel();
 	container.setClass( 'menu' );
 	container.setClass( 'menu' );
 
 
@@ -72,112 +70,6 @@ function MenubarFile( editor ) {
 
 
 	options.add( new UIHorizontalRule() );
 	options.add( new UIHorizontalRule() );
 
 
-	// Export Geometry
-
-	option = new UIRow();
-	option.setClass( 'option' );
-	option.setTextContent( strings.getKey( 'menubar/file/export/geometry' ) );
-	option.onClick( function () {
-
-		const object = editor.selected;
-
-		if ( object === null ) {
-
-			alert( 'No object selected.' );
-			return;
-
-		}
-
-		const geometry = object.geometry;
-
-		if ( geometry === undefined ) {
-
-			alert( 'The selected object doesn\'t have geometry.' );
-			return;
-
-		}
-
-		let output = geometry.toJSON();
-
-		try {
-
-			output = JSON.stringify( output, null, '\t' );
-			output = output.replace( /[\n\t]+([\d\.e\-\[\]]+)/g, '$1' );
-
-		} catch ( e ) {
-
-			output = JSON.stringify( output );
-
-		}
-
-		saveString( output, 'geometry.json' );
-
-	} );
-	options.add( option );
-
-	// Export Object
-
-	option = new UIRow();
-	option.setClass( 'option' );
-	option.setTextContent( strings.getKey( 'menubar/file/export/object' ) );
-	option.onClick( function () {
-
-		const object = editor.selected;
-
-		if ( object === null ) {
-
-			alert( 'No object selected' );
-			return;
-
-		}
-
-		let output = object.toJSON();
-
-		try {
-
-			output = JSON.stringify( output, null, '\t' );
-			output = output.replace( /[\n\t]+([\d\.e\-\[\]]+)/g, '$1' );
-
-		} catch ( e ) {
-
-			output = JSON.stringify( output );
-
-		}
-
-		saveString( output, 'model.json' );
-
-	} );
-	options.add( option );
-
-	// Export Scene
-
-	option = new UIRow();
-	option.setClass( 'option' );
-	option.setTextContent( strings.getKey( 'menubar/file/export/scene' ) );
-	option.onClick( function () {
-
-		let output = editor.scene.toJSON();
-
-		try {
-
-			output = JSON.stringify( output, null, '\t' );
-			output = output.replace( /[\n\t]+([\d\.e\-\[\]]+)/g, '$1' );
-
-		} catch ( e ) {
-
-			output = JSON.stringify( output );
-
-		}
-
-		saveString( output, 'scene.json' );
-
-	} );
-	options.add( option );
-
-	//
-
-	options.add( new UIHorizontalRule() );
-
 	// Export DRC
 	// Export DRC
 
 
 	option = new UIRow();
 	option = new UIRow();
@@ -393,119 +285,6 @@ function MenubarFile( editor ) {
 
 
 	//
 	//
 
 
-	options.add( new UIHorizontalRule() );
-
-	// Publish
-
-	option = new UIRow();
-	option.setClass( 'option' );
-	option.setTextContent( strings.getKey( 'menubar/file/publish' ) );
-	option.onClick( function () {
-
-		const toZip = {};
-
-		//
-
-		let output = editor.toJSON();
-		output.metadata.type = 'App';
-		delete output.history;
-
-		output = JSON.stringify( output, null, '\t' );
-		output = output.replace( /[\n\t]+([\d\.e\-\[\]]+)/g, '$1' );
-
-		toZip[ 'app.json' ] = strToU8( output );
-
-		//
-
-		const title = config.getKey( 'project/title' );
-
-		const manager = new THREE.LoadingManager( function () {
-
-			const zipped = zipSync( toZip, { level: 9 } );
-
-			const blob = new Blob( [ zipped.buffer ], { type: 'application/zip' } );
-
-			save( blob, ( title !== '' ? title : 'untitled' ) + '.zip' );
-
-		} );
-
-		const loader = new THREE.FileLoader( manager );
-		loader.load( 'js/libs/app/index.html', function ( content ) {
-
-			content = content.replace( '<!-- title -->', title );
-
-			const includes = [];
-
-			content = content.replace( '<!-- includes -->', includes.join( '\n\t\t' ) );
-
-			let editButton = '';
-
-			if ( config.getKey( 'project/editable' ) ) {
-
-				editButton = [
-					'			let button = document.createElement( \'a\' );',
-					'			button.href = \'https://threejs.org/editor/#file=\' + location.href.split( \'/\' ).slice( 0, - 1 ).join( \'/\' ) + \'/app.json\';',
-					'			button.style.cssText = \'position: absolute; bottom: 20px; right: 20px; padding: 10px 16px; color: #fff; border: 1px solid #fff; border-radius: 20px; text-decoration: none;\';',
-					'			button.target = \'_blank\';',
-					'			button.textContent = \'EDIT\';',
-					'			document.body.appendChild( button );',
-				].join( '\n' );
-
-			}
-
-			content = content.replace( '\t\t\t/* edit button */', editButton );
-
-			toZip[ 'index.html' ] = strToU8( content );
-
-		} );
-		loader.load( 'js/libs/app.js', function ( content ) {
-
-			toZip[ 'js/app.js' ] = strToU8( content );
-
-		} );
-		loader.load( '../build/three.module.js', function ( content ) {
-
-			toZip[ 'js/three.module.js' ] = strToU8( content );
-
-		} );
-		loader.load( '../examples/jsm/webxr/VRButton.js', function ( content ) {
-
-			toZip[ 'js/VRButton.js' ] = strToU8( content );
-
-		} );
-
-	} );
-	options.add( option );
-
-	//
-
-	const link = document.createElement( 'a' );
-	function save( blob, filename ) {
-
-		if ( link.href ) {
-
-			URL.revokeObjectURL( link.href );
-
-		}
-
-		link.href = URL.createObjectURL( blob );
-		link.download = filename || 'data.json';
-		link.dispatchEvent( new MouseEvent( 'click' ) );
-
-	}
-
-	function saveArrayBuffer( buffer, filename ) {
-
-		save( new Blob( [ buffer ], { type: 'application/octet-stream' } ), filename );
-
-	}
-
-	function saveString( text, filename ) {
-
-		save( new Blob( [ text ], { type: 'text/plain' } ), filename );
-
-	}
-
 	function getAnimations( scene ) {
 	function getAnimations( scene ) {
 
 
 		const animations = [];
 		const animations = [];

+ 0 - 39
editor/js/Menubar.Play.js

@@ -1,39 +0,0 @@
-import { UIPanel } from './libs/ui.js';
-
-function MenubarPlay( editor ) {
-
-	const signals = editor.signals;
-	const strings = editor.strings;
-
-	const container = new UIPanel();
-	container.setClass( 'menu' );
-
-	let isPlaying = false;
-
-	const title = new UIPanel();
-	title.setClass( 'title' );
-	title.setTextContent( strings.getKey( 'menubar/play' ) );
-	title.onClick( function () {
-
-		if ( isPlaying === false ) {
-
-			isPlaying = true;
-			title.setTextContent( strings.getKey( 'menubar/play/stop' ) );
-			signals.startPlayer.dispatch();
-
-		} else {
-
-			isPlaying = false;
-			title.setTextContent( strings.getKey( 'menubar/play/play' ) );
-			signals.stopPlayer.dispatch();
-
-		}
-
-	} );
-	container.add( title );
-
-	return container;
-
-}
-
-export { MenubarPlay };

+ 42 - 12
editor/js/Menubar.View.js

@@ -2,6 +2,7 @@ import { UIPanel, UIRow } from './libs/ui.js';
 
 
 function MenubarView( editor ) {
 function MenubarView( editor ) {
 
 
+	const signals = editor.signals;
 	const strings = editor.strings;
 	const strings = editor.strings;
 
 
 	const container = new UIPanel();
 	const container = new UIPanel();
@@ -48,29 +49,58 @@ function MenubarView( editor ) {
 	} );
 	} );
 	options.add( option );
 	options.add( option );
 
 
-	// VR (Work in progress)
+	// XR (Work in progress)
 
 
 	if ( 'xr' in navigator ) {
 	if ( 'xr' in navigator ) {
 
 
-		navigator.xr.isSessionSupported( 'immersive-vr' )
-			.then( function ( supported ) {
+		if ( 'offerSession' in navigator.xr ) {
 
 
-				if ( supported ) {
+			signals.offerXR.dispatch( 'immersive-ar' );
 
 
-					const option = new UIRow();
-					option.setClass( 'option' );
-					option.setTextContent( 'VR' );
-					option.onClick( function () {
+		} else {
 
 
-						editor.signals.toggleVR.dispatch();
+			navigator.xr.isSessionSupported( 'immersive-ar' )
+				.then( function ( supported ) {
 
 
-					} );
-					options.add( option );
+					if ( supported ) {
 
 
-				}
+						const option = new UIRow();
+						option.setClass( 'option' );
+						option.setTextContent( 'AR' );
+						option.onClick( function () {
+
+							signals.enterXR.dispatch( 'immersive-ar' );
+
+						} );
+						options.add( option );
+
+					} else {
+
+						navigator.xr.isSessionSupported( 'immersive-vr' )
+							.then( function ( supported ) {
+
+								if ( supported ) {
+
+									const option = new UIRow();
+									option.setClass( 'option' );
+									option.setTextContent( 'VR' );
+									option.onClick( function () {
+
+										signals.enterXR.dispatch( 'immersive-vr' );
+
+									} );
+									options.add( option );
+
+								}
+
+							} );
+
+					}
 
 
 			} );
 			} );
 
 
+		}
+
 	}
 	}
 
 
 	return container;
 	return container;

+ 0 - 2
editor/js/Menubar.js

@@ -6,7 +6,6 @@ import { MenubarFile } from './Menubar.File.js';
 import { MenubarExamples } from './Menubar.Examples.js';
 import { MenubarExamples } from './Menubar.Examples.js';
 import { MenubarView } from './Menubar.View.js';
 import { MenubarView } from './Menubar.View.js';
 import { MenubarHelp } from './Menubar.Help.js';
 import { MenubarHelp } from './Menubar.Help.js';
-import { MenubarPlay } from './Menubar.Play.js';
 import { MenubarStatus } from './Menubar.Status.js';
 import { MenubarStatus } from './Menubar.Status.js';
 
 
 function Menubar( editor ) {
 function Menubar( editor ) {
@@ -17,7 +16,6 @@ function Menubar( editor ) {
 	container.add( new MenubarFile( editor ) );
 	container.add( new MenubarFile( editor ) );
 	container.add( new MenubarEdit( editor ) );
 	container.add( new MenubarEdit( editor ) );
 	container.add( new MenubarAdd( editor ) );
 	container.add( new MenubarAdd( editor ) );
-	container.add( new MenubarPlay( editor ) );
 	container.add( new MenubarExamples( editor ) );
 	container.add( new MenubarExamples( editor ) );
 	container.add( new MenubarView( editor ) );
 	container.add( new MenubarView( editor ) );
 	container.add( new MenubarHelp( editor ) );
 	container.add( new MenubarHelp( editor ) );

+ 35 - 0
editor/js/Viewport.Selector.js → editor/js/Selector.js

@@ -1,3 +1,8 @@
+import * as THREE from 'three';
+
+const mouse = new THREE.Vector2();
+const raycaster = new THREE.Raycaster();
+
 class Selector {
 class Selector {
 
 
 	constructor( editor ) {
 	constructor( editor ) {
@@ -37,6 +42,36 @@ class Selector {
 
 
 	}
 	}
 
 
+	getIntersects( raycaster ) {
+
+		const objects = [];
+
+		this.editor.scene.traverseVisible( function ( child ) {
+
+			objects.push( child );
+
+		} );
+
+		this.editor.sceneHelpers.traverseVisible( function ( child ) {
+
+			if ( child.name === 'picker' ) objects.push( child );
+
+		} );
+
+		return raycaster.intersectObjects( objects, false );
+
+	}
+
+	getPointerIntersects( point, camera ) {
+
+		mouse.set( ( point.x * 2 ) - 1, - ( point.y * 2 ) + 1 );
+
+		raycaster.setFromCamera( mouse, camera );
+
+		return this.getIntersects( raycaster );
+
+	}
+
 	select( object ) {
 	select( object ) {
 
 
 		if ( this.editor.selected === object ) return;
 		if ( this.editor.selected === object ) return;

+ 9 - 9
editor/js/Sidebar.Geometry.BoxGeometry.js

@@ -16,9 +16,9 @@ function GeometryParametersPanel( editor, object ) {
 	// width
 	// width
 
 
 	const widthRow = new UIRow();
 	const widthRow = new UIRow();
-	const width = new UINumber( parameters.width ).onChange( update );
+	const width = new UINumber().setPrecision( 3 ).setValue( parameters.width ).onChange( update );
 
 
-	widthRow.add( new UIText( strings.getKey( 'sidebar/geometry/box_geometry/width' ) ).setWidth( '90px' ) );
+	widthRow.add( new UIText( strings.getKey( 'sidebar/geometry/box_geometry/width' ) ).setClass( 'Label' ) );
 	widthRow.add( width );
 	widthRow.add( width );
 
 
 	container.add( widthRow );
 	container.add( widthRow );
@@ -26,9 +26,9 @@ function GeometryParametersPanel( editor, object ) {
 	// height
 	// height
 
 
 	const heightRow = new UIRow();
 	const heightRow = new UIRow();
-	const height = new UINumber( parameters.height ).onChange( update );
+	const height = new UINumber().setPrecision( 3 ).setValue( parameters.height ).onChange( update );
 
 
-	heightRow.add( new UIText( strings.getKey( 'sidebar/geometry/box_geometry/height' ) ).setWidth( '90px' ) );
+	heightRow.add( new UIText( strings.getKey( 'sidebar/geometry/box_geometry/height' ) ).setClass( 'Label' ) );
 	heightRow.add( height );
 	heightRow.add( height );
 
 
 	container.add( heightRow );
 	container.add( heightRow );
@@ -36,9 +36,9 @@ function GeometryParametersPanel( editor, object ) {
 	// depth
 	// depth
 
 
 	const depthRow = new UIRow();
 	const depthRow = new UIRow();
-	const depth = new UINumber( parameters.depth ).onChange( update );
+	const depth = new UINumber().setPrecision( 3 ).setValue( parameters.depth ).onChange( update );
 
 
-	depthRow.add( new UIText( strings.getKey( 'sidebar/geometry/box_geometry/depth' ) ).setWidth( '90px' ) );
+	depthRow.add( new UIText( strings.getKey( 'sidebar/geometry/box_geometry/depth' ) ).setClass( 'Label' ) );
 	depthRow.add( depth );
 	depthRow.add( depth );
 
 
 	container.add( depthRow );
 	container.add( depthRow );
@@ -48,7 +48,7 @@ function GeometryParametersPanel( editor, object ) {
 	const widthSegmentsRow = new UIRow();
 	const widthSegmentsRow = new UIRow();
 	const widthSegments = new UIInteger( parameters.widthSegments ).setRange( 1, Infinity ).onChange( update );
 	const widthSegments = new UIInteger( parameters.widthSegments ).setRange( 1, Infinity ).onChange( update );
 
 
-	widthSegmentsRow.add( new UIText( strings.getKey( 'sidebar/geometry/box_geometry/widthseg' ) ).setWidth( '90px' ) );
+	widthSegmentsRow.add( new UIText( strings.getKey( 'sidebar/geometry/box_geometry/widthseg' ) ).setClass( 'Label' ) );
 	widthSegmentsRow.add( widthSegments );
 	widthSegmentsRow.add( widthSegments );
 
 
 	container.add( widthSegmentsRow );
 	container.add( widthSegmentsRow );
@@ -58,7 +58,7 @@ function GeometryParametersPanel( editor, object ) {
 	const heightSegmentsRow = new UIRow();
 	const heightSegmentsRow = new UIRow();
 	const heightSegments = new UIInteger( parameters.heightSegments ).setRange( 1, Infinity ).onChange( update );
 	const heightSegments = new UIInteger( parameters.heightSegments ).setRange( 1, Infinity ).onChange( update );
 
 
-	heightSegmentsRow.add( new UIText( strings.getKey( 'sidebar/geometry/box_geometry/heightseg' ) ).setWidth( '90px' ) );
+	heightSegmentsRow.add( new UIText( strings.getKey( 'sidebar/geometry/box_geometry/heightseg' ) ).setClass( 'Label' ) );
 	heightSegmentsRow.add( heightSegments );
 	heightSegmentsRow.add( heightSegments );
 
 
 	container.add( heightSegmentsRow );
 	container.add( heightSegmentsRow );
@@ -68,7 +68,7 @@ function GeometryParametersPanel( editor, object ) {
 	const depthSegmentsRow = new UIRow();
 	const depthSegmentsRow = new UIRow();
 	const depthSegments = new UIInteger( parameters.depthSegments ).setRange( 1, Infinity ).onChange( update );
 	const depthSegments = new UIInteger( parameters.depthSegments ).setRange( 1, Infinity ).onChange( update );
 
 
-	depthSegmentsRow.add( new UIText( strings.getKey( 'sidebar/geometry/box_geometry/depthseg' ) ).setWidth( '90px' ) );
+	depthSegmentsRow.add( new UIText( strings.getKey( 'sidebar/geometry/box_geometry/depthseg' ) ).setClass( 'Label' ) );
 	depthSegmentsRow.add( depthSegments );
 	depthSegmentsRow.add( depthSegments );
 
 
 	container.add( depthSegmentsRow );
 	container.add( depthSegmentsRow );

+ 3 - 3
editor/js/Sidebar.Geometry.BufferGeometry.js

@@ -24,7 +24,7 @@ function SidebarGeometryBufferGeometry( editor ) {
 
 
 			const attributesRow = new UIRow();
 			const attributesRow = new UIRow();
 
 
-			const textAttributes = new UIText( strings.getKey( 'sidebar/geometry/buffer_geometry/attributes' ) ).setWidth( '90px' );
+			const textAttributes = new UIText( strings.getKey( 'sidebar/geometry/buffer_geometry/attributes' ) ).setClass( 'Label' );
 			attributesRow.add( textAttributes );
 			attributesRow.add( textAttributes );
 
 
 			const containerAttributes = new UISpan().setDisplay( 'inline-block' ).setVerticalAlign( 'middle' ).setWidth( '160px' );
 			const containerAttributes = new UISpan().setDisplay( 'inline-block' ).setVerticalAlign( 'middle' ).setWidth( '160px' );
@@ -65,7 +65,7 @@ function SidebarGeometryBufferGeometry( editor ) {
 
 
 				const rowMorphAttributes = new UIRow();
 				const rowMorphAttributes = new UIRow();
 
 
-				const textMorphAttributes = new UIText( strings.getKey( 'sidebar/geometry/buffer_geometry/morphAttributes' ) ).setWidth( '90px' );
+				const textMorphAttributes = new UIText( strings.getKey( 'sidebar/geometry/buffer_geometry/morphAttributes' ) ).setClass( 'Label' );
 				rowMorphAttributes.add( textMorphAttributes );
 				rowMorphAttributes.add( textMorphAttributes );
 
 
 				const containerMorphAttributes = new UISpan().setDisplay( 'inline-block' ).setVerticalAlign( 'middle' ).setWidth( '160px' );
 				const containerMorphAttributes = new UISpan().setDisplay( 'inline-block' ).setVerticalAlign( 'middle' ).setWidth( '160px' );
@@ -87,7 +87,7 @@ function SidebarGeometryBufferGeometry( editor ) {
 
 
 				const rowMorphRelative = new UIRow();
 				const rowMorphRelative = new UIRow();
 
 
-				const textMorphRelative = new UIText( strings.getKey( 'sidebar/geometry/buffer_geometry/morphRelative' ) ).setWidth( '90px' );
+				const textMorphRelative = new UIText( strings.getKey( 'sidebar/geometry/buffer_geometry/morphRelative' ) ).setClass( 'Label' );
 				rowMorphRelative.add( textMorphRelative );
 				rowMorphRelative.add( textMorphRelative );
 
 
 				const checkboxMorphRelative = new UICheckbox().setValue( geometry.morphTargetsRelative ).setDisabled( true );
 				const checkboxMorphRelative = new UICheckbox().setValue( geometry.morphTargetsRelative ).setDisabled( true );

+ 4 - 4
editor/js/Sidebar.Geometry.CapsuleGeometry.js

@@ -18,7 +18,7 @@ function GeometryParametersPanel( editor, object ) {
 	const radiusRow = new UIRow();
 	const radiusRow = new UIRow();
 	const radius = new UINumber( parameters.radius ).onChange( update );
 	const radius = new UINumber( parameters.radius ).onChange( update );
 
 
-	radiusRow.add( new UIText( strings.getKey( 'sidebar/geometry/capsule_geometry/radius' ) ).setWidth( '90px' ) );
+	radiusRow.add( new UIText( strings.getKey( 'sidebar/geometry/capsule_geometry/radius' ) ).setClass( 'Label' ) );
 	radiusRow.add( radius );
 	radiusRow.add( radius );
 
 
 	container.add( radiusRow );
 	container.add( radiusRow );
@@ -28,7 +28,7 @@ function GeometryParametersPanel( editor, object ) {
 	const lengthRow = new UIRow();
 	const lengthRow = new UIRow();
 	const length = new UINumber( parameters.length ).onChange( update );
 	const length = new UINumber( parameters.length ).onChange( update );
 
 
-	lengthRow.add( new UIText( strings.getKey( 'sidebar/geometry/capsule_geometry/length' ) ).setWidth( '90px' ) );
+	lengthRow.add( new UIText( strings.getKey( 'sidebar/geometry/capsule_geometry/length' ) ).setClass( 'Label' ) );
 	lengthRow.add( length );
 	lengthRow.add( length );
 
 
 	container.add( lengthRow );
 	container.add( lengthRow );
@@ -38,7 +38,7 @@ function GeometryParametersPanel( editor, object ) {
 	const capSegmentsRow = new UIRow();
 	const capSegmentsRow = new UIRow();
 	const capSegments = new UINumber( parameters.capSegments ).onChange( update );
 	const capSegments = new UINumber( parameters.capSegments ).onChange( update );
 
 
-	capSegmentsRow.add( new UIText( strings.getKey( 'sidebar/geometry/capsule_geometry/capseg' ) ).setWidth( '90px' ) );
+	capSegmentsRow.add( new UIText( strings.getKey( 'sidebar/geometry/capsule_geometry/capseg' ) ).setClass( 'Label' ) );
 	capSegmentsRow.add( capSegments );
 	capSegmentsRow.add( capSegments );
 
 
 	container.add( capSegmentsRow );
 	container.add( capSegmentsRow );
@@ -48,7 +48,7 @@ function GeometryParametersPanel( editor, object ) {
 	const radialSegmentsRow = new UIRow();
 	const radialSegmentsRow = new UIRow();
 	const radialSegments = new UIInteger( parameters.radialSegments ).setRange( 1, Infinity ).onChange( update );
 	const radialSegments = new UIInteger( parameters.radialSegments ).setRange( 1, Infinity ).onChange( update );
 
 
-	radialSegmentsRow.add( new UIText( strings.getKey( 'sidebar/geometry/capsule_geometry/radialseg' ) ).setWidth( '90px' ) );
+	radialSegmentsRow.add( new UIText( strings.getKey( 'sidebar/geometry/capsule_geometry/radialseg' ) ).setClass( 'Label' ) );
 	radialSegmentsRow.add( radialSegments );
 	radialSegmentsRow.add( radialSegments );
 
 
 	container.add( radialSegmentsRow );
 	container.add( radialSegmentsRow );

+ 4 - 4
editor/js/Sidebar.Geometry.CircleGeometry.js

@@ -18,7 +18,7 @@ function GeometryParametersPanel( editor, object ) {
 	const radiusRow = new UIRow();
 	const radiusRow = new UIRow();
 	const radius = new UINumber( parameters.radius ).onChange( update );
 	const radius = new UINumber( parameters.radius ).onChange( update );
 
 
-	radiusRow.add( new UIText( strings.getKey( 'sidebar/geometry/circle_geometry/radius' ) ).setWidth( '90px' ) );
+	radiusRow.add( new UIText( strings.getKey( 'sidebar/geometry/circle_geometry/radius' ) ).setClass( 'Label' ) );
 	radiusRow.add( radius );
 	radiusRow.add( radius );
 
 
 	container.add( radiusRow );
 	container.add( radiusRow );
@@ -28,7 +28,7 @@ function GeometryParametersPanel( editor, object ) {
 	const segmentsRow = new UIRow();
 	const segmentsRow = new UIRow();
 	const segments = new UIInteger( parameters.segments ).setRange( 3, Infinity ).onChange( update );
 	const segments = new UIInteger( parameters.segments ).setRange( 3, Infinity ).onChange( update );
 
 
-	segmentsRow.add( new UIText( strings.getKey( 'sidebar/geometry/circle_geometry/segments' ) ).setWidth( '90px' ) );
+	segmentsRow.add( new UIText( strings.getKey( 'sidebar/geometry/circle_geometry/segments' ) ).setClass( 'Label' ) );
 	segmentsRow.add( segments );
 	segmentsRow.add( segments );
 
 
 	container.add( segmentsRow );
 	container.add( segmentsRow );
@@ -38,7 +38,7 @@ function GeometryParametersPanel( editor, object ) {
 	const thetaStartRow = new UIRow();
 	const thetaStartRow = new UIRow();
 	const thetaStart = new UINumber( parameters.thetaStart * THREE.MathUtils.RAD2DEG ).setStep( 10 ).onChange( update );
 	const thetaStart = new UINumber( parameters.thetaStart * THREE.MathUtils.RAD2DEG ).setStep( 10 ).onChange( update );
 
 
-	thetaStartRow.add( new UIText( strings.getKey( 'sidebar/geometry/circle_geometry/thetastart' ) ).setWidth( '90px' ) );
+	thetaStartRow.add( new UIText( strings.getKey( 'sidebar/geometry/circle_geometry/thetastart' ) ).setClass( 'Label' ) );
 	thetaStartRow.add( thetaStart );
 	thetaStartRow.add( thetaStart );
 
 
 	container.add( thetaStartRow );
 	container.add( thetaStartRow );
@@ -48,7 +48,7 @@ function GeometryParametersPanel( editor, object ) {
 	const thetaLengthRow = new UIRow();
 	const thetaLengthRow = new UIRow();
 	const thetaLength = new UINumber( parameters.thetaLength * THREE.MathUtils.RAD2DEG ).setStep( 10 ).onChange( update );
 	const thetaLength = new UINumber( parameters.thetaLength * THREE.MathUtils.RAD2DEG ).setStep( 10 ).onChange( update );
 
 
-	thetaLengthRow.add( new UIText( strings.getKey( 'sidebar/geometry/circle_geometry/thetalength' ) ).setWidth( '90px' ) );
+	thetaLengthRow.add( new UIText( strings.getKey( 'sidebar/geometry/circle_geometry/thetalength' ) ).setClass( 'Label' ) );
 	thetaLengthRow.add( thetaLength );
 	thetaLengthRow.add( thetaLength );
 
 
 	container.add( thetaLengthRow );
 	container.add( thetaLengthRow );

+ 6 - 6
editor/js/Sidebar.Geometry.CylinderGeometry.js

@@ -18,7 +18,7 @@ function GeometryParametersPanel( editor, object ) {
 	const radiusTopRow = new UIRow();
 	const radiusTopRow = new UIRow();
 	const radiusTop = new UINumber( parameters.radiusTop ).onChange( update );
 	const radiusTop = new UINumber( parameters.radiusTop ).onChange( update );
 
 
-	radiusTopRow.add( new UIText( strings.getKey( 'sidebar/geometry/cylinder_geometry/radiustop' ) ).setWidth( '90px' ) );
+	radiusTopRow.add( new UIText( strings.getKey( 'sidebar/geometry/cylinder_geometry/radiustop' ) ).setClass( 'Label' ) );
 	radiusTopRow.add( radiusTop );
 	radiusTopRow.add( radiusTop );
 
 
 	container.add( radiusTopRow );
 	container.add( radiusTopRow );
@@ -28,7 +28,7 @@ function GeometryParametersPanel( editor, object ) {
 	const radiusBottomRow = new UIRow();
 	const radiusBottomRow = new UIRow();
 	const radiusBottom = new UINumber( parameters.radiusBottom ).onChange( update );
 	const radiusBottom = new UINumber( parameters.radiusBottom ).onChange( update );
 
 
-	radiusBottomRow.add( new UIText( strings.getKey( 'sidebar/geometry/cylinder_geometry/radiusbottom' ) ).setWidth( '90px' ) );
+	radiusBottomRow.add( new UIText( strings.getKey( 'sidebar/geometry/cylinder_geometry/radiusbottom' ) ).setClass( 'Label' ) );
 	radiusBottomRow.add( radiusBottom );
 	radiusBottomRow.add( radiusBottom );
 
 
 	container.add( radiusBottomRow );
 	container.add( radiusBottomRow );
@@ -38,7 +38,7 @@ function GeometryParametersPanel( editor, object ) {
 	const heightRow = new UIRow();
 	const heightRow = new UIRow();
 	const height = new UINumber( parameters.height ).onChange( update );
 	const height = new UINumber( parameters.height ).onChange( update );
 
 
-	heightRow.add( new UIText( strings.getKey( 'sidebar/geometry/cylinder_geometry/height' ) ).setWidth( '90px' ) );
+	heightRow.add( new UIText( strings.getKey( 'sidebar/geometry/cylinder_geometry/height' ) ).setClass( 'Label' ) );
 	heightRow.add( height );
 	heightRow.add( height );
 
 
 	container.add( heightRow );
 	container.add( heightRow );
@@ -48,7 +48,7 @@ function GeometryParametersPanel( editor, object ) {
 	const radialSegmentsRow = new UIRow();
 	const radialSegmentsRow = new UIRow();
 	const radialSegments = new UIInteger( parameters.radialSegments ).setRange( 1, Infinity ).onChange( update );
 	const radialSegments = new UIInteger( parameters.radialSegments ).setRange( 1, Infinity ).onChange( update );
 
 
-	radialSegmentsRow.add( new UIText( strings.getKey( 'sidebar/geometry/cylinder_geometry/radialsegments' ) ).setWidth( '90px' ) );
+	radialSegmentsRow.add( new UIText( strings.getKey( 'sidebar/geometry/cylinder_geometry/radialsegments' ) ).setClass( 'Label' ) );
 	radialSegmentsRow.add( radialSegments );
 	radialSegmentsRow.add( radialSegments );
 
 
 	container.add( radialSegmentsRow );
 	container.add( radialSegmentsRow );
@@ -58,7 +58,7 @@ function GeometryParametersPanel( editor, object ) {
 	const heightSegmentsRow = new UIRow();
 	const heightSegmentsRow = new UIRow();
 	const heightSegments = new UIInteger( parameters.heightSegments ).setRange( 1, Infinity ).onChange( update );
 	const heightSegments = new UIInteger( parameters.heightSegments ).setRange( 1, Infinity ).onChange( update );
 
 
-	heightSegmentsRow.add( new UIText( strings.getKey( 'sidebar/geometry/cylinder_geometry/heightsegments' ) ).setWidth( '90px' ) );
+	heightSegmentsRow.add( new UIText( strings.getKey( 'sidebar/geometry/cylinder_geometry/heightsegments' ) ).setClass( 'Label' ) );
 	heightSegmentsRow.add( heightSegments );
 	heightSegmentsRow.add( heightSegments );
 
 
 	container.add( heightSegmentsRow );
 	container.add( heightSegmentsRow );
@@ -68,7 +68,7 @@ function GeometryParametersPanel( editor, object ) {
 	const openEndedRow = new UIRow();
 	const openEndedRow = new UIRow();
 	const openEnded = new UICheckbox( parameters.openEnded ).onChange( update );
 	const openEnded = new UICheckbox( parameters.openEnded ).onChange( update );
 
 
-	openEndedRow.add( new UIText( strings.getKey( 'sidebar/geometry/cylinder_geometry/openended' ) ).setWidth( '90px' ) );
+	openEndedRow.add( new UIText( strings.getKey( 'sidebar/geometry/cylinder_geometry/openended' ) ).setClass( 'Label' ) );
 	openEndedRow.add( openEnded );
 	openEndedRow.add( openEnded );
 
 
 	container.add( openEndedRow );
 	container.add( openEndedRow );

+ 2 - 2
editor/js/Sidebar.Geometry.DodecahedronGeometry.js

@@ -18,7 +18,7 @@ function GeometryParametersPanel( editor, object ) {
 	const radiusRow = new UIRow();
 	const radiusRow = new UIRow();
 	const radius = new UINumber( parameters.radius ).onChange( update );
 	const radius = new UINumber( parameters.radius ).onChange( update );
 
 
-	radiusRow.add( new UIText( strings.getKey( 'sidebar/geometry/dodecahedron_geometry/radius' ) ).setWidth( '90px' ) );
+	radiusRow.add( new UIText( strings.getKey( 'sidebar/geometry/dodecahedron_geometry/radius' ) ).setClass( 'Label' ) );
 	radiusRow.add( radius );
 	radiusRow.add( radius );
 
 
 	container.add( radiusRow );
 	container.add( radiusRow );
@@ -28,7 +28,7 @@ function GeometryParametersPanel( editor, object ) {
 	const detailRow = new UIRow();
 	const detailRow = new UIRow();
 	const detail = new UIInteger( parameters.detail ).setRange( 0, Infinity ).onChange( update );
 	const detail = new UIInteger( parameters.detail ).setRange( 0, Infinity ).onChange( update );
 
 
-	detailRow.add( new UIText( strings.getKey( 'sidebar/geometry/dodecahedron_geometry/detail' ) ).setWidth( '90px' ) );
+	detailRow.add( new UIText( strings.getKey( 'sidebar/geometry/dodecahedron_geometry/detail' ) ).setClass( 'Label' ) );
 	detailRow.add( detail );
 	detailRow.add( detail );
 
 
 	container.add( detailRow );
 	container.add( detailRow );

+ 9 - 9
editor/js/Sidebar.Geometry.ExtrudeGeometry.js

@@ -27,7 +27,7 @@ function GeometryParametersPanel( editor, object ) {
 	const curveSegmentsRow = new UIRow();
 	const curveSegmentsRow = new UIRow();
 	const curveSegments = new UIInteger( options.curveSegments ).onChange( update ).setRange( 1, Infinity );
 	const curveSegments = new UIInteger( options.curveSegments ).onChange( update ).setRange( 1, Infinity );
 
 
-	curveSegmentsRow.add( new UIText( strings.getKey( 'sidebar/geometry/extrude_geometry/curveSegments' ) ).setWidth( '90px' ) );
+	curveSegmentsRow.add( new UIText( strings.getKey( 'sidebar/geometry/extrude_geometry/curveSegments' ) ).setClass( 'Label' ) );
 	curveSegmentsRow.add( curveSegments );
 	curveSegmentsRow.add( curveSegments );
 
 
 	container.add( curveSegmentsRow );
 	container.add( curveSegmentsRow );
@@ -37,7 +37,7 @@ function GeometryParametersPanel( editor, object ) {
 	const stepsRow = new UIRow();
 	const stepsRow = new UIRow();
 	const steps = new UIInteger( options.steps ).onChange( update ).setRange( 1, Infinity );
 	const steps = new UIInteger( options.steps ).onChange( update ).setRange( 1, Infinity );
 
 
-	stepsRow.add( new UIText( strings.getKey( 'sidebar/geometry/extrude_geometry/steps' ) ).setWidth( '90px' ) );
+	stepsRow.add( new UIText( strings.getKey( 'sidebar/geometry/extrude_geometry/steps' ) ).setClass( 'Label' ) );
 	stepsRow.add( steps );
 	stepsRow.add( steps );
 
 
 	container.add( stepsRow );
 	container.add( stepsRow );
@@ -47,7 +47,7 @@ function GeometryParametersPanel( editor, object ) {
 	const depthRow = new UIRow();
 	const depthRow = new UIRow();
 	const depth = new UINumber( options.depth ).onChange( update ).setRange( 1, Infinity );
 	const depth = new UINumber( options.depth ).onChange( update ).setRange( 1, Infinity );
 
 
-	depthRow.add( new UIText( strings.getKey( 'sidebar/geometry/extrude_geometry/depth' ) ).setWidth( '90px' ) );
+	depthRow.add( new UIText( strings.getKey( 'sidebar/geometry/extrude_geometry/depth' ) ).setClass( 'Label' ) );
 	depthRow.add( depth );
 	depthRow.add( depth );
 
 
 	container.add( depthRow );
 	container.add( depthRow );
@@ -57,7 +57,7 @@ function GeometryParametersPanel( editor, object ) {
 	const enabledRow = new UIRow();
 	const enabledRow = new UIRow();
 	const enabled = new UICheckbox( options.bevelEnabled ).onChange( update );
 	const enabled = new UICheckbox( options.bevelEnabled ).onChange( update );
 
 
-	enabledRow.add( new UIText( strings.getKey( 'sidebar/geometry/extrude_geometry/bevelEnabled' ) ).setWidth( '90px' ) );
+	enabledRow.add( new UIText( strings.getKey( 'sidebar/geometry/extrude_geometry/bevelEnabled' ) ).setClass( 'Label' ) );
 	enabledRow.add( enabled );
 	enabledRow.add( enabled );
 
 
 	container.add( enabledRow );
 	container.add( enabledRow );
@@ -71,7 +71,7 @@ function GeometryParametersPanel( editor, object ) {
 		const thicknessRow = new UIRow();
 		const thicknessRow = new UIRow();
 		thickness = new UINumber( options.bevelThickness ).onChange( update );
 		thickness = new UINumber( options.bevelThickness ).onChange( update );
 
 
-		thicknessRow.add( new UIText( strings.getKey( 'sidebar/geometry/extrude_geometry/bevelThickness' ) ).setWidth( '90px' ) );
+		thicknessRow.add( new UIText( strings.getKey( 'sidebar/geometry/extrude_geometry/bevelThickness' ) ).setClass( 'Label' ) );
 		thicknessRow.add( thickness );
 		thicknessRow.add( thickness );
 
 
 		container.add( thicknessRow );
 		container.add( thicknessRow );
@@ -81,7 +81,7 @@ function GeometryParametersPanel( editor, object ) {
 		const sizeRow = new UIRow();
 		const sizeRow = new UIRow();
 		size = new UINumber( options.bevelSize ).onChange( update );
 		size = new UINumber( options.bevelSize ).onChange( update );
 
 
-		sizeRow.add( new UIText( strings.getKey( 'sidebar/geometry/extrude_geometry/bevelSize' ) ).setWidth( '90px' ) );
+		sizeRow.add( new UIText( strings.getKey( 'sidebar/geometry/extrude_geometry/bevelSize' ) ).setClass( 'Label' ) );
 		sizeRow.add( size );
 		sizeRow.add( size );
 
 
 		container.add( sizeRow );
 		container.add( sizeRow );
@@ -91,7 +91,7 @@ function GeometryParametersPanel( editor, object ) {
 		const offsetRow = new UIRow();
 		const offsetRow = new UIRow();
 		offset = new UINumber( options.bevelOffset ).onChange( update );
 		offset = new UINumber( options.bevelOffset ).onChange( update );
 
 
-		offsetRow.add( new UIText( strings.getKey( 'sidebar/geometry/extrude_geometry/bevelOffset' ) ).setWidth( '90px' ) );
+		offsetRow.add( new UIText( strings.getKey( 'sidebar/geometry/extrude_geometry/bevelOffset' ) ).setClass( 'Label' ) );
 		offsetRow.add( offset );
 		offsetRow.add( offset );
 
 
 		container.add( offsetRow );
 		container.add( offsetRow );
@@ -101,14 +101,14 @@ function GeometryParametersPanel( editor, object ) {
 		const segmentsRow = new UIRow();
 		const segmentsRow = new UIRow();
 		segments = new UIInteger( options.bevelSegments ).onChange( update ).setRange( 0, Infinity );
 		segments = new UIInteger( options.bevelSegments ).onChange( update ).setRange( 0, Infinity );
 
 
-		segmentsRow.add( new UIText( strings.getKey( 'sidebar/geometry/extrude_geometry/bevelSegments' ) ).setWidth( '90px' ) );
+		segmentsRow.add( new UIText( strings.getKey( 'sidebar/geometry/extrude_geometry/bevelSegments' ) ).setClass( 'Label' ) );
 		segmentsRow.add( segments );
 		segmentsRow.add( segments );
 
 
 		container.add( segmentsRow );
 		container.add( segmentsRow );
 
 
 	}
 	}
 
 
-	const button = new UIButton( strings.getKey( 'sidebar/geometry/extrude_geometry/shape' ) ).onClick( toShape ).setWidth( '90px' ).setMarginLeft( '90px' );
+	const button = new UIButton( strings.getKey( 'sidebar/geometry/extrude_geometry/shape' ) ).onClick( toShape ).setClass( 'Label' ).setMarginLeft( '120px' );
 	container.add( button );
 	container.add( button );
 
 
 	//
 	//

+ 2 - 2
editor/js/Sidebar.Geometry.IcosahedronGeometry.js

@@ -20,7 +20,7 @@ function GeometryParametersPanel( editor, object ) {
 	const radiusRow = new UIRow();
 	const radiusRow = new UIRow();
 	const radius = new UINumber( parameters.radius ).onChange( update );
 	const radius = new UINumber( parameters.radius ).onChange( update );
 
 
-	radiusRow.add( new UIText( strings.getKey( 'sidebar/geometry/icosahedron_geometry/radius' ) ).setWidth( '90px' ) );
+	radiusRow.add( new UIText( strings.getKey( 'sidebar/geometry/icosahedron_geometry/radius' ) ).setClass( 'Label' ) );
 	radiusRow.add( radius );
 	radiusRow.add( radius );
 
 
 	container.add( radiusRow );
 	container.add( radiusRow );
@@ -30,7 +30,7 @@ function GeometryParametersPanel( editor, object ) {
 	const detailRow = new UIRow();
 	const detailRow = new UIRow();
 	const detail = new UIInteger( parameters.detail ).setRange( 0, Infinity ).onChange( update );
 	const detail = new UIInteger( parameters.detail ).setRange( 0, Infinity ).onChange( update );
 
 
-	detailRow.add( new UIText( strings.getKey( 'sidebar/geometry/icosahedron_geometry/detail' ) ).setWidth( '90px' ) );
+	detailRow.add( new UIText( strings.getKey( 'sidebar/geometry/icosahedron_geometry/detail' ) ).setClass( 'Label' ) );
 	detailRow.add( detail );
 	detailRow.add( detail );
 
 
 	container.add( detailRow );
 	container.add( detailRow );

+ 4 - 4
editor/js/Sidebar.Geometry.LatheGeometry.js

@@ -19,7 +19,7 @@ function GeometryParametersPanel( editor, object ) {
 	const segmentsRow = new UIRow();
 	const segmentsRow = new UIRow();
 	const segments = new UIInteger( parameters.segments ).onChange( update );
 	const segments = new UIInteger( parameters.segments ).onChange( update );
 
 
-	segmentsRow.add( new UIText( strings.getKey( 'sidebar/geometry/lathe_geometry/segments' ) ).setWidth( '90px' ) );
+	segmentsRow.add( new UIText( strings.getKey( 'sidebar/geometry/lathe_geometry/segments' ) ).setClass( 'Label' ) );
 	segmentsRow.add( segments );
 	segmentsRow.add( segments );
 
 
 	container.add( segmentsRow );
 	container.add( segmentsRow );
@@ -29,7 +29,7 @@ function GeometryParametersPanel( editor, object ) {
 	const phiStartRow = new UIRow();
 	const phiStartRow = new UIRow();
 	const phiStart = new UINumber( parameters.phiStart * 180 / Math.PI ).onChange( update );
 	const phiStart = new UINumber( parameters.phiStart * 180 / Math.PI ).onChange( update );
 
 
-	phiStartRow.add( new UIText( strings.getKey( 'sidebar/geometry/lathe_geometry/phistart' ) ).setWidth( '90px' ) );
+	phiStartRow.add( new UIText( strings.getKey( 'sidebar/geometry/lathe_geometry/phistart' ) ).setClass( 'Label' ) );
 	phiStartRow.add( phiStart );
 	phiStartRow.add( phiStart );
 
 
 	container.add( phiStartRow );
 	container.add( phiStartRow );
@@ -39,7 +39,7 @@ function GeometryParametersPanel( editor, object ) {
 	const phiLengthRow = new UIRow();
 	const phiLengthRow = new UIRow();
 	const phiLength = new UINumber( parameters.phiLength * 180 / Math.PI ).onChange( update );
 	const phiLength = new UINumber( parameters.phiLength * 180 / Math.PI ).onChange( update );
 
 
-	phiLengthRow.add( new UIText( strings.getKey( 'sidebar/geometry/lathe_geometry/philength' ) ).setWidth( '90px' ) );
+	phiLengthRow.add( new UIText( strings.getKey( 'sidebar/geometry/lathe_geometry/philength' ) ).setClass( 'Label' ) );
 	phiLengthRow.add( phiLength );
 	phiLengthRow.add( phiLength );
 
 
 	container.add( phiLengthRow );
 	container.add( phiLengthRow );
@@ -47,7 +47,7 @@ function GeometryParametersPanel( editor, object ) {
 	// points
 	// points
 
 
 	const pointsRow = new UIRow();
 	const pointsRow = new UIRow();
-	pointsRow.add( new UIText( strings.getKey( 'sidebar/geometry/lathe_geometry/points' ) ).setWidth( '90px' ) );
+	pointsRow.add( new UIText( strings.getKey( 'sidebar/geometry/lathe_geometry/points' ) ).setClass( 'Label' ) );
 
 
 	const points = new UIPoints2().setValue( parameters.points ).onChange( update );
 	const points = new UIPoints2().setValue( parameters.points ).onChange( update );
 	pointsRow.add( points );
 	pointsRow.add( points );

Some files were not shown because too many files changed in this diff