Mr.doob 1 year ago
parent
commit
73c996c9e1
100 changed files with 3750 additions and 2699 deletions
  1. 220 115
      build/three.cjs
  2. 220 115
      build/three.js
  3. 0 0
      build/three.min.js
  4. 220 115
      build/three.module.js
  5. 0 0
      build/three.module.min.js
  6. 36 3
      docs/api/ar/core/Object3D.html
  7. 2 0
      docs/api/ar/helpers/DirectionalLightHelper.html
  8. 2 1
      docs/api/ar/materials/LineDashedMaterial.html
  9. 1 1
      docs/api/ar/materials/MeshPhysicalMaterial.html
  10. 63 59
      docs/api/ar/math/Matrix3.html
  11. 39 35
      docs/api/ar/math/Matrix4.html
  12. 1 4
      docs/api/ar/objects/Skeleton.html
  13. 3 3
      docs/api/ar/renderers/WebGL3DRenderTarget.html
  14. 3 3
      docs/api/ar/renderers/WebGLArrayRenderTarget.html
  15. 2 2
      docs/api/ar/renderers/WebGLCubeRenderTarget.html
  16. 18 6
      docs/api/en/core/BufferAttribute.html
  17. 21 4
      docs/api/en/core/InterleavedBuffer.html
  18. 35 2
      docs/api/en/core/Object3D.html
  19. 2 0
      docs/api/en/helpers/DirectionalLightHelper.html
  20. 2 1
      docs/api/en/materials/LineDashedMaterial.html
  21. 1 1
      docs/api/en/materials/MeshPhysicalMaterial.html
  22. 170 166
      docs/api/en/math/Matrix3.html
  23. 466 462
      docs/api/en/math/Matrix4.html
  24. 229 0
      docs/api/en/objects/BatchedMesh.html
  25. 0 3
      docs/api/en/objects/Skeleton.html
  26. 8 8
      docs/api/en/renderers/WebGL3DRenderTarget.html
  27. 8 9
      docs/api/en/renderers/WebGLArrayRenderTarget.html
  28. 2 2
      docs/api/en/renderers/WebGLCubeRenderTarget.html
  29. 4 1
      docs/api/fr/materials/LineDashedMaterial.html
  30. 1 1
      docs/api/fr/materials/MeshPhysicalMaterial.html
  31. 27 2
      docs/api/it/core/Object3D.html
  32. 2 0
      docs/api/it/helpers/DirectionalLightHelper.html
  33. 4 1
      docs/api/it/materials/LineDashedMaterial.html
  34. 1 1
      docs/api/it/materials/MeshPhysicalMaterial.html
  35. 67 63
      docs/api/it/math/Matrix3.html
  36. 369 365
      docs/api/it/math/Matrix4.html
  37. 0 5
      docs/api/it/objects/Skeleton.html
  38. 6 4
      docs/api/it/renderers/WebGL3DRenderTarget.html
  39. 6 4
      docs/api/it/renderers/WebGLArrayRenderTarget.html
  40. 2 2
      docs/api/it/renderers/WebGLCubeRenderTarget.html
  41. 27 2
      docs/api/ko/core/Object3D.html
  42. 27 2
      docs/api/zh/core/Object3D.html
  43. 2 0
      docs/api/zh/helpers/DirectionalLightHelper.html
  44. 4 1
      docs/api/zh/materials/LineDashedMaterial.html
  45. 43 39
      docs/api/zh/math/Matrix3.html
  46. 191 189
      docs/api/zh/math/Matrix4.html
  47. 0 5
      docs/api/zh/objects/Skeleton.html
  48. 6 5
      docs/api/zh/renderers/WebGL3DRenderTarget.html
  49. 4 2
      docs/api/zh/renderers/WebGLArrayRenderTarget.html
  50. 2 2
      docs/api/zh/renderers/WebGLCubeRenderTarget.html
  51. 4 14
      docs/examples/en/loaders/GLTFLoader.html
  52. 1 0
      docs/examples/en/postprocessing/EffectComposer.html
  53. 1 0
      docs/examples/zh/postprocessing/EffectComposer.html
  54. 2 0
      docs/list.json
  55. 74 186
      docs/manual/ar/introduction/Creating-a-scene.html
  56. 49 36
      docs/manual/ar/introduction/How-to-update-things.html
  57. 111 0
      docs/manual/ar/introduction/Libraries-and-Plugins.html
  58. 1 0
      docs/manual/en/introduction/Libraries-and-Plugins.html
  59. 1 0
      docs/manual/fr/introduction/Libraries-and-Plugins.html
  60. 1 0
      docs/manual/it/introduction/Libraries-and-Plugins.html
  61. 1 0
      docs/manual/ja/introduction/Libraries-and-Plugins.html
  62. 1 1
      docs/manual/pt-br/introduction/Creating-a-scene.html
  63. 1 0
      docs/manual/pt-br/introduction/Libraries-and-Plugins.html
  64. 1 0
      docs/manual/ru/introduction/Libraries-and-Plugins.html
  65. 1 0
      docs/manual/zh/introduction/Libraries-and-Plugins.html
  66. 2 1
      docs/page.css
  67. 1 0
      editor/js/Editor.js
  68. 36 63
      editor/js/Loader.js
  69. 1 1
      editor/js/Sidebar.Material.MapProperty.js
  70. 3 3
      editor/js/Sidebar.Scene.js
  71. 0 48
      editor/js/Sidebar.Settings.Viewport.js
  72. 0 2
      editor/js/Sidebar.Settings.js
  73. 1 1
      editor/js/Storage.js
  74. 9 12
      editor/js/Strings.js
  75. 0 48
      editor/js/Viewport.Camera.js
  76. 88 0
      editor/js/Viewport.Controls.js
  77. 5 8
      editor/js/Viewport.Info.js
  78. 0 21
      editor/js/Viewport.Shading.js
  79. 16 12
      editor/js/Viewport.js
  80. 11 1
      editor/js/libs/ui.js
  81. 5 146
      editor/js/libs/ui.three.js
  82. 1 3
      editor/sw.js
  83. 5 0
      examples/files.json
  84. 2 1
      examples/jsm/Addons.js
  85. 0 2
      examples/jsm/controls/OrbitControls.js
  86. 79 1
      examples/jsm/exporters/GLTFExporter.js
  87. 4 11
      examples/jsm/exporters/USDZExporter.js
  88. 237 0
      examples/jsm/helpers/TextureHelper.js
  89. 9 2
      examples/jsm/interactive/HTMLMesh.js
  90. 0 6
      examples/jsm/loaders/ColladaLoader.js
  91. 294 124
      examples/jsm/loaders/FBXLoader.js
  92. 69 1
      examples/jsm/loaders/GLTFLoader.js
  93. 0 13
      examples/jsm/loaders/NRRDLoader.js
  94. 4 4
      examples/jsm/loaders/SVGLoader.js
  95. 3 17
      examples/jsm/loaders/USDZLoader.js
  96. 15 4
      examples/jsm/math/Octree.js
  97. 3 6
      examples/jsm/misc/TubePainter.js
  98. 7 6
      examples/jsm/nodes/Nodes.js
  99. 18 2
      examples/jsm/nodes/accessors/CameraNode.js
  100. 3 76
      examples/jsm/nodes/accessors/CubeTextureNode.js

File diff suppressed because it is too large
+ 220 - 115
build/three.cjs


File diff suppressed because it is too large
+ 220 - 115
build/three.js


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


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


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


+ 36 - 3
docs/api/ar/core/Object3D.html

@@ -143,6 +143,21 @@
 			أو [page:Bone] ليست قابلة للتقديم وبالتالي لا يتم تنفيذ هذا الرد الاتصال
 			أو [page:Bone] ليست قابلة للتقديم وبالتالي لا يتم تنفيذ هذا الرد الاتصال
 			لمثل هذه الكائنات.
 			لمثل هذه الكائنات.
 		</p>
 		</p>
+
+		<h3>[property:Function onAfterShadow]</h3>
+		<p>
+			An optional callback that is executed immediately after a 3D object is
+			rendered to a shadow map. This function is called with the following parameters: renderer,
+			scene, camera, shadowCamera, geometry, depthMaterial, group.
+		</p>
+		<p>
+			يرجى ملاحظة أن هذا الرد الاتصال يتم تنفيذه فقط لـ `renderable` 3D
+			كائنات. معنى كائنات ثلاثية الأبعاد التي تحدد مظهرها المرئي مع
+			الهندسة والمواد مثل نسخ [page:Mesh]، [page:Line]،
+			[page:Points] أو [page:Sprite]. نسخ من [page:Object3D]، [page:Group]
+			أو [page:Bone] ليست قابلة للتقديم وبالتالي لا يتم تنفيذ هذا الرد الاتصال
+			لمثل هذه الكائنات.
+		</p>
 			 
 			 
 		<h3>[property:Function onBeforeRender]</h3>
 		<h3>[property:Function onBeforeRender]</h3>
 		<p>
 		<p>
@@ -158,6 +173,21 @@
 			أو [page:Bone] ليست قابلة للتقديم وبالتالي لا يتم تنفيذ هذا الرد الاتصال
 			أو [page:Bone] ليست قابلة للتقديم وبالتالي لا يتم تنفيذ هذا الرد الاتصال
 			لمثل هذه الكائنات.
 			لمثل هذه الكائنات.
 		</p>
 		</p>
+
+		<h3>[property:Function onBeforeShadow]</h3>
+		<p>
+			An optional callback that is executed immediately before a 3D object is
+			rendered to a shadow map. This function is called with the following parameters: renderer,
+			scene, camera, shadowCamera, geometry, depthMaterial, group.
+		</p>
+		<p>
+			يرجى ملاحظة أن هذا الرد الاتصال يتم تنفيذه فقط لـ `renderable` 3D
+			كائنات. معنى كائنات ثلاثية الأبعاد التي تحدد مظهرها المرئي مع
+			الهندسة والمواد مثل نسخ [page:Mesh]، [page:Line]،
+			[page:Points] أو [page:Sprite]. نسخ من [page:Object3D]، [page:Group]
+			أو [page:Bone] ليست قابلة للتقديم وبالتالي لا يتم تنفيذ هذا الرد الاتصال
+			لمثل هذه الكائنات.
+		</p>
 			 
 			 
 		<h3>[property:Object3D parent]</h3>
 		<h3>[property:Object3D parent]</h3>
 		<p>
 		<p>
@@ -322,11 +352,14 @@
 			معطى.
 			معطى.
 		</p>
 		</p>
 			 
 			 
-		<h3>[method:Object3D getObjectsByProperty]( [param:String name], [param:Any value] )</h3>
+		<h3>[method:Object3D getObjectsByProperty]( [param:String name], [param:Any value], [param:Array optionalTarget] )</h3>
 		<p>
 		<p>
 			name -- اسم الخاصية التي يتم البحث عنها. <br />
 			name -- اسم الخاصية التي يتم البحث عنها. <br />
-			value -- قيمة الخاصية المعطاة. <br /><br />
-			 
+			value -- قيمة الخاصية المعطاة. <br />
+			optionalTarget -- (optional) target to set the result.
+			Otherwise a new Array is instantiated. If set, you must clear this
+			array prior to each call (i.e., array.length = 0;). <br /><br />
+
 			يبحث في كائن وأطفاله، بدءًا من الكائن
 			يبحث في كائن وأطفاله، بدءًا من الكائن
 			نفسه، ويرجع جميع الكائنات مع خاصية تطابق القيمة
 			نفسه، ويرجع جميع الكائنات مع خاصية تطابق القيمة
 			معطى.
 			معطى.

+ 2 - 0
docs/api/ar/helpers/DirectionalLightHelper.html

@@ -20,6 +20,8 @@
 
 
 		<code>
 		<code>
 		const light = new THREE.DirectionalLight( 0xFFFFFF );
 		const light = new THREE.DirectionalLight( 0xFFFFFF );
+		scene.add( light );
+
 		const helper = new THREE.DirectionalLightHelper( light, 5 );
 		const helper = new THREE.DirectionalLightHelper( light, 5 );
 		scene.add( helper );
 		scene.add( helper );
 		</code>
 		</code>

+ 2 - 1
docs/api/ar/materials/LineDashedMaterial.html

@@ -12,7 +12,8 @@
 		<h1>[name]</h1>
 		<h1>[name]</h1>
 
 
 		<p class="desc">
 		<p class="desc">
-			مادة لرسم الهندسة على طريقة الإطار السلكي بخطوط متقطعة.
+			مادة لرسم الهندسة على طريقة الإطار السلكي بخطوط متقطعة.<br />
+			Note: You must call [page:Line.computeLineDistances]() when using [name].
 		</p>
 		</p>
 		 
 		 
 		<h2>مثال الكود</h2>
 		<h2>مثال الكود</h2>

+ 1 - 1
docs/api/ar/materials/MeshPhysicalMaterial.html

@@ -242,7 +242,7 @@
 		المواد البلاستيكية أو الزجاجية رقيقة أو شفافة أو نصف شفافة تظل
 		المواد البلاستيكية أو الزجاجية رقيقة أو شفافة أو نصف شفافة تظل
 		عاكسة إلى حد كبير حتى لو كانت مُرسِلَة بالكامل. يمكن استخدام خاصية الإرسال لنمذجة هذه المواد.<br />
 		عاكسة إلى حد كبير حتى لو كانت مُرسِلَة بالكامل. يمكن استخدام خاصية الإرسال لنمذجة هذه المواد.<br />
 		
 		
-		عندما يكون الإرسال غير صفر، يجب تعيين [page:Material.opacity opacity] إلى `0`.
+		عندما يكون الإرسال غير صفر، يجب تعيين [page:Material.opacity opacity] `إلى `1.
 		</p>
 		</p>
 		
 		
 		<h3>[property:Texture transmissionMap]</h3>
 		<h3>[property:Texture transmissionMap]</h3>

+ 63 - 59
docs/api/ar/math/Matrix3.html

@@ -86,9 +86,10 @@ m.elements = [ 11, 21, 31,
 		<p>
 		<p>
 		يستخرج [link:https://en.wikipedia.org/wiki/Basis_(linear_algebra) الأساس]
 		يستخرج [link:https://en.wikipedia.org/wiki/Basis_(linear_algebra) الأساس]
 		لهذه المصفوفة في ثلاثة متجهات محورية مقدمة. إذا كانت هذه المصفوفة
 		لهذه المصفوفة في ثلاثة متجهات محورية مقدمة. إذا كانت هذه المصفوفة
-		هي:<br /><br />
+		هي:
+		</p>
 
 
-		<math>
+		<math display="block">
 			<mrow>
 			<mrow>
 				<mo>[</mo>
 				<mo>[</mo>
 				<mtable>
 				<mtable>
@@ -110,53 +111,56 @@ m.elements = [ 11, 21, 31,
 				</mtable>
 				</mtable>
 				<mo>]</mo>
 				<mo>]</mo>
 			</mrow>
 			</mrow>
-		</math><br /><br />
+		</math>
 
 
+		<p>
 		ثم سيتم تعيين [page:Vector3 xAxis] ، [page:Vector3 yAxis] ، [page:Vector3 zAxis]
 		ثم سيتم تعيين [page:Vector3 xAxis] ، [page:Vector3 yAxis] ، [page:Vector3 zAxis]
-		إلى:<br /><br />
+		إلى:
+		</p>
 
 
-		<math>
-			<mrow>
-				<mi>xAxis</mi>
-				<mo>=</mo>
-				<mo>[</mo>
-				<mtable>
-					<mtr><mtd style="height: 1rem"><mi>a</mi></mtd></mtr>
-					<mtr><mtd style="height: 1rem"><mi>d</mi></mtd></mtr>
-					<mtr><mtd style="height: 1rem"><mi>g</mi></mtd></mtr>
-				</mtable>
-				<mo>]</mo>
-			</mrow>
-		</math>,
+		<div style="text-align: center">
+			<math>
+				<mrow>
+					<mi>xAxis</mi>
+					<mo>=</mo>
+					<mo>[</mo>
+					<mtable>
+						<mtr><mtd style="height: 1rem"><mi>a</mi></mtd></mtr>
+						<mtr><mtd style="height: 1rem"><mi>d</mi></mtd></mtr>
+						<mtr><mtd style="height: 1rem"><mi>g</mi></mtd></mtr>
+					</mtable>
+					<mo>]</mo>
+				</mrow>
+			</math>,
 
 
-		<math>
-			<mrow>
-				<mi>yAxis</mi>
-				<mo>=</mo>
-				<mo>[</mo>
-				<mtable>
-					<mtr><mtd style="height: 1rem"><mi>b</mi></mtd></mtr>
-					<mtr><mtd style="height: 1rem"><mi>e</mi></mtd></mtr>
-					<mtr><mtd style="height: 1rem"><mi>h</mi></mtd></mtr>
-				</mtable>
-				<mo>]</mo>
-			</mrow>
-		</math>, and
+			<math>
+				<mrow>
+					<mi>yAxis</mi>
+					<mo>=</mo>
+					<mo>[</mo>
+					<mtable>
+						<mtr><mtd style="height: 1rem"><mi>b</mi></mtd></mtr>
+						<mtr><mtd style="height: 1rem"><mi>e</mi></mtd></mtr>
+						<mtr><mtd style="height: 1rem"><mi>h</mi></mtd></mtr>
+					</mtable>
+					<mo>]</mo>
+				</mrow>
+			</math>, and
 
 
-		<math>
-			<mrow>
-				<mi>zAxis</mi>
-				<mo>=</mo>
-				<mo>[</mo>
-				<mtable>
-					<mtr><mtd style="height: 1rem"><mi>c</mi></mtd></mtr>
-					<mtr><mtd style="height: 1rem"><mi>f</mi></mtd></mtr>
-					<mtr><mtd style="height: 1rem"><mi>i</mi></mtd></mtr>
-				</mtable>
-				<mo>]</mo>
-			</mrow>
-		</math>
-		</p>
+			<math>
+				<mrow>
+					<mi>zAxis</mi>
+					<mo>=</mo>
+					<mo>[</mo>
+					<mtable>
+						<mtr><mtd style="height: 1rem"><mi>c</mi></mtd></mtr>
+						<mtr><mtd style="height: 1rem"><mi>f</mi></mtd></mtr>
+						<mtr><mtd style="height: 1rem"><mi>i</mi></mtd></mtr>
+					</mtable>
+					<mo>]</mo>
+				</mrow>
+			</math>
+		</div>
 	 
 	 
 		<h3>
 		<h3>
 		[method:this fromArray]( [param:Array array], [param:Integer offset] )
 		[method:this fromArray]( [param:Array array], [param:Integer offset] )
@@ -192,9 +196,10 @@ m.elements = [ 11, 21, 31,
 	 
 	 
 		<h3>[method:this identity]()</h3>
 		<h3>[method:this identity]()</h3>
 		<p>
 		<p>
-		يعيد هذه المصفوفة إلى مصفوفة الهوية 3x3:<br /><br />
+		يعيد هذه المصفوفة إلى مصفوفة الهوية 3x3:
+		</p>
 
 
-		<math>
+		<math display="block">
 			<mrow>
 			<mrow>
 				<mo>[</mo>
 				<mo>[</mo>
 				<mtable>
 				<mtable>
@@ -217,7 +222,6 @@ m.elements = [ 11, 21, 31,
 				<mo>]</mo>
 				<mo>]</mo>
 			</mrow>
 			</mrow>
 		</math>
 		</math>
-		</p>
 	 
 	 
 		<h3>[method:this makeRotation]( [param:Float theta] )</h3>
 		<h3>[method:this makeRotation]( [param:Float theta] )</h3>
 		<p>
 		<p>
@@ -225,9 +229,10 @@ m.elements = [ 11, 21, 31,
 		عكس عقارب الساعة.<br /><br />
 		عكس عقارب الساعة.<br /><br />
 	 
 	 
 		يضع هذه المصفوفة كتحول دوران ثنائي الأبعاد بـ [page:Float theta]
 		يضع هذه المصفوفة كتحول دوران ثنائي الأبعاد بـ [page:Float theta]
-		راديان. المصفوفة الناتجة ستكون:<br /><br />
+		راديان. المصفوفة الناتجة ستكون:
+		</p>
 
 
-		<math>
+		<math display="block">
 			<mrow>
 			<mrow>
 				<mo>[</mo>
 				<mo>[</mo>
 				<mtable>
 				<mtable>
@@ -266,16 +271,16 @@ m.elements = [ 11, 21, 31,
 				<mo>]</mo>
 				<mo>]</mo>
 			</mrow>
 			</mrow>
 		</math>
 		</math>
-		</p>
 	 
 	 
 		<h3>[method:this makeScale]( [param:Float x], [param:Float y] )</h3>
 		<h3>[method:this makeScale]( [param:Float x], [param:Float y] )</h3>
 		<p>
 		<p>
 		[page:Float x] - المبلغ الذي يتم قياسه في المحور X.<br />
 		[page:Float x] - المبلغ الذي يتم قياسه في المحور X.<br />
 		[page:Float y] - المبلغ الذي يتم قياسه في المحور Y.<br />
 		[page:Float y] - المبلغ الذي يتم قياسه في المحور Y.<br />
 	 
 	 
-		يضع هذه المصفوفة كتحول قياس ثنائي الأبعاد:<br /><br />
+		يضع هذه المصفوفة كتحول قياس ثنائي الأبعاد:
+		</p>
 
 
-		<math>
+		<math display="block">
 			<mrow>
 			<mrow>
 				<mo>[</mo>
 				<mo>[</mo>
 				<mtable>
 				<mtable>
@@ -298,7 +303,6 @@ m.elements = [ 11, 21, 31,
 				<mo>]</mo>
 				<mo>]</mo>
 			</mrow>
 			</mrow>
 		</math>
 		</math>
-		</p>
 	 
 	 
 		<h3>[method:this makeTranslation]( [param:Vector2 v] )</h3>
 		<h3>[method:this makeTranslation]( [param:Vector2 v] )</h3>
 		<h3>[method:this makeTranslation]( [param:Float x], [param:Float y] )</h3>
 		<h3>[method:this makeTranslation]( [param:Float x], [param:Float y] )</h3>
@@ -308,9 +312,10 @@ m.elements = [ 11, 21, 31,
 		[page:Float x] - المبلغ الذي يتم ترجمته في المحور X.<br />
 		[page:Float x] - المبلغ الذي يتم ترجمته في المحور X.<br />
 		[page:Float y] - المبلغ الذي يتم ترجمته في المحور Y.<br />
 		[page:Float y] - المبلغ الذي يتم ترجمته في المحور Y.<br />
 	 
 	 
-		يضع هذه المصفوفة كتحويل ترجمة ثنائي الأبعاد:<br /><br />
+		يضع هذه المصفوفة كتحويل ترجمة ثنائي الأبعاد:
+		</p>
 
 
-		<math>
+		<math display="block">
 			<mrow>
 			<mrow>
 				<mo>[</mo>
 				<mo>[</mo>
 				<mtable>
 				<mtable>
@@ -333,7 +338,6 @@ m.elements = [ 11, 21, 31,
 				<mo>]</mo>
 				<mo>]</mo>
 			</mrow>
 			</mrow>
 		</math>
 		</math>
-		</p>
 	 
 	 
 		<h3>[method:this multiply]( [param:Matrix3 m] )</h3>
 		<h3>[method:this multiply]( [param:Matrix3 m] )</h3>
 		<p>يضرب هذه المصفوفة بعد [page:Matrix3 m].</p>
 		<p>يضرب هذه المصفوفة بعد [page:Matrix3 m].</p>
@@ -357,9 +361,10 @@ m.elements = [ 11, 21, 31,
 		</h3>
 		</h3>
 		<p>
 		<p>
 		يضع قيم المصفوفة 3x3 على
 		يضع قيم المصفوفة 3x3 على
-		[link:https://en.wikipedia.org/wiki/Row-_and_column-major_order تسلسل قيم رئيسية للصف]:<br /><br />
+		[link:https://en.wikipedia.org/wiki/Row-_and_column-major_order تسلسل قيم رئيسية للصف]:
+		</p>
 
 
-		<math>
+		<math display="block">
 			<mrow>
 			<mrow>
 				<mo>[</mo>
 				<mo>[</mo>
 				<mtable>
 				<mtable>
@@ -382,7 +387,6 @@ m.elements = [ 11, 21, 31,
 				<mo>]</mo>
 				<mo>]</mo>
 			</mrow>
 			</mrow>
 		</math>
 		</math>
-		</p>
 	 
 	 
 		<h3>[method:this premultiply]( [param:Matrix3 m] )</h3>
 		<h3>[method:this premultiply]( [param:Matrix3 m] )</h3>
 		<p>Pre-multiplies this matrix by [page:Matrix3 m].</p>
 		<p>Pre-multiplies this matrix by [page:Matrix3 m].</p>

+ 39 - 35
docs/api/ar/math/Matrix4.html

@@ -194,9 +194,10 @@
 		<p>
 		<p>
 		يستخرج[link:https://en.wikipedia.org/wiki/Basis_(linear_algebra) basis] 
 		يستخرج[link:https://en.wikipedia.org/wiki/Basis_(linear_algebra) basis] 
 		من هذه المصفوفة في المتجهات الثلاثة المحورية المقدمة. إذا كانت هذه المصفوفة
 		من هذه المصفوفة في المتجهات الثلاثة المحورية المقدمة. إذا كانت هذه المصفوفة
-		:<br /><br />
+		:
+		</p>
 
 
-		<math>
+		<math display="block">
 			<mrow>
 			<mrow>
 				<mo>[</mo>
 				<mo>[</mo>
 				<mtable>
 				<mtable>
@@ -227,11 +228,14 @@
 				</mtable>
 				</mtable>
 				<mo>]</mo>
 				<mo>]</mo>
 			</mrow>
 			</mrow>
-		</math><br /><br />
+		</math>
 
 
+		<p>
 		ثم سيتم تعيين[page:Vector3 xAxis] ،[page:Vector3 yAxis] ،[page:Vector3 zAxis]
 		ثم سيتم تعيين[page:Vector3 xAxis] ،[page:Vector3 yAxis] ،[page:Vector3 zAxis]
-		إلى:<br /><br />
+		إلى:
+		</p>
 
 
+		<div style="text-align: center">
 		<math>
 		<math>
 			<mrow>
 			<mrow>
 				<mi>xAxis</mi>
 				<mi>xAxis</mi>
@@ -273,7 +277,7 @@
 				<mo>]</mo>
 				<mo>]</mo>
 			</mrow>
 			</mrow>
 		</math>
 		</math>
-		</p>
+		</div>
 
 
 		<h3>[method:this extractRotation]( [param:Matrix4 m] )</h3>
 		<h3>[method:this extractRotation]( [param:Matrix4 m] )</h3>
 		<p>
 		<p>
@@ -337,9 +341,10 @@
 		</h3>
 		</h3>
 		<p>
 		<p>
 		قم بتعيين هذا إلى [link:https://en.wikipedia.org/wiki/Basis_(linear_algebra) basis] 
 		قم بتعيين هذا إلى [link:https://en.wikipedia.org/wiki/Basis_(linear_algebra) basis] 
-		مصفوفة تتكون من المتجهات الأساسية الثلاثة المقدمة:<br /><br />
+		مصفوفة تتكون من المتجهات الأساسية الثلاثة المقدمة:
+		</p>
 
 
-		<math>
+		<math display="block">
 			<mrow>
 			<mrow>
 				<mo>[</mo>
 				<mo>[</mo>
 				<mtable>
 				<mtable>
@@ -371,7 +376,6 @@
 				<mo>]</mo>
 				<mo>]</mo>
 			</mrow>
 			</mrow>
 		</math>
 		</math>
-		</p>
 		 
 		 
 		<h3>
 		<h3>
 		[method:this makePerspective]( [param:Float left], [param:Float right], [param:Float top], [param:Float bottom], [param:Float near], [param:Float far] )
 		[method:this makePerspective]( [param:Float left], [param:Float right], [param:Float top], [param:Float bottom], [param:Float near], [param:Float far] )
@@ -406,9 +410,10 @@
 		[page:Quaternion q] ، كما هو مبين
 		[page:Quaternion q] ، كما هو مبين
 		[link:https://en.wikipedia.org/wiki/Rotation_matrix#Quaternion هنا]. ال
 		[link:https://en.wikipedia.org/wiki/Rotation_matrix#Quaternion هنا]. ال
 		باقي من المصفوفة يتم تعيينه إلى المعرف. لذلك ، بالنظر إلى[page:Quaternion q] =
 		باقي من المصفوفة يتم تعيينه إلى المعرف. لذلك ، بالنظر إلى[page:Quaternion q] =
-		w + xi + yj + zk ، فإن المصفوفة الناتجة ستكون:<br /><br />
+		w + xi + yj + zk ، فإن المصفوفة الناتجة ستكون:
+		</p>
 
 
-		<math>
+		<math display="block">
 			<mrow>
 			<mrow>
 				<mo>[</mo>
 				<mo>[</mo>
 				<mtable>
 				<mtable>
@@ -536,16 +541,16 @@
 				<mo>]</mo>
 				<mo>]</mo>
 			</mrow>
 			</mrow>
 		</math>
 		</math>
-		</p>
 
 
 		<h3>[method:this makeRotationX]( [param:Float theta] )</h3>
 		<h3>[method:this makeRotationX]( [param:Float theta] )</h3>
 		<p>
 		<p>
 		[page:Float theta] - زاوية الدوران بالراديان. <br /><br />
 		[page:Float theta] - زاوية الدوران بالراديان. <br /><br />
 	 
 	 
 		يضع هذه المصفوفة كتحويل دوران حول محور X بواسطة
 		يضع هذه المصفوفة كتحويل دوران حول محور X بواسطة
-		[page:Float theta] (&theta;) راديان. المصفوفة الناتجة ستكون:<br /><br />
+		[page:Float theta] (&theta;) راديان. المصفوفة الناتجة ستكون:
+		</p>
 
 
-		<math>
+		<math display="block">
 			<mrow>
 			<mrow>
 				<mo>[</mo>
 				<mo>[</mo>
 				<mtable>
 				<mtable>
@@ -598,16 +603,16 @@
 				<mo>]</mo>
 				<mo>]</mo>
 			</mrow>
 			</mrow>
 		</math>
 		</math>
-		</p>
 	 
 	 
 		<h3>[method:this makeRotationY]( [param:Float theta] )</h3>
 		<h3>[method:this makeRotationY]( [param:Float theta] )</h3>
 		<p>
 		<p>
 		[page:Float theta] - زاوية الدوران بالراديان. <br /><br />
 		[page:Float theta] - زاوية الدوران بالراديان. <br /><br />
 	 
 	 
 		يضع هذه المصفوفة كتحويل دوران حول محور Y بواسطة
 		يضع هذه المصفوفة كتحويل دوران حول محور Y بواسطة
-		[page:Float theta] (&theta;) راديان. المصفوفة الناتجة ستكون:<br /><br />
+		[page:Float theta] (&theta;) راديان. المصفوفة الناتجة ستكون:
+		</p>
 
 
-		<math>
+		<math display="block">
 			<mrow>
 			<mrow>
 				<mo>[</mo>
 				<mo>[</mo>
 				<mtable>
 				<mtable>
@@ -660,16 +665,16 @@
 				<mo>]</mo>
 				<mo>]</mo>
 			</mrow>
 			</mrow>
 		</math>
 		</math>
-		</p>
 	 
 	 
 		<h3>[method:this makeRotationZ]( [param:Float theta] )</h3>
 		<h3>[method:this makeRotationZ]( [param:Float theta] )</h3>
 		<p>
 		<p>
 		[page:Float theta] - زاوية الدوران بالراديان. <br /><br />
 		[page:Float theta] - زاوية الدوران بالراديان. <br /><br />
 	 
 	 
 		يضع هذه المصفوفة كتحويل دوران حول محور Z بواسطة
 		يضع هذه المصفوفة كتحويل دوران حول محور Z بواسطة
-		[page:Float theta] (&theta;) راديان. المصفوفة الناتجة ستكون:<br /><br />
+		[page:Float theta] (&theta;) راديان. المصفوفة الناتجة ستكون:
+		</p>
 			
 			
-		<math>
+		<math display="block">
 			<mrow>
 			<mrow>
 				<mo>[</mo>
 				<mo>[</mo>
 				<mtable>
 				<mtable>
@@ -722,7 +727,6 @@
 				<mo>]</mo>
 				<mo>]</mo>
 			</mrow>
 			</mrow>
 		</math>
 		</math>
-		</p>
 	 
 	 
 		<h3>
 		<h3>
 		[method:this makeScale]( [param:Float x], [param:Float y], [param:Float z] )
 		[method:this makeScale]( [param:Float x], [param:Float y], [param:Float z] )
@@ -732,9 +736,10 @@
 		[page:Float y] - المقدار الذي يجب تغييره في محور Y. <br />
 		[page:Float y] - المقدار الذي يجب تغييره في محور Y. <br />
 		[page:Float z] - المقدار الذي يجب تغييره في محور Z. <br /><br />
 		[page:Float z] - المقدار الذي يجب تغييره في محور Z. <br /><br />
 	 
 	 
-		يضع هذه المصفوفة كتحويل قياس:<br /><br />
+		يضع هذه المصفوفة كتحويل قياس:
+		</p>
 
 
-		<math>
+		<math display="block">
 			<mrow>
 			<mrow>
 				<mo>[</mo>
 				<mo>[</mo>
 				<mtable>
 				<mtable>
@@ -766,7 +771,6 @@
 				<mo>]</mo>
 				<mo>]</mo>
 			</mrow>
 			</mrow>
 		</math>
 		</math>
-		</p>
 	 
 	 
 		<h3>
 		<h3>
 		[method:this makeShear]( [param:Float xy], [param:Float xz], [param:Float yx], 
 		[method:this makeShear]( [param:Float xy], [param:Float xz], [param:Float yx], 
@@ -780,9 +784,10 @@
 		[page:Float zx] - المقدار الذي يجب قصه Z بواسطة X. <br />
 		[page:Float zx] - المقدار الذي يجب قصه Z بواسطة X. <br />
 		[page:Float zy] - المقدار الذي يجب قصه Z بواسطة Y. <br /><br />
 		[page:Float zy] - المقدار الذي يجب قصه Z بواسطة Y. <br /><br />
 		 
 		 
-		يضع هذه المصفوفة كتحويل قص:<br /><br />
+		يضع هذه المصفوفة كتحويل قص:
+		</p>
 
 
-		<math>
+		<math display="block">
 			<mrow>
 			<mrow>
 				<mo>[</mo>
 				<mo>[</mo>
 				<mtable>
 				<mtable>
@@ -814,16 +819,16 @@
 				<mo>]</mo>
 				<mo>]</mo>
 			</mrow>
 			</mrow>
 		</math>
 		</math>
-		</p>
 		 
 		 
 		<h3>[method:this makeTranslation]( [param:Vector3 v] )</h3>
 		<h3>[method:this makeTranslation]( [param:Vector3 v] )</h3>
 		<h3>
 		<h3>
 		[method:this makeTranslation]( [param:Float x], [param:Float y], [param:Float z] ) // واجهة برمجة التطبيقات الاختيارية
 		[method:this makeTranslation]( [param:Float x], [param:Float y], [param:Float z] ) // واجهة برمجة التطبيقات الاختيارية
 		</h3>
 		</h3>
 		<p>
 		<p>
-		يضع هذه المصفوفة كتحويل ترجمة من متجه [page:Vector3 v] ، أو أرقام [page:Float x] ، [page:Float y] و [page:Float z]:<br /><br />
+		يضع هذه المصفوفة كتحويل ترجمة من متجه [page:Vector3 v] ، أو أرقام [page:Float x] ، [page:Float y] و [page:Float z]:
+		</p>
 
 
-		<math>
+		<math display="block">
 			<mrow>
 			<mrow>
 				<mo>[</mo>
 				<mo>[</mo>
 				<mtable>
 				<mtable>
@@ -855,7 +860,6 @@
 				<mo>]</mo>
 				<mo>]</mo>
 			</mrow>
 			</mrow>
 		</math>
 		</math>
-		</p>
 		 
 		 
 		<h3>[method:this multiply]( [param:Matrix4 m] )</h3>
 		<h3>[method:this multiply]( [param:Matrix4 m] )</h3>
 		<p>تعدل هذه المصفوفة بعد ضربها بـ[page:Matrix4 m].</p>
 		<p>تعدل هذه المصفوفة بعد ضربها بـ[page:Matrix4 m].</p>
@@ -897,9 +901,10 @@
 		<p>
 		<p>
 		يضع مكون الموضع لهذه المصفوفة من المتجه [page:Vector3 v] ،
 		يضع مكون الموضع لهذه المصفوفة من المتجه [page:Vector3 v] ،
 		دون التأثير على بقية المصفوفة - أي إذا كانت المصفوفة هي
 		دون التأثير على بقية المصفوفة - أي إذا كانت المصفوفة هي
-		حاليا:<br /><br />
+		حاليا:
+		</p>
 
 
-		<math>
+		<math display="block">
 			<mrow>
 			<mrow>
 				<mo>[</mo>
 				<mo>[</mo>
 				<mtable>
 				<mtable>
@@ -930,11 +935,11 @@
 				</mtable>
 				</mtable>
 				<mo>]</mo>
 				<mo>]</mo>
 			</mrow>
 			</mrow>
-		</math><br /><br />
+		</math>
 
 
-		هذا يصبح:<br /><br />
+		<p>هذا يصبح:</p>
 
 
-		<math>
+		<math display="block">
 			<mrow>
 			<mrow>
 				<mo>[</mo>
 				<mo>[</mo>
 				<mtable>
 				<mtable>
@@ -966,7 +971,6 @@
 				<mo>]</mo>
 				<mo>]</mo>
 			</mrow>
 			</mrow>
 		</math>
 		</math>
-		</p>
 		 
 		 
 		<h3>
 		<h3>
 		[method:Array toArray]( [param:Array array], [param:Integer offset] )
 		[method:Array toArray]( [param:Array array], [param:Integer offset] )

+ 1 - 4
docs/api/ar/objects/Skeleton.html

@@ -76,10 +76,7 @@
 		<p>
 		<p>
 		[page:DataTexture] التي تحمل بيانات العظام عند استخدام نسيج الرأس.
 		[page:DataTexture] التي تحمل بيانات العظام عند استخدام نسيج الرأس.
 		</p>
 		</p>
-		
-		<h3>[property:Integer boneTextureSize]</h3>
-		<p>حجم [page:.boneTexture].</p>
-		
+
 		<h2>الطرق (Methods)</h2>
 		<h2>الطرق (Methods)</h2>
 		
 		
 		<h3>[method:Skeleton clone]()</h3>
 		<h3>[method:Skeleton clone]()</h3>

+ 3 - 3
docs/api/ar/renderers/WebGL3DRenderTarget.html

@@ -16,7 +16,7 @@
 		<h2>المنشئ (Constructor)</h2>
 		<h2>المنشئ (Constructor)</h2>
 	 
 	 
 		<h3>
 		<h3>
-		[name]( [param:Number width], [param:Number height], [param:Number depth] )
+		[name]( [param:Number width], [param:Number height], [param:Number depth], [param:Object options] )
 		</h3>
 		</h3>
 		<p>
 		<p>
 		[page:Number width] - عرض هدف العرض ، بالبكسل. الافتراضي
 		[page:Number width] - عرض هدف العرض ، بالبكسل. الافتراضي
@@ -29,7 +29,7 @@
 		</p>
 		</p>
 	 
 	 
 		<h2>الخصائص (Properties)</h2>
 		<h2>الخصائص (Properties)</h2>
-		<h3>انظر [page:WebGLRenderTarget] للخصائص الموروثة</h3>
+		<p>انظر [page:WebGLRenderTarget] للخصائص الموروثة.</p>
 	 
 	 
 		<h3>[property:number depth]</h3>
 		<h3>[property:number depth]</h3>
 		<p>عمق هدف العرض.</p>
 		<p>عمق هدف العرض.</p>
@@ -41,7 +41,7 @@
 		</p>
 		</p>
 	 
 	 
 		<h2>الطرق (Methods)</h2>
 		<h2>الطرق (Methods)</h2>
-		<h3>انظر [page:WebGLRenderTarget] للطرق الموروثة</h3>
+		<p>انظر [page:WebGLRenderTarget] للطرق الموروثة.</p>
 	 
 	 
 		<h2>المصدر (Source)</h2>
 		<h2>المصدر (Source)</h2>
 		<p>
 		<p>

+ 3 - 3
docs/api/ar/renderers/WebGLArrayRenderTarget.html

@@ -24,7 +24,7 @@
 		<h2>المنشئ (Constructor)</h2>
 		<h2>المنشئ (Constructor)</h2>
 		 
 		 
 		<h3>
 		<h3>
-		[name]( [param:Number width], [param:Number height], [param:Number depth] )
+		[name]( [param:Number width], [param:Number height], [param:Number depth], [param:Object options] )
 		</h3>
 		</h3>
 		<p>
 		<p>
 		[page:Number width] - عرض هدف العرض ، بالبكسل. الافتراضي
 		[page:Number width] - عرض هدف العرض ، بالبكسل. الافتراضي
@@ -39,7 +39,7 @@
 		 
 		 
 		<h2>الخصائص (Properties)</h2>
 		<h2>الخصائص (Properties)</h2>
 		 
 		 
-		<h3>انظر [page:WebGLRenderTarget] للخصائص الموروثة</h3>
+		<p>انظر [page:WebGLRenderTarget] للخصائص الموروثة.</p>
 		 
 		 
 		<h3>[property:number depth]</h3>
 		<h3>[property:number depth]</h3>
 		<p>عمق هدف العرض.</p>
 		<p>عمق هدف العرض.</p>
@@ -51,7 +51,7 @@
 		</p>
 		</p>
 		 
 		 
 		<h2>الطرق (Methods)</h2>
 		<h2>الطرق (Methods)</h2>
-		<h3>انظر [page:WebGLRenderTarget] للطرق الموروثة</h3>
+		<p>انظر [page:WebGLRenderTarget] للطرق الموروثة.</p>
 		 
 		 
 		<h2>المصدر (Source)</h2>
 		<h2>المصدر (Source)</h2>
 		<p>
 		<p>

+ 2 - 2
docs/api/ar/renderers/WebGLCubeRenderTarget.html

@@ -52,11 +52,11 @@
 
 
 		<h2>الخصائص (Properties)</h2>
 		<h2>الخصائص (Properties)</h2>
 
 
-		<h3>انظر [page:WebGLRenderTarget] للخصائص الموروثة</h3>
+		<p>انظر [page:WebGLRenderTarget] للخصائص الموروثة.</p>
 	 
 	 
 		<h2>الطرق (Methods)</h2>
 		<h2>الطرق (Methods)</h2>
 	 
 	 
-		<h3>انظر [page:WebGLRenderTarget] للطرق الموروثة</h3>
+		<p>انظر [page:WebGLRenderTarget] للطرق الموروثة.</p>
 	 
 	 
 		<h3>
 		<h3>
 		[method:this fromEquirectangularTexture]( [param:WebGLRenderer renderer], [param:Texture texture] )
 		[method:this fromEquirectangularTexture]( [param:WebGLRenderer renderer], [param:Texture texture] )

+ 18 - 6
docs/api/en/core/BufferAttribute.html

@@ -99,16 +99,16 @@
 			the attribute array data to the GPU.
 			the attribute array data to the GPU.
 		</p>
 		</p>
 
 
-		<h3>[property:Object updateRange]</h3>
+		<h3>[property:Object updateRanges]</h3>
 		<p>
 		<p>
-			Object containing:<br />
-			[page:Integer offset]: Default is `0`. Position at which to start
+			Array of objects containing:<br />
+			[page:Integer start]: Position at which to start
 			update.<br />
 			update.<br />
-			[page:Integer count]: Default is `-1`, which means don't use update
-			ranges. <br /><br />
+			[page:Integer count]: The number of components to update. <br /><br />
 
 
 			This can be used to only update some components of stored vectors (for
 			This can be used to only update some components of stored vectors (for
-			example, just the component related to color).
+			example, just the component related to color). Use the [page:BufferAttribute.addUpdateRange addUpdateRange]
+			function to add ranges to this array.
 		</p>
 		</p>
 
 
 		<h3>[property:Usage usage]</h3>
 		<h3>[property:Usage usage]</h3>
@@ -155,6 +155,18 @@
 			BufferAttribute, interpreting the elements as a direction vectors.
 			BufferAttribute, interpreting the elements as a direction vectors.
 		</p>
 		</p>
 
 
+		<h3>[method:this addUpdateRange]( [param:Integer start], [param:Integer count] )</h3>
+		<p>
+			Adds a range of data in the data array to be updated on the GPU. Adds an
+			object describing the range to the [page:BufferAttribute.updateRanges updateRanges]
+			array.
+		</p>
+
+		<h3>[method:this clearUpdateRanges]()</h3>
+		<p>
+			Clears the [page:BufferAttribute.updateRanges updateRanges] array.
+		</p>
+
 		<h3>[method:BufferAttribute clone]()</h3>
 		<h3>[method:BufferAttribute clone]()</h3>
 		<p>Return a copy of this bufferAttribute.</p>
 		<p>Return a copy of this bufferAttribute.</p>
 
 

+ 21 - 4
docs/api/en/core/InterleavedBuffer.html

@@ -40,11 +40,16 @@
 		<h3>[property:Integer count]</h3>
 		<h3>[property:Integer count]</h3>
 		<p>Gives the total number of elements in the array.</p>
 		<p>Gives the total number of elements in the array.</p>
 
 
-		<h3>[property:Object updateRange]</h3>
+		<h3>[property:Object updateRanges]</h3>
 		<p>
 		<p>
-			Object containing offset and count.<br />
-			- [page:Number offset]: Default is `0`.<br />
-			- [page:Number count]: Default is `-1`.<br />
+			Array of objects containing:<br />
+			[page:Integer start]: Position at which to start
+			update.<br />
+			[page:Integer count]: The number of components to update. <br /><br />
+
+			This can be used to only update some components of stored data. Use
+			the [page:InterleavedBuffer.addUpdateRange addUpdateRange] function
+			to add ranges to this array.
 		</p>
 		</p>
 
 
 		<h3>[property:String uuid]</h3>
 		<h3>[property:String uuid]</h3>
@@ -75,6 +80,18 @@
 
 
 		<h2>Methods</h2>
 		<h2>Methods</h2>
 
 
+		<h3>[method:this addUpdateRange]( [param:Integer start], [param:Integer count] )</h3>
+		<p>
+			Adds a range of data in the data array to be updated on the GPU. Adds an
+			object describing the range to the [page:InterleavedBuffer.updateRanges updateRanges]
+			array.
+		</p>
+
+		<h3>[method:this clearUpdateRanges]()</h3>
+		<p>
+			Clears the [page:InterleavedBuffer.updateRanges updateRanges] array.
+		</p>
+
 		<h3>[method:this copy]( [param:InterleavedBuffer source] )</h3>
 		<h3>[method:this copy]( [param:InterleavedBuffer source] )</h3>
 		<p>Copies another [name] to this [name].</p>
 		<p>Copies another [name] to this [name].</p>
 
 

+ 35 - 2
docs/api/en/core/Object3D.html

@@ -144,6 +144,21 @@
 			for such objects.
 			for such objects.
 		</p>
 		</p>
 
 
+		<h3>[property:Function onAfterShadow]</h3>
+		<p>
+			An optional callback that is executed immediately after a 3D object is
+			rendered to a shadow map. This function is called with the following parameters: renderer,
+			scene, camera, shadowCamera, geometry, depthMaterial, group.
+		</p>
+		<p>
+			Please notice that this callback is only executed for `renderable` 3D
+			objects. Meaning 3D objects which define their visual appearance with
+			geometries and materials like instances of [page:Mesh], [page:Line],
+			[page:Points] or [page:Sprite]. Instances of [page:Object3D], [page:Group]
+			or [page:Bone] are not renderable and thus this callback is not executed
+			for such objects.
+		</p>
+
 		<h3>[property:Function onBeforeRender]</h3>
 		<h3>[property:Function onBeforeRender]</h3>
 		<p>
 		<p>
 			An optional callback that is executed immediately before a 3D object is
 			An optional callback that is executed immediately before a 3D object is
@@ -159,6 +174,21 @@
 			for such objects.
 			for such objects.
 		</p>
 		</p>
 
 
+		<h3>[property:Function onBeforeShadow]</h3>
+		<p>
+			An optional callback that is executed immediately before a 3D object is
+			rendered to a shadow map. This function is called with the following parameters: renderer,
+			scene, camera, shadowCamera, geometry, depthMaterial, group.
+		</p>
+		<p>
+			Please notice that this callback is only executed for `renderable` 3D
+			objects. Meaning 3D objects which define their visual appearance with
+			geometries and materials like instances of [page:Mesh], [page:Line],
+			[page:Points] or [page:Sprite]. Instances of [page:Object3D], [page:Group]
+			or [page:Bone] are not renderable and thus this callback is not executed
+			for such objects.
+		</p>
+
 		<h3>[property:Object3D parent]</h3>
 		<h3>[property:Object3D parent]</h3>
 		<p>
 		<p>
 			Object's parent in the [link:https://en.wikipedia.org/wiki/Scene_graph scene graph]. An object can have at most one parent.
 			Object's parent in the [link:https://en.wikipedia.org/wiki/Scene_graph scene graph]. An object can have at most one parent.
@@ -334,10 +364,13 @@
 			given.
 			given.
 		</p>
 		</p>
 
 
-		<h3>[method:Object3D getObjectsByProperty]( [param:String name], [param:Any value] )</h3>
+		<h3>[method:Object3D getObjectsByProperty]( [param:String name], [param:Any value], [param:Array optionalTarget] )</h3>
 		<p>
 		<p>
 			name -- the property name to search for. <br />
 			name -- the property name to search for. <br />
-			value -- value of the given property. <br /><br />
+			value -- value of the given property. <br />
+			optionalTarget -- (optional) target to set the result.
+			Otherwise a new Array is instantiated. If set, you must clear this
+			array prior to each call (i.e., array.length = 0;). <br /><br />
 
 
 			Searches through an object and its children, starting with the object
 			Searches through an object and its children, starting with the object
 			itself, and returns all the objects with a property that matches the value
 			itself, and returns all the objects with a property that matches the value

+ 2 - 0
docs/api/en/helpers/DirectionalLightHelper.html

@@ -21,6 +21,8 @@
 
 
 		<code>
 		<code>
 		const light = new THREE.DirectionalLight( 0xFFFFFF );
 		const light = new THREE.DirectionalLight( 0xFFFFFF );
+		scene.add( light );
+
 		const helper = new THREE.DirectionalLightHelper( light, 5 );
 		const helper = new THREE.DirectionalLightHelper( light, 5 );
 		scene.add( helper );
 		scene.add( helper );
 		</code>
 		</code>

+ 2 - 1
docs/api/en/materials/LineDashedMaterial.html

@@ -12,7 +12,8 @@
 		<h1>[name]</h1>
 		<h1>[name]</h1>
 
 
 		<p class="desc">
 		<p class="desc">
-			A material for drawing wireframe-style geometries with dashed lines.
+			A material for drawing wireframe-style geometries with dashed lines.<br />
+			Note: You must call [page:Line.computeLineDistances]() when using [name].
 		</p>
 		</p>
 
 
 		<h2>Code Example</h2>
 		<h2>Code Example</h2>

+ 1 - 1
docs/api/en/materials/MeshPhysicalMaterial.html

@@ -286,7 +286,7 @@
 			property can be used to model these materials.<br />
 			property can be used to model these materials.<br />
 
 
 			When transmission is non-zero, [page:Material.opacity opacity] should be
 			When transmission is non-zero, [page:Material.opacity opacity] should be
-			set to `0`.
+			set to `1`.
 		</p>
 		</p>
 
 
 		<h3>[property:Texture transmissionMap]</h3>
 		<h3>[property:Texture transmissionMap]</h3>

+ 170 - 166
docs/api/en/math/Matrix3.html

@@ -86,35 +86,39 @@ m.elements = [ 11, 21, 31,
 		<p>
 		<p>
 			Extracts the [link:https://en.wikipedia.org/wiki/Basis_(linear_algebra) basis] 
 			Extracts the [link:https://en.wikipedia.org/wiki/Basis_(linear_algebra) basis] 
 			of this matrix into the three axis vectors provided. If this matrix
 			of this matrix into the three axis vectors provided. If this matrix
-			is:<br /><br />
+			is:
+		</p>
 
 
-			<math>
-				<mrow>
-					<mo>[</mo>
-					<mtable>
-						<mtr>
-							<mtd><mi>a</mi></mtd>
-							<mtd><mi>b</mi></mtd>
-							<mtd><mi>c</mi></mtd>
-						</mtr>
-						<mtr>
-							<mtd><mi>d</mi></mtd>
-							<mtd><mi>e</mi></mtd>
-							<mtd><mi>f</mi></mtd>
-						</mtr>
-						<mtr>
-							<mtd><mi>g</mi></mtd>
-							<mtd><mi>h</mi></mtd>
-							<mtd><mi>i</mi></mtd>
-						</mtr>
-					</mtable>
-					<mo>]</mo>
-				</mrow>
-			</math><br /><br />
+		<math display="block">
+			<mrow>
+				<mo>[</mo>
+				<mtable>
+					<mtr>
+						<mtd><mi>a</mi></mtd>
+						<mtd><mi>b</mi></mtd>
+						<mtd><mi>c</mi></mtd>
+					</mtr>
+					<mtr>
+						<mtd><mi>d</mi></mtd>
+						<mtd><mi>e</mi></mtd>
+						<mtd><mi>f</mi></mtd>
+					</mtr>
+					<mtr>
+						<mtd><mi>g</mi></mtd>
+						<mtd><mi>h</mi></mtd>
+						<mtd><mi>i</mi></mtd>
+					</mtr>
+				</mtable>
+				<mo>]</mo>
+			</mrow>
+		</math>
 
 
+		<p>
 			then the [page:Vector3 xAxis], [page:Vector3 yAxis], [page:Vector3 zAxis]
 			then the [page:Vector3 xAxis], [page:Vector3 yAxis], [page:Vector3 zAxis]
-			will be set to:<br /><br />
+			will be set to:
+		</p>
 
 
+		<p style="text-align: center">
 			<math>
 			<math>
 				<mrow>
 				<mrow>
 					<mi>xAxis</mi>
 					<mi>xAxis</mi>
@@ -193,114 +197,114 @@ m.elements = [ 11, 21, 31,
 
 
 		<h3>[method:this identity]()</h3>
 		<h3>[method:this identity]()</h3>
 		<p>
 		<p>
-			Resets this matrix to the 3x3 identity matrix:<br /><br />
-
-			<math>
-				<mrow>
-					<mo>[</mo>
-					<mtable>
-						<mtr>
-							<mtd><mn>1</mn></mtd>
-							<mtd><mn>0</mn></mtd>
-							<mtd><mn>0</mn></mtd>
-						</mtr>
-						<mtr>
-							<mtd><mn>0</mn></mtd>
-							<mtd><mn>1</mn></mtd>
-							<mtd><mn>0</mn></mtd>
-						</mtr>
-						<mtr>
-							<mtd><mn>0</mn></mtd>
-							<mtd><mn>0</mn></mtd>
-							<mtd><mn>1</mn></mtd>
-						</mtr>
-					</mtable>
-					<mo>]</mo>
-				</mrow>
-			</math>
+			Resets this matrix to the 3x3 identity matrix:
 		</p>
 		</p>
 
 
+		<math display="block">
+			<mrow>
+				<mo>[</mo>
+				<mtable>
+					<mtr>
+						<mtd><mn>1</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+					</mtr>
+					<mtr>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>1</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+					</mtr>
+					<mtr>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>1</mn></mtd>
+					</mtr>
+				</mtable>
+				<mo>]</mo>
+			</mrow>
+		</math>
+
 		<h3>[method:this makeRotation]( [param:Float theta] )</h3>
 		<h3>[method:this makeRotation]( [param:Float theta] )</h3>
 		<p>
 		<p>
 			[page:Float theta] — Rotation angle in radians. Positive values rotate
 			[page:Float theta] — Rotation angle in radians. Positive values rotate
 			counterclockwise.<br /><br />
 			counterclockwise.<br /><br />
 
 
 			Sets this matrix as a 2D rotational transformation by [page:Float theta]
 			Sets this matrix as a 2D rotational transformation by [page:Float theta]
-			radians. The resulting matrix will be:<br /><br />
-
-			<math>
-				<mrow>
-					<mo>[</mo>
-					<mtable>
-						<mtr>
-							<mtd>
-								<mi>cos</mi>
-								<mi>&theta;</mi>
-							</mtd>
-							<mtd>
-								<mi>-sin</mi>
-								<mi>&theta;</mi>
-							</mtd>
-							<mtd>
-								<mn>0</mn>
-							</mtd>
-						</mtr>
-						<mtr>
-							<mtd>
-								<mi>sin</mi>
-								<mi>&theta;</mi>
-							</mtd>
-							<mtd>
-								<mi>cos</mi>
-								<mi>&theta;</mi>
-							</mtd>
-							<mtd>
-								<mn>0</mn>
-							</mtd>
-						</mtr>
-						<mtr>
-							<mtd><mn>0</mn></mtd>
-							<mtd><mn>0</mn></mtd>
-							<mtd><mn>1</mn></mtd>
-						</mtr>
-					</mtable>
-					<mo>]</mo>
-				</mrow>
-			</math>
+			radians. The resulting matrix will be:
 		</p>
 		</p>
 
 
+		<math display="block">
+			<mrow>
+				<mo>[</mo>
+				<mtable>
+					<mtr>
+						<mtd>
+							<mi>cos</mi>
+							<mi>&theta;</mi>
+						</mtd>
+						<mtd>
+							<mi>-sin</mi>
+							<mi>&theta;</mi>
+						</mtd>
+						<mtd>
+							<mn>0</mn>
+						</mtd>
+					</mtr>
+					<mtr>
+						<mtd>
+							<mi>sin</mi>
+							<mi>&theta;</mi>
+						</mtd>
+						<mtd>
+							<mi>cos</mi>
+							<mi>&theta;</mi>
+						</mtd>
+						<mtd>
+							<mn>0</mn>
+						</mtd>
+					</mtr>
+					<mtr>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>1</mn></mtd>
+					</mtr>
+				</mtable>
+				<mo>]</mo>
+			</mrow>
+		</math>
+
 		<h3>[method:this makeScale]( [param:Float x], [param:Float y] )</h3>
 		<h3>[method:this makeScale]( [param:Float x], [param:Float y] )</h3>
 		<p>
 		<p>
 			[page:Float x] - the amount to scale in the X axis.<br />
 			[page:Float x] - the amount to scale in the X axis.<br />
 			[page:Float y] - the amount to scale in the Y axis.<br />
 			[page:Float y] - the amount to scale in the Y axis.<br />
 
 
-			Sets this matrix as a 2D scale transform:<br /><br />
-
-			<math>
-				<mrow>
-					<mo>[</mo>
-					<mtable>
-						<mtr>
-							<mtd><mi>x</mi></mtd>
-							<mtd><mn>0</mn></mtd>
-							<mtd><mn>0</mn></mtd>
-						</mtr>
-						<mtr>
-							<mtd><mn>0</mn></mtd>
-							<mtd><mi>y</mi></mtd>
-							<mtd><mn>0</mn></mtd>
-						</mtr>
-						<mtr>
-							<mtd><mn>0</mn></mtd>
-							<mtd><mn>0</mn></mtd>
-							<mtd><mn>1</mn></mtd>
-						</mtr>
-					</mtable>
-					<mo>]</mo>
-				</mrow>
-			</math>
+			Sets this matrix as a 2D scale transform:
 		</p>
 		</p>
 
 
+		<math display="block">
+			<mrow>
+				<mo>[</mo>
+				<mtable>
+					<mtr>
+						<mtd><mi>x</mi></mtd>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+					</mtr>
+					<mtr>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mi>y</mi></mtd>
+						<mtd><mn>0</mn></mtd>
+					</mtr>
+					<mtr>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>1</mn></mtd>
+					</mtr>
+				</mtable>
+				<mo>]</mo>
+			</mrow>
+		</math>
+
 		<h3>[method:this makeTranslation]( [param:Vector2 v] )</h3>
 		<h3>[method:this makeTranslation]( [param:Vector2 v] )</h3>
 		<h3>[method:this makeTranslation]( [param:Float x], [param:Float y] )</h3>
 		<h3>[method:this makeTranslation]( [param:Float x], [param:Float y] )</h3>
 		<p>
 		<p>
@@ -309,33 +313,33 @@ m.elements = [ 11, 21, 31,
 			[page:Float x] - the amount to translate in the X axis.<br />
 			[page:Float x] - the amount to translate in the X axis.<br />
 			[page:Float y] - the amount to translate in the Y axis.<br />
 			[page:Float y] - the amount to translate in the Y axis.<br />
 
 
-			Sets this matrix as a 2D translation transform:<br /><br />
-
-			<math>
-				<mrow>
-					<mo>[</mo>
-					<mtable>
-						<mtr>
-							<mtd><mn>1</mn></mtd>
-							<mtd><mn>0</mn></mtd>
-							<mtd><mi>x</mi></mtd>
-						</mtr>
-						<mtr>
-							<mtd><mn>0</mn></mtd>
-							<mtd><mn>1</mn></mtd>
-							<mtd><mi>y</mi></mtd>
-						</mtr>
-						<mtr>
-							<mtd><mn>0</mn></mtd>
-							<mtd><mn>0</mn></mtd>
-							<mtd><mn>1</mn></mtd>
-						</mtr>
-					</mtable>
-					<mo>]</mo>
-				</mrow>
-			</math>
+			Sets this matrix as a 2D translation transform:
 		</p>
 		</p>
 
 
+		<math display="block">
+			<mrow>
+				<mo>[</mo>
+				<mtable>
+					<mtr>
+						<mtd><mn>1</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mi>x</mi></mtd>
+					</mtr>
+					<mtr>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>1</mn></mtd>
+						<mtd><mi>y</mi></mtd>
+					</mtr>
+					<mtr>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>1</mn></mtd>
+					</mtr>
+				</mtable>
+				<mo>]</mo>
+			</mrow>
+		</math>
+
 		<h3>[method:this multiply]( [param:Matrix3 m] )</h3>
 		<h3>[method:this multiply]( [param:Matrix3 m] )</h3>
 		<p>Post-multiplies this matrix by [page:Matrix3 m].</p>
 		<p>Post-multiplies this matrix by [page:Matrix3 m].</p>
 
 
@@ -359,33 +363,33 @@ m.elements = [ 11, 21, 31,
 		<p>
 		<p>
 			Sets the 3x3 matrix values to the given
 			Sets the 3x3 matrix values to the given
 			[link:https://en.wikipedia.org/wiki/Row-_and_column-major_order row-major]
 			[link:https://en.wikipedia.org/wiki/Row-_and_column-major_order row-major]
-			sequence of values:<br /><br />
-
-			<math>
-				<mrow>
-					<mo>[</mo>
-					<mtable>
-						<mtr>
-							<mtd><mi>n11</mi></mtd>
-							<mtd><mi>n12</mi></mtd>
-							<mtd><mi>n13</mi></mtd>
-						</mtr>
-						<mtr>
-							<mtd><mi>n21</mi></mtd>
-							<mtd><mi>n22</mi></mtd>
-							<mtd><mi>n23</mi></mtd>
-						</mtr>
-						<mtr>
-							<mtd><mi>n31</mi></mtd>
-							<mtd><mi>n32</mi></mtd>
-							<mtd><mi>n33</mi></mtd>
-						</mtr>
-					</mtable>
-					<mo>]</mo>
-				</mrow>
-			</math>
+			sequence of values:
 		</p>
 		</p>
 
 
+		<math display="block">
+			<mrow>
+				<mo>[</mo>
+				<mtable>
+					<mtr>
+						<mtd><mi>n11</mi></mtd>
+						<mtd><mi>n12</mi></mtd>
+						<mtd><mi>n13</mi></mtd>
+					</mtr>
+					<mtr>
+						<mtd><mi>n21</mi></mtd>
+						<mtd><mi>n22</mi></mtd>
+						<mtd><mi>n23</mi></mtd>
+					</mtr>
+					<mtr>
+						<mtd><mi>n31</mi></mtd>
+						<mtd><mi>n32</mi></mtd>
+						<mtd><mi>n33</mi></mtd>
+					</mtr>
+				</mtable>
+				<mo>]</mo>
+			</mrow>
+		</math>
+
 		<h3>[method:this premultiply]( [param:Matrix3 m] )</h3>
 		<h3>[method:this premultiply]( [param:Matrix3 m] )</h3>
 		<p>Pre-multiplies this matrix by [page:Matrix3 m].</p>
 		<p>Pre-multiplies this matrix by [page:Matrix3 m].</p>
 
 

File diff suppressed because it is too large
+ 466 - 462
docs/api/en/math/Matrix4.html


+ 229 - 0
docs/api/en/objects/BatchedMesh.html

@@ -0,0 +1,229 @@
+<!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:Mesh] &rarr;
+
+		<h1>[name]</h1>
+
+		<p class="desc">
+			A special version of [page:Mesh] with multi draw batch rendering support. Use
+			[name] if you have to render a large number of objects with the same
+			material but with different world transformations and geometry. The usage
+			of [name] will help you to reduce the number of draw calls and thus
+			improve the overall rendering performance in your application.
+
+			<br/>
+			<br/>
+
+			If the [link:https://developer.mozilla.org/en-US/docs/Web/API/WEBGL_multi_draw WEBGL_multi_draw extension] is
+			not supported then a less performant callback is used.
+		</p>
+
+		<h2>Code Example</h2>
+
+		<code>
+		const box = new THREE.BoxGeometry( 1, 1, 1 );
+		const sphere = new THREE.BoxGeometry( 1, 1, 1 );
+		const material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
+
+		// initialize and add geometries into the batched mesh
+		const batchedMesh = new BatchedMesh( 10, 5000, 10000, material );
+		const boxId = batchedMesh.addGeometry( box );
+		const sphereId = batchedMesh.addGeometry( sphere );
+
+		// position the geometries
+		batchedMesh.setMatrixAt( boxId, boxMatrix );
+		batchedMesh.setMatrixAt( sphereId, sphereMatrix );
+
+		scene.add( batchedMesh );
+		</code>
+
+		<h2>Examples</h2>
+		<p>
+			[example:webgl_mesh_batch WebGL / mesh / batch]<br />
+		</p>
+
+		<h2>Constructor</h2>
+		<h3>
+			[name](
+				[param:Integer maxGeometryCount], [param:Integer maxVertexCount],
+				[param:Integer maxIndexCount], [param:Material material],
+			)
+		</h3>
+		<p>
+			[page:Integer maxGeometryCount] - the max number of individual geometries planned to be added.<br />
+			[page:Integer maxVertexCount] - the max number of vertices to be used by all geometries.<br />
+			[page:Integer maxIndexCount] - the max number of indices to be used by all geometries.<br />
+			[page:Material material] - an instance of [page:Material]. Default is a
+			new [page:MeshBasicMaterial].<br />
+		</p>
+
+		<h2>Properties</h2>
+		<p>See the base [page:Mesh] class for common properties.</p>
+
+		<h3>[property:Box3 boundingBox]</h3>
+		<p>
+			This bounding box encloses all instances of the [name]. Can be calculated
+			with [page:.computeBoundingBox](). Default is `null`.
+		</p>
+
+		<h3>[property:Sphere boundingSphere]</h3>
+		<p>
+			This bounding sphere encloses all instances of the [name]. Can be
+			calculated with [page:.computeBoundingSphere](). Default is `null`.
+		</p>
+
+		<h3>[property:Boolean perObjectFrustumCulled]</h3>
+		<p>
+			If true then the individual objects within the [name] are frustum culled. Default is `true`.
+		</p>
+
+		<h3>[property:Boolean sortObjects]</h3>
+		<p>
+			If true then the individual objects within the [name] are sorted to improve overdraw-related artifacts.
+			If the material is marked as "transparent" objects are rendered back to front and if not then they are
+			rendered front to back. Default is `true`.
+		</p>
+
+		<h3>[property:Integer maxGeometryCount]</h3>
+		<p>
+			The maximum number of individual geometries that can be stored in the [name]. Read only.
+		</p>
+
+		<h3>[property:Boolean isBatchedMesh]</h3>
+		<p>Read-only flag to check if a given object is of type [name].</p>
+
+		<h2>Methods</h2>
+		<p>See the base [page:Mesh] class for common methods.</p>
+
+		<h3>[method:undefined computeBoundingBox]()</h3>
+		<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`.
+		</p>
+
+		<h3>[method:undefined computeBoundingSphere]()</h3>
+		<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`.
+		</p>
+
+		<h3>[method:undefined dispose]()</h3>
+		<p>
+			Frees the GPU-related resources allocated by this instance. Call this
+			method whenever this instance is no longer used in your app.
+		</p>
+
+		<h3>[method:this setCustomSort]( [param:Function sortFunction] )</h3>
+		<p>
+			Takes a sort a function that is run before render. The function takes a list of items to sort and a camera. The objects
+			in the list include a "z" field to perform a depth-ordered sort with.
+		</p>
+
+		<h3>
+			[method:Matrix4 getMatrixAt]( [param:Integer index], [param:Matrix4 matrix] )
+		</h3>
+		<p>
+			[page:Integer index]: The index of an instance. Values have to be in the
+			range [0, count].
+		</p>
+		<p>
+			[page:Matrix4 matrix]: This 4x4 matrix will be set to the local
+			transformation matrix of the defined instance.
+		</p>
+		<p>Get the local transformation matrix of the defined instance.</p>
+
+		<h3>
+			[method:Boolean getVisibleAt]( [param:Integer index] )
+		</h3>
+		<p>
+			[page:Integer index]: The index of an instance. Values have to be in the
+			range [0, count].
+		</p>
+		<p>Get whether the given instance is marked as "visible" or not.</p>
+
+		<h3>
+			[method:this setMatrixAt]( [param:Integer index], [param:Matrix4 matrix] )
+		</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 4x4 matrix representing the local transformation
+			of a single instance.
+		</p>
+		<p>
+			Sets the given local transformation matrix to the defined instance.
+		</p>
+
+		<h3>
+			[method:this setVisibleAt]( [param:Integer index], [param:Boolean visible] )
+		</h3>
+		<p>
+			[page:Integer index]: The index of an instance. Values have to be in the
+			range [0, count].
+		</p>
+		<p>
+			[page:Boolean visible]: A boolean value indicating the visibility state.
+		</p>
+		<p>
+			Sets the visibility of the object at the given index.
+		</p>
+
+		<h3>
+			[method:Integer addGeometry]( [param:BufferGeometry geometry], [param:Integer reservedVertexRange], [param:Integer reservedIndexRange] )
+		</h3>
+		<p>
+			[page:BufferGeometry geometry]: The geometry to add into the [name].
+		</p>
+		<p>
+			[page:Integer reservedVertexRange]: Optional parameter specifying the amount of vertex buffer space to reserve for the added geometry. This
+			is necessary if it is planned to set a new geometry at this index at a later time that is larger than the original geometry. Defaults to
+			the length of the given geometry vertex buffer.
+		</p>
+		<p>
+			[page:Integer reservedIndexRange]: Optional parameter specifying the amount of index buffer space to reserve for the added geometry. This
+			is necessary if it is planned to set a new geometry at this index at a later time that is larger than the original geometry. Defaults to
+			the length of the given geometry index buffer.
+		</p>
+		<p>
+			Adds the given geometry to the [name] and returns the associated index referring to it.
+		</p>
+
+		<h3>
+			[method:Integer setGeometryAt]( [param:Integer index], [param:BufferGeometry geometry] )
+		</h3>
+		<p>
+			[page:Integer index]: Which geometry index to replace with this geometry.
+		</p>
+		<p>
+			[page:BufferGeometry geometry]: The geometry to substitute at the given geometry index.
+		</p>
+		<p>
+			Replaces the geometry at `index` with the provided geometry. Throws an error if there is not enough space reserved for geometry at the index.
+		</p>
+
+		<h3>
+			[method:this deleteGeometry]( [param:Integer index] )
+		</h3>
+		<p>
+			Marks the geometry at the given index as deleted and to not be rendered anymore.
+		</p>
+
+		<h2>Source</h2>
+
+		<p>
+			[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
+		</p>
+	</body>
+</html>

+ 0 - 3
docs/api/en/objects/Skeleton.html

@@ -77,9 +77,6 @@
 			The [page:DataTexture] holding the bone data when using a vertex texture.
 			The [page:DataTexture] holding the bone data when using a vertex texture.
 		</p>
 		</p>
 
 
-		<h3>[property:Integer boneTextureSize]</h3>
-		<p>The size of the [page:.boneTexture].</p>
-
 		<h2>Methods</h2>
 		<h2>Methods</h2>
 
 
 		<h3>[method:Skeleton clone]()</h3>
 		<h3>[method:Skeleton clone]()</h3>

+ 8 - 8
docs/api/en/renderers/WebGL3DRenderTarget.html

@@ -16,20 +16,20 @@
 		<h2>Constructor</h2>
 		<h2>Constructor</h2>
 
 
 		<h3>
 		<h3>
-			[name]( [param:Number width], [param:Number height], [param:Number depth] )
+			[name]( [param:Number width], [param:Number height], [param:Number depth], [param:Object options] )
 		</h3>
 		</h3>
 		<p>
 		<p>
-			[page:Number width] - the width of the render target, in pixels. Default
-			is `1`.<br />
-			[page:Number height] - the height of the render target, in pixels. Default
-			is `1`.<br />
-			[page:Number depth] - the depth of the render target. Default is `1`.<br /><br />
+			[page:Number width] - the width of the render target, in pixels. Default is `1`.<br />
+			[page:Number height] - the height of the render target, in pixels. Default is `1`.<br />
+			[page:Number depth] - the depth of the render target. Default is `1`.<br />
+			[page:Object options] - optional object that holds texture parameters for an
+			auto-generated target texture and depthBuffer/stencilBuffer booleans. See [page:WebGLRenderTarget] for details.<br /><br />
 
 
 			Creates a new [name].
 			Creates a new [name].
 		</p>
 		</p>
 
 
 		<h2>Properties</h2>
 		<h2>Properties</h2>
-		<h3>See [page:WebGLRenderTarget] for inherited properties</h3>
+		<p>See [page:WebGLRenderTarget] for inherited properties.</p>
 
 
 		<h3>[property:number depth]</h3>
 		<h3>[property:number depth]</h3>
 		<p>The depth of the render target.</p>
 		<p>The depth of the render target.</p>
@@ -41,7 +41,7 @@
 		</p>
 		</p>
 
 
 		<h2>Methods</h2>
 		<h2>Methods</h2>
-		<h3>See [page:WebGLRenderTarget] for inherited methods</h3>
+		<p>See [page:WebGLRenderTarget] for inherited methods.</p>
 
 
 		<h2>Source</h2>
 		<h2>Source</h2>
 		<p>
 		<p>

+ 8 - 9
docs/api/en/renderers/WebGLArrayRenderTarget.html

@@ -24,22 +24,21 @@
 		<h2>Constructor</h2>
 		<h2>Constructor</h2>
 
 
 		<h3>
 		<h3>
-			[name]( [param:Number width], [param:Number height], [param:Number depth] )
+			[name]( [param:Number width], [param:Number height], [param:Number depth], [param:Object options] )
 		</h3>
 		</h3>
 		<p>
 		<p>
-			[page:Number width] - the width of the render target, in pixels. Default
-			is `1`.<br />
-			[page:Number height] - the height of the render target, in pixels. Default
-			is `1`.<br />
-			[page:Number depth] - the depth/layer count of the render target. Default
-			is `1`.<br /><br />
+			[page:Number width] - the width of the render target, in pixels. Default is `1`.<br />
+			[page:Number height] - the height of the render target, in pixels. Default is `1`.<br />
+			[page:Number depth] - the depth/layer count of the render target. Default is `1`.<br />
+			[page:Object options] - optional object that holds texture parameters for an
+			auto-generated target texture and depthBuffer/stencilBuffer booleans. See [page:WebGLRenderTarget] for details.<br /><br />
 
 
 			Creates a new [name].
 			Creates a new [name].
 		</p>
 		</p>
 
 
 		<h2>Properties</h2>
 		<h2>Properties</h2>
 
 
-		<h3>See [page:WebGLRenderTarget] for inherited properties</h3>
+		<p>See [page:WebGLRenderTarget] for inherited properties.</p>
 
 
 		<h3>[property:number depth]</h3>
 		<h3>[property:number depth]</h3>
 		<p>The depth of the render target.</p>
 		<p>The depth of the render target.</p>
@@ -51,7 +50,7 @@
 		</p>
 		</p>
 
 
 		<h2>Methods</h2>
 		<h2>Methods</h2>
-		<h3>See [page:WebGLRenderTarget] for inherited methods</h3>
+		<p>See [page:WebGLRenderTarget] for inherited methods.</p>
 
 
 		<h2>Source</h2>
 		<h2>Source</h2>
 		<p>
 		<p>

+ 2 - 2
docs/api/en/renderers/WebGLCubeRenderTarget.html

@@ -52,11 +52,11 @@
 
 
 		<h2>Properties</h2>
 		<h2>Properties</h2>
 
 
-		<h3>See [page:WebGLRenderTarget] for inherited properties</h3>
+		<p>See [page:WebGLRenderTarget] for inherited properties.</p>
 
 
 		<h2>Methods</h2>
 		<h2>Methods</h2>
 
 
-		<h3>See [page:WebGLRenderTarget] for inherited methods</h3>
+		<p>See [page:WebGLRenderTarget] for inherited methods.</p>
 
 
 		<h3>
 		<h3>
 			[method:this fromEquirectangularTexture]( [param:WebGLRenderer renderer], [param:Texture texture] )
 			[method:this fromEquirectangularTexture]( [param:WebGLRenderer renderer], [param:Texture texture] )

+ 4 - 1
docs/api/fr/materials/LineDashedMaterial.html

@@ -11,7 +11,10 @@
 
 
 		<h1>[name]</h1>
 		<h1>[name]</h1>
 
 
-		<p class="desc">Un matériau pour dessiner des géométries de style filaire, avec des pointillés.</p>
+		<p class="desc">
+			Un matériau pour dessiner des géométries de style filaire, avec des pointillés.<br />
+			Note: You must call [page:Line.computeLineDistances]() when using [name].
+		</p>
 
 
 		<h2>Exemple de Code</h2>
 		<h2>Exemple de Code</h2>
 
 

+ 1 - 1
docs/api/fr/materials/MeshPhysicalMaterial.html

@@ -212,7 +212,7 @@
 
 
 		La propriété de transmission peut être utilisée pour modéliser ces matériaux.<br />
 		La propriété de transmission peut être utilisée pour modéliser ces matériaux.<br />
 
 
-		Lorsque la transmission est différente de zéro, [page:Material.opacity opacity] doit être défini sur "0".
+		Lorsque la transmission est différente de zéro, [page:Material.opacity opacity] doit être défini sur `1`.
 		</p>
 		</p>
 
 
 		<h3>[property:Texture transmissionMap]</h3>
 		<h3>[property:Texture transmissionMap]</h3>

+ 27 - 2
docs/api/it/core/Object3D.html

@@ -128,6 +128,17 @@
       Invece, le istanze di [page:Object3D], [page:Group] o [page:Bone] non sono renderizzabili e quindi questa callback non viene eseguita su questi oggetti.
       Invece, le istanze di [page:Object3D], [page:Group] o [page:Bone] non sono renderizzabili e quindi questa callback non viene eseguita su questi oggetti.
 		</p>
 		</p>
 
 
+		<h3>[property:Function onAfterShadow]</h3>
+		<p>
+			An optional callback that is executed immediately after a 3D object is rendered to a shadow map. 
+			Questa funzione è chiamata con i seguenti parametri: renderer, scene, camera, shadowCamera, geometry, depthMaterial, group.
+		</p>
+		<p>
+			Si noti che questa funzione di callback viene eseguita per oggi 3D `renderizzabili` (renderable). Ovvero oggetti 3D che definiscono
+			il loro aspetto visivo con geometrie e materiali come istanze di [page:Mesh], [page:Line], [page:Points] o [page:Sprite].
+			Invece, le istanze di [page:Object3D], [page:Group] o [page:Bone] non sono renderizzabili e quindi questa callback non viene eseguita su questi oggetti.
+		</p>
+
 		<h3>[property:Function onBeforeRender]</h3>
 		<h3>[property:Function onBeforeRender]</h3>
 		<p>
 		<p>
       Una callback opzionale che viene eseguita immediatamente prima che un oggetto 3D è stato renderizzato.
       Una callback opzionale che viene eseguita immediatamente prima che un oggetto 3D è stato renderizzato.
@@ -139,6 +150,17 @@
       Invece, le istanze di [page:Object3D], [page:Group] o [page:Bone] non sono renderizzabili e quindi questa callback non viene eseguita su questi oggetti.
       Invece, le istanze di [page:Object3D], [page:Group] o [page:Bone] non sono renderizzabili e quindi questa callback non viene eseguita su questi oggetti.
 		</p>
 		</p>
 
 
+		<h3>[property:Function onBeforeShadow]</h3>
+		<p>
+			An optional callback that is executed immediately before a 3D object is rendered to a shadow map. 
+			Questa funzione è chiamata con i seguenti parametri: renderer, scene, camera, shadowCamera, geometry, depthMaterial, group.
+		</p>
+		<p>
+			Si noti che questa funzione di callback viene eseguita per oggi 3D `renderizzabili` (renderable). Ovvero oggetti 3D che definiscono
+			il loro aspetto visivo con geometrie e materiali come istanze di [page:Mesh], [page:Line], [page:Points] o [page:Sprite].
+			Invece, le istanze di [page:Object3D], [page:Group] o [page:Bone] non sono renderizzabili e quindi questa callback non viene eseguita su questi oggetti.
+		</p>
+
 		<h3>[property:Object3D parent]</h3>
 		<h3>[property:Object3D parent]</h3>
 		<p>Genitore dell'oggetto nel [link:https://en.wikipedia.org/wiki/Scene_graph grafo della scena]. Un oggetto può avere più
 		<p>Genitore dell'oggetto nel [link:https://en.wikipedia.org/wiki/Scene_graph grafo della scena]. Un oggetto può avere più
       di un genitore.</p>
       di un genitore.</p>
@@ -285,10 +307,13 @@
       Cerca in un oggetto e nei suoi figli, partendo dall'oggetto stesso, e restituisce il primo con la proprietà che corrisponde al valore passato.
       Cerca in un oggetto e nei suoi figli, partendo dall'oggetto stesso, e restituisce il primo con la proprietà che corrisponde al valore passato.
 		</p>
 		</p>
 
 
-		<h3>[method:Object3D getObjectsByProperty]( [param:String name], [param:Any value] )</h3>
+		<h3>[method:Object3D getObjectsByProperty]( [param:String name], [param:Any value], [param:Array optionalTarget] )</h3>
 		<p>
 		<p>
 		  name -- il nome della proprietà da cercare. <br />
 		  name -- il nome della proprietà da cercare. <br />
-		  value -- il valore della proprietà data. <br /><br />
+		  value -- il valore della proprietà data. <br />
+		  optionalTarget -- (opzionale) array dove impostare il risultato.
+		  Altrimenti viene istanziato un nuovo Array. 
+		  Se impostato, è necessario cancellare questo array prima di ogni chiamata (ad esempio, array.length = 0;). <br /><br />
 
 
       Cerca in un oggetto e nei suoi figli, partendo dall'oggetto stesso, e restituisce tutti gli oggetti con la proprietà che corrisponde al valore passato.
       Cerca in un oggetto e nei suoi figli, partendo dall'oggetto stesso, e restituisce tutti gli oggetti con la proprietà che corrisponde al valore passato.
 		</p>
 		</p>

+ 2 - 0
docs/api/it/helpers/DirectionalLightHelper.html

@@ -20,6 +20,8 @@
 
 
 		<code>
 		<code>
 		const light = new THREE.DirectionalLight( 0xFFFFFF );
 		const light = new THREE.DirectionalLight( 0xFFFFFF );
+		scene.add( light );
+
 		const helper = new THREE.DirectionalLightHelper( light, 5 );
 		const helper = new THREE.DirectionalLightHelper( light, 5 );
 		scene.add( helper );
 		scene.add( helper );
 		</code>
 		</code>

+ 4 - 1
docs/api/it/materials/LineDashedMaterial.html

@@ -11,7 +11,10 @@
 
 
 		<h1>[name]</h1>
 		<h1>[name]</h1>
 
 
-		<p class="desc">Un materiale per disegnare geometrie in stile wireframe con linee tratteggiate.</p>
+		<p class="desc">
+			Un materiale per disegnare geometrie in stile wireframe con linee tratteggiate.<br />
+			Note: You must call [page:Line.computeLineDistances]() when using [name].
+		</p>
 
 
 		<h2>Codice di Esempio</h2>
 		<h2>Codice di Esempio</h2>
 
 

+ 1 - 1
docs/api/it/materials/MeshPhysicalMaterial.html

@@ -219,7 +219,7 @@
 			riflettenti anche se sono completamente trasmissivi. La proprietà di trasmissione può
 			riflettenti anche se sono completamente trasmissivi. La proprietà di trasmissione può
 			essere utilizzata per modellare questi materiali.<br />
 			essere utilizzata per modellare questi materiali.<br />
 
 
-			Quando la trasmissione è diversa da zero, l'[page:Material.opacity] deve essere impostata a `0`.
+			Quando la trasmissione è diversa da zero, l'[page:Material.opacity] deve essere impostata a `1`.
 		</p>
 		</p>
 
 
 		<h3>[property:Texture transmissionMap]</h3>
 		<h3>[property:Texture transmissionMap]</h3>

+ 67 - 63
docs/api/it/math/Matrix3.html

@@ -81,34 +81,38 @@ m.elements = [ 11, 21, 31,
 		<h3>[method:this extractBasis]( [param:Vector3 xAxis], [param:Vector3 yAxis], [param:Vector3 zAxis] )</h3>
 		<h3>[method:this extractBasis]( [param:Vector3 xAxis], [param:Vector3 yAxis], [param:Vector3 zAxis] )</h3>
 		<p>
 		<p>
 			Estrae la [link:https://en.wikipedia.org/wiki/Basis_(linear_algebra) base] di questa matrice
 			Estrae la [link:https://en.wikipedia.org/wiki/Basis_(linear_algebra) base] di questa matrice
-			nei tre vettori asse forniti. Se questa matrice è:<br /><br />
+			nei tre vettori asse forniti. Se questa matrice è:
+		</p>
 
 
-			<math>
-				<mrow>
-					<mo>[</mo>
-					<mtable>
-						<mtr>
-							<mtd><mi>a</mi></mtd>
-							<mtd><mi>b</mi></mtd>
-							<mtd><mi>c</mi></mtd>
-						</mtr>
-						<mtr>
-							<mtd><mi>d</mi></mtd>
-							<mtd><mi>e</mi></mtd>
-							<mtd><mi>f</mi></mtd>
-						</mtr>
-						<mtr>
-							<mtd><mi>g</mi></mtd>
-							<mtd><mi>h</mi></mtd>
-							<mtd><mi>i</mi></mtd>
-						</mtr>
-					</mtable>
-					<mo>]</mo>
-				</mrow>
-			</math><br /><br />
+		<math display="block">
+			<mrow>
+				<mo>[</mo>
+				<mtable>
+					<mtr>
+						<mtd><mi>a</mi></mtd>
+						<mtd><mi>b</mi></mtd>
+						<mtd><mi>c</mi></mtd>
+					</mtr>
+					<mtr>
+						<mtd><mi>d</mi></mtd>
+						<mtd><mi>e</mi></mtd>
+						<mtd><mi>f</mi></mtd>
+					</mtr>
+					<mtr>
+						<mtd><mi>g</mi></mtd>
+						<mtd><mi>h</mi></mtd>
+						<mtd><mi>i</mi></mtd>
+					</mtr>
+				</mtable>
+				<mo>]</mo>
+			</mrow>
+		</math>
 
 
-			allora [page:Vector3 xAxis], [page:Vector3 yAxis], [page:Vector3 zAxis] saranno impostate a:<br /><br />
+		<p>
+			allora [page:Vector3 xAxis], [page:Vector3 yAxis], [page:Vector3 zAxis] saranno impostate a:
+		</p>
 
 
+		<div style="text-align: center">
 			<math>
 			<math>
 				<mrow>
 				<mrow>
 					<mi>xAxis</mi>
 					<mi>xAxis</mi>
@@ -150,7 +154,7 @@ m.elements = [ 11, 21, 31,
 					<mo>]</mo>
 					<mo>]</mo>
 				</mrow>
 				</mrow>
 			</math>
 			</math>
-		</p>
+		</div>
 
 
 		<h3>[method:this fromArray]( [param:Array array], [param:Integer offset] )</h3>
 		<h3>[method:this fromArray]( [param:Array array], [param:Integer offset] )</h3>
 		<p>
 		<p>
@@ -179,41 +183,42 @@ m.elements = [ 11, 21, 31,
 
 
 		<h3>[method:this identity]()</h3>
 		<h3>[method:this identity]()</h3>
 		<p>
 		<p>
-			Reimposta questa matrice alla matrice identità 3x3:<br /><br />
-
-			<math>
-				<mrow>
-					<mo>[</mo>
-					<mtable>
-						<mtr>
-							<mtd><mn>1</mn></mtd>
-							<mtd><mn>0</mn></mtd>
-							<mtd><mn>0</mn></mtd>
-						</mtr>
-						<mtr>
-							<mtd><mn>0</mn></mtd>
-							<mtd><mn>1</mn></mtd>
-							<mtd><mn>0</mn></mtd>
-						</mtr>
-						<mtr>
-							<mtd><mn>0</mn></mtd>
-							<mtd><mn>0</mn></mtd>
-							<mtd><mn>1</mn></mtd>
-						</mtr>
-					</mtable>
-					<mo>]</mo>
-				</mrow>
-			</math>
+			Reimposta questa matrice alla matrice identità 3x3:
 		</p>
 		</p>
 
 
+		<math display="block">
+			<mrow>
+				<mo>[</mo>
+				<mtable>
+					<mtr>
+						<mtd><mn>1</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+					</mtr>
+					<mtr>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>1</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+					</mtr>
+					<mtr>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>1</mn></mtd>
+					</mtr>
+				</mtable>
+				<mo>]</mo>
+			</mrow>
+		</math>
+
 		<h3>[method:this makeRotation]( [param:Float theta] )</h3>
 		<h3>[method:this makeRotation]( [param:Float theta] )</h3>
 		<p>
 		<p>
 		[page:Float theta] — Angolo di rotazione in radianti. I valori positivi ruotano in senso antiorario.<br /><br />
 		[page:Float theta] — Angolo di rotazione in radianti. I valori positivi ruotano in senso antiorario.<br /><br />
 
 
 		Imposta questa matrice come una trasformazione rotazionale 2D di [page:Float teta] radianti.
 		Imposta questa matrice come una trasformazione rotazionale 2D di [page:Float teta] radianti.
-		La matrice risultante sarà:<br /><br />
+		La matrice risultante sarà:
+		</p>
 
 
-		<math>
+		<math display="block">
 			<mrow>
 			<mrow>
 				<mo>[</mo>
 				<mo>[</mo>
 				<mtable>
 				<mtable>
@@ -252,16 +257,16 @@ m.elements = [ 11, 21, 31,
 				<mo>]</mo>
 				<mo>]</mo>
 			</mrow>
 			</mrow>
 		</math>
 		</math>
-		</p>
 
 
 		<h3>[method:this makeScale]( [param:Float x], [param:Float y] )</h3>
 		<h3>[method:this makeScale]( [param:Float x], [param:Float y] )</h3>
 		<p>
 		<p>
 		[page:Float x] - la quantità da scalare sull'asse X.<br />
 		[page:Float x] - la quantità da scalare sull'asse X.<br />
 		[page:Float y] - la quantità da scalare sull'asse Y.<br />
 		[page:Float y] - la quantità da scalare sull'asse Y.<br />
 
 
-		Imposta questa matrice come una trasformazione di scala 2D:<br /><br />
+		Imposta questa matrice come una trasformazione di scala 2D:
+		</p>
 
 
-		<math>
+		<math display="block">
 			<mrow>
 			<mrow>
 				<mo>[</mo>
 				<mo>[</mo>
 				<mtable>
 				<mtable>
@@ -284,7 +289,6 @@ m.elements = [ 11, 21, 31,
 				<mo>]</mo>
 				<mo>]</mo>
 			</mrow>
 			</mrow>
 		</math>
 		</math>
-		</p>
 
 
 		<h3>[method:this makeTranslation]( [param:Vector2 v] )</h3>
 		<h3>[method:this makeTranslation]( [param:Vector2 v] )</h3>
 		<h3>[method:this makeTranslation]( [param:Float x], [param:Float y] )</h3>
 		<h3>[method:this makeTranslation]( [param:Float x], [param:Float y] )</h3>
@@ -294,9 +298,10 @@ m.elements = [ 11, 21, 31,
 		[page:Float x] - la quantità da translare sull'asse X.<br />
 		[page:Float x] - la quantità da translare sull'asse X.<br />
 		[page:Float y] - la quantità da translare sull'asse Y.<br />
 		[page:Float y] - la quantità da translare sull'asse Y.<br />
 
 
-		Imposta questa matrice come una trasformazione di traslazione 2D:<br /><br />
+		Imposta questa matrice come una trasformazione di traslazione 2D:
+		</p>
 
 
-		<math>
+		<math display="block">
 			<mrow>
 			<mrow>
 				<mo>[</mo>
 				<mo>[</mo>
 				<mtable>
 				<mtable>
@@ -319,7 +324,6 @@ m.elements = [ 11, 21, 31,
 				<mo>]</mo>
 				<mo>]</mo>
 			</mrow>
 			</mrow>
 		</math>
 		</math>
-		</p>
 
 
 		<h3>[method:this multiply]( [param:Matrix3 m] )</h3>
 		<h3>[method:this multiply]( [param:Matrix3 m] )</h3>
 		<p>Post-moltiplica questa matrice per [page:Matrix3 m].</p>
 		<p>Post-moltiplica questa matrice per [page:Matrix3 m].</p>
@@ -339,9 +343,10 @@ m.elements = [ 11, 21, 31,
 		<h3>[method:this set]( [param:Float n11], [param:Float n12], [param:Float n13], [param:Float n21], [param:Float n22], [param:Float n23], [param:Float n31], [param:Float n32], [param:Float n33] )</h3>
 		<h3>[method:this set]( [param:Float n11], [param:Float n12], [param:Float n13], [param:Float n21], [param:Float n22], [param:Float n23], [param:Float n31], [param:Float n32], [param:Float n33] )</h3>
 		<p>
 		<p>
 		Imposta i valori della matrice 3x3 sulla sequenza di valori della
 		Imposta i valori della matrice 3x3 sulla sequenza di valori della
-		[link:https://en.wikipedia.org/wiki/Row-_and_column-major_order row-major] specificata.<br /><br />
+		[link:https://en.wikipedia.org/wiki/Row-_and_column-major_order row-major] specificata.
+		</p>
 
 
-		<math>
+		<math display="block">
 			<mrow>
 			<mrow>
 				<mo>[</mo>
 				<mo>[</mo>
 				<mtable>
 				<mtable>
@@ -364,7 +369,6 @@ m.elements = [ 11, 21, 31,
 				<mo>]</mo>
 				<mo>]</mo>
 			</mrow>
 			</mrow>
 		</math>
 		</math>
-		</p>
 
 
 		<h3>[method:this premultiply]( [param:Matrix3 m] )</h3>
 		<h3>[method:this premultiply]( [param:Matrix3 m] )</h3>
 		<p>Pre-moltiplica questa matrice per [page:Matrix3 m].</p>
 		<p>Pre-moltiplica questa matrice per [page:Matrix3 m].</p>

+ 369 - 365
docs/api/it/math/Matrix4.html

@@ -164,44 +164,48 @@ m.elements = [ 11, 21, 31, 41,
 		<h3>[method:this extractBasis]( [param:Vector3 xAxis], [param:Vector3 yAxis], [param:Vector3 zAxis] )</h3>
 		<h3>[method:this extractBasis]( [param:Vector3 xAxis], [param:Vector3 yAxis], [param:Vector3 zAxis] )</h3>
 		<p>
 		<p>
 			Estrae la [link:https://en.wikipedia.org/wiki/Basis_(linear_algebra) base] di questa matrice
 			Estrae la [link:https://en.wikipedia.org/wiki/Basis_(linear_algebra) base] di questa matrice
-			nei tre vettori asse forniti. Se questa matrice è:<br /><br />
+			nei tre vettori asse forniti. Se questa matrice è:
+		</p>
 
 
-			<math>
-				<mrow>
-					<mo>[</mo>
-					<mtable>
-						<mtr>
-							<mtd><mi>a</mi></mtd>
-							<mtd><mi>b</mi></mtd>
-							<mtd><mi>c</mi></mtd>
-							<mtd><mi>d</mi></mtd>
-						</mtr>
-						<mtr>
-							<mtd><mi>e</mi></mtd>
-							<mtd><mi>f</mi></mtd>
-							<mtd><mi>g</mi></mtd>
-							<mtd><mi>h</mi></mtd>
-						</mtr>
-						<mtr>
-							<mtd><mi>i</mi></mtd>
-							<mtd><mi>j</mi></mtd>
-							<mtd><mi>k</mi></mtd>
-							<mtd><mi>l</mi></mtd>
-						</mtr>
-						<mtr>
-							<mtd><mi>m</mi></mtd>
-							<mtd><mi>n</mi></mtd>
-							<mtd><mi>o</mi></mtd>
-							<mtd><mi>p</mi></mtd>
-						</mtr>
-					</mtable>
-					<mo>]</mo>
-				</mrow>
-			</math><br /><br />
+		<math display="block">
+			<mrow>
+				<mo>[</mo>
+				<mtable>
+					<mtr>
+						<mtd><mi>a</mi></mtd>
+						<mtd><mi>b</mi></mtd>
+						<mtd><mi>c</mi></mtd>
+						<mtd><mi>d</mi></mtd>
+					</mtr>
+					<mtr>
+						<mtd><mi>e</mi></mtd>
+						<mtd><mi>f</mi></mtd>
+						<mtd><mi>g</mi></mtd>
+						<mtd><mi>h</mi></mtd>
+					</mtr>
+					<mtr>
+						<mtd><mi>i</mi></mtd>
+						<mtd><mi>j</mi></mtd>
+						<mtd><mi>k</mi></mtd>
+						<mtd><mi>l</mi></mtd>
+					</mtr>
+					<mtr>
+						<mtd><mi>m</mi></mtd>
+						<mtd><mi>n</mi></mtd>
+						<mtd><mi>o</mi></mtd>
+						<mtd><mi>p</mi></mtd>
+					</mtr>
+				</mtable>
+				<mo>]</mo>
+			</mrow>
+		</math>
 
 
+		<p>
 			then the [page:Vector3 xAxis], [page:Vector3 yAxis], [page:Vector3 zAxis]
 			then the [page:Vector3 xAxis], [page:Vector3 yAxis], [page:Vector3 zAxis]
-			will be set to:<br /><br />
+			will be set to:
+		</p>
 
 
+		<div style="text-align: center">
 			<math>
 			<math>
 				<mrow>
 				<mrow>
 					<mi>xAxis</mi>
 					<mi>xAxis</mi>
@@ -243,7 +247,7 @@ m.elements = [ 11, 21, 31, 41,
 					<mo>]</mo>
 					<mo>]</mo>
 				</mrow>
 				</mrow>
 			</math>
 			</math>
-		</p>
+		</div>
 
 
 		<h3>[method:this extractRotation]( [param:Matrix4 m] )</h3>
 		<h3>[method:this extractRotation]( [param:Matrix4 m] )</h3>
 		<p>
 		<p>
@@ -292,42 +296,42 @@ m.elements = [ 11, 21, 31, 41,
 		<h3>[method:this makeBasis]( [param:Vector3 xAxis], [param:Vector3 yAxis], [param:Vector3 zAxis] )</h3>
 		<h3>[method:this makeBasis]( [param:Vector3 xAxis], [param:Vector3 yAxis], [param:Vector3 zAxis] )</h3>
 		<p>
 		<p>
 			Imposta questo sulla matrice di [link:https://en.wikipedia.org/wiki/Basis_(linear_algebra) base] composta dai tre
 			Imposta questo sulla matrice di [link:https://en.wikipedia.org/wiki/Basis_(linear_algebra) base] composta dai tre
-			vettori di base forniti:<br /><br />
-
-			<math>
-				<mrow>
-					<mo>[</mo>
-					<mtable>
-						<mtr>
-							<mtd><mi>xAxis.x</mi></mtd>
-							<mtd><mi>yAxis.x</mi></mtd>
-							<mtd><mi>zAxis.x</mi></mtd>
-							<mtd><mn>0</mn></mtd>
-						</mtr>
-						<mtr>
-							<mtd><mi>xAxis.y</mi></mtd>
-							<mtd><mi>yAxis.y</mi></mtd>
-							<mtd><mi>zAxis.y</mi></mtd>
-							<mtd><mn>0</mn></mtd>
-						</mtr>
-						<mtr>
-							<mtd><mi>xAxis.z</mi></mtd>
-							<mtd><mi>yAxis.z</mi></mtd>
-							<mtd><mi>zAxis.z</mi></mtd>
-							<mtd><mn>0</mn></mtd>
-						</mtr>
-						<mtr>
-							<mtd><mn>0</mn></mtd>
-							<mtd><mn>0</mn></mtd>
-							<mtd><mn>0</mn></mtd>
-							<mtd><mn>1</mn></mtd>
-						</mtr>
-					</mtable>
-					<mo>]</mo>
-				</mrow>
-			</math>
+			vettori di base forniti:
 		</p>
 		</p>
 
 
+		<math display="block">
+			<mrow>
+				<mo>[</mo>
+				<mtable>
+					<mtr>
+						<mtd><mi>xAxis.x</mi></mtd>
+						<mtd><mi>yAxis.x</mi></mtd>
+						<mtd><mi>zAxis.x</mi></mtd>
+						<mtd><mn>0</mn></mtd>
+					</mtr>
+					<mtr>
+						<mtd><mi>xAxis.y</mi></mtd>
+						<mtd><mi>yAxis.y</mi></mtd>
+						<mtd><mi>zAxis.y</mi></mtd>
+						<mtd><mn>0</mn></mtd>
+					</mtr>
+					<mtr>
+						<mtd><mi>xAxis.z</mi></mtd>
+						<mtd><mi>yAxis.z</mi></mtd>
+						<mtd><mi>zAxis.z</mi></mtd>
+						<mtd><mn>0</mn></mtd>
+					</mtr>
+					<mtr>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>1</mn></mtd>
+					</mtr>
+				</mtable>
+				<mo>]</mo>
+			</mrow>
+		</math>
+
 		<h3>[method:this makePerspective]( [param:Float left], [param:Float right], [param:Float top], [param:Float bottom], [param:Float near], [param:Float far] )</h3>
 		<h3>[method:this makePerspective]( [param:Float left], [param:Float right], [param:Float top], [param:Float bottom], [param:Float near], [param:Float far] )</h3>
 		<p>
 		<p>
 			Crea una matrice di [link:https://en.wikipedia.org/wiki/3D_projection#Perspective_projection proiezione prospettica].
 			Crea una matrice di [link:https://en.wikipedia.org/wiki/3D_projection#Perspective_projection proiezione prospettica].
@@ -351,146 +355,147 @@ m.elements = [ 11, 21, 31, 41,
 		<p>
 		<p>
 			Imposta il componente rotazinoe di questa matrice alla rotazione specificata da [page:Quaternion q], come 
 			Imposta il componente rotazinoe di questa matrice alla rotazione specificata da [page:Quaternion q], come 
 			descritto [link:https://en.wikipedia.org/wiki/Rotation_matrix#Quaternion qui].
 			descritto [link:https://en.wikipedia.org/wiki/Rotation_matrix#Quaternion qui].
-			Il resto della matrice è impostato all'identità. Quindi, dato [page:Quaternion q] = w + xi + yj + zk, la matrice risultante sarà:<br /><br />
+			Il resto della matrice è impostato all'identità. Quindi, dato [page:Quaternion q] = w + xi + yj + zk, la matrice risultante sarà:
+		</p>
 
 
-			<math>
-				<mrow>
-					<mo>[</mo>
-					<mtable>
-						<mtr>
-							<mtd>
-								<mn>1</mn>
-								<mo>-</mo>
-								<mn>2</mn>
-								<msup>
-									<mi>y</mi>
-									<mn>2</mn>
-								</msup>
-								<mo>-</mo>
-								<mn>2</mn>
-								<msup>
-									<mi>z</mi>
-									<mn>2</mn>
-								</msup>
-							</mtd>
-							<mtd>
-								<mn>2</mn>
-								<mi>x</mi>
+		<math display="block">
+			<mrow>
+				<mo>[</mo>
+				<mtable>
+					<mtr>
+						<mtd>
+							<mn>1</mn>
+							<mo>-</mo>
+							<mn>2</mn>
+							<msup>
 								<mi>y</mi>
 								<mi>y</mi>
-								<mo>-</mo>
 								<mn>2</mn>
 								<mn>2</mn>
+							</msup>
+							<mo>-</mo>
+							<mn>2</mn>
+							<msup>
 								<mi>z</mi>
 								<mi>z</mi>
-								<mi>w</mi>
-							</mtd>
-							<mtd>
-								<mn>2</mn>
-								<mi>x</mi>
-								<mi>z</mi>
-								<mo>+</mo>
-								<mn>2</mn>
-								<mi>y</mi>
-								<mi>w</mi>
-							</mtd>
-							<mtd>
-								<mn>0</mn>
-							</mtd>
-						</mtr>
-						<mtr>
-							<mtd>
 								<mn>2</mn>
 								<mn>2</mn>
+							</msup>
+						</mtd>
+						<mtd>
+							<mn>2</mn>
+							<mi>x</mi>
+							<mi>y</mi>
+							<mo>-</mo>
+							<mn>2</mn>
+							<mi>z</mi>
+							<mi>w</mi>
+						</mtd>
+						<mtd>
+							<mn>2</mn>
+							<mi>x</mi>
+							<mi>z</mi>
+							<mo>+</mo>
+							<mn>2</mn>
+							<mi>y</mi>
+							<mi>w</mi>
+						</mtd>
+						<mtd>
+							<mn>0</mn>
+						</mtd>
+					</mtr>
+					<mtr>
+						<mtd>
+							<mn>2</mn>
+							<mi>x</mi>
+							<mi>y</mi>
+							<mo>+</mo>
+							<mn>2</mn>
+							<mi>z</mi>
+							<mi>w</mi>
+						</mtd>
+						<mtd>
+							<mn>1</mn>
+							<mo>-</mo>
+							<mn>2</mn>
+							<msup>
 								<mi>x</mi>
 								<mi>x</mi>
-								<mi>y</mi>
-								<mo>+</mo>
-								<mn>2</mn>
-								<mi>z</mi>
-								<mi>w</mi>
-							</mtd>
-							<mtd>
-								<mn>1</mn>
-								<mo>-</mo>
-								<mn>2</mn>
-								<msup>
-									<mi>x</mi>
-									<mn>2</mn>
-								</msup>
-								<mo>-</mo>
 								<mn>2</mn>
 								<mn>2</mn>
-								<msup>
-									<mi>z</mi>
-									<mn>2</mn>
-								</msup>
-							</mtd>
-							<mtd>
-								<mn>2</mn>
-								<mi>y</mi>
+							</msup>
+							<mo>-</mo>
+							<mn>2</mn>
+							<msup>
 								<mi>z</mi>
 								<mi>z</mi>
-								<mo>-</mo>
-								<mn>2</mn>
-								<mi>x</mi>
-								<mi>w</mi>
-							</mtd>
-							<mtd>
-								<mn>0</mn>
-							</mtd>
-						</mtr>
-						<mtr>
-							<mtd>
 								<mn>2</mn>
 								<mn>2</mn>
+							</msup>
+						</mtd>
+						<mtd>
+							<mn>2</mn>
+							<mi>y</mi>
+							<mi>z</mi>
+							<mo>-</mo>
+							<mn>2</mn>
+							<mi>x</mi>
+							<mi>w</mi>
+						</mtd>
+						<mtd>
+							<mn>0</mn>
+						</mtd>
+					</mtr>
+					<mtr>
+						<mtd>
+							<mn>2</mn>
+							<mi>x</mi>
+							<mi>z</mi>
+							<mo>-</mo>
+							<mn>2</mn>
+							<mi>y</mi>
+							<mi>w</mi>
+						</mtd>
+						<mtd>
+							<mn>2</mn>
+							<mi>y</mi>
+							<mi>z</mi>
+							<mo>+</mo>
+							<mn>2</mn>
+							<mi>x</mi>
+							<mi>w</mi>
+						</mtd>
+						<mtd>
+							<mn>1</mn>
+							<mo>-</mo>
+							<mn>2</mn>
+							<msup>
 								<mi>x</mi>
 								<mi>x</mi>
-								<mi>z</mi>
-								<mo>-</mo>
-								<mn>2</mn>
-								<mi>y</mi>
-								<mi>w</mi>
-							</mtd>
-							<mtd>
 								<mn>2</mn>
 								<mn>2</mn>
+							</msup>
+							<mo>-</mo>
+							<mn>2</mn>
+							<msup>
 								<mi>y</mi>
 								<mi>y</mi>
-								<mi>z</mi>
-								<mo>+</mo>
-								<mn>2</mn>
-								<mi>x</mi>
-								<mi>w</mi>
-							</mtd>
-							<mtd>
-								<mn>1</mn>
-								<mo>-</mo>
-								<mn>2</mn>
-								<msup>
-									<mi>x</mi>
-									<mn>2</mn>
-								</msup>
-								<mo>-</mo>
 								<mn>2</mn>
 								<mn>2</mn>
-								<msup>
-									<mi>y</mi>
-									<mn>2</mn>
-								</msup>
-							</mtd>
-							<mtd>
-								<mn>0</mn>
-							</mtd>
-						</mtr>
-						<mtr>
-							<mtd><mn>0</mn></mtd>
-							<mtd><mn>0</mn></mtd>
-							<mtd><mn>0</mn></mtd>
-							<mtd><mn>1</mn></mtd>
-						</mtr>
-					</mtable>
-					<mo>]</mo>
-				</mrow>
-			</math>
-		</p>
+							</msup>
+						</mtd>
+						<mtd>
+							<mn>0</mn>
+						</mtd>
+					</mtr>
+					<mtr>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>1</mn></mtd>
+					</mtr>
+				</mtable>
+				<mo>]</mo>
+			</mrow>
+		</math>
 
 
 		<h3>[method:this makeRotationX]( [param:Float theta] )</h3>
 		<h3>[method:this makeRotationX]( [param:Float theta] )</h3>
 		<p>
 		<p>
 		[page:Float theta] — Angolo rotazione in radianti.<br /><br />
 		[page:Float theta] — Angolo rotazione in radianti.<br /><br />
 
 
 		Imposta questa matrice come una trasformazione rotazionale attorno all'asse X in radianti theta [page:Float theta] (&theta;).
 		Imposta questa matrice come una trasformazione rotazionale attorno all'asse X in radianti theta [page:Float theta] (&theta;).
-		La matrice risultante sarà:<br /><br />
+		La matrice risultante sarà:
+		</p>
 
 
-		<math>
+		<math display="block">
 			<mrow>
 			<mrow>
 				<mo>[</mo>
 				<mo>[</mo>
 				<mtable>
 				<mtable>
@@ -543,16 +548,16 @@ m.elements = [ 11, 21, 31, 41,
 				<mo>]</mo>
 				<mo>]</mo>
 			</mrow>
 			</mrow>
 		</math>
 		</math>
-		</p>
 
 
 		<h3>[method:this makeRotationY]( [param:Float theta] )</h3>
 		<h3>[method:this makeRotationY]( [param:Float theta] )</h3>
 		<p>
 		<p>
 		[page:Float theta] — Angolo rotazione in radianti.<br /><br />
 		[page:Float theta] — Angolo rotazione in radianti.<br /><br />
 
 
 		Imposta questa matrice come una trasformazione rotazionale attorno all'asse Y in radianti theta [page:Float theta] (&theta;).
 		Imposta questa matrice come una trasformazione rotazionale attorno all'asse Y in radianti theta [page:Float theta] (&theta;).
-		La matrice risultante sarà:<br /><br />
+		La matrice risultante sarà:
+		</p>
 
 
-		<math>
+		<math display="block">
 			<mrow>
 			<mrow>
 				<mo>[</mo>
 				<mo>[</mo>
 				<mtable>
 				<mtable>
@@ -605,16 +610,16 @@ m.elements = [ 11, 21, 31, 41,
 				<mo>]</mo>
 				<mo>]</mo>
 			</mrow>
 			</mrow>
 		</math>
 		</math>
-		</p>
 
 
 		<h3>[method:this makeRotationZ]( [param:Float theta] )</h3>
 		<h3>[method:this makeRotationZ]( [param:Float theta] )</h3>
 		<p>
 		<p>
 		[page:Float theta] — Angolo rotazione in radianti.<br /><br />
 		[page:Float theta] — Angolo rotazione in radianti.<br /><br />
 
 
 		Imposta questa matrice come una trasformazione rotazionale attorno all'asse Z in radianti theta [page:Float theta] (&theta;).
 		Imposta questa matrice come una trasformazione rotazionale attorno all'asse Z in radianti theta [page:Float theta] (&theta;).
-		La matrice risultante sarà:<br /><br />
+		La matrice risultante sarà:
+		</p>
 			
 			
-		<math>
+		<math display="block">
 			<mrow>
 			<mrow>
 				<mo>[</mo>
 				<mo>[</mo>
 				<mtable>
 				<mtable>
@@ -667,7 +672,6 @@ m.elements = [ 11, 21, 31, 41,
 				<mo>]</mo>
 				<mo>]</mo>
 			</mrow>
 			</mrow>
 		</math>
 		</math>
-		</p>
 
 
 		<h3>[method:this makeScale]( [param:Float x], [param:Float y], [param:Float z] )</h3>
 		<h3>[method:this makeScale]( [param:Float x], [param:Float y], [param:Float z] )</h3>
 		<p>
 		<p>
@@ -675,42 +679,42 @@ m.elements = [ 11, 21, 31, 41,
 			[page:Float y] - la quantità da scalare sull'asse Y.<br />
 			[page:Float y] - la quantità da scalare sull'asse Y.<br />
 			[page:Float z] - la quantità da scalare sull'asse Z.<br /><br />
 			[page:Float z] - la quantità da scalare sull'asse Z.<br /><br />
 
 
-			Imposta questa matrice come trasformazione di scala:<br /><br />
-
-			<math>
-				<mrow>
-					<mo>[</mo>
-					<mtable>
-						<mtr>
-							<mtd><mi>x</mi></mtd>
-							<mtd><mn>0</mn></mtd>
-							<mtd><mn>0</mn></mtd>
-							<mtd><mn>0</mn></mtd>
-						</mtr>
-						<mtr>
-							<mtd><mn>0</mn></mtd>
-							<mtd><mi>y</mi></mtd>
-							<mtd><mn>0</mn></mtd>
-							<mtd><mn>0</mn></mtd>
-						</mtr>
-						<mtr>
-							<mtd><mn>0</mn></mtd>
-							<mtd><mn>0</mn></mtd>
-							<mtd><mi>z</mi></mtd>
-							<mtd><mn>0</mn></mtd>
-						</mtr>
-						<mtr>
-							<mtd><mn>0</mn></mtd>
-							<mtd><mn>0</mn></mtd>
-							<mtd><mn>0</mn></mtd>
-							<mtd><mn>1</mn></mtd>
-						</mtr>
-					</mtable>
-					<mo>]</mo>
-				</mrow>
-			</math>
+			Imposta questa matrice come trasformazione di scala:
 		</p>
 		</p>
 
 
+		<math display="block">
+			<mrow>
+				<mo>[</mo>
+				<mtable>
+					<mtr>
+						<mtd><mi>x</mi></mtd>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+					</mtr>
+					<mtr>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mi>y</mi></mtd>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+					</mtr>
+					<mtr>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mi>z</mi></mtd>
+						<mtd><mn>0</mn></mtd>
+					</mtr>
+					<mtr>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>1</mn></mtd>
+					</mtr>
+				</mtable>
+				<mo>]</mo>
+			</mrow>
+		</math>
+
 		<h3>[method:this makeShear]( [param:Float xy], [param:Float xz], [param:Float yx], [param:Float yz], [param:Float zx], [param:Float zy] )</h3>
 		<h3>[method:this makeShear]( [param:Float xy], [param:Float xz], [param:Float yx], [param:Float yz], [param:Float zx], [param:Float zy] )</h3>
 		<p>
 		<p>
 			[page:Float xy] - la quantità di taglio di X per Y.<br />
 			[page:Float xy] - la quantità di taglio di X per Y.<br />
@@ -720,83 +724,83 @@ m.elements = [ 11, 21, 31, 41,
 			[page:Float zx] - la quantità di taglio di Z per X.<br />
 			[page:Float zx] - la quantità di taglio di Z per X.<br />
 			[page:Float zy] - la quantità di taglio di Z per Y.<br /><br />
 			[page:Float zy] - la quantità di taglio di Z per Y.<br /><br />
 
 
-			Imposta questa matrice come trasformata di taglio:<br /><br />
-
-			<math>
-				<mrow>
-					<mo>[</mo>
-					<mtable>
-						<mtr>
-							<mtd><mn>1</mn></mtd>
-							<mtd><mi>y</mi><mi>x</mi></mtd>
-							<mtd><mi>z</mi><mi>x</mi></mtd>
-							<mtd><mn>0</mn></mtd>
-						</mtr>
-						<mtr>
-							<mtd><mi>x</mi><mi>y</mi></mtd>
-							<mtd><mn>1</mn></mtd>
-							<mtd><mi>z</mi><mi>y</mi></mtd>
-							<mtd><mn>0</mn></mtd>
-						</mtr>
-						<mtr>
-							<mtd><mi>x</mi><mi>z</mi></mtd>
-							<mtd><mi>y</mi><mi>z</mi></mtd>
-							<mtd><mn>1</mn></mtd>
-							<mtd><mn>0</mn></mtd>
-						</mtr>
-						<mtr>
-							<mtd><mn>0</mn></mtd>
-							<mtd><mn>0</mn></mtd>
-							<mtd><mn>0</mn></mtd>
-							<mtd><mn>1</mn></mtd>
-						</mtr>
-					</mtable>
-					<mo>]</mo>
-				</mrow>
-			</math>
+			Imposta questa matrice come trasformata di taglio:
 		</p>
 		</p>
 
 
+		<math display="block">
+			<mrow>
+				<mo>[</mo>
+				<mtable>
+					<mtr>
+						<mtd><mn>1</mn></mtd>
+						<mtd><mi>y</mi><mi>x</mi></mtd>
+						<mtd><mi>z</mi><mi>x</mi></mtd>
+						<mtd><mn>0</mn></mtd>
+					</mtr>
+					<mtr>
+						<mtd><mi>x</mi><mi>y</mi></mtd>
+						<mtd><mn>1</mn></mtd>
+						<mtd><mi>z</mi><mi>y</mi></mtd>
+						<mtd><mn>0</mn></mtd>
+					</mtr>
+					<mtr>
+						<mtd><mi>x</mi><mi>z</mi></mtd>
+						<mtd><mi>y</mi><mi>z</mi></mtd>
+						<mtd><mn>1</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+					</mtr>
+					<mtr>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>1</mn></mtd>
+					</mtr>
+				</mtable>
+				<mo>]</mo>
+			</mrow>
+		</math>
+
 		<h3>[method:this makeTranslation]( [param:Vector3 v] )</h3>
 		<h3>[method:this makeTranslation]( [param:Vector3 v] )</h3>
 		<h3>
 		<h3>
 			[method:this makeTranslation]( [param:Float x], [param:Float y], [param:Float z] ) // optional API
 			[method:this makeTranslation]( [param:Float x], [param:Float y], [param:Float z] ) // optional API
 		</h3>
 		</h3>
 		<p>
 		<p>
-			Imposta questa matrice come una trasformata di traslazione dal vettore [page:Vector3 v]:<br /><br />
-
-			<math>
-				<mrow>
-					<mo>[</mo>
-					<mtable>
-						<mtr>
-							<mtd><mn>1</mn></mtd>
-							<mtd><mn>0</mn></mtd>
-							<mtd><mn>0</mn></mtd>
-							<mtd><mi>x</mi></mtd>
-						</mtr>
-						<mtr>
-							<mtd><mn>0</mn></mtd>
-							<mtd><mn>1</mn></mtd>
-							<mtd><mn>0</mn></mtd>
-							<mtd><mi>y</mi></mtd>
-						</mtr>
-						<mtr>
-							<mtd><mn>0</mn></mtd>
-							<mtd><mn>0</mn></mtd>
-							<mtd><mn>1</mn></mtd>
-							<mtd><mi>z</mi></mtd>
-						</mtr>
-						<mtr>
-							<mtd><mn>0</mn></mtd>
-							<mtd><mn>0</mn></mtd>
-							<mtd><mn>0</mn></mtd>
-							<mtd><mn>1</mn></mtd>
-						</mtr>
-					</mtable>
-					<mo>]</mo>
-				</mrow>
-			</math>
+			Imposta questa matrice come una trasformata di traslazione dal vettore [page:Vector3 v]:
 		</p>
 		</p>
 
 
+		<math display="block">
+			<mrow>
+				<mo>[</mo>
+				<mtable>
+					<mtr>
+						<mtd><mn>1</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mi>x</mi></mtd>
+					</mtr>
+					<mtr>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>1</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mi>y</mi></mtd>
+					</mtr>
+					<mtr>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>1</mn></mtd>
+						<mtd><mi>z</mi></mtd>
+					</mtr>
+					<mtr>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>1</mn></mtd>
+					</mtr>
+				</mtable>
+				<mo>]</mo>
+			</mrow>
+		</math>
+
 		<h3>[method:this multiply]( [param:Matrix4 m] )</h3>
 		<h3>[method:this multiply]( [param:Matrix4 m] )</h3>
 		<p>Post-moltiplica questa matrice per [page:Matrix4 m].</p>
 		<p>Post-moltiplica questa matrice per [page:Matrix4 m].</p>
 
 
@@ -825,76 +829,76 @@ m.elements = [ 11, 21, 31, 41,
 		<h3>[method:this setPosition]( [param:Float x], [param:Float y], [param:Float z] ) // optional API</h3>
 		<h3>[method:this setPosition]( [param:Float x], [param:Float y], [param:Float z] ) // optional API</h3>
 		<p>
 		<p>
 			Imposta la componente posizione per questa matrice dal vettore [page:Vector3 v], senza influenzare 
 			Imposta la componente posizione per questa matrice dal vettore [page:Vector3 v], senza influenzare 
-			il resto della matrice - ovvero se la matrice è attulmente:<br /><br />
+			il resto della matrice - ovvero se la matrice è attulmente:
+		</p>
 
 
-			<math>
-				<mrow>
-					<mo>[</mo>
-					<mtable>
-						<mtr>
-							<mtd><mi>a</mi></mtd>
-							<mtd><mi>b</mi></mtd>
-							<mtd><mi>c</mi></mtd>
-							<mtd><mi>d</mi></mtd>
-						</mtr>
-						<mtr>
-							<mtd><mi>e</mi></mtd>
-							<mtd><mi>f</mi></mtd>
-							<mtd><mi>g</mi></mtd>
-							<mtd><mi>h</mi></mtd>
-						</mtr>
-						<mtr>
-							<mtd><mi>i</mi></mtd>
-							<mtd><mi>j</mi></mtd>
-							<mtd><mi>k</mi></mtd>
-							<mtd><mi>l</mi></mtd>
-						</mtr>
-						<mtr>
-							<mtd><mi>m</mi></mtd>
-							<mtd><mi>n</mi></mtd>
-							<mtd><mi>o</mi></mtd>
-							<mtd><mi>p</mi></mtd>
-						</mtr>
-					</mtable>
-					<mo>]</mo>
-				</mrow>
-			</math><br /><br />
+		<math display="block">
+			<mrow>
+				<mo>[</mo>
+				<mtable>
+					<mtr>
+						<mtd><mi>a</mi></mtd>
+						<mtd><mi>b</mi></mtd>
+						<mtd><mi>c</mi></mtd>
+						<mtd><mi>d</mi></mtd>
+					</mtr>
+					<mtr>
+						<mtd><mi>e</mi></mtd>
+						<mtd><mi>f</mi></mtd>
+						<mtd><mi>g</mi></mtd>
+						<mtd><mi>h</mi></mtd>
+					</mtr>
+					<mtr>
+						<mtd><mi>i</mi></mtd>
+						<mtd><mi>j</mi></mtd>
+						<mtd><mi>k</mi></mtd>
+						<mtd><mi>l</mi></mtd>
+					</mtr>
+					<mtr>
+						<mtd><mi>m</mi></mtd>
+						<mtd><mi>n</mi></mtd>
+						<mtd><mi>o</mi></mtd>
+						<mtd><mi>p</mi></mtd>
+					</mtr>
+				</mtable>
+				<mo>]</mo>
+			</mrow>
+		</math>
 
 
-			Questa diventa:<br /><br />
+		<p>Questa diventa:</p>
 
 
-			<math>
-				<mrow>
-					<mo>[</mo>
-					<mtable>
-						<mtr>
-							<mtd><mi>a</mi></mtd>
-							<mtd><mi>b</mi></mtd>
-							<mtd><mi>c</mi></mtd>
-							<mtd><mi>v.x</mi></mtd>
-						</mtr>
-						<mtr>
-							<mtd><mi>e</mi></mtd>
-							<mtd><mi>f</mi></mtd>
-							<mtd><mi>g</mi></mtd>
-							<mtd><mi>v.y</mi></mtd>
-						</mtr>
-						<mtr>
-							<mtd><mi>i</mi></mtd>
-							<mtd><mi>j</mi></mtd>
-							<mtd><mi>k</mi></mtd>
-							<mtd><mi>v.z</mi></mtd>
-						</mtr>
-						<mtr>
-							<mtd><mi>m</mi></mtd>
-							<mtd><mi>n</mi></mtd>
-							<mtd><mi>o</mi></mtd>
-							<mtd><mi>p</mi></mtd>
-						</mtr>
-					</mtable>
-					<mo>]</mo>
-				</mrow>
-			</math>
-		</p>
+		<math display="block">
+			<mrow>
+				<mo>[</mo>
+				<mtable>
+					<mtr>
+						<mtd><mi>a</mi></mtd>
+						<mtd><mi>b</mi></mtd>
+						<mtd><mi>c</mi></mtd>
+						<mtd><mi>v.x</mi></mtd>
+					</mtr>
+					<mtr>
+						<mtd><mi>e</mi></mtd>
+						<mtd><mi>f</mi></mtd>
+						<mtd><mi>g</mi></mtd>
+						<mtd><mi>v.y</mi></mtd>
+					</mtr>
+					<mtr>
+						<mtd><mi>i</mi></mtd>
+						<mtd><mi>j</mi></mtd>
+						<mtd><mi>k</mi></mtd>
+						<mtd><mi>v.z</mi></mtd>
+					</mtr>
+					<mtr>
+						<mtd><mi>m</mi></mtd>
+						<mtd><mi>n</mi></mtd>
+						<mtd><mi>o</mi></mtd>
+						<mtd><mi>p</mi></mtd>
+					</mtr>
+				</mtable>
+				<mo>]</mo>
+			</mrow>
+		</math>
 
 
 		<h3>[method:Array toArray]( [param:Array array], [param:Integer offset] )</h3>
 		<h3>[method:Array toArray]( [param:Array array], [param:Integer offset] )</h3>
 		<p>
 		<p>

+ 0 - 5
docs/api/it/objects/Skeleton.html

@@ -79,11 +79,6 @@
 			Il [page:DataTexture] che contiene i dati dell'osso quando si utilizza una texture di vertice.
 			Il [page:DataTexture] che contiene i dati dell'osso quando si utilizza una texture di vertice.
 		</p>
 		</p>
 
 
-		<h3>[property:Integer boneTextureSize]</h3>
-		<p>
-			La dimensione del [page:.boneTexture].
-		</p>
-
 		<h2>Metodi</h2>
 		<h2>Metodi</h2>
 
 
 		<h3>[method:Skeleton clone]()</h3>
 		<h3>[method:Skeleton clone]()</h3>

+ 6 - 4
docs/api/it/renderers/WebGL3DRenderTarget.html

@@ -17,18 +17,20 @@
 
 
 		<h2>Costruttore</h2>
 		<h2>Costruttore</h2>
 
 
-		<h3>[name]( [param:Number width], [param:Number height], [param:Number depth] )</h3>
+		<h3>[name]( [param:Number width], [param:Number height], [param:Number depth], [param:Object options] )</h3>
 		<p>
 		<p>
 		[page:Number width] - la lunghezza del render target, in pixel. Il valore predefinito è `1`.<br />
 		[page:Number width] - la lunghezza del render target, in pixel. Il valore predefinito è `1`.<br />
 		[page:Number height] - l'altezza del render target, in pixel. Il valore predefinito è `1`.<br />
 		[page:Number height] - l'altezza del render target, in pixel. Il valore predefinito è `1`.<br />
-		[page:Number depth] - la profondità del render target. Il valore predefinito è `1`.<br /><br />
+		[page:Number depth] - la profondità del render target. Il valore predefinito è `1`.<br />
+		[page:Object options] - (opzionale) oggetto che contiene i parametri della texture per un target texture auto generato 
+		e i booleani depthBuffer/stencilBuffer. See [page:WebGLRenderTarget] for details.<br /><br />
 
 
 		Crea un nuovo [name].
 		Crea un nuovo [name].
 		</p>
 		</p>
 
 
 		<h2>Proprietà</h2>
 		<h2>Proprietà</h2>
 
 
-		<h3>Vedi [page:WebGLRenderTarget] per le proprietà ereditate</h3>
+		<p>Vedi [page:WebGLRenderTarget] per le proprietà ereditate.</p>
 
 
 		<h3>[property:number depth]</h3>
 		<h3>[property:number depth]</h3>
 		<p>
 		<p>
@@ -42,7 +44,7 @@
 
 
 		<h2>Metodi</h2>
 		<h2>Metodi</h2>
 
 
-		<h3>Vedi [page:WebGLRenderTarget] per i metodi ereditati</h3>
+		<p>Vedi [page:WebGLRenderTarget] per i metodi ereditati.</p>
 
 
 		<h2>Source</h2>
 		<h2>Source</h2>
 
 

+ 6 - 4
docs/api/it/renderers/WebGLArrayRenderTarget.html

@@ -23,18 +23,20 @@
 
 
 		<h2>Costruttore</h2>
 		<h2>Costruttore</h2>
 
 
-		<h3>[name]( [param:Number width], [param:Number height], [param:Number depth] )</h3>
+		<h3>[name]( [param:Number width], [param:Number height], [param:Number depth], [param:Object options] )</h3>
 		<p>
 		<p>
 		[page:Number width] - la lunghezza del render target, in pixel. Il valore predefinito è `1`.<br />
 		[page:Number width] - la lunghezza del render target, in pixel. Il valore predefinito è `1`.<br />
 		[page:Number height] - l'altezza del render target, in pixel. Il valore predefinito è `1`.<br />
 		[page:Number height] - l'altezza del render target, in pixel. Il valore predefinito è `1`.<br />
-		[page:Number depth] - la profondità del render target. Il valore predefinito è `1`.<br /><br />
+		[page:Number depth] - la profondità del render target. Il valore predefinito è `1`.<br />
+		[page:Object options] - (opzionale) oggetto che contiene i parametri della texture per un target texture auto generato 
+		e i booleani depthBuffer/stencilBuffer. See [page:WebGLRenderTarget] for details.<br /><br />
 
 
 		Crea un nuovo [name].
 		Crea un nuovo [name].
 		</p>
 		</p>
 
 
 		<h2>Proprietà</h2>
 		<h2>Proprietà</h2>
 
 
-		<h3>Vedi [page:WebGLRenderTarget] per le proprietà ereditate</h3>
+		<p>Vedi [page:WebGLRenderTarget] per le proprietà ereditate.</p>
 
 
 		<h3>[property:number depth]</h3>
 		<h3>[property:number depth]</h3>
 		<p>
 		<p>
@@ -48,7 +50,7 @@
 
 
 		<h2>Metodi</h2>
 		<h2>Metodi</h2>
 
 
-		<h3>Vedi [page:WebGLRenderTarget] per i metodi ereditati</h3>
+		<p>Vedi [page:WebGLRenderTarget] per i metodi ereditati.</p>
 
 
 		<h2>Source</h2>
 		<h2>Source</h2>
 
 

+ 2 - 2
docs/api/it/renderers/WebGLCubeRenderTarget.html

@@ -49,11 +49,11 @@
 
 
 		<h2>Proprietà</h2>
 		<h2>Proprietà</h2>
 
 
-		<h3>Vedi [page:WebGLRenderTarget] per le proprietà ereditate</h3>
+		<p>Vedi [page:WebGLRenderTarget] per le proprietà ereditate.</p>
 
 
 		<h2>Metodi</h2>
 		<h2>Metodi</h2>
 
 
-		<h3>Vedi [page:WebGLRenderTarget] per i metodi ereditati</h3>
+		<p>Vedi [page:WebGLRenderTarget] per i metodi ereditati.</p>
 
 
 		<h3>[method:this fromEquirectangularTexture]( [param:WebGLRenderer renderer], [param:Texture texture] )</h3>
 		<h3>[method:this fromEquirectangularTexture]( [param:WebGLRenderer renderer], [param:Texture texture] )</h3>
 		<p>
 		<p>

+ 27 - 2
docs/api/ko/core/Object3D.html

@@ -122,6 +122,17 @@
 		[page:Object3D], [page:Group] 혹은 [page:Bone] 인스턴스는 렌더링할 수 없으므로 이러한 객체에 대해서는 콜백이 실행되지 않습니다.
 		[page:Object3D], [page:Group] 혹은 [page:Bone] 인스턴스는 렌더링할 수 없으므로 이러한 객체에 대해서는 콜백이 실행되지 않습니다.
 		</p>
 		</p>
 
 
+		<h3>[property:Function onAfterShadow]</h3>
+		<p>
+			An optional callback that is executed immediately after a 3D object is
+			rendered to a shadow map. This function is called with the following parameters: renderer,
+			scene, camera, shadowCamera, geometry, depthMaterial, group.
+		</p>
+		<p>
+			이 콜백은 *렌더링 가능한* 3D 객체에만 실행됩니다. [page:Mesh], [page:Line], [page:Points] 혹은 [page:Sprite]같은 기하학 및 재질로 시각적 표현을 정의하는 3D 객체들에 한정됩니다.
+			[page:Object3D], [page:Group] 혹은 [page:Bone] 인스턴스는 렌더링할 수 없으므로 이러한 객체에 대해서는 콜백이 실행되지 않습니다.
+		</p>
+
 		<h3>[property:Function onBeforeRender]</h3>
 		<h3>[property:Function onBeforeRender]</h3>
 		<p>
 		<p>
 			3D 객체가 렌더링되기 바로 전에 실행되는 선택적 콜백입니다.
 			3D 객체가 렌더링되기 바로 전에 실행되는 선택적 콜백입니다.
@@ -132,6 +143,17 @@
 			[page:Object3D], [page:Group] 혹은 [page:Bone] 인스턴스는 렌더링할 수 없으므로 이러한 객체에 대해서는 콜백이 실행되지 않습니다.
 			[page:Object3D], [page:Group] 혹은 [page:Bone] 인스턴스는 렌더링할 수 없으므로 이러한 객체에 대해서는 콜백이 실행되지 않습니다.
 		</p>
 		</p>
 
 
+		<h3>[property:Function onBeforeShadow]</h3>
+		<p>
+			An optional callback that is executed immediately before a 3D object is
+			rendered to a shadow map. This function is called with the following parameters: renderer,
+			scene, camera, shadowCamera, geometry, depthMaterial, group.
+		</p>
+		<p>
+			이 콜백은 *렌더링 가능한* 3D 객체에만 실행됩니다. [page:Mesh], [page:Line], [page:Points] 혹은 [page:Sprite]같은 기하학 및 재질로 시각적 표현을 정의하는 3D 객체들에 한정됩니다.
+			[page:Object3D], [page:Group] 혹은 [page:Bone] 인스턴스는 렌더링할 수 없으므로 이러한 객체에 대해서는 콜백이 실행되지 않습니다.
+		</p>
+
 		<h3>[property:Object3D parent]</h3>
 		<h3>[property:Object3D parent]</h3>
 		<p>[link:https://en.wikipedia.org/wiki/Scene_graph scene graph]에 있는 객체의 부모입니다. 객체는 최대 한 개의 부모만 가질 수 있습니다.</p>
 		<p>[link:https://en.wikipedia.org/wiki/Scene_graph scene graph]에 있는 객체의 부모입니다. 객체는 최대 한 개의 부모만 가질 수 있습니다.</p>
 
 
@@ -271,10 +293,13 @@
 		객체 자신부터 시작하여 객체와 객체 자식 항목을 검색하고 일치하는 값의 첫 번째 항목을 리턴합니다.
 		객체 자신부터 시작하여 객체와 객체 자식 항목을 검색하고 일치하는 값의 첫 번째 항목을 리턴합니다.
 		</p>
 		</p>
 
 
-		<h3>[method:Object3D getObjectsByProperty]( [param:String name], [param:Any value] )</h3>
+		<h3>[method:Object3D getObjectsByProperty]( [param:String name], [param:Any value], [param:Array optionalTarget] )</h3>
 		<p>
 		<p>
 		name -- 검색하고자하는 이름 프로퍼티. <br />
 		name -- 검색하고자하는 이름 프로퍼티. <br />
-		value -- 프로퍼티의 값. <br /><br />
+		value -- 프로퍼티의 값. <br />
+		optionalTarget -- (optional) target to set the result.
+		Otherwise a new Array is instantiated. If set, you must clear this
+		array prior to each call (i.e., array.length = 0;). <br /><br />
 
 
 		개체 자체부터 시작하여 개체와 해당 자식을 검색하고 일치하는 값의 모든 개체를 반환합니다.
 		개체 자체부터 시작하여 개체와 해당 자식을 검색하고 일치하는 값의 모든 개체를 반환합니다.
 		</p>
 		</p>

+ 27 - 2
docs/api/zh/core/Object3D.html

@@ -116,6 +116,17 @@
 	[page:Object3D]、 [page:Group] 或者 [page:Bone] 这些是不可渲染的物体,因此此回调函数不会在这样的物体上执行。
 	[page:Object3D]、 [page:Group] 或者 [page:Bone] 这些是不可渲染的物体,因此此回调函数不会在这样的物体上执行。
 	</p>
 	</p>
 
 
+	<h3>[property:Function onAfterShadow]</h3>
+	<p>
+		An optional callback that is executed immediately after a 3D object is
+		rendered to a shadow map. This function is called with the following parameters: renderer,
+		scene, camera, shadowCamera, geometry, depthMaterial, group.
+	</p>
+	<p>
+		注意此回调函数只会在*可渲染*的3D物体上执行。可渲染的3D物体指的是那种拥有视觉表现的、定义了几何体与材质的物体,例如像是[page:Mesh]、[page:Line]、[page:Points] 或者[page:Sprite]。
+		[page:Object3D]、 [page:Group] 或者 [page:Bone] 这些是不可渲染的物体,因此此回调函数不会在这样的物体上执行。
+	</p>
+
 	<h3>[property:Function onBeforeRender]</h3>
 	<h3>[property:Function onBeforeRender]</h3>
 	<p>
 	<p>
 		一个可选的回调函数,在Object3D渲染之前直接执行。
 		一个可选的回调函数,在Object3D渲染之前直接执行。
@@ -126,6 +137,17 @@
 	[page:Object3D]、 [page:Group] 或者 [page:Bone] 这些是不可渲染的物体,因此此回调函数不会在这样的物体上执行。
 	[page:Object3D]、 [page:Group] 或者 [page:Bone] 这些是不可渲染的物体,因此此回调函数不会在这样的物体上执行。
 	</p>
 	</p>
 
 
+	<h3>[property:Function onBeforeShadow]</h3>
+	<p>
+		An optional callback that is executed immediately before a 3D object is
+		rendered to a shadow map. This function is called with the following parameters: renderer,
+		scene, camera, shadowCamera, geometry, depthMaterial, group.
+	</p>
+	<p>
+		注意此回调函数只会在*可渲染*的3D物体上执行。可渲染的3D物体指的是那种拥有视觉表现的、定义了几何体与材质的物体,例如像是[page:Mesh]、[page:Line]、[page:Points] 或者[page:Sprite]。
+		[page:Object3D]、 [page:Group] 或者 [page:Bone] 这些是不可渲染的物体,因此此回调函数不会在这样的物体上执行。
+	</p>
+
 	<h3>[property:Object3D parent]</h3>
 	<h3>[property:Object3D parent]</h3>
 	<p>在[link:https://en.wikipedia.org/wiki/Scene_graph scene graph](场景图)中,一个对象的父级对象。
 	<p>在[link:https://en.wikipedia.org/wiki/Scene_graph scene graph](场景图)中,一个对象的父级对象。
 		一个对象最多仅能有一个父级对象。</p>
 		一个对象最多仅能有一个父级对象。</p>
@@ -264,10 +286,13 @@
 		从该对象开始,搜索一个对象及其子级,返回第一个给定的属性中包含有匹配的值的子对象。
 		从该对象开始,搜索一个对象及其子级,返回第一个给定的属性中包含有匹配的值的子对象。
 	</p>
 	</p>
 
 
-	<h3>[method:Object3D getObjectsByProperty]( [param:String name], [param:Any value] )</h3>
+	<h3>[method:Object3D getObjectsByProperty]( [param:String name], [param:Any value], [param:Array optionalTarget] )</h3>
 	<p>
 	<p>
 		name —— 将要用于查找的属性的名称。<br />
 		name —— 将要用于查找的属性的名称。<br />
-		value —— 给定的属性的值。 <br /><br />
+		value —— 给定的属性的值。 <br />
+		optionalTarget -- (optional) target to set the result.
+		Otherwise a new Array is instantiated. If set, you must clear this
+		array prior to each call (i.e., array.length = 0;). <br /><br />
 		从此对象开始,搜索一个对象及其子对象,返回包含给定属性的匹配值的所有子对象。
 		从此对象开始,搜索一个对象及其子对象,返回包含给定属性的匹配值的所有子对象。
 	</p>
 	</p>
 
 

+ 2 - 0
docs/api/zh/helpers/DirectionalLightHelper.html

@@ -21,6 +21,8 @@
 
 
 		<code>
 		<code>
 		const light = new THREE.DirectionalLight( 0xFFFFFF );
 		const light = new THREE.DirectionalLight( 0xFFFFFF );
+		scene.add( light );
+
 		const helper = new THREE.DirectionalLightHelper( light, 5 );
 		const helper = new THREE.DirectionalLightHelper( light, 5 );
 		scene.add( helper );
 		scene.add( helper );
 		</code>
 		</code>

+ 4 - 1
docs/api/zh/materials/LineDashedMaterial.html

@@ -11,7 +11,10 @@
 
 
 		<h1>虚线材质([name])</h1>
 		<h1>虚线材质([name])</h1>
 
 
-		<p class="desc">一种用于绘制虚线样式几何体的材质。</p>
+		<p class="desc">
+			一种用于绘制虚线样式几何体的材质。<br />
+			Note: You must call [page:Line.computeLineDistances]() when using [name].
+		</p>
 
 
 		<h2>代码示例</h2>
 		<h2>代码示例</h2>
 
 

+ 43 - 39
docs/api/zh/math/Matrix3.html

@@ -79,9 +79,10 @@ m.elements = [ 11, 21, 31,
 
 
 		<h3>[method:this extractBasis]( [param:Vector3 xAxis], [param:Vector3 yAxis], [param:Vector3 zAxis] )</h3>
 		<h3>[method:this extractBasis]( [param:Vector3 xAxis], [param:Vector3 yAxis], [param:Vector3 zAxis] )</h3>
 		<p>
 		<p>
-		将该矩阵的基向量 [link:https://en.wikipedia.org/wiki/Basis_(linear_algebra) basis] 提取到提供的三个轴向中。如果该矩阵如下:<br /><br />
+		将该矩阵的基向量 [link:https://en.wikipedia.org/wiki/Basis_(linear_algebra) basis] 提取到提供的三个轴向中。如果该矩阵如下:
+		</p>
 
 
-		<math>
+		<math display="block">
 			<mrow>
 			<mrow>
 				<mo>[</mo>
 				<mo>[</mo>
 				<mtable>
 				<mtable>
@@ -103,10 +104,13 @@ m.elements = [ 11, 21, 31,
 				</mtable>
 				</mtable>
 				<mo>]</mo>
 				<mo>]</mo>
 			</mrow>
 			</mrow>
-		</math><br /><br />
+		</math>
 
 
-		那么 [page:Vector3 xAxis], [page:Vector3 yAxis], [page:Vector3 zAxis] 将会被设置为:<br /><br />
+		<p>
+		那么 [page:Vector3 xAxis], [page:Vector3 yAxis], [page:Vector3 zAxis] 将会被设置为:
+		</p>
 
 
+		<div style="text-align: center">
 		<math>
 		<math>
 			<mrow>
 			<mrow>
 				<mi>xAxis</mi>
 				<mi>xAxis</mi>
@@ -148,7 +152,7 @@ m.elements = [ 11, 21, 31,
 				<mo>]</mo>
 				<mo>]</mo>
 			</mrow>
 			</mrow>
 		</math>
 		</math>
-		</p>
+		</div>
 
 
 		<h3>[method:this fromArray]( [param:Array array], [param:Integer offset] )</h3>
 		<h3>[method:this fromArray]( [param:Array array], [param:Integer offset] )</h3>
 		<p>
 		<p>
@@ -173,41 +177,42 @@ m.elements = [ 11, 21, 31,
 
 
 		<h3>[method:this identity]()</h3>
 		<h3>[method:this identity]()</h3>
 		<p>
 		<p>
-			将此矩阵重置为3x3单位矩阵:<br /><br />
-
-			<math>
-				<mrow>
-					<mo>[</mo>
-					<mtable>
-						<mtr>
-							<mtd><mn>1</mn></mtd>
-							<mtd><mn>0</mn></mtd>
-							<mtd><mn>0</mn></mtd>
-						</mtr>
-						<mtr>
-							<mtd><mn>0</mn></mtd>
-							<mtd><mn>1</mn></mtd>
-							<mtd><mn>0</mn></mtd>
-						</mtr>
-						<mtr>
-							<mtd><mn>0</mn></mtd>
-							<mtd><mn>0</mn></mtd>
-							<mtd><mn>1</mn></mtd>
-						</mtr>
-					</mtable>
-					<mo>]</mo>
-				</mrow>
-			</math>
+			将此矩阵重置为3x3单位矩阵:
 		</p>
 		</p>
 
 
+		<math display="block">
+			<mrow>
+				<mo>[</mo>
+				<mtable>
+					<mtr>
+						<mtd><mn>1</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+					</mtr>
+					<mtr>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>1</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+					</mtr>
+					<mtr>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>1</mn></mtd>
+					</mtr>
+				</mtable>
+				<mo>]</mo>
+			</mrow>
+		</math>
+
 		<h3>[method:this makeRotation]( [param:Float theta] )</h3>
 		<h3>[method:this makeRotation]( [param:Float theta] )</h3>
 		<p>
 		<p>
 		[page:Float theta] — Rotation angle in radians. Positive values rotate counterclockwise.<br /><br />
 		[page:Float theta] — Rotation angle in radians. Positive values rotate counterclockwise.<br /><br />
 
 
 		Sets this matrix as a 2D rotational transformation by [page:Float theta] radians.
 		Sets this matrix as a 2D rotational transformation by [page:Float theta] radians.
-		The resulting matrix will be:<br /><br />
+		The resulting matrix will be:
+		</p>
 
 
-		<math>
+		<math display="block">
 			<mrow>
 			<mrow>
 				<mo>[</mo>
 				<mo>[</mo>
 				<mtable>
 				<mtable>
@@ -246,7 +251,6 @@ m.elements = [ 11, 21, 31,
 				<mo>]</mo>
 				<mo>]</mo>
 			</mrow>
 			</mrow>
 		</math>
 		</math>
-		</p>
 
 
 		<h3>[method:this makeScale]( [param:Float x], [param:Float y] )</h3>
 		<h3>[method:this makeScale]( [param:Float x], [param:Float y] )</h3>
 		<p>
 		<p>
@@ -288,9 +292,10 @@ m.elements = [ 11, 21, 31,
 		[page:Float x] - the amount to translate in the X axis.<br />
 		[page:Float x] - the amount to translate in the X axis.<br />
 		[page:Float y] - the amount to translate in the Y axis.<br />
 		[page:Float y] - the amount to translate in the Y axis.<br />
 
 
-		Sets this matrix as a 2D translation transform:<br /><br />
+		Sets this matrix as a 2D translation transform:
+		</p>
 
 
-		<math>
+		<math display="block">
 			<mrow>
 			<mrow>
 				<mo>[</mo>
 				<mo>[</mo>
 				<mtable>
 				<mtable>
@@ -313,7 +318,6 @@ m.elements = [ 11, 21, 31,
 				<mo>]</mo>
 				<mo>]</mo>
 			</mrow>
 			</mrow>
 		</math>
 		</math>
-		</p>
 
 
 		<h3>[method:this multiply]( [param:Matrix3 m] )</h3>
 		<h3>[method:this multiply]( [param:Matrix3 m] )</h3>
 		<p>将当前矩阵乘以矩阵[page:Matrix3 m]。</p>
 		<p>将当前矩阵乘以矩阵[page:Matrix3 m]。</p>
@@ -326,9 +330,10 @@ m.elements = [ 11, 21, 31,
 
 
 		<h3>[method:this set]( [param:Float n11], [param:Float n12], [param:Float n13], [param:Float n21], [param:Float n22], [param:Float n23], [param:Float n31], [param:Float n32], [param:Float n33] )</h3>
 		<h3>[method:this set]( [param:Float n11], [param:Float n12], [param:Float n13], [param:Float n21], [param:Float n22], [param:Float n23], [param:Float n31], [param:Float n32], [param:Float n33] )</h3>
 		<p>
 		<p>
-		使用行优先 [link:https://en.wikipedia.org/wiki/Row-_and_column-major_order row-major] 的格式来设置该矩阵:<br /><br />
+		使用行优先 [link:https://en.wikipedia.org/wiki/Row-_and_column-major_order row-major] 的格式来设置该矩阵:
+		</p>
 
 
-		<math>
+		<math display="block">
 			<mrow>
 			<mrow>
 				<mo>[</mo>
 				<mo>[</mo>
 				<mtable>
 				<mtable>
@@ -351,7 +356,6 @@ m.elements = [ 11, 21, 31,
 				<mo>]</mo>
 				<mo>]</mo>
 			</mrow>
 			</mrow>
 		</math>
 		</math>
-		</p>
 
 
 		<h3>[method:this premultiply]( [param:Matrix3 m] )</h3>
 		<h3>[method:this premultiply]( [param:Matrix3 m] )</h3>
 		<p>将矩阵[page:Matrix3 m]乘以当前矩阵。</p>
 		<p>将矩阵[page:Matrix3 m]乘以当前矩阵。</p>

+ 191 - 189
docs/api/zh/math/Matrix4.html

@@ -152,43 +152,45 @@ m.elements = [ 11, 21, 31, 41,
 		<h3>[method:this extractBasis]( [param:Vector3 xAxis], [param:Vector3 yAxis], [param:Vector3 zAxis] )</h3>
 		<h3>[method:this extractBasis]( [param:Vector3 xAxis], [param:Vector3 yAxis], [param:Vector3 zAxis] )</h3>
 		<p>
 		<p>
 			将矩阵的基向量[link:https://en.wikipedia.org/wiki/Basis_(linear_algebra) basis]提取到指定的3个轴向量中。
 			将矩阵的基向量[link:https://en.wikipedia.org/wiki/Basis_(linear_algebra) basis]提取到指定的3个轴向量中。
-			如果矩阵如下:<br /><br />
+			如果矩阵如下:
+		</p>
 
 
-			<math>
-				<mrow>
-					<mo>[</mo>
-					<mtable>
-						<mtr>
-							<mtd><mi>a</mi></mtd>
-							<mtd><mi>b</mi></mtd>
-							<mtd><mi>c</mi></mtd>
-							<mtd><mi>d</mi></mtd>
-						</mtr>
-						<mtr>
-							<mtd><mi>e</mi></mtd>
-							<mtd><mi>f</mi></mtd>
-							<mtd><mi>g</mi></mtd>
-							<mtd><mi>h</mi></mtd>
-						</mtr>
-						<mtr>
-							<mtd><mi>i</mi></mtd>
-							<mtd><mi>j</mi></mtd>
-							<mtd><mi>k</mi></mtd>
-							<mtd><mi>l</mi></mtd>
-						</mtr>
-						<mtr>
-							<mtd><mi>m</mi></mtd>
-							<mtd><mi>n</mi></mtd>
-							<mtd><mi>o</mi></mtd>
-							<mtd><mi>p</mi></mtd>
-						</mtr>
-					</mtable>
-					<mo>]</mo>
-				</mrow>
-			</math><br /><br />
+		<math display="block">
+			<mrow>
+				<mo>[</mo>
+				<mtable>
+					<mtr>
+						<mtd><mi>a</mi></mtd>
+						<mtd><mi>b</mi></mtd>
+						<mtd><mi>c</mi></mtd>
+						<mtd><mi>d</mi></mtd>
+					</mtr>
+					<mtr>
+						<mtd><mi>e</mi></mtd>
+						<mtd><mi>f</mi></mtd>
+						<mtd><mi>g</mi></mtd>
+						<mtd><mi>h</mi></mtd>
+					</mtr>
+					<mtr>
+						<mtd><mi>i</mi></mtd>
+						<mtd><mi>j</mi></mtd>
+						<mtd><mi>k</mi></mtd>
+						<mtd><mi>l</mi></mtd>
+					</mtr>
+					<mtr>
+						<mtd><mi>m</mi></mtd>
+						<mtd><mi>n</mi></mtd>
+						<mtd><mi>o</mi></mtd>
+						<mtd><mi>p</mi></mtd>
+					</mtr>
+				</mtable>
+				<mo>]</mo>
+			</mrow>
+		</math>
 
 
-			然后x轴y轴z轴被设为:<br /><br />
+		<p>然后x轴y轴z轴被设为:</p>
 
 
+		<div style="text-align: center">
 			<math>
 			<math>
 				<mrow>
 				<mrow>
 					<mi>xAxis</mi>
 					<mi>xAxis</mi>
@@ -230,7 +232,7 @@ m.elements = [ 11, 21, 31, 41,
 					<mo>]</mo>
 					<mo>]</mo>
 				</mrow>
 				</mrow>
 			</math>
 			</math>
-		</p>
+		</div>
 
 
 		<h3>[method:this extractRotation]( [param:Matrix4 m] )</h3>
 		<h3>[method:this extractRotation]( [param:Matrix4 m] )</h3>
 		<p>
 		<p>
@@ -273,42 +275,42 @@ m.elements = [ 11, 21, 31, 41,
 
 
 		<h3>[method:this makeBasis]( [param:Vector3 xAxis], [param:Vector3 yAxis], [param:Vector3 zAxis] )</h3>
 		<h3>[method:this makeBasis]( [param:Vector3 xAxis], [param:Vector3 yAxis], [param:Vector3 zAxis] )</h3>
 		<p>
 		<p>
-			通过给定的三个向量设置该矩阵为基矩阵[link:https://en.wikipedia.org/wiki/Basis_(linear_algebra) basis]:<br /><br />
-
-			<math>
-				<mrow>
-					<mo>[</mo>
-					<mtable>
-						<mtr>
-							<mtd><mi>xAxis.x</mi></mtd>
-							<mtd><mi>yAxis.x</mi></mtd>
-							<mtd><mi>zAxis.x</mi></mtd>
-							<mtd><mn>0</mn></mtd>
-						</mtr>
-						<mtr>
-							<mtd><mi>xAxis.y</mi></mtd>
-							<mtd><mi>yAxis.y</mi></mtd>
-							<mtd><mi>zAxis.y</mi></mtd>
-							<mtd><mn>0</mn></mtd>
-						</mtr>
-						<mtr>
-							<mtd><mi>xAxis.z</mi></mtd>
-							<mtd><mi>yAxis.z</mi></mtd>
-							<mtd><mi>zAxis.z</mi></mtd>
-							<mtd><mn>0</mn></mtd>
-						</mtr>
-						<mtr>
-							<mtd><mn>0</mn></mtd>
-							<mtd><mn>0</mn></mtd>
-							<mtd><mn>0</mn></mtd>
-							<mtd><mn>1</mn></mtd>
-						</mtr>
-					</mtable>
-					<mo>]</mo>
-				</mrow>
-			</math>
+			通过给定的三个向量设置该矩阵为基矩阵[link:https://en.wikipedia.org/wiki/Basis_(linear_algebra) basis]:
 		</p>
 		</p>
 
 
+		<math display="block">
+			<mrow>
+				<mo>[</mo>
+				<mtable>
+					<mtr>
+						<mtd><mi>xAxis.x</mi></mtd>
+						<mtd><mi>yAxis.x</mi></mtd>
+						<mtd><mi>zAxis.x</mi></mtd>
+						<mtd><mn>0</mn></mtd>
+					</mtr>
+					<mtr>
+						<mtd><mi>xAxis.y</mi></mtd>
+						<mtd><mi>yAxis.y</mi></mtd>
+						<mtd><mi>zAxis.y</mi></mtd>
+						<mtd><mn>0</mn></mtd>
+					</mtr>
+					<mtr>
+						<mtd><mi>xAxis.z</mi></mtd>
+						<mtd><mi>yAxis.z</mi></mtd>
+						<mtd><mi>zAxis.z</mi></mtd>
+						<mtd><mn>0</mn></mtd>
+					</mtr>
+					<mtr>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>1</mn></mtd>
+					</mtr>
+				</mtable>
+				<mo>]</mo>
+			</mrow>
+		</math>
+
 		<h3>[method:this makePerspective]( [param:Float left], [param:Float right], [param:Float top], [param:Float bottom], [param:Float near], [param:Float far] )</h3>
 		<h3>[method:this makePerspective]( [param:Float left], [param:Float right], [param:Float top], [param:Float bottom], [param:Float near], [param:Float far] )</h3>
 		<p>
 		<p>
 			创建一个透视投影矩阵[link:https://en.wikipedia.org/wiki/3D_projection#Perspective_projection perspective projection]。
 			创建一个透视投影矩阵[link:https://en.wikipedia.org/wiki/3D_projection#Perspective_projection perspective projection]。
@@ -331,9 +333,10 @@ m.elements = [ 11, 21, 31, 41,
 		<h3>[method:this makeRotationFromQuaternion]( [param:Quaternion q] )</h3>
 		<h3>[method:this makeRotationFromQuaternion]( [param:Quaternion q] )</h3>
 		<p>
 		<p>
 		将这个矩阵的旋转分量设置为四元数[page:Quaternion q]指定的旋转,如下链接所诉[link:https://en.wikipedia.org/wiki/Rotation_matrix#Quaternion here]。
 		将这个矩阵的旋转分量设置为四元数[page:Quaternion q]指定的旋转,如下链接所诉[link:https://en.wikipedia.org/wiki/Rotation_matrix#Quaternion here]。
-		矩阵的其余部分被设为单位矩阵。因此,给定四元数[page:Quaternion q] = w + xi + yj + zk,得到的矩阵为:<br /><br />
+		矩阵的其余部分被设为单位矩阵。因此,给定四元数[page:Quaternion q] = w + xi + yj + zk,得到的矩阵为:
+		</p>
 
 
-		<math>
+		<math display="block">
 			<mrow>
 			<mrow>
 				<mo>[</mo>
 				<mo>[</mo>
 				<mtable>
 				<mtable>
@@ -461,16 +464,16 @@ m.elements = [ 11, 21, 31, 41,
 				<mo>]</mo>
 				<mo>]</mo>
 			</mrow>
 			</mrow>
 		</math>
 		</math>
-		</p>
 
 
 		<h3>[method:this makeRotationX]( [param:Float theta] )</h3>
 		<h3>[method:this makeRotationX]( [param:Float theta] )</h3>
 		<p>
 		<p>
 		[page:Float theta] — Rotation angle in radians.<br /><br />
 		[page:Float theta] — Rotation angle in radians.<br /><br />
 
 
 		把该矩阵设置为绕x轴旋转弧度[page:Float theta] (&theta;)大小的矩阵。
 		把该矩阵设置为绕x轴旋转弧度[page:Float theta] (&theta;)大小的矩阵。
-		结果如下:<br /><br />
+		结果如下:
+		</p>
 
 
-		<math>
+		<math display="block">
 			<mrow>
 			<mrow>
 				<mo>[</mo>
 				<mo>[</mo>
 				<mtable>
 				<mtable>
@@ -523,16 +526,16 @@ m.elements = [ 11, 21, 31, 41,
 				<mo>]</mo>
 				<mo>]</mo>
 			</mrow>
 			</mrow>
 		</math>
 		</math>
-		</p>
 
 
 		<h3>[method:this makeRotationY]( [param:Float theta] )</h3>
 		<h3>[method:this makeRotationY]( [param:Float theta] )</h3>
 		<p>
 		<p>
 		[page:Float theta] — Rotation angle in radians.<br /><br />
 		[page:Float theta] — Rotation angle in radians.<br /><br />
 
 
 		把该矩阵设置为绕Y轴旋转弧度[page:Float theta] (&theta;)大小的矩阵。
 		把该矩阵设置为绕Y轴旋转弧度[page:Float theta] (&theta;)大小的矩阵。
-		结果如下:<br /><br />
+		结果如下:
+		</p>
 
 
-		<math>
+		<math display="block">
 			<mrow>
 			<mrow>
 				<mo>[</mo>
 				<mo>[</mo>
 				<mtable>
 				<mtable>
@@ -585,16 +588,16 @@ m.elements = [ 11, 21, 31, 41,
 				<mo>]</mo>
 				<mo>]</mo>
 			</mrow>
 			</mrow>
 		</math>
 		</math>
-		</p>
 
 
 		<h3>[method:this makeRotationZ]( [param:Float theta] )</h3>
 		<h3>[method:this makeRotationZ]( [param:Float theta] )</h3>
 		<p>
 		<p>
 		[page:Float theta] — Rotation angle in radians.<br /><br />
 		[page:Float theta] — Rotation angle in radians.<br /><br />
 
 
 		把该矩阵设置为绕z轴旋转弧度[page:Float theta] (&theta;)大小的矩阵。
 		把该矩阵设置为绕z轴旋转弧度[page:Float theta] (&theta;)大小的矩阵。
-		结果如下:<br /><br />
-			
-		<math>
+		结果如下:
+		</p>
+
+		<math display="block">
 			<mrow>
 			<mrow>
 				<mo>[</mo>
 				<mo>[</mo>
 				<mtable>
 				<mtable>
@@ -647,7 +650,6 @@ m.elements = [ 11, 21, 31, 41,
 				<mo>]</mo>
 				<mo>]</mo>
 			</mrow>
 			</mrow>
 		</math>
 		</math>
-		</p>
 
 
 		<h3>[method:this makeScale]( [param:Float x], [param:Float y], [param:Float z] )</h3>
 		<h3>[method:this makeScale]( [param:Float x], [param:Float y], [param:Float z] )</h3>
 		<p>
 		<p>
@@ -655,51 +657,52 @@ m.elements = [ 11, 21, 31, 41,
 			[page:Float y] - 在Y轴方向的缩放比。<br />
 			[page:Float y] - 在Y轴方向的缩放比。<br />
 			[page:Float z] - 在Z轴方向的缩放比。<br /><br />
 			[page:Float z] - 在Z轴方向的缩放比。<br /><br />
 
 
-			将这个矩阵设置为缩放变换:<br /><br />
-
-			<math>
-				<mrow>
-					<mo>[</mo>
-					<mtable>
-						<mtr>
-							<mtd><mi>x</mi></mtd>
-							<mtd><mn>0</mn></mtd>
-							<mtd><mn>0</mn></mtd>
-							<mtd><mn>0</mn></mtd>
-						</mtr>
-						<mtr>
-							<mtd><mn>0</mn></mtd>
-							<mtd><mi>y</mi></mtd>
-							<mtd><mn>0</mn></mtd>
-							<mtd><mn>0</mn></mtd>
-						</mtr>
-						<mtr>
-							<mtd><mn>0</mn></mtd>
-							<mtd><mn>0</mn></mtd>
-							<mtd><mi>z</mi></mtd>
-							<mtd><mn>0</mn></mtd>
-						</mtr>
-						<mtr>
-							<mtd><mn>0</mn></mtd>
-							<mtd><mn>0</mn></mtd>
-							<mtd><mn>0</mn></mtd>
-							<mtd><mn>1</mn></mtd>
-						</mtr>
-					</mtable>
-					<mo>]</mo>
-				</mrow>
-			</math>
+			将这个矩阵设置为缩放变换:
 		</p>
 		</p>
 
 
+		<math display="block">
+			<mrow>
+				<mo>[</mo>
+				<mtable>
+					<mtr>
+						<mtd><mi>x</mi></mtd>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+					</mtr>
+					<mtr>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mi>y</mi></mtd>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+					</mtr>
+					<mtr>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mi>z</mi></mtd>
+						<mtd><mn>0</mn></mtd>
+					</mtr>
+					<mtr>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>0</mn></mtd>
+						<mtd><mn>1</mn></mtd>
+					</mtr>
+				</mtable>
+				<mo>]</mo>
+			</mrow>
+		</math>
+
 		<h3>[method:this makeShear]( [param:Float x], [param:Float y], [param:Float z] )</h3>
 		<h3>[method:this makeShear]( [param:Float x], [param:Float y], [param:Float z] )</h3>
 		<p>
 		<p>
 		[page:Float x] - 在X轴上剪切的量。<br />
 		[page:Float x] - 在X轴上剪切的量。<br />
 		[page:Float y] - 在Y轴上剪切的量。<br />
 		[page:Float y] - 在Y轴上剪切的量。<br />
 		[page:Float z] - 在Z轴上剪切的量。<br /><br />
 		[page:Float z] - 在Z轴上剪切的量。<br /><br />
 
 
-		将此矩阵设置为剪切变换:<br /><br />
+		将此矩阵设置为剪切变换:
+		</p>
 
 
-		<math>
+		<math display="block">
 			<mrow>
 			<mrow>
 				<mo>[</mo>
 				<mo>[</mo>
 				<mtable>
 				<mtable>
@@ -731,16 +734,16 @@ m.elements = [ 11, 21, 31, 41,
 				<mo>]</mo>
 				<mo>]</mo>
 			</mrow>
 			</mrow>
 		</math>
 		</math>
-		</p>
 
 
 		<h3>[method:this makeTranslation]( [param:Vector3 v] )</h3>
 		<h3>[method:this makeTranslation]( [param:Vector3 v] )</h3>
 		<h3>
 		<h3>
 			[method:this makeTranslation]( [param:Float x], [param:Float y], [param:Float z] ) // optional API
 			[method:this makeTranslation]( [param:Float x], [param:Float y], [param:Float z] ) // optional API
 		</h3>
 		</h3>
 		<p>
 		<p>
-		取传入参数[param:Vector3 v]中值设设置该矩阵为平移变换:<br /><br />
+		取传入参数[param:Vector3 v]中值设设置该矩阵为平移变换:
+		</p>
 
 
-		<math>
+		<math display="block">
 			<mrow>
 			<mrow>
 				<mo>[</mo>
 				<mo>[</mo>
 				<mtable>
 				<mtable>
@@ -772,7 +775,6 @@ m.elements = [ 11, 21, 31, 41,
 				<mo>]</mo>
 				<mo>]</mo>
 			</mrow>
 			</mrow>
 		</math>
 		</math>
-		</p>
 
 
 		<h3>[method:this multiply]( [param:Matrix4 m] )</h3>
 		<h3>[method:this multiply]( [param:Matrix4 m] )</h3>
 		<p>将当前矩阵乘以矩阵[page:Matrix4 m]。</p>
 		<p>将当前矩阵乘以矩阵[page:Matrix4 m]。</p>
@@ -800,76 +802,76 @@ m.elements = [ 11, 21, 31, 41,
 		<h3>[method:this setPosition]( [param:Vector3 v] )</h3>
 		<h3>[method:this setPosition]( [param:Vector3 v] )</h3>
 		<h3>[method:this setPosition]( [param:Float x], [param:Float y], [param:Float z] ) // optional API</h3>
 		<h3>[method:this setPosition]( [param:Float x], [param:Float y], [param:Float z] ) // optional API</h3>
 		<p>
 		<p>
-			取传入参数[param:Vector3 v]中值设置该矩阵的位置分量,不影响该矩阵的其余部分——即,如果该矩阵当前为:<br /><br />
+			取传入参数[param:Vector3 v]中值设置该矩阵的位置分量,不影响该矩阵的其余部分——即,如果该矩阵当前为:
+		</p>
 
 
-			<math>
-				<mrow>
-					<mo>[</mo>
-					<mtable>
-						<mtr>
-							<mtd><mi>a</mi></mtd>
-							<mtd><mi>b</mi></mtd>
-							<mtd><mi>c</mi></mtd>
-							<mtd><mi>d</mi></mtd>
-						</mtr>
-						<mtr>
-							<mtd><mi>e</mi></mtd>
-							<mtd><mi>f</mi></mtd>
-							<mtd><mi>g</mi></mtd>
-							<mtd><mi>h</mi></mtd>
-						</mtr>
-						<mtr>
-							<mtd><mi>i</mi></mtd>
-							<mtd><mi>j</mi></mtd>
-							<mtd><mi>k</mi></mtd>
-							<mtd><mi>l</mi></mtd>
-						</mtr>
-						<mtr>
-							<mtd><mi>m</mi></mtd>
-							<mtd><mi>n</mi></mtd>
-							<mtd><mi>o</mi></mtd>
-							<mtd><mi>p</mi></mtd>
-						</mtr>
-					</mtable>
-					<mo>]</mo>
-				</mrow>
-			</math><br /><br />
+		<math display="block">
+			<mrow>
+				<mo>[</mo>
+				<mtable>
+					<mtr>
+						<mtd><mi>a</mi></mtd>
+						<mtd><mi>b</mi></mtd>
+						<mtd><mi>c</mi></mtd>
+						<mtd><mi>d</mi></mtd>
+					</mtr>
+					<mtr>
+						<mtd><mi>e</mi></mtd>
+						<mtd><mi>f</mi></mtd>
+						<mtd><mi>g</mi></mtd>
+						<mtd><mi>h</mi></mtd>
+					</mtr>
+					<mtr>
+						<mtd><mi>i</mi></mtd>
+						<mtd><mi>j</mi></mtd>
+						<mtd><mi>k</mi></mtd>
+						<mtd><mi>l</mi></mtd>
+					</mtr>
+					<mtr>
+						<mtd><mi>m</mi></mtd>
+						<mtd><mi>n</mi></mtd>
+						<mtd><mi>o</mi></mtd>
+						<mtd><mi>p</mi></mtd>
+					</mtr>
+				</mtable>
+				<mo>]</mo>
+			</mrow>
+		</math>
 
 
-			变成:<br /><br />
+		<p>变成:</p>
 
 
-			<math>
-				<mrow>
-					<mo>[</mo>
-					<mtable>
-						<mtr>
-							<mtd><mi>a</mi></mtd>
-							<mtd><mi>b</mi></mtd>
-							<mtd><mi>c</mi></mtd>
-							<mtd><mi>v.x</mi></mtd>
-						</mtr>
-						<mtr>
-							<mtd><mi>e</mi></mtd>
-							<mtd><mi>f</mi></mtd>
-							<mtd><mi>g</mi></mtd>
-							<mtd><mi>v.y</mi></mtd>
-						</mtr>
-						<mtr>
-							<mtd><mi>i</mi></mtd>
-							<mtd><mi>j</mi></mtd>
-							<mtd><mi>k</mi></mtd>
-							<mtd><mi>v.z</mi></mtd>
-						</mtr>
-						<mtr>
-							<mtd><mi>m</mi></mtd>
-							<mtd><mi>n</mi></mtd>
-							<mtd><mi>o</mi></mtd>
-							<mtd><mi>p</mi></mtd>
-						</mtr>
-					</mtable>
-					<mo>]</mo>
-				</mrow>
-			</math>
-		</p>
+		<math display="block">
+			<mrow>
+				<mo>[</mo>
+				<mtable>
+					<mtr>
+						<mtd><mi>a</mi></mtd>
+						<mtd><mi>b</mi></mtd>
+						<mtd><mi>c</mi></mtd>
+						<mtd><mi>v.x</mi></mtd>
+					</mtr>
+					<mtr>
+						<mtd><mi>e</mi></mtd>
+						<mtd><mi>f</mi></mtd>
+						<mtd><mi>g</mi></mtd>
+						<mtd><mi>v.y</mi></mtd>
+					</mtr>
+					<mtr>
+						<mtd><mi>i</mi></mtd>
+						<mtd><mi>j</mi></mtd>
+						<mtd><mi>k</mi></mtd>
+						<mtd><mi>v.z</mi></mtd>
+					</mtr>
+					<mtr>
+						<mtd><mi>m</mi></mtd>
+						<mtd><mi>n</mi></mtd>
+						<mtd><mi>o</mi></mtd>
+						<mtd><mi>p</mi></mtd>
+					</mtr>
+				</mtable>
+				<mo>]</mo>
+			</mrow>
+		</math>
 
 
 		<h3>[method:Array toArray]( [param:Array array], [param:Integer offset] )</h3>
 		<h3>[method:Array toArray]( [param:Array array], [param:Integer offset] )</h3>
 		<p>
 		<p>

+ 0 - 5
docs/api/zh/objects/Skeleton.html

@@ -76,11 +76,6 @@
 		当使用顶点纹理时,[page:DataTexture]保存着骨骼数据。
 		当使用顶点纹理时,[page:DataTexture]保存着骨骼数据。
 		</p>
 		</p>
 
 
-		<h3>[property:Integer boneTextureSize]</h3>
-		<p>
-		The size of the [page:.boneTexture].
-		</p>
-
 		<h2>方法</h2>
 		<h2>方法</h2>
 
 
 		<h3>[method:Skeleton clone]()</h3>
 		<h3>[method:Skeleton clone]()</h3>

+ 6 - 5
docs/api/zh/renderers/WebGL3DRenderTarget.html

@@ -16,18 +16,19 @@
 		<h2>构造函数</h2>
 		<h2>构造函数</h2>
 
 
 		<h3>
 		<h3>
-			[name]( [param:Number width], [param:Number height], [param:Number depth] )
+			[name]( [param:Number width], [param:Number height], [param:Number depth], [param:Object options] )
 		</h3>
 		</h3>
 		<p>
 		<p>
 			[page:Number width] - 渲染目标的宽度,单位为像素。默认值为`1`。<br />
 			[page:Number width] - 渲染目标的宽度,单位为像素。默认值为`1`。<br />
 			[page:Number height] - 渲染目标的高度,单位为像素。默认值为`1`。<br />
 			[page:Number height] - 渲染目标的高度,单位为像素。默认值为`1`。<br />
-			[page:Number depth] - 渲染目标的深度。 默认值为`1`。<br /><br />
-
+			[page:Number depth] - 渲染目标的深度。 默认值为`1`。<br />
+			[page:Object options] - (可选)一个保存着自动生成的目标纹理的纹理参数以及表示是否使用深度缓存/模板缓存的布尔值的对象。
+			有关纹理参数的说明,请参阅[page:Texture Texture]. See [page:WebGLRenderTarget] for details.<br /><br />
 			创建新的[name].
 			创建新的[name].
 		</p>
 		</p>
 
 
 		<h2>属性</h2>
 		<h2>属性</h2>
-		<h3>继承属性请参考[page:WebGLRenderTarget]</h3>
+		<p>继承属性请参考[page:WebGLRenderTarget]。</p>
 
 
 		<h3>[property:number depth]</h3>
 		<h3>[property:number depth]</h3>
 		<p>渲染目标的深度。</p>
 		<p>渲染目标的深度。</p>
@@ -38,7 +39,7 @@
 		</p>
 		</p>
 
 
 		<h2>方法</h2>
 		<h2>方法</h2>
-		<h3>继承方法请参考[page:WebGLRenderTarget]</h3>
+		<p>继承方法请参考[page:WebGLRenderTarget]。</p>
 
 
 		<h2>源码</h2>
 		<h2>源码</h2>
 		<p>
 		<p>

+ 4 - 2
docs/api/zh/renderers/WebGLArrayRenderTarget.html

@@ -24,12 +24,14 @@
 		<h2>构造函数</h2>
 		<h2>构造函数</h2>
 
 
 		<h3>
 		<h3>
-			[name]( [param:Number width], [param:Number height], [param:Number depth] )
+			[name]( [param:Number width], [param:Number height], [param:Number depth], [param:Object options] )
 		</h3>
 		</h3>
 		<p>
 		<p>
 			[page:Number width] - 渲染目标的宽度,单位为像素。默认值为`1`。<br />
 			[page:Number width] - 渲染目标的宽度,单位为像素。默认值为`1`。<br />
 			[page:Number height] - 渲染目标的高度,单位为像素。默认值为`1`。<br />
 			[page:Number height] - 渲染目标的高度,单位为像素。默认值为`1`。<br />
-			[page:Number depth] - 渲染目标的深度或图层数。 默认值为`1`。<br /><br />
+			[page:Number depth] - 渲染目标的深度或图层数。 默认值为`1`。<br />
+			[page:Object options] - (可选)一个保存着自动生成的目标纹理的纹理参数以及表示是否使用深度缓存/模板缓存的布尔值的对象。
+			有关纹理参数的说明,请参阅[page:Texture Texture]. See [page:WebGLRenderTarget] for details.<br /><br />
 
 
 			创建新的[name].
 			创建新的[name].
 		</p>
 		</p>

+ 2 - 2
docs/api/zh/renderers/WebGLCubeRenderTarget.html

@@ -46,12 +46,12 @@
 
 
 		<h2>属性</h2>
 		<h2>属性</h2>
 
 
-		<h3>继承属性,请参阅[page:WebGLRenderTarget]</h3>
+		<p>继承属性,请参阅[page:WebGLRenderTarget]。</p>
 
 
 
 
 		<h2>方法</h2>
 		<h2>方法</h2>
 
 
-		<h3>继承方法,请参阅[page:WebGLRenderTarget]</h3>
+		<p>继承方法,请参阅[page:WebGLRenderTarget]。</p>
 
 
 		<h3>[method:this fromEquirectangularTexture]( [param:WebGLRenderer renderer], [param:Texture texture] )</h3>
 		<h3>[method:this fromEquirectangularTexture]( [param:WebGLRenderer renderer], [param:Texture texture] )</h3>
 		<p>
 		<p>

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

@@ -124,22 +124,12 @@
 
 
 		<h2>Textures</h2>
 		<h2>Textures</h2>
 
 
-		<p>Textures containing color information (.map, .emissiveMap, and .specularMap) always use sRGB colorspace in
-		glTF, while vertex colors and material properties (.color, .emissive, .specular) use linear colorspace. In a
-		typical rendering workflow, textures are converted to linear colorspace by the renderer, lighting calculations
-		are made, then final output is converted back to sRGB and displayed on screen. Unless you need post-processing
-		in linear colorspace, always configure [page:WebGLRenderer] as follows when using glTF:</p>
+		<p>When loading textures externally (e.g., using [page:TextureLoader]) and applying them to a glTF model,
+		textures must be configured. Textures referenced from the glTF model are configured automatically by
+		GLTFLoader.</p>
 
 
 		<code>
 		<code>
-		renderer.outputColorSpace = THREE.SRGBColorSpace;
-		</code>
-
-		<p>GLTFLoader will automatically configure textures referenced from a .gltf or .glb file correctly, with the
-		assumption that the renderer is set up as shown above. When loading textures externally (e.g., using
-		[page:TextureLoader]) and applying them to a glTF model, colorspace and orientation must be given:</p>
-
-		<code>
-		// If texture is used for color information, set colorspace.
+		// If texture is used for color information (.map, .emissiveMap, .specularMap, ...), set color space
 		texture.colorSpace = THREE.SRGBColorSpace;
 		texture.colorSpace = THREE.SRGBColorSpace;
 
 
 		// UVs use the convention that (0, 0) corresponds to the upper left corner of a texture.
 		// UVs use the convention that (0, 0) corresponds to the upper left corner of a texture.

+ 1 - 0
docs/examples/en/postprocessing/EffectComposer.html

@@ -39,6 +39,7 @@
 			[example:webgl_postprocessing_fxaa postprocessing fxaa]<br />
 			[example:webgl_postprocessing_fxaa postprocessing fxaa]<br />
 			[example:webgl_postprocessing_glitch postprocessing glitch]<br />
 			[example:webgl_postprocessing_glitch postprocessing glitch]<br />
 			[example:webgl_postprocessing_godrays postprocessing godrays]<br />
 			[example:webgl_postprocessing_godrays postprocessing godrays]<br />
+			[example:webgl_postprocessing_hbao postprocessing hbao]<br />
 			[example:webgl_postprocessing_masking postprocessing masking]<br />
 			[example:webgl_postprocessing_masking postprocessing masking]<br />
 			[example:webgl_postprocessing_outline postprocessing outline]<br />
 			[example:webgl_postprocessing_outline postprocessing outline]<br />
 			[example:webgl_postprocessing_pixel postprocessing pixelate]<br />
 			[example:webgl_postprocessing_pixel postprocessing pixelate]<br />

+ 1 - 0
docs/examples/zh/postprocessing/EffectComposer.html

@@ -38,6 +38,7 @@
 			[example:webgl_postprocessing_fxaa postprocessing fxaa]<br />
 			[example:webgl_postprocessing_fxaa postprocessing fxaa]<br />
 			[example:webgl_postprocessing_glitch postprocessing glitch]<br />
 			[example:webgl_postprocessing_glitch postprocessing glitch]<br />
 			[example:webgl_postprocessing_godrays postprocessing godrays]<br />
 			[example:webgl_postprocessing_godrays postprocessing godrays]<br />
+			[example:webgl_postprocessing_hbao postprocessing hbao]<br />
 			[example:webgl_postprocessing_masking postprocessing masking]<br />
 			[example:webgl_postprocessing_masking postprocessing masking]<br />
 			[example:webgl_postprocessing_outline postprocessing outline]<br />
 			[example:webgl_postprocessing_outline postprocessing outline]<br />
 			[example:webgl_postprocessing_pixel postprocessing pixelate]<br />
 			[example:webgl_postprocessing_pixel postprocessing pixelate]<br />

+ 2 - 0
docs/list.json

@@ -262,6 +262,7 @@
 			},
 			},
 
 
 			"Objects": {
 			"Objects": {
+				"BatchedMesh": "api/en/objects/BatchedMesh",
 				"Bone": "api/en/objects/Bone",
 				"Bone": "api/en/objects/Bone",
 				"Group": "api/en/objects/Group",
 				"Group": "api/en/objects/Group",
 				"InstancedMesh": "api/en/objects/InstancedMesh",
 				"InstancedMesh": "api/en/objects/InstancedMesh",
@@ -448,6 +449,7 @@
 				"رسم خطوط": "manual/ar/introduction/Drawing-lines",
 				"رسم خطوط": "manual/ar/introduction/Drawing-lines",
 				"إنشاء نص": "manual/ar/introduction/Creating-text",
 				"إنشاء نص": "manual/ar/introduction/Creating-text",
 				"تحميل نماذج ثلاثية الأبعاد": "manual/ar/introduction/Loading-3D-models",
 				"تحميل نماذج ثلاثية الأبعاد": "manual/ar/introduction/Loading-3D-models",
+				"المكتبات والإضافات": "manual/ar/introduction/Libraries-and-Plugins",
 				"الأسئلة الشائعة": "manual/ar/introduction/FAQ",
 				"الأسئلة الشائعة": "manual/ar/introduction/FAQ",
 				"روابط مفيدة": "manual/ar/introduction/Useful-links"
 				"روابط مفيدة": "manual/ar/introduction/Useful-links"
 			},
 			},

+ 74 - 186
docs/manual/ar/introduction/Creating-a-scene.html

@@ -6,47 +6,25 @@
 		<script src="page.js"></script>
 		<script src="page.js"></script>
 		<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">
-		<h1>إنشاء مشهد([name]</h1>
+		<h1>إنشاء مشهد([name])</h1>
 
 
-		<p>الهدف من هذا القسم هو تقديم لمحة وجيزة عن كيفية عمل المكتبة. سنبدأ بتحضير مشهد يتمثل في مكعب ثلاثي الأبعاد .الصفحة مرفوقة بمثال أسفلها في حالة واجهتك بعض المشاكل وإحتجت إلى المساعدة.</p>
+		<p>الهدف من هذا القسم هو تقديم مقدمة مختصرة عن three.js. سنبدأ بإعداد مشهد باستخدام مكعب دوار. متوفر مثال عملي جاهز في أسفل الصفحة في حالة واجهتك مشكلة و علقت واحتجت إلى المساعدة.</p>
 
 
-		<h2>قبل أن نبدأ</h2>
+		<h2>قبل أن تبدأ</h2>
 
 
-		<p>قبل أن تتمكن من استخدام three.js ، تحتاج إلى مكان لعرضه. احفظ HTML التالي في ملف على جهاز الكمبيوتر الخاص بك وافتحه في المتصفح الخاص بك.</p>
+		<p>إذا لم تقم بذلك بعد، فانتقل إلى دليل [link:#manual/ar/introduction/Installation تثبيت]. سنفترض أنك قمت بالفعل بإعداد نفس هيكل المشروع (يشمل ذلك Index.html وmain.js)، وقمت بتثبيت three.js، وأنك تقوم بستخدم أداة بناء ، أو تستخدم خادم محلي مع CDN و import maps.</p>
 
 
-		<code>
-		&lt;!DOCTYPE html&gt;
-		&lt;html&gt;
-			&lt;head&gt;
-				&lt;meta charset="utf-8"&gt;
-				&lt;title&gt;My first three.js app&lt;/title&gt;
-				&lt;style&gt;
-					body { margin: 0; }
-				&lt;/style&gt;
-			&lt;/head&gt;
-			&lt;body&gt;
-				&lt;script type="module"&gt;
-					import * as THREE from 'https://unpkg.com/three/build/three.module.js';
+		<h2>إنشاء المشهد</h2>
 
 
-					// Our Javascript will go here.
-				&lt;/script&gt;
-			&lt;/body&gt;
-		&lt;/html&gt;
-		</code>
-
-		<p>
-			هذا كل شيء. بقية الأوامر البرمجية ستكون محتوات في وسم &lt;script&gt; الفارغ حاليا.
-		</p>
-
-		<h2>إنشاء مشهد</h2>
+		<p>لكي نتمكن فعلًا من عرض أي شيء باستخدام three.js، نحتاج إلى ثلاثة عناصر: المشهد (scene) والكاميرا (camera) والعارض (renderer)، بحيث يمكننا عرض المشهد بواسطة الكاميرا.</p>
 
 
-		<p>
-			لنتمكن من إظهار أي شيء بإستهمال three.js، نحتاج ثلاثة عناصر أساسية: المسرح (Scene)، الكاميرا (Camera)، و العارض
-			(Renderer).
-		</p>
+		<p class="RtlTitle"><i >main.js —</i></p>
 
 
 		<code>
 		<code>
+		import * as THREE from 'three';
+
 		const scene = new THREE.Scene();
 		const scene = new THREE.Scene();
 		const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );
 		const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );
 
 
@@ -55,68 +33,24 @@
 		document.body.appendChild( renderer.domElement );
 		document.body.appendChild( renderer.domElement );
 		</code>
 		</code>
 
 
-		<p>
-			لنتمهل لحظة من أجل توضيح ما يحصل هنا. لقد قمنا بتحضير كل من المسرح، الكاميرا، و العارض.
-		</p>
-
-		<p>
-			توفر مكتبة three.js العديد من الخيارات بخصوص نوع الكاميرا. للوقت الراهن، سنستعمل
-			<strong>PerspectiveCamera</strong>.
-		</p>
-
-		<p>
-			أول ميزة هي <strong>مجال الرؤية - Field of view</strong>. يمكن التعبير عنها بإستعمال إختصارها كالأتي FOV. هذه
-			القيمة تمثل مجال
-			المشاهدة المتاح في أي وقت
-			من العرض. وحده قيسها هي الدرجة (degrees)
-		</p>
-
-		<p>
-			القيمة الثانية هي <strong>نسبة العرض إلى الارتفاع - aspect ratio</strong>. من المستحسن إستعمال نتيجة قسمة عرض و
-			طول العنصر الحاوي، و إلا ستحصل على تجربة مماثلة
-			لمشاهدة فيلم قديم على تلفاز عريض حيث ستكون الصورة متغيرة.
-		</p>
-
-		<p>
-			القيمتين المتبقيتين هما <strong>أقرب</strong> و <strong>أبعد</strong> سطح فاصل. نقصد بدلك أن أي عنصر في المشهد
-			أبعد من السطح الفاصل البعيد بالنسبة
-			للكاميرا أو أقرب من السطح الفاصل القريب لن يتم عرضه.
-			أنت لست مطالب بالقلق حيال هذا، و لكن من الممكن أن تريد إستعمال قيم أخرى من أجل الحصول على أداء أفضل.
-		</p>
-
-		<p>
-			نصل الأن إلى العارض. هنا أين يكمن السحر. بالإضافة لإستعمال WebGLRenderer، المكتبة تتكفل بتمكين بعض المتصفحات
-			القديمة التي لا
-			تدعم WebGL لسبب ما من الخصائص المفقودة.
-		</p>
-
-		<p>
-			إلي جانب إنشاء نموذج من مكون عارض، نحن مطالبون بتوفير قياس المشهد المراد عرضه. إنها لا فكرة جيدة أن نستعمل عرض و
-			طول المنطقة التي نريد ملأها في الصفحة. في هذه الحالة إستعملنا عرض و طول نافدة المتصفح. بالنسبة لتطبيقات عالية
-			الأداء، يمكنك توفير قيم أقل مثل <strong>window.innerWidth/2</strong> و <strong>window.innerHeight/2</strong>،
-			التي
-			ستجعل المشهد يعرض أسرع بنصف المدة السابقة.
-		</p>
-
-		<p>
-			على سبيل المثال إلغاء قيمة <strong>updateStyle</strong> كالأتي:
-			<br />
-			<strong>setSize(window.innerWidth/2, window.innerHeight/2, false)</strong>
-			<br />
-			ستجعل المشهد يعرض بدقة أقل بنصف
-			الدرجة القديمة، مع العلم أن < canvas>
-				الخاصة بك تم إمدادها ب100% في كلا الطول و العرض.
-		</p>
-
-		<p>
-			أخيرا و ليس أخرا، سنقوم بإضافة <strong>العارض</strong> إلى ملف الـHTML.
-			<br />
-			< canvas> هو وسم يستعمله العارض لإظهار المشهد من خلاله.
-		</p>
-
-		<p>
-			<em>"كل شيء جيد، و لكن أي المكعب الذي وعدتنا به؟"</em> لنقم بإضافته الأن.
-		</p>
+		<p>لنتمهل لحظة من أجل توضيح ما يحصل هنا. لقد قمنا بتحضير كل من المسرح، الكاميرا، و العارض.</p>
+
+		<p>هناك العديد من الخيارات بخصوص نوع الكاميرا. للوقت الراهن، سنستعمل `PerspectiveCamera`.</p>
+
+		<p>أول قيمه هي `مجال الرؤية - field of view `.FOV تمثل مجال المشاهدة المتاح في أي وقت من العرض. وحده قيسها هي الدرجة (degrees)</p>
+		
+		<p>ثاني قيمة هي `نسبة العرض إلى الارتفاع - aspect ratio`. من المستحسن إستعمال نتيجة قسمة عرض وطول العنصر الحاوي، و إلا ستحصل على تجربة مماثلة لمشاهدة فيلم قديم على تلفاز عريض حيث ستكون الصورة مضغوطة.</p>
+
+		<p>القيمتين المتبقيتين هما `أقرب - near` و `أبعد - far` سطح فاصل. القصد هو اي شيء بعيد عن الكاميرا من قيمه `far` او اقرب من قيمه `near` لن يتم عرضهم.أنت لست مطالب بالقلق حيال هذا، و لكن من الممكن أن تريد إستعمال قيم أخرى من أجل الحصول على أداء أفضل.</p>
+	
+		<p>الخطوة التالية الأن هوالعارض. بالإضافة إلى إنشاء مثيل العارض,يتعين علينا أيضًا تعيين الحجم الذي نرغب في عرض تطبيقنا به.هنا من الفكرة الجيدة استخدام عرض وارتفاع المنطقة التي نرغب في ملئها بتطبيقنا - في هذه الحالة، عرض وارتفاع نافذة المتصفح. بالنسبة لتطبيقات تتطلب أداءً مكثفًا، يمكنك أيضًا تقديم قيم أصغر لـ `setSize`، مثل `window.innerWidth/2` و `window.innerHeight/2`، مما سيجعل التطبيق يعرض بحجم ربع الشاشة.</p>
+				
+		<p>إذا كنت ترغب في الاحتفاظ بحجم تطبيقك ولكن تقديمه بدقة أقل، يمكنك القيام بذلك عن طريق استخدام `setSize` و استخدام قيمه false ل`updateStyle` المعامل الثالث . على سبيل المثال، setSize(window.innerWidth/2, window.innerHeight/2, false) سيقوم بتقديم تطبيقك بدقة نصف الحجم، شريطةً أن لديك &lt;canvas&gt; بعرض وارتفاع 100% </p>
+
+		<p>أخيرا و ليس أخرا، سنقوم بإضافة `العارض - renderer` إلى ملف الHTML. <br> &lt; canvas &gt; هو وسم يستعمله العارض لإظهار المشهد من خلاله.</p>
+
+		<p><em>"كل شيء جيد، و لكن أي المكعب الذي وعدتنا به؟"</em> لنقم بإضافته الأن.</p>
+
 
 
 		<code>
 		<code>
 		const geometry = new THREE.BoxGeometry( 1, 1, 1 );
 		const geometry = new THREE.BoxGeometry( 1, 1, 1 );
@@ -126,44 +60,18 @@
 
 
 		camera.position.z = 5;
 		camera.position.z = 5;
 		</code>
 		</code>
+		
+		<p>لكي نقوم بإنشاء مكعب، نحتاج مكون `BoxGeometry`. هذا الأخير مسؤول عن حفض أماكن كل النقاط (`vertices`) و تعبئة كل الأوجه (`faces`) المكونة للمكعب. سنقوم بالتعمق في هذا الموضوع مستقبلا.</p>
+
+		<p>بالإضافة إلى الهندسة الخاصة بالمكعب، نحتاج الي مادة له لتعطيه لون. Three.js تأتي مع العديد من المواد،ولكن سنكتفي بإستعمال `MeshBasicMaterial` الان. كل المواد تأخذ مجموعة من القيم ستطبق عليها من أجل الوصول إلى النتيجة المرادة. لإبقاء الأشياء بسيطة، قمنا بإرفاق قيمة اللون التي `0x00ff00`، و الذي يمثل اللون الأخضر. كيفية إحتساب القيمة هي نفسها كإستعمال CSS أو Photoshop(`hex colors`).</p>
+		
+		<p>الخطوة التالية هي إنشاء `جسم - Mesh`. نقصد به الشيء الذي سيتكفل بالتعامل مع هندسة الشكل و تطبيقهاعلى المادة المرفوقة، و من ثم يمكننا إدخال الشكل الجسم النهائي إلى المشهد، و التحرك بحرية حوله.</p>
 
 
-		<p>
-			لكي نقوم بإنشاء مكعب، نحتاج مكون <strong>BoxGeometry</strong>. هذا الأخير مسؤول عن حفض أماكن كل النقاط
-			(<strong>vertices</strong>) و تعبئة كل الأوجه
-			(<strong>faces</strong>) المكونة للمكعب. سنقوم بالتعمق في هذا الموضوع مستقبلا.
-		</p>
-
-		<p>
-			بالإضافة إلى الهندسة الخاصة بالمكعب، نحتاج المادة المكونة له لتعطيه لون. Three.js تأتي مع العديد من المواد،
-			و
-			لكن سنكتفي بإستعمال <strong>MeshBasicMaterial</strong> للوقت الراهن. كل المواد تأخذ مجموعة من القيم ستطبق
-			عليها
-			من أجل الوصول إلى النتيجة المرادة. لإبقاء الأشياء بسيطة، قمنا بإرفاق قيمة اللون التي تحمل
-			<strong>0x00ff00</strong>، و الذي يمثل اللون الأخضر. كيفية إحتساب القيمة هي نفسها كإستعمال CSS أو Photoshop
-			(<strong>hex colors</strong>).
-		</p>
-
-		<p>
-			الخطوة التالية هي إنشاء جسم <strong>Mesh</strong>. نقصد به الشيء الذي سيتكفل بالتعامل مع هندسة الشكل و
-			تطبيقها
-			على المادة المرفوقة، و من ثم يمكننا إدخال الشكل الجسم النهائي إلى المشهد، و التحرك بحرية حوله.
-		</p>
-
-		<p>
-			عند إستعمال أمر <strong>()scene.add</strong>، الشيء المراد إضافته للمشهد سيضاف في الإحداثيات التالية
-			(<strong>0,0,0</strong>). هذا يمكن له أن يشكل بعض المشاكل كون الكاميرا في هذه الحالة وسط المكعب. لتجنب هذا
-			نقوم
-			ببساطة بإبعاد الكاميرا قليلا.
-		</p>
+		<p>بشكل افتراضي عند إستعمال أمر `scene.add()`، الشيء المراد إضافته للمشهد سيضاف في الإحداثيات التالية (`0,0,0`) . هذا يمكن له أن يشكل بعض المشاكل كون الكاميرا في هذه الحالة داخل المكعب. لتجنب هذا نقوم ببساطة بإبعاد الكاميرا قليلا.</p>
 
 
 		<h2>عرض المشهد</h2>
 		<h2>عرض المشهد</h2>
 
 
-		<p>
-			إن قمت بنسخ الأوامر البرمجية الموجودة أعله وسط ملف HTML الذي قمنا بإنشائه مسبقا، لم تتمكن من رؤية أي شيء حتى
-			الأن. هذا بسبب أننا لم نقم بعرض أي شيء حتى اللحظة. لذلك، ما نحتاجه يدعى العرض (<strong>render</strong>) أو
-			حلقة
-			الحركات (<strong>animation loop</strong>).
-		</p>
+		<p>إن قمت بنسخ الأوامر البرمجية الموجودة أعله وسط ملف HTML الذي قمنا بإنشائه مسبقا، لم تتمكن من رؤية أي شيء حتى الأن. هذا بسبب أننا لم نقم بعرض أي شيء حتى اللحظة. لذلك، ما نحتاجه يدعى  (`العرض - render`) أو (`حلقةالحركات - animation loop`).</p>
 
 
 		<code>
 		<code>
 		function animate() {
 		function animate() {
@@ -172,57 +80,33 @@
 		}
 		}
 		animate();
 		animate();
 		</code>
 		</code>
-
-		<p>
-			هذه الشفرة البرمجية تقوم بإنشاء حلقة تجعل العارض يعيد تحديث المشهد كل مرة يحدث فيها تغيير في الصفحة (أو نظريا
-			هذا يعني 60
-			مرة
-			خلال كل ثانية). إن كنت لا تملك تجربة مسبقة في صناعة ألعاب المتصفح، ستتسائل <em>"لماذا لا نستعمل
-				setInterval؟"</em> الحقيقة أننا بإمكاننا ذلك و لكن <strong>requestAnimationFrame</strong> تقدم لنا
-			العديد من
-			المزايا. من أهما أنها تقوم بإيقاف العمل عندما يقوم المستعمل بتغيير الصفحة، بالإضافة لعدم إستهلاك قدرة
-			الحاسب الخاص بالجهاز و عمر البطارية.
-		</p>
+		
+		<p>هذه الشفره ستقوم بإنشاء حلقة تكراريه تجعل العارض يعيد تحديث المشهد كل مرة يحدث فيها تغيير في الصفحة (أو نظرياهذا يعني 60 مرةخلال كل ثانية). إن كنت لا تملك تجربة مسبقة في صناعة ألعاب المتصفح، ستتسائل <em>"لماذا لا نستعمل setInterval؟"</em> الحقيقة أننا بإمكاننا ذلك و لكن `requestAnimationFrame` تقدم لنا العديد من المزايا. من أهما أنها تقوم بإيقاف العمل عندما يقوم المستعمل بتغيير الصفحة، بالإضافة لعدم إستهلاك قدرة الحاسب الخاص بالجهاز و عمر البطارية.</p>
 
 
 		<h2>تحريك المكعب</h2>
 		<h2>تحريك المكعب</h2>
 
 
-		<p>
-			إن قمت بإضافة الأوامر البرمجية السابقة للملف الخاص بك، من الأرجح أنك ترى الأن مكعبا أخضر اللون. لنقم بجعله
-			أكثر
-			جذابية من خلال تدويره.
-		</p>
+		<p>إن قمت بإضافة الشفرات السابقه للملف الخاص بك، من الأرجح أنك ترى الأن مكعبا أخضر اللون. لنقم بجعله أكثر جذابية من خلال تدويره.</p>
 
 
-		<p>
-			قم بإضافة الشفرة التالية فوق السطر الذي يحتوي أمر <strong>renderer.render</strong> في الوظيفة
-			(<strong>animate</strong>):
-		</p>
+		<p>قم بإضافة الشفرة التالية فوق السطر الذي يحتوي أمر `renderer.render` في الوظيفة `animate`:</p>
 
 
 		<code>
 		<code>
 		cube.rotation.x += 0.01;
 		cube.rotation.x += 0.01;
 		cube.rotation.y += 0.01;
 		cube.rotation.y += 0.01;
 		</code>
 		</code>
 
 
-		<p>
-			هذه الأوامر سيتم تشغيلها في كل إطار (frame). ما يعني 60 مرة في الثانية تقريبا، و بذلك ستمكن المكعب من الدوران.
-			في
-			الأساس، أي شيء تريد تحريكه أو تغيره خلال فترة عمل التطبيق يستوجب أن تكون الأوامر الخاصة بذلك قد تم تشغيلها
-			داخل
-			حلقة الحركات. يمكنك بالتأكيد مناداة وظائف أخرى، لكي لا ينتهي بك المطاف بوظيفة واحدة تحتوي على مئات السطور.
-		</p>
+		<p>هذه الأوامر سيتم تشغيلها في كل  (اطار - frame,ما يعني 60 مرة في الثانية تقريبا).و بذلك ستمكن المكعب من الدوران. في الأساس، أي شيء تريد تحريكه أو تغيره خلال فترة عمل التطبيق يستوجب أن تكون الأوامر الخاصة بذلك قد تم تشغيلها داخل حلقة الحركات. يمكنك بالتأكيد مناداة وظائف أخرى، لكي لا ينتهي بك المطاف بوظيفة واحدة تحتوي على مئات السطور.</p>
 
 
 		<h2>النتيجة</h2>
 		<h2>النتيجة</h2>
-		<p>
-			تهانينا! لقد قمت بإكمال أول تطبيق three.js لك. الأمر ليس معقدا، يجب عليك فقد البدأ بشيء ما.
-		</p>
+		
+		<p>تهانينا! لقد قمت بإكمال أول تطبيق three.js لك. الأمر ليس معقدا، يجب عليك فقد البدأ من مكان ما.</p>
 
 
-		<p>
-			الشفرة البرمجية الكاملة في الأسفل إلى جانب محرر مباشر [link:https://jsfiddle.net/0c1oqf38/ live example].
-			أنت
-			مدعو للعب بالأوامر البرمجية لكي تصبح صورة كيفية عملها أوضح من قبل.
-		</p>
+		<p>الشفرة البرمجية الكاملة في الأسفل إلى جانب محرر مباشر [link:https://jsfiddle.net/0c1oqf38/ live example]. العب بالأوامر البرمجية لتكون صورة افضل عن كيفية عملها.</p>
+
+		<p class="RtlTitle"><i>index.html —</i></p>
 
 
 		<code>
 		<code>
-		&lt;html&gt;
+		&lt;!DOCTYPE html&gt;
+		&lt;html lang="en"&gt;
 			&lt;head&gt;
 			&lt;head&gt;
 				&lt;meta charset="utf-8"&gt;
 				&lt;meta charset="utf-8"&gt;
 				&lt;title&gt;My first three.js app&lt;/title&gt;
 				&lt;title&gt;My first three.js app&lt;/title&gt;
@@ -231,36 +115,40 @@
 				&lt;/style&gt;
 				&lt;/style&gt;
 			&lt;/head&gt;
 			&lt;/head&gt;
 			&lt;body&gt;
 			&lt;body&gt;
-				&lt;script type="module"&gt;
-					import * as THREE from 'https://unpkg.com/three/build/three.module.js';
+				&lt;script type="module" src="/main.js"&gt;&lt;/script&gt;
+			&lt;/body&gt;
+		&lt;/html&gt;
+		</code>
 
 
-					const scene = new THREE.Scene();
-					const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );
+		<p class="RtlTitle"><i>main.js —</i></p>
 
 
-					const renderer = new THREE.WebGLRenderer();
-					renderer.setSize( window.innerWidth, window.innerHeight );
-					document.body.appendChild( renderer.domElement );
+		<code>
+		import * as THREE from 'three';
 
 
-					const geometry = new THREE.BoxGeometry( 1, 1, 1 );
-					const material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
-					const cube = new THREE.Mesh( geometry, material );
-					scene.add( cube );
+		const scene = new THREE.Scene();
+		const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );
 
 
-					camera.position.z = 5;
+		const renderer = new THREE.WebGLRenderer();
+		renderer.setSize( window.innerWidth, window.innerHeight );
+		document.body.appendChild( renderer.domElement );
 
 
-					function animate() {
-						requestAnimationFrame( animate );
+		const geometry = new THREE.BoxGeometry( 1, 1, 1 );
+		const material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
+		const cube = new THREE.Mesh( geometry, material );
+		scene.add( cube );
 
 
-						cube.rotation.x += 0.01;
-						cube.rotation.y += 0.01;
+		camera.position.z = 5;
 
 
-						renderer.render( scene, camera );
-					}
+		function animate() {
+			requestAnimationFrame( animate );
 
 
-					animate();
-				&lt;/script&gt;
-			&lt;/body&gt;
-		&lt;/html&gt;
+			cube.rotation.x += 0.01;
+			cube.rotation.y += 0.01;
+
+			renderer.render( scene, camera );
+		}
+
+		animate();
 		</code>
 		</code>
 	</body>
 	</body>
 </html>
 </html>

+ 49 - 36
docs/manual/ar/introduction/How-to-update-things.html

@@ -11,24 +11,24 @@
 		<div>
 		<div>
 			<p>تقوم كل الكائنات بشكل ألي بتحديث حالتها تلقائيًا إذا تمت إضافتها إلى المشهد باستخدام</p>
 			<p>تقوم كل الكائنات بشكل ألي بتحديث حالتها تلقائيًا إذا تمت إضافتها إلى المشهد باستخدام</p>
 			<code>
 			<code>
-const object = new THREE.Object3D();
-scene.add( object );
+			const object = new THREE.Object3D();
+			scene.add( object );
 			</code>
 			</code>
 			<p>أو إذا كانوا أبناء كائن آخر تمت إضافته إلى المشهد:</p>
 			<p>أو إذا كانوا أبناء كائن آخر تمت إضافته إلى المشهد:</p>
 			<code>
 			<code>
-const object1 = new THREE.Object3D();
-const object2 = new THREE.Object3D();
+			const object1 = new THREE.Object3D();
+			const object2 = new THREE.Object3D();
 
 
-object1.add( object2 );
-scene.add( object1 ); //object1 and object2 will automatically update their matrices
+			object1.add( object2 );
+			scene.add( object1 ); //object1 and object2 will automatically update their matrices
 			</code>
 			</code>
 		</div>
 		</div>
 
 
 		<p>ومع ذلك ، إذا كنت تعلم أن الكائن سيكون ثابتًا ، فيمكنك تعطيل هذا وتحديث وضيفة التحديث يدويًا عند الحاجة فقط.</p>
 		<p>ومع ذلك ، إذا كنت تعلم أن الكائن سيكون ثابتًا ، فيمكنك تعطيل هذا وتحديث وضيفة التحديث يدويًا عند الحاجة فقط.</p>
 
 
 		<code>
 		<code>
-object.matrixAutoUpdate = false;
-object.updateMatrix();
+		object.matrixAutoUpdate = false;
+		object.updateMatrix();
 		</code>
 		</code>
 
 
 		<h2>BufferGeometry</h2>
 		<h2>BufferGeometry</h2>
@@ -48,62 +48,67 @@ object.updateMatrix();
 				سنستخدم مثال السطر الذي سيتم تمديده في وقت العرض. سنخصص مساحة في المخزن المؤقت لـ 500 رأس لكننا نرسم اثنين فقط في البداية ، باستخدام [page:BufferGeometry.drawRange].
 				سنستخدم مثال السطر الذي سيتم تمديده في وقت العرض. سنخصص مساحة في المخزن المؤقت لـ 500 رأس لكننا نرسم اثنين فقط في البداية ، باستخدام [page:BufferGeometry.drawRange].
 			</p>
 			</p>
 			<code>
 			<code>
-const MAX_POINTS = 500;
+			const MAX_POINTS = 500;
 
 
-// geometry
-const geometry = new THREE.BufferGeometry();
+			// geometry
+			const geometry = new THREE.BufferGeometry();
 
 
-// attributes
-const positions = new Float32Array( MAX_POINTS * 3 ); // 3 vertices per point
-geometry.setAttribute( 'position', new THREE.BufferAttribute( positions, 3 ) );
+			// attributes
+			const positions = new Float32Array( MAX_POINTS * 3 ); // 3 vertices per point
+			geometry.setAttribute( 'position', new THREE.BufferAttribute( positions, 3 ) );
 
 
-// draw range
-const drawCount = 2; // draw the first 2 points, only
-geometry.setDrawRange( 0, drawCount );
+			// draw range
+			const drawCount = 2; // draw the first 2 points, only
+			geometry.setDrawRange( 0, drawCount );
 
 
-// material
-const material = new THREE.LineBasicMaterial( { color: 0xff0000 } );
+			// material
+			const material = new THREE.LineBasicMaterial( { color: 0xff0000 } );
 
 
-// line
-const line = new THREE.Line( geometry, material );
-scene.add( line );
+			// line
+			const line = new THREE.Line( geometry, material );
+			scene.add( line );
 			</code>
 			</code>
 		 	<p>
 		 	<p>
 				بعد ذلك سنضيف نقاطًا بشكل عشوائي إلى الخط باستخدام نمط مثل:
 				بعد ذلك سنضيف نقاطًا بشكل عشوائي إلى الخط باستخدام نمط مثل:
 			</p>
 			</p>
 			<code>
 			<code>
-const positionAttribute = line.geometry.getAttribute( 'position' );
+			const positionAttribute = line.geometry.getAttribute( 'position' );
 
 
-let x = 0, y = 0, z = 0;
+			let x = 0, y = 0, z = 0;
 
 
-for ( let i = 0; i < positionAttribute.count; i ++ ) {
+			for ( let i = 0; i < positionAttribute.count; i ++ ) {
 
 
-	positionAttribute.setXYZ( i, x, y, z );
+				positionAttribute.setXYZ( i, x, y, z );
 
 
-	x += ( Math.random() - 0.5 ) * 30;
-	y += ( Math.random() - 0.5 ) * 30;
-	z += ( Math.random() - 0.5 ) * 30;
+				x += ( Math.random() - 0.5 ) * 30;
+				y += ( Math.random() - 0.5 ) * 30;
+				z += ( Math.random() - 0.5 ) * 30;
 
 
-}
+			}
 			</code>
 			</code>
+			
 			<p>
 			<p>
 				إذا كنت تريد تغيير <em>عدد النقاط</em> التي تم إظهارها بعد العرض الأول ، فقم بما يلي:
 				إذا كنت تريد تغيير <em>عدد النقاط</em> التي تم إظهارها بعد العرض الأول ، فقم بما يلي:
 			</p>
 			</p>
+
 			<code>
 			<code>
-line.geometry.setDrawRange( 0, newValue );
+			line.geometry.setDrawRange( 0, newValue );
 			</code>
 			</code>
+			
 			<p>
 			<p>
 				إذا كنت تريد تغيير قيم بيانات الموضع بعد العرض الأول ، فأنت بحاجة إلى تعيين علامة needsUpdate على النحو التالي:
 				إذا كنت تريد تغيير قيم بيانات الموضع بعد العرض الأول ، فأنت بحاجة إلى تعيين علامة needsUpdate على النحو التالي:
 			</p>
 			</p>
+			
 			<code>
 			<code>
-positionAttribute.needsUpdate = true; // required after the first render
+			positionAttribute.needsUpdate = true; // required after the first render
 			</code>
 			</code>
 
 
 			<p>
 			<p>
 				إذا قمت بتغيير قيم بيانات الموقع بعد التصيير الأولي ، فقد تحتاج إلى استدعاء `` .computeBoundingSphere () 'لإعادة حساب المجال المحيط للهندسة.
 				إذا قمت بتغيير قيم بيانات الموقع بعد التصيير الأولي ، فقد تحتاج إلى استدعاء `` .computeBoundingSphere () 'لإعادة حساب المجال المحيط للهندسة.
 			</p>
 			</p>
+			
 			<code>
 			<code>
-line.geometry.computeBoundingSphere();
+			line.geometry.computeBoundingSphere();
 			</code>
 			</code>
 
 
 			<p>
 			<p>
@@ -143,6 +148,7 @@ line.geometry.computeBoundingSphere();
 			</ul>
 			</ul>
 
 
 			<p>تتطلب التغييرات في هذه بناء برنامج شادر (shader) جديد. سوف تحتاج إلى ضبط</p>
 			<p>تتطلب التغييرات في هذه بناء برنامج شادر (shader) جديد. سوف تحتاج إلى ضبط</p>
+			
 			<code>material.needsUpdate = true</code>
 			<code>material.needsUpdate = true</code>
 
 
 			<p>ضع في اعتبارك أن هذا قد يكون بطيئًا للغاية ويؤدي إلى اهتزاز في معدل الإطارات (خاصة على Windows ، حيث أن التحويل البرمجي للشادر (shader) يكون أبطأ في DirectX منه في OpenGL).</p>
 			<p>ضع في اعتبارك أن هذا قد يكون بطيئًا للغاية ويؤدي إلى اهتزاز في معدل الإطارات (خاصة على Windows ، حيث أن التحويل البرمجي للشادر (shader) يكون أبطأ في DirectX منه في OpenGL).</p>
@@ -152,11 +158,13 @@ line.geometry.computeBoundingSphere();
 			<p>يمكنك تغيير المواد المستخدمة في القطع الهندسية بحرية ، ولكن لا يمكنك تغيير كيفية تقسيم الكائن إلى أجزاء (وفقًا لمواد الوجه). </p>
 			<p>يمكنك تغيير المواد المستخدمة في القطع الهندسية بحرية ، ولكن لا يمكنك تغيير كيفية تقسيم الكائن إلى أجزاء (وفقًا لمواد الوجه). </p>
 
 
 			<h3>إذا كنت بحاجة إلى تكوينات مختلفة من المواد أثناء وقت التشغيل:</h3>
 			<h3>إذا كنت بحاجة إلى تكوينات مختلفة من المواد أثناء وقت التشغيل:</h3>
+			
 			<p>إذا كان عدد المواد / القطع الصغيرًة ، فيمكنك تقسيم الجسم مسبقًا (مثل الشعر / الوجه / الجسم / الملابس العلوية / السراويل للإنسان ، أمامي / جوانب / الجزء العلوي / الزجاج / الإطار / الجزء الداخلي للسيارة). </p>
 			<p>إذا كان عدد المواد / القطع الصغيرًة ، فيمكنك تقسيم الجسم مسبقًا (مثل الشعر / الوجه / الجسم / الملابس العلوية / السراويل للإنسان ، أمامي / جوانب / الجزء العلوي / الزجاج / الإطار / الجزء الداخلي للسيارة). </p>
 
 
 			<p>إذا كان الرقم كبيرًا (على سبيل المثال ، من المحتمل أن يكون كل وجه مختلفًا) ، ففكر في حل مختلف ، مثل استخدام السمات / القوام للحصول على مظهر مختلف لكل وجه.</p>
 			<p>إذا كان الرقم كبيرًا (على سبيل المثال ، من المحتمل أن يكون كل وجه مختلفًا) ، ففكر في حل مختلف ، مثل استخدام السمات / القوام للحصول على مظهر مختلف لكل وجه.</p>
 
 
 			<h3>أمثلة</h3>
 			<h3>أمثلة</h3>
+			
 			<p>
 			<p>
 				[example:webgl_materials_car WebGL / materials / car]<br />
 				[example:webgl_materials_car WebGL / materials / car]<br />
 				[example:webgl_postprocessing_dof WebGL / webgl_postprocessing / dof]
 				[example:webgl_postprocessing_dof WebGL / webgl_postprocessing / dof]
@@ -167,9 +175,11 @@ line.geometry.computeBoundingSphere();
 		<h2>النسيج (Textures)</h2>
 		<h2>النسيج (Textures)</h2>
 		<div>
 		<div>
 			<p>يجب أن يتم تعيين العلامات التالية في الصورة ، canvas والفيديو والبيانات إذا تم تغييرها:</p>
 			<p>يجب أن يتم تعيين العلامات التالية في الصورة ، canvas والفيديو والبيانات إذا تم تغييرها:</p>
+			
 			<code>
 			<code>
-				texture.needsUpdate = true;
+			texture.needsUpdate = true;
 			</code>
 			</code>
+			
 			<p>العرض يستهدف التحديث تلقائيا.</p>
 			<p>العرض يستهدف التحديث تلقائيا.</p>
 
 
 			<h3>أمثلة</h3>
 			<h3>أمثلة</h3>
@@ -184,6 +194,7 @@ line.geometry.computeBoundingSphere();
 		<h2>الكاميرات (Cameras)</h2>
 		<h2>الكاميرات (Cameras)</h2>
 		<div>
 		<div>
 			<p>يتم تحديث موضع الكاميرا وهدفها تلقائيًا. إذا كنت بحاجة إلى التغيير</p>
 			<p>يتم تحديث موضع الكاميرا وهدفها تلقائيًا. إذا كنت بحاجة إلى التغيير</p>
+			
 			<ul>
 			<ul>
 				<li>
 				<li>
 					fov
 					fov
@@ -198,12 +209,14 @@ line.geometry.computeBoundingSphere();
 					far
 					far
 				</li>
 				</li>
 			</ul>
 			</ul>
+			
 			<p>
 			<p>
 				ثم ستحتاج إلى إعادة حساب مصفوفة الإسقاط(the projection matrix):
 				ثم ستحتاج إلى إعادة حساب مصفوفة الإسقاط(the projection matrix):
 			</p>
 			</p>
+			
 			<code>
 			<code>
-camera.aspect = window.innerWidth / window.innerHeight;
-camera.updateProjectionMatrix();
+			camera.aspect = window.innerWidth / window.innerHeight;
+			camera.updateProjectionMatrix();
 			</code>
 			</code>
 		</div>
 		</div>
 	</body>
 	</body>

+ 111 - 0
docs/manual/ar/introduction/Libraries-and-Plugins.html

@@ -0,0 +1,111 @@
+<!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">
+		<h1>المكتبات والإضافات ([name])</h1>
+
+		<p class="desc">
+			هنا تُدرج المكتبات والإضافات المتوافقة التي تم تطويرها خارجيًا لمكتبة three.js. هذه القائمة والحزم المرتبطة بها تُدار بواسطة المجتمع ولا يمكن ضمان تحديثها دائمًا. إذا كنت ترغب في تحديث هذه القائمة، يُمكنك عمل PR!"
+		</p>
+
+		<h3 >الفيزياء(Physics)</h3>
+
+		<ul>
+			<li>[link:https://github.com/lo-th/Oimo.js/ Oimo.js]</li>
+			<li>[link:https://enable3d.io/ enable3d]</li>
+			<li>[link:https://github.com/kripken/ammo.js/ ammo.js]</li>
+			<li>[link:https://github.com/pmndrs/cannon-es cannon-es]</li>
+			<li>[link:https://rapier.rs/ rapier]</li>
+			
+		</ul>
+
+		<h3>المعالجة البعدية(Postprocessing)</h3>
+
+		<p>
+		"بالإضافة إلى [link:https://github.com/mrdoob/three.js/tree/dev/examples/jsm/postprocessing تأثيرات المعالجة البعدية الرسمية لمكتبة three.js],يتوفر دعم لبعض التأثيرات والأطُر الإضافية من خلال مكتبات خارجية."
+		</p>
+
+		<ul>
+			<li>[link:https://github.com/vanruesc/postprocessing postprocessing]</li>
+		</ul>
+
+		<h3>أداء التقاطع والاختبار بالأشعة (Intersection and Raycast Performance)</h3>
+
+		<ul>
+			<li>[link:https://github.com/gkjohnson/three-mesh-bvh three-mesh-bvh]</li>
+		</ul>
+
+		<h3>تتبع المسار (Path Tracing)</h3>
+		
+		<ul>
+			<li>[link:https://github.com/gkjohnson/three-gpu-pathtracer three-gpu-pathtracer]</li>
+		</ul>
+		
+		<h3>صيغ الملفات (File Formats)</h3>
+
+		<p>
+		بالإضافة إلى [link:https://github.com/mrdoob/three.js/tree/dev/examples/jsm/loaders محمّلات three.js الرسمية],يتوفر دعم لبعض الصيغ الإضافية من خلال مكتبات خارجية.
+		</p>
+
+		<ul>
+			<li>[link:https://github.com/gkjohnson/urdf-loaders/tree/master/javascript urdf-loader]</li>
+			<li>[link:https://github.com/NASA-AMMOS/3DTilesRendererJS 3d-tiles-renderer-js]</li>
+			<li>[link:https://github.com/kaisalmen/WWOBJLoader WebWorker OBJLoader]</li>
+			<li>[link:https://github.com/IFCjs/web-ifc-three IFC.js]</li>
+		</ul>
+
+		<h3>الشكليات (Geometry)</h3>
+
+		<ul>
+			<li>[link:https://github.com/spite/THREE.MeshLine THREE.MeshLine]</li>
+		</ul>
+
+		<h3>النص ثلاثي الأبعاد والتخطيط (3D Text and Layout)</h3>
+
+		<ul>
+			<li>[link:https://github.com/protectwise/troika/tree/master/packages/troika-three-text troika-three-text]</li>
+			<li>[link:https://github.com/felixmariotto/three-mesh-ui three-mesh-ui]</li>
+		</ul>
+
+		<h3>نظام الجسيمات (Particle Systems)</h3>
+
+		<ul>
+			<li>[link:https://github.com/Alchemist0823/three.quarks three.quarks]</li>
+			<li>[link:https://github.com/creativelifeform/three-nebula three-nebula]</li>
+		</ul>
+
+		<h3>الحركة العكسية الحركية (Inverse Kinematics)</h3>
+
+		<ul>
+			<li>[link:https://github.com/jsantell/THREE.IK THREE.IK]</li>
+			<li>[link:https://github.com/lo-th/fullik fullik]</li>
+			<li>[link:https://github.com/gkjohnson/closed-chain-ik-js closed-chain-ik]</li>
+		</ul>
+
+		<h3>ذكاء اللعبة الاصطناعي (Game AI)</h3>
+
+		<ul>
+			<li>[link:https://mugen87.github.io/yuka/ yuka]</li>
+			<li>[link:https://github.com/donmccurdy/three-pathfinding three-pathfinding]</li>
+			<li>[link:https://github.com/isaac-mason/recast-navigation-js recast-navigation-js]</li>
+		</ul>
+
+		<h3>الأغلفة والأطُر (Wrappers and Frameworks)</h3>
+
+		<ul>
+			<li>[link:https://aframe.io/ A-Frame]</li>
+			<li>[link:https://lume.io/ Lume] - HTML elements for 3D graphics built on Three.</li>
+			<li>[link:https://github.com/pmndrs/react-three-fiber react-three-fiber] - React components for 3D graphics built on Three.</li>
+			<li>[link:https://github.com/ecsyjs/ecsy-three ECSY]</li>
+			<li>[link:https://threlte.xyz/ Threlte] - Svelte components for 3D graphics built on Three.</li>
+			<li>[link:https://needle.tools/ Needle Engine]</li>
+			<li>[link:https://tresjs.org/ tresjs] - Vue components for 3D graphics built on Three.</li>
+		</ul>
+
+	</body>
+</html>

+ 1 - 0
docs/manual/en/introduction/Libraries-and-Plugins.html

@@ -108,6 +108,7 @@
 			<li>[link:https://github.com/ecsyjs/ecsy-three ECSY]</li>
 			<li>[link:https://github.com/ecsyjs/ecsy-three ECSY]</li>
 			<li>[link:https://threlte.xyz/ Threlte] - Svelte components for 3D graphics built on Three.</li>
 			<li>[link:https://threlte.xyz/ Threlte] - Svelte components for 3D graphics built on Three.</li>
 			<li>[link:https://needle.tools/ Needle Engine]</li>
 			<li>[link:https://needle.tools/ Needle Engine]</li>
+			<li>[link:https://tresjs.org/ tresjs] - Vue components for 3D graphics built on Three.</li>
 		</ul>
 		</ul>
 
 
 	</body>
 	</body>

+ 1 - 0
docs/manual/fr/introduction/Libraries-and-Plugins.html

@@ -107,6 +107,7 @@
 			<li>[link:https://github.com/ecsyjs/ecsy-three ECSY]</li>
 			<li>[link:https://github.com/ecsyjs/ecsy-three ECSY]</li>
 			<li>[link:https://threlte.xyz/ Threlte] - Svelte components for 3D graphics built on Three.</li>
 			<li>[link:https://threlte.xyz/ Threlte] - Svelte components for 3D graphics built on Three.</li>
 			<li>[link:https://needle.tools/ Needle Engine]</li>
 			<li>[link:https://needle.tools/ Needle Engine]</li>
+			<li>[link:https://tresjs.org/ tresjs] - Vue components for 3D graphics built on Three.</li>
 		</ul>
 		</ul>
 
 
 	</body>
 	</body>

+ 1 - 0
docs/manual/it/introduction/Libraries-and-Plugins.html

@@ -107,6 +107,7 @@
 			<li>[link:https://github.com/ecsyjs/ecsy-three ECSY]</li>
 			<li>[link:https://github.com/ecsyjs/ecsy-three ECSY]</li>
 			<li>[link:https://threlte.xyz/ Threlte] - Svelte components for 3D graphics built on Three.</li>
 			<li>[link:https://threlte.xyz/ Threlte] - Svelte components for 3D graphics built on Three.</li>
 			<li>[link:https://needle.tools/ Needle Engine]</li>
 			<li>[link:https://needle.tools/ Needle Engine]</li>
+			<li>[link:https://tresjs.org/ tresjs] - Vue components for 3D graphics built on Three.</li>
 		</ul>
 		</ul>
 
 
 	</body>
 	</body>

+ 1 - 0
docs/manual/ja/introduction/Libraries-and-Plugins.html

@@ -100,6 +100,7 @@
         <li>[link:https://github.com/ecsyjs/ecsy-three ECSY]</li>
         <li>[link:https://github.com/ecsyjs/ecsy-three ECSY]</li>
         <li>[link:https://threlte.xyz/ Threlte] - Svelte components for 3D graphics built on Three.</li>
         <li>[link:https://threlte.xyz/ Threlte] - Svelte components for 3D graphics built on Three.</li>
         <li>[link:https://needle.tools/ Needle Engine]</li>
         <li>[link:https://needle.tools/ Needle Engine]</li>
+        <li>[link:https://tresjs.org/ tresjs] - Vue components for 3D graphics built on Three.</li>
     </ul>
     </ul>
 
 
 </body>
 </body>

+ 1 - 1
docs/manual/pt-br/introduction/Creating-a-scene.html

@@ -61,7 +61,7 @@
 
 
 		<p>Os próximos dois atributos são os planos de corte `near` e `far`. Isso significa que os objetos mais distantes da câmera do que o valor `far` ou mais próximos que o valor `near` não serão renderizados. Você não precisa se preocupar com isso agora, mas pode ser necessário usar outros valores em seus apps para obter uma melhor performance.</p>
 		<p>Os próximos dois atributos são os planos de corte `near` e `far`. Isso significa que os objetos mais distantes da câmera do que o valor `far` ou mais próximos que o valor `near` não serão renderizados. Você não precisa se preocupar com isso agora, mas pode ser necessário usar outros valores em seus apps para obter uma melhor performance.</p>
 
 
-		<p>Em seguida temos o renderizador. É aqui que a mágica acontece. Além da criação da intância do renderizador, nós também precisamos configurar o tamanho em que queremos renderizar nossa aplicação. É uma boa ideia usar o comprimento e a altura da área que queremos preencher com nossa aplicação - no nosso caso, o comprimento e altura da janela do navegador. Para aplicativos de alto desempenho, você pode fornecer valores menores para o `setSize`, como `window.innerWidth/2` e `window.innerHeight/2`, o que fará com que a aplicação seja renderizada no tamanho de um quarto do original.</p>
+		<p>Em seguida temos o renderizador. É aqui que a mágica acontece. Além da criação da instância do renderizador, nós também precisamos configurar o tamanho em que queremos renderizar nossa aplicação. É uma boa ideia usar o comprimento e a altura da área que queremos preencher com nossa aplicação - no nosso caso, o comprimento e altura da janela do navegador. Para aplicativos de alto desempenho, você pode fornecer valores menores para o `setSize`, como `window.innerWidth/2` e `window.innerHeight/2`, o que fará com que a aplicação seja renderizada no tamanho de um quarto do original.</p>
 
 
 		<p>Se você deseja manter o tamanho do seu aplicativo mas renderizá-lo em uma resolução mais baixa, você pode chamar o `setSize` passando false como `updateStyle` (o terceiro argumento). Por exemplo, `setSize(window.innerWidth/2, window.innerHeight/2, false)` irá renderizar sua aplicação na metade da resolução, já que seu elemento &lt;canvas&gt; tem 100% de comprimento e altura.</p>
 		<p>Se você deseja manter o tamanho do seu aplicativo mas renderizá-lo em uma resolução mais baixa, você pode chamar o `setSize` passando false como `updateStyle` (o terceiro argumento). Por exemplo, `setSize(window.innerWidth/2, window.innerHeight/2, false)` irá renderizar sua aplicação na metade da resolução, já que seu elemento &lt;canvas&gt; tem 100% de comprimento e altura.</p>
 
 

+ 1 - 0
docs/manual/pt-br/introduction/Libraries-and-Plugins.html

@@ -107,6 +107,7 @@
 			<li>[link:https://github.com/ecsyjs/ecsy-three ECSY]</li>
 			<li>[link:https://github.com/ecsyjs/ecsy-three ECSY]</li>
 			<li>[link:https://threlte.xyz/ Threlte] - Svelte components for 3D graphics built on Three.</li>
 			<li>[link:https://threlte.xyz/ Threlte] - Svelte components for 3D graphics built on Three.</li>
 			<li>[link:https://needle.tools/ Needle Engine]</li>
 			<li>[link:https://needle.tools/ Needle Engine]</li>
+			<li>[link:https://tresjs.org/ tresjs] - Vue components for 3D graphics built on Three.</li>
 		</ul>
 		</ul>
 
 
 	</body>
 	</body>

+ 1 - 0
docs/manual/ru/introduction/Libraries-and-Plugins.html

@@ -107,6 +107,7 @@
 			<li>[link:https://github.com/ecsyjs/ecsy-three ECSY]</li>
 			<li>[link:https://github.com/ecsyjs/ecsy-three ECSY]</li>
 			<li>[link:https://threlte.xyz/ Threlte] - Svelte components for 3D graphics built on Three.</li>
 			<li>[link:https://threlte.xyz/ Threlte] - Svelte components for 3D graphics built on Three.</li>
 			<li>[link:https://needle.tools/ Needle Engine]</li>
 			<li>[link:https://needle.tools/ Needle Engine]</li>
+			<li>[link:https://tresjs.org/ tresjs] - Vue components for 3D graphics built on Three.</li>
 		</ul>
 		</ul>
 
 
 	</body>
 	</body>

+ 1 - 0
docs/manual/zh/introduction/Libraries-and-Plugins.html

@@ -104,6 +104,7 @@
 			<li>[link:https://github.com/ecsyjs/ecsy-three ECSY]</li>
 			<li>[link:https://github.com/ecsyjs/ecsy-three ECSY]</li>
 			<li>[link:https://threlte.xyz/ Threlte] - Svelte components for 3D graphics built on Three.</li>
 			<li>[link:https://threlte.xyz/ Threlte] - Svelte components for 3D graphics built on Three.</li>
 			<li>[link:https://needle.tools/ Needle Engine]</li>
 			<li>[link:https://needle.tools/ Needle Engine]</li>
+			<li>[link:https://tresjs.org/ tresjs] - Vue components for 3D graphics built on Three.</li>
 		</ul>
 		</ul>
 
 
 	</body>
 	</body>

+ 2 - 1
docs/page.css

@@ -74,7 +74,8 @@ body.rtl ol,
 body.rtl table {
 body.rtl table {
 	direction: rtl !important;
 	direction: rtl !important;
 }
 }
-body.rtl code {
+body.rtl code,
+body.rtl .RtlTitle {
 	direction: ltr !important;
 	direction: ltr !important;
 	text-align: initial;
 	text-align: initial;
 }
 }

+ 1 - 0
editor/js/Editor.js

@@ -44,6 +44,7 @@ function Editor() {
 		spaceChanged: new Signal(),
 		spaceChanged: new Signal(),
 		rendererCreated: new Signal(),
 		rendererCreated: new Signal(),
 		rendererUpdated: new Signal(),
 		rendererUpdated: new Signal(),
+		rendererDetectKTX2Support: new Signal(),
 
 
 		sceneBackgroundChanged: new Signal(),
 		sceneBackgroundChanged: new Signal(),
 		sceneEnvironmentChanged: new Signal(),
 		sceneEnvironmentChanged: new Signal(),

+ 36 - 63
editor/js/Loader.js

@@ -269,21 +269,8 @@ function Loader( editor ) {
 
 
 					const contents = event.target.result;
 					const contents = event.target.result;
 
 
-					const { GLTFLoader } = await import( 'three/addons/loaders/GLTFLoader.js' );
-					const { DRACOLoader } = await import( 'three/addons/loaders/DRACOLoader.js' );
-					const { KTX2Loader } = await import( 'three/addons/loaders/KTX2Loader.js' );
-					const { MeshoptDecoder } = await import( 'three/addons/libs/meshopt_decoder.module.js' );
-
-					const dracoLoader = new DRACOLoader();
-					dracoLoader.setDecoderPath( '../examples/jsm/libs/draco/gltf/' );
-
-					const ktx2Loader = new KTX2Loader();
-					ktx2Loader.setTranscoderPath( '../examples/jsm/libs/basis/' );
+					const loader = await createGLTFLoader();
 
 
-					const loader = new GLTFLoader();
-					loader.setDRACOLoader( dracoLoader );
-					loader.setKTX2Loader( ktx2Loader );
-					loader.setMeshoptDecoder( MeshoptDecoder );
 					loader.parse( contents, '', function ( result ) {
 					loader.parse( contents, '', function ( result ) {
 
 
 						const scene = result.scene;
 						const scene = result.scene;
@@ -292,7 +279,8 @@ function Loader( editor ) {
 						scene.animations.push( ...result.animations );
 						scene.animations.push( ...result.animations );
 						editor.execute( new AddObjectCommand( editor, scene ) );
 						editor.execute( new AddObjectCommand( editor, scene ) );
 
 
-						dracoLoader.dispose();
+						loader.dracoLoader.dispose();
+						loader.ktx2Loader.dispose();
 
 
 					} );
 					} );
 
 
@@ -311,21 +299,7 @@ function Loader( editor ) {
 
 
 					const contents = event.target.result;
 					const contents = event.target.result;
 
 
-					const { DRACOLoader } = await import( 'three/addons/loaders/DRACOLoader.js' );
-					const { GLTFLoader } = await import( 'three/addons/loaders/GLTFLoader.js' );
-					const { KTX2Loader } = await import( 'three/addons/loaders/KTX2Loader.js' );
-					const { MeshoptDecoder } = await import( 'three/addons/libs/meshopt_decoder.module.js' );
-
-					const dracoLoader = new DRACOLoader();
-					dracoLoader.setDecoderPath( '../examples/jsm/libs/draco/gltf/' );
-
-					const ktx2Loader = new KTX2Loader();
-					ktx2Loader.setTranscoderPath( '../examples/jsm/libs/basis/' );
-
-					const loader = new GLTFLoader( manager );
-					loader.setDRACOLoader( dracoLoader );
-					loader.setKTX2Loader( ktx2Loader );
-					loader.setMeshoptDecoder( MeshoptDecoder );
+					const loader = await createGLTFLoader();
 
 
 					loader.parse( contents, '', function ( result ) {
 					loader.parse( contents, '', function ( result ) {
 
 
@@ -335,7 +309,8 @@ function Loader( editor ) {
 						scene.animations.push( ...result.animations );
 						scene.animations.push( ...result.animations );
 						editor.execute( new AddObjectCommand( editor, scene ) );
 						editor.execute( new AddObjectCommand( editor, scene ) );
 
 
-						dracoLoader.dispose();
+						loader.dracoLoader.dispose();
+						loader.ktx2Loader.dispose();
 
 
 					} );
 					} );
 
 
@@ -966,21 +941,7 @@ function Loader( editor ) {
 
 
 				{
 				{
 
 
-					const { GLTFLoader } = await import( 'three/addons/loaders/GLTFLoader.js' );
-					const { DRACOLoader } = await import( 'three/addons/loaders/DRACOLoader.js' );
-					const { KTX2Loader } = await import( 'three/addons/loaders/KTX2Loader.js' );
-					const { MeshoptDecoder } = await import( 'three/addons/libs/meshopt_decoder.module.js' );
-
-					const dracoLoader = new DRACOLoader();
-					dracoLoader.setDecoderPath( '../examples/jsm/libs/draco/gltf/' );
-
-					const ktx2Loader = new KTX2Loader();
-					ktx2Loader.setTranscoderPath( '../examples/jsm/libs/basis/' );
-
-					const loader = new GLTFLoader();
-					loader.setDRACOLoader( dracoLoader );
-					loader.setKTX2Loader( ktx2Loader );
-					loader.setMeshoptDecoder( MeshoptDecoder );
+					const loader = await createGLTFLoader();
 
 
 					loader.parse( file.buffer, '', function ( result ) {
 					loader.parse( file.buffer, '', function ( result ) {
 
 
@@ -989,7 +950,8 @@ function Loader( editor ) {
 						scene.animations.push( ...result.animations );
 						scene.animations.push( ...result.animations );
 						editor.execute( new AddObjectCommand( editor, scene ) );
 						editor.execute( new AddObjectCommand( editor, scene ) );
 
 
-						dracoLoader.dispose();
+						loader.dracoLoader.dispose();
+						loader.ktx2Loader.dispose();
 
 
 					} );
 					} );
 
 
@@ -1001,21 +963,7 @@ function Loader( editor ) {
 
 
 				{
 				{
 
 
-					const { GLTFLoader } = await import( 'three/addons/loaders/GLTFLoader.js' );
-					const { DRACOLoader } = await import( 'three/addons/loaders/DRACOLoader.js' );
-					const { KTX2Loader } = await import( 'three/addons/loaders/KTX2Loader.js' );
-					const { MeshoptDecoder } = await import( 'three/addons/libs/meshopt_decoder.module.js' );
-
-					const dracoLoader = new DRACOLoader();
-					dracoLoader.setDecoderPath( '../examples/jsm/libs/draco/gltf/' );
-
-					const ktx2Loader = new KTX2Loader();
-					ktx2Loader.setTranscoderPath( '../examples/jsm/libs/basis/' );
-
-					const loader = new GLTFLoader();
-					loader.setDRACOLoader( dracoLoader );
-					loader.setKTX2Loader( ktx2Loader );
-					loader.setMeshoptDecoder( MeshoptDecoder );
+					const loader = await createGLTFLoader();
 					
 					
 					loader.parse( strFromU8( file ), '', function ( result ) {
 					loader.parse( strFromU8( file ), '', function ( result ) {
 
 
@@ -1024,7 +972,8 @@ function Loader( editor ) {
 						scene.animations.push( ...result.animations );
 						scene.animations.push( ...result.animations );
 						editor.execute( new AddObjectCommand( editor, scene ) );
 						editor.execute( new AddObjectCommand( editor, scene ) );
 
 
-						dracoLoader.dispose();
+						loader.dracoLoader.dispose();
+						loader.ktx2Loader.dispose();
 
 
 					} );
 					} );
 
 
@@ -1038,6 +987,30 @@ function Loader( editor ) {
 
 
 	}
 	}
 
 
+	async function createGLTFLoader() {
+
+		const { GLTFLoader } = await import( 'three/addons/loaders/GLTFLoader.js' );
+		const { DRACOLoader } = await import( 'three/addons/loaders/DRACOLoader.js' );
+		const { KTX2Loader } = await import( 'three/addons/loaders/KTX2Loader.js' );
+		const { MeshoptDecoder } = await import( 'three/addons/libs/meshopt_decoder.module.js' );
+
+		const dracoLoader = new DRACOLoader();
+		dracoLoader.setDecoderPath( '../examples/jsm/libs/draco/gltf/' );
+
+		const ktx2Loader = new KTX2Loader();
+		ktx2Loader.setTranscoderPath( '../examples/jsm/libs/basis/' );
+
+		editor.signals.rendererDetectKTX2Support.dispatch( ktx2Loader );
+
+		const loader = new GLTFLoader();
+		loader.setDRACOLoader( dracoLoader );
+		loader.setKTX2Loader( ktx2Loader );
+		loader.setMeshoptDecoder( MeshoptDecoder );
+
+		return loader;
+
+	}
+
 }
 }
 
 
 export { Loader };
 export { Loader };

+ 1 - 1
editor/js/Sidebar.Material.MapProperty.js

@@ -17,7 +17,7 @@ function SidebarMaterialMapProperty( editor, property, name ) {
 	const enabled = new UICheckbox( false ).setMarginRight( '8px' ).onChange( onChange );
 	const enabled = new UICheckbox( false ).setMarginRight( '8px' ).onChange( onChange );
 	container.add( enabled );
 	container.add( enabled );
 
 
-	const map = new UITexture().onChange( onMapChange );
+	const map = new UITexture( editor ).onChange( onMapChange );
 	container.add( map );
 	container.add( map );
 
 
 	const mapType = property.replace( 'Map', '' );
 	const mapType = property.replace( 'Map', '' );

+ 3 - 3
editor/js/Sidebar.Scene.js

@@ -175,11 +175,11 @@ function SidebarScene( editor ) {
 	const backgroundColor = new UIColor().setValue( '#000000' ).setMarginLeft( '8px' ).onInput( onBackgroundChanged );
 	const backgroundColor = new UIColor().setValue( '#000000' ).setMarginLeft( '8px' ).onInput( onBackgroundChanged );
 	backgroundRow.add( backgroundColor );
 	backgroundRow.add( backgroundColor );
 
 
-	const backgroundTexture = new UITexture().setMarginLeft( '8px' ).onChange( onBackgroundChanged );
+	const backgroundTexture = new UITexture( editor ).setMarginLeft( '8px' ).onChange( onBackgroundChanged );
 	backgroundTexture.setDisplay( 'none' );
 	backgroundTexture.setDisplay( 'none' );
 	backgroundRow.add( backgroundTexture );
 	backgroundRow.add( backgroundTexture );
 
 
-	const backgroundEquirectangularTexture = new UITexture().setMarginLeft( '8px' ).onChange( onBackgroundChanged );
+	const backgroundEquirectangularTexture = new UITexture( editor ).setMarginLeft( '8px' ).onChange( onBackgroundChanged );
 	backgroundEquirectangularTexture.setDisplay( 'none' );
 	backgroundEquirectangularTexture.setDisplay( 'none' );
 	backgroundRow.add( backgroundEquirectangularTexture );
 	backgroundRow.add( backgroundEquirectangularTexture );
 
 
@@ -244,7 +244,7 @@ function SidebarScene( editor ) {
 	environmentRow.add( new UIText( strings.getKey( 'sidebar/scene/environment' ) ).setWidth( '90px' ) );
 	environmentRow.add( new UIText( strings.getKey( 'sidebar/scene/environment' ) ).setWidth( '90px' ) );
 	environmentRow.add( environmentType );
 	environmentRow.add( environmentType );
 
 
-	const environmentEquirectangularTexture = new UITexture().setMarginLeft( '8px' ).onChange( onEnvironmentChanged );
+	const environmentEquirectangularTexture = new UITexture( editor ).setMarginLeft( '8px' ).onChange( onEnvironmentChanged );
 	environmentEquirectangularTexture.setDisplay( 'none' );
 	environmentEquirectangularTexture.setDisplay( 'none' );
 	environmentRow.add( environmentEquirectangularTexture );
 	environmentRow.add( environmentEquirectangularTexture );
 
 

+ 0 - 48
editor/js/Sidebar.Settings.Viewport.js

@@ -1,48 +0,0 @@
-import { UIPanel, UIText, UIRow } from './libs/ui.js';
-import { UIBoolean } from './libs/ui.three.js';
-
-
-function SidebarSettingsViewport( editor ) {
-
-	const signals = editor.signals;
-	const strings = editor.strings;
-
-	const container = new UIPanel();
-
-	const headerRow = new UIRow();
-	headerRow.add( new UIText( strings.getKey( 'sidebar/settings/viewport' ).toUpperCase() ) );
-	container.add( headerRow );
-
-	// grid
-
-	const showGridRow = new UIRow();
-
-	showGridRow.add( new UIText( strings.getKey( 'sidebar/settings/viewport/grid' ) ).setWidth( '90px' ) );
-
-	const showGrid = new UIBoolean( true ).onChange( function () {
-
-		signals.showGridChanged.dispatch( showGrid.getValue() );
-
-	} );
-	showGridRow.add( showGrid );
-	container.add( showGridRow );
-
-	// helpers
-
-	const showHelpersRow = new UIRow();
-
-	showHelpersRow.add( new UIText( strings.getKey( 'sidebar/settings/viewport/helpers' ) ).setWidth( '90px' ) );
-
-	const showHelpers = new UIBoolean( true ).onChange( function () {
-
-		signals.showHelpersChanged.dispatch( showHelpers.getValue() );
-
-	} );
-	showHelpersRow.add( showHelpers );
-	container.add( showHelpersRow );
-
-	return container;
-
-}
-
-export { SidebarSettingsViewport };

+ 0 - 2
editor/js/Sidebar.Settings.js

@@ -1,6 +1,5 @@
 import { UIPanel, UIRow, UISelect, UISpan, UIText } from './libs/ui.js';
 import { UIPanel, UIRow, UISelect, UISpan, UIText } from './libs/ui.js';
 
 
-import { SidebarSettingsViewport } from './Sidebar.Settings.Viewport.js';
 import { SidebarSettingsShortcuts } from './Sidebar.Settings.Shortcuts.js';
 import { SidebarSettingsShortcuts } from './Sidebar.Settings.Shortcuts.js';
 import { SidebarSettingsHistory } from './Sidebar.Settings.History.js';
 import { SidebarSettingsHistory } from './Sidebar.Settings.History.js';
 
 
@@ -49,7 +48,6 @@ function SidebarSettings( editor ) {
 
 
 	//
 	//
 
 
-	container.add( new SidebarSettingsViewport( editor ) );
 	container.add( new SidebarSettingsShortcuts( editor ) );
 	container.add( new SidebarSettingsShortcuts( editor ) );
 	container.add( new SidebarSettingsHistory( editor ) );
 	container.add( new SidebarSettingsHistory( editor ) );
 
 

+ 1 - 1
editor/js/Storage.js

@@ -1,6 +1,6 @@
 function Storage() {
 function Storage() {
 
 
-	const indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;
+	const indexedDB = window.indexedDB;
 
 
 	if ( indexedDB === undefined ) {
 	if ( indexedDB === undefined ) {
 
 

+ 9 - 12
editor/js/Strings.js

@@ -336,10 +336,6 @@ function Strings( config ) {
 			'sidebar/settings/shortcuts/undo': 'Undo',
 			'sidebar/settings/shortcuts/undo': 'Undo',
 			'sidebar/settings/shortcuts/focus': 'Focus',
 			'sidebar/settings/shortcuts/focus': 'Focus',
 
 
-			'sidebar/settings/viewport': 'Viewport',
-			'sidebar/settings/viewport/grid': 'Grid',
-			'sidebar/settings/viewport/helpers': 'Helpers',
-
 			'sidebar/history': 'History',
 			'sidebar/history': 'History',
 			'sidebar/history/persistent': 'persistent',
 			'sidebar/history/persistent': 'persistent',
 
 
@@ -348,6 +344,9 @@ function Strings( config ) {
 			'toolbar/scale': 'Scale',
 			'toolbar/scale': 'Scale',
 			'toolbar/local': 'Local',
 			'toolbar/local': 'Local',
 
 
+			'viewport/controls/grid': 'Grid',
+			'viewport/controls/helpers': 'Helpers',
+
 			'viewport/info/objects': 'Objects',
 			'viewport/info/objects': 'Objects',
 			'viewport/info/vertices': 'Vertices',
 			'viewport/info/vertices': 'Vertices',
 			'viewport/info/triangles': 'Triangles',
 			'viewport/info/triangles': 'Triangles',
@@ -685,10 +684,6 @@ function Strings( config ) {
 			'sidebar/settings/shortcuts/undo': 'Annuler',
 			'sidebar/settings/shortcuts/undo': 'Annuler',
 			'sidebar/settings/shortcuts/focus': 'Focus',
 			'sidebar/settings/shortcuts/focus': 'Focus',
 
 
-			'sidebar/settings/viewport': 'Viewport',
-			'sidebar/settings/viewport/grid': 'Grille',
-			'sidebar/settings/viewport/helpers': 'Helpers',
-
 			'sidebar/history': 'Historique',
 			'sidebar/history': 'Historique',
 			'sidebar/history/persistent': 'permanent',
 			'sidebar/history/persistent': 'permanent',
 
 
@@ -697,6 +692,9 @@ function Strings( config ) {
 			'toolbar/scale': 'Échelle',
 			'toolbar/scale': 'Échelle',
 			'toolbar/local': 'Local',
 			'toolbar/local': 'Local',
 
 
+			'viewport/controls/grid': 'Grille',
+			'viewport/controls/helpers': 'Helpers',
+
 			'viewport/info/objects': 'Objets',
 			'viewport/info/objects': 'Objets',
 			'viewport/info/vertices': 'Sommets',
 			'viewport/info/vertices': 'Sommets',
 			'viewport/info/triangles': 'Triangles',
 			'viewport/info/triangles': 'Triangles',
@@ -1034,10 +1032,6 @@ function Strings( config ) {
 			'sidebar/settings/shortcuts/undo': '撤销',
 			'sidebar/settings/shortcuts/undo': '撤销',
 			'sidebar/settings/shortcuts/focus': '聚焦',
 			'sidebar/settings/shortcuts/focus': '聚焦',
 
 
-			'sidebar/settings/viewport': '视窗',
-			'sidebar/settings/viewport/grid': '网格',
-			'sidebar/settings/viewport/helpers': '辅助',
-
 			'sidebar/history': '历史记录',
 			'sidebar/history': '历史记录',
 			'sidebar/history/persistent': '本地存储',
 			'sidebar/history/persistent': '本地存储',
 
 
@@ -1046,6 +1040,9 @@ function Strings( config ) {
 			'toolbar/scale': '缩放',
 			'toolbar/scale': '缩放',
 			'toolbar/local': '本地',
 			'toolbar/local': '本地',
 
 
+			'viewport/controls/grid': '网格',
+			'viewport/controls/helpers': '辅助',
+
 			'viewport/info/objects': '物体',
 			'viewport/info/objects': '物体',
 			'viewport/info/vertices': '顶点',
 			'viewport/info/vertices': '顶点',
 			'viewport/info/triangles': '三角形',
 			'viewport/info/triangles': '三角形',

+ 0 - 48
editor/js/Viewport.Camera.js

@@ -1,48 +0,0 @@
-import { UISelect } from './libs/ui.js';
-
-function ViewportCamera( editor ) {
-
-	const signals = editor.signals;
-
-	//
-
-	const select = new UISelect();
-	select.setPosition( 'absolute' );
-	select.setRight( '120px' );
-	select.setTop( '10px' );
-	select.onChange( function () {
-
-		editor.setViewportCamera( this.getValue() );
-
-	} );
-
-	signals.cameraAdded.add( update );
-	signals.cameraRemoved.add( update );
-
-	update();
-
-	//
-
-	function update() {
-
-		const options = {};
-
-		const cameras = editor.cameras;
-
-		for ( const key in cameras ) {
-
-			const camera = cameras[ key ];
-			options[ camera.uuid ] = camera.name;
-
-		}
-
-		select.setOptions( options );
-		select.setValue( editor.viewportCamera.uuid );
-
-	}
-
-	return select;
-
-}
-
-export { ViewportCamera };

+ 88 - 0
editor/js/Viewport.Controls.js

@@ -0,0 +1,88 @@
+import { UIPanel, UISelect } from './libs/ui.js';
+import { UIBoolean } from './libs/ui.three.js';
+
+function ViewportControls( editor ) {
+
+	const signals = editor.signals;
+	const strings = editor.strings;
+
+	const container = new UIPanel();
+	container.setPosition( 'absolute' );
+	container.setRight( '10px' );
+	container.setTop( '10px' );
+	container.setColor( '#ffffff' );
+
+	// grid
+
+	const gridCheckbox = new UIBoolean( true, strings.getKey( 'viewport/controls/grid' ) );
+	gridCheckbox.onChange( function () {
+
+		signals.showGridChanged.dispatch( this.getValue() );
+
+	} );
+	container.add( gridCheckbox );
+
+	// helpers
+
+	const helpersCheckbox = new UIBoolean( true, strings.getKey( 'viewport/controls/helpers' ) );
+	helpersCheckbox.onChange( function () {
+
+		signals.showHelpersChanged.dispatch( this.getValue() );
+
+	} );
+	container.add( helpersCheckbox );
+
+	// camera
+
+	const cameraSelect = new UISelect();
+	cameraSelect.setMarginLeft( '10px' );
+	cameraSelect.setMarginRight( '10px' );
+	cameraSelect.onChange( function () {
+
+		editor.setViewportCamera( this.getValue() );
+
+	} );
+	container.add( cameraSelect );
+
+	signals.cameraAdded.add( update );
+	signals.cameraRemoved.add( update );
+
+	// shading
+
+	const shadingSelect = new UISelect();
+	shadingSelect.setOptions( { 'default': 'default', 'normals': 'normals', 'wireframe': 'wireframe' } );
+	shadingSelect.setValue( 'default' );
+	shadingSelect.onChange( function () {
+
+		editor.setViewportShading( this.getValue() );
+
+	} );
+	container.add( shadingSelect );
+
+	update();
+
+	//
+
+	function update() {
+
+		const options = {};
+
+		const cameras = editor.cameras;
+
+		for ( const key in cameras ) {
+
+			const camera = cameras[ key ];
+			options[ camera.uuid ] = camera.name;
+
+		}
+
+		cameraSelect.setOptions( options );
+		cameraSelect.setValue( editor.viewportCamera.uuid );
+
+	}
+
+	return container;
+
+}
+
+export { ViewportControls };

+ 5 - 8
editor/js/Viewport.Info.js

@@ -12,20 +12,17 @@ function ViewportInfo( editor ) {
 	container.setBottom( '10px' );
 	container.setBottom( '10px' );
 	container.setFontSize( '12px' );
 	container.setFontSize( '12px' );
 	container.setColor( '#fff' );
 	container.setColor( '#fff' );
+	container.setTextTransform( 'lowercase' );
 
 
 	const objectsText = new UIText( '0' ).setMarginLeft( '6px' );
 	const objectsText = new UIText( '0' ).setMarginLeft( '6px' );
 	const verticesText = new UIText( '0' ).setMarginLeft( '6px' );
 	const verticesText = new UIText( '0' ).setMarginLeft( '6px' );
 	const trianglesText = new UIText( '0' ).setMarginLeft( '6px' );
 	const trianglesText = new UIText( '0' ).setMarginLeft( '6px' );
 	const frametimeText = new UIText( '0' ).setMarginLeft( '6px' );
 	const frametimeText = new UIText( '0' ).setMarginLeft( '6px' );
 
 
-	container.add( new UIText( strings.getKey( 'viewport/info/objects' ) ).setTextTransform( 'lowercase' ) );
-	container.add( objectsText, new UIBreak() );
-	container.add( new UIText( strings.getKey( 'viewport/info/vertices' ) ).setTextTransform( 'lowercase' ) );
-	container.add( verticesText, new UIBreak() );
-	container.add( new UIText( strings.getKey( 'viewport/info/triangles' ) ).setTextTransform( 'lowercase' ) );
-	container.add( trianglesText, new UIBreak() );
-	container.add( new UIText( strings.getKey( 'viewport/info/frametime' ) ).setTextTransform( 'lowercase' ) );
-	container.add( frametimeText, new UIBreak() );
+	container.add( new UIText( strings.getKey( 'viewport/info/objects' ) ), objectsText, new UIBreak() );
+	container.add( new UIText( strings.getKey( 'viewport/info/vertices' ) ), verticesText, new UIBreak() );
+	container.add( new UIText( strings.getKey( 'viewport/info/triangles' ) ), trianglesText, new UIBreak() );
+	container.add( new UIText( strings.getKey( 'viewport/info/frametime' ) ), frametimeText, new UIBreak() );
 
 
 	signals.objectAdded.add( update );
 	signals.objectAdded.add( update );
 	signals.objectRemoved.add( update );
 	signals.objectRemoved.add( update );

+ 0 - 21
editor/js/Viewport.Shading.js

@@ -1,21 +0,0 @@
-import { UISelect } from './libs/ui.js';
-
-function ViewportShading( editor ) {
-
-	const select = new UISelect();
-	select.setPosition( 'absolute' );
-	select.setRight( '10px' );
-	select.setTop( '10px' );
-	select.setOptions( { 'default': 'default', 'normals': 'normals', 'wireframe': 'wireframe' } );
-	select.setValue( 'default' );
-	select.onChange( function () {
-
-		editor.setViewportShading( this.getValue() );
-
-	} );
-
-	return select;
-
-}
-
-export { ViewportShading };

+ 16 - 12
editor/js/Viewport.js

@@ -6,8 +6,7 @@ import { UIPanel } from './libs/ui.js';
 
 
 import { EditorControls } from './EditorControls.js';
 import { EditorControls } from './EditorControls.js';
 
 
-import { ViewportCamera } from './Viewport.Camera.js';
-import { ViewportShading } from './Viewport.Shading.js';
+import { ViewportControls } from './Viewport.Controls.js';
 import { ViewportInfo } from './Viewport.Info.js';
 import { ViewportInfo } from './Viewport.Info.js';
 
 
 import { ViewHelper } from './Viewport.ViewHelper.js';
 import { ViewHelper } from './Viewport.ViewHelper.js';
@@ -27,8 +26,7 @@ function Viewport( editor ) {
 	container.setId( 'viewport' );
 	container.setId( 'viewport' );
 	container.setPosition( 'absolute' );
 	container.setPosition( 'absolute' );
 
 
-	container.add( new ViewportCamera( editor ) );
-	container.add( new ViewportShading( editor ) );
+	container.add( new ViewportControls( editor ) );
 	container.add( new ViewportInfo( editor ) );
 	container.add( new ViewportInfo( editor ) );
 
 
 	//
 	//
@@ -39,12 +37,10 @@ function Viewport( editor ) {
 	const camera = editor.camera;
 	const camera = editor.camera;
 	const scene = editor.scene;
 	const scene = editor.scene;
 	const sceneHelpers = editor.sceneHelpers;
 	const sceneHelpers = editor.sceneHelpers;
-	let showSceneHelpers = true;
 
 
 	// helpers
 	// helpers
 
 
 	const grid = new THREE.Group();
 	const grid = new THREE.Group();
-	sceneHelpers.add( grid );
 
 
 	const grid1 = new THREE.GridHelper( 30, 30, 0x888888 );
 	const grid1 = new THREE.GridHelper( 30, 30, 0x888888 );
 	grid1.material.color.setHex( 0x888888 );
 	grid1.material.color.setHex( 0x888888 );
@@ -388,6 +384,12 @@ function Viewport( editor ) {
 
 
 	} );
 	} );
 
 
+	signals.rendererDetectKTX2Support.add( function ( ktx2Loader ) {
+
+		ktx2Loader.detectSupport( renderer );
+
+	} );
+
 	signals.sceneGraphChanged.add( function () {
 	signals.sceneGraphChanged.add( function () {
 
 
 		render();
 		render();
@@ -671,17 +673,18 @@ function Viewport( editor ) {
 
 
 	} );
 	} );
 
 
-	signals.showGridChanged.add( function ( showGrid ) {
+	signals.showGridChanged.add( function ( value ) {
+
+		grid.visible = value;
 
 
-		grid.visible = showGrid;
 		render();
 		render();
 
 
 	} );
 	} );
 
 
-	signals.showHelpersChanged.add( function ( showHelpers ) {
+	signals.showHelpersChanged.add( function ( value ) {
 
 
-		showSceneHelpers = showHelpers;
-		transformControls.enabled = showHelpers;
+		sceneHelpers.visible = value;
+		transformControls.enabled = value;
 
 
 		render();
 		render();
 
 
@@ -756,7 +759,8 @@ function Viewport( editor ) {
 		if ( camera === editor.viewportCamera ) {
 		if ( camera === editor.viewportCamera ) {
 
 
 			renderer.autoClear = false;
 			renderer.autoClear = false;
-			if ( showSceneHelpers === true ) renderer.render( sceneHelpers, camera );
+			if ( grid.visible === true ) renderer.render( grid, camera );
+			if ( sceneHelpers.visible === true ) renderer.render( sceneHelpers, camera );
 			if ( vr.currentSession === null ) viewHelper.render( renderer );
 			if ( vr.currentSession === null ) viewHelper.render( renderer );
 			renderer.autoClear = true;
 			renderer.autoClear = true;
 
 

+ 11 - 1
editor/js/libs/ui.js

@@ -429,6 +429,14 @@ class UICheckbox extends UIElement {
 		this.dom.className = 'Checkbox';
 		this.dom.className = 'Checkbox';
 		this.dom.type = 'checkbox';
 		this.dom.type = 'checkbox';
 
 
+		this.dom.addEventListener( 'pointerdown', function ( event ) {
+
+			// Workaround for TransformControls blocking events in Viewport.Controls checkboxes
+
+			event.stopPropagation();
+		
+		} );
+
 		this.setValue( boolean );
 		this.setValue( boolean );
 
 
 	}
 	}
@@ -608,7 +616,7 @@ class UINumber extends UIElement {
 				prevPointer.x = event.touches[ 0 ].pageX;
 				prevPointer.x = event.touches[ 0 ].pageX;
 				prevPointer.y = event.touches[ 0 ].pageY;
 				prevPointer.y = event.touches[ 0 ].pageY;
 
 
-				document.addEventListener( 'touchmove', onTouchMove );
+				document.addEventListener( 'touchmove', onTouchMove, { passive: false } );
 				document.addEventListener( 'touchend', onTouchEnd );
 				document.addEventListener( 'touchend', onTouchEnd );
 
 
 			}
 			}
@@ -617,6 +625,8 @@ class UINumber extends UIElement {
 
 
 		function onTouchMove( event ) {
 		function onTouchMove( event ) {
 
 
+			event.preventDefault();
+
 			const currentValue = scope.value;
 			const currentValue = scope.value;
 
 
 			pointer.x = event.touches[ 0 ].pageX;
 			pointer.x = event.touches[ 0 ].pageX;

+ 5 - 146
editor/js/libs/ui.three.js

@@ -4,12 +4,12 @@ import { KTX2Loader } from 'three/addons/loaders/KTX2Loader.js';
 import { RGBELoader } from 'three/addons/loaders/RGBELoader.js';
 import { RGBELoader } from 'three/addons/loaders/RGBELoader.js';
 import { TGALoader } from 'three/addons/loaders/TGALoader.js';
 import { TGALoader } from 'three/addons/loaders/TGALoader.js';
 
 
-import { UIElement, UISpan, UIDiv, UIRow, UIButton, UICheckbox, UIText, UINumber } from './ui.js';
+import { UISpan, UIDiv, UIRow, UIButton, UICheckbox, UIText, UINumber } from './ui.js';
 import { MoveObjectCommand } from '../commands/MoveObjectCommand.js';
 import { MoveObjectCommand } from '../commands/MoveObjectCommand.js';
 
 
 class UITexture extends UISpan {
 class UITexture extends UISpan {
 
 
-	constructor( mapping ) {
+	constructor( editor ) {
 
 
 		super();
 		super();
 
 
@@ -100,10 +100,9 @@ class UITexture extends UISpan {
 
 
 					const arrayBuffer = event.target.result;
 					const arrayBuffer = event.target.result;
 					const blobURL = URL.createObjectURL( new Blob( [ arrayBuffer ] ) );
 					const blobURL = URL.createObjectURL( new Blob( [ arrayBuffer ] ) );
-					const tempRenderer = new THREE.WebGLRenderer();
 					const ktx2Loader = new KTX2Loader();
 					const ktx2Loader = new KTX2Loader();
 					ktx2Loader.setTranscoderPath( '../../examples/jsm/libs/basis/' );
 					ktx2Loader.setTranscoderPath( '../../examples/jsm/libs/basis/' );
-					ktx2Loader.detectSupport( tempRenderer );
+					editor.signals.rendererDetectKTX2Support.dispatch( ktx2Loader );
 
 
 					ktx2Loader.load( blobURL, function ( texture ) {
 					ktx2Loader.load( blobURL, function ( texture ) {
 
 
@@ -114,7 +113,6 @@ class UITexture extends UISpan {
 
 
 						if ( scope.onChangeCallback ) scope.onChangeCallback( texture );
 						if ( scope.onChangeCallback ) scope.onChangeCallback( texture );
 						ktx2Loader.dispose();
 						ktx2Loader.dispose();
-						tempRenderer.dispose();
 
 
 					} );
 					} );
 
 
@@ -129,7 +127,7 @@ class UITexture extends UISpan {
 					const image = document.createElement( 'img' );
 					const image = document.createElement( 'img' );
 					image.addEventListener( 'load', function () {
 					image.addEventListener( 'load', function () {
 
 
-						const texture = new THREE.Texture( this, mapping );
+						const texture = new THREE.Texture( this );
 						texture.sourceFile = file.name;
 						texture.sourceFile = file.name;
 						texture.needsUpdate = true;
 						texture.needsUpdate = true;
 
 
@@ -235,145 +233,6 @@ class UITexture extends UISpan {
 
 
 }
 }
 
 
-class UICubeTexture extends UIElement {
-
-	constructor() {
-
-		const container = new UIDiv();
-
-		super( container.dom );
-
-		this.cubeTexture = null;
-		this.onChangeCallback = null;
-
-		this.textures = [];
-
-		const scope = this;
-
-		const pRow = new UIRow();
-		const nRow = new UIRow();
-
-		pRow.add( new UIText( 'P:' ).setWidth( '35px' ) );
-		nRow.add( new UIText( 'N:' ).setWidth( '35px' ) );
-
-		const posXTexture = new UITexture().onChange( onTextureChanged );
-		const negXTexture = new UITexture().onChange( onTextureChanged );
-		const posYTexture = new UITexture().onChange( onTextureChanged );
-		const negYTexture = new UITexture().onChange( onTextureChanged );
-		const posZTexture = new UITexture().onChange( onTextureChanged );
-		const negZTexture = new UITexture().onChange( onTextureChanged );
-
-		this.textures.push( posXTexture, negXTexture, posYTexture, negYTexture, posZTexture, negZTexture );
-
-		pRow.add( posXTexture );
-		pRow.add( posYTexture );
-		pRow.add( posZTexture );
-
-		nRow.add( negXTexture );
-		nRow.add( negYTexture );
-		nRow.add( negZTexture );
-
-		container.add( pRow, nRow );
-
-		function onTextureChanged() {
-
-			const images = [];
-
-			for ( let i = 0; i < scope.textures.length; i ++ ) {
-
-				const texture = scope.textures[ i ].getValue();
-
-				if ( texture !== null ) {
-
-					images.push( texture.isHDRTexture ? texture : texture.image );
-
-				}
-
-			}
-
-			if ( images.length === 6 ) {
-
-				const cubeTexture = new THREE.CubeTexture( images );
-				cubeTexture.needsUpdate = true;
-
-				if ( images[ 0 ].isHDRTexture ) cubeTexture.isHDRTexture = true;
-
-				scope.cubeTexture = cubeTexture;
-
-				if ( scope.onChangeCallback ) scope.onChangeCallback( cubeTexture );
-
-			}
-
-		}
-
-	}
-
-	setColorSpace( colorSpace ) {
-
-		const cubeTexture = this.getValue();
-		if ( cubeTexture !== null ) {
-
-			cubeTexture.colorSpace = colorSpace;
-
-		}
-
-		return this;
-
-	}
-
-	getValue() {
-
-		return this.cubeTexture;
-
-	}
-
-	setValue( cubeTexture ) {
-
-		this.cubeTexture = cubeTexture;
-
-		if ( cubeTexture !== null ) {
-
-			const images = cubeTexture.image;
-
-			if ( Array.isArray( images ) === true && images.length === 6 ) {
-
-				for ( let i = 0; i < images.length; i ++ ) {
-
-					const image = images[ i ];
-
-					const texture = new THREE.Texture( image );
-					this.textures[ i ].setValue( texture );
-
-				}
-
-			}
-
-		} else {
-
-			const textures = this.textures;
-
-			for ( let i = 0; i < textures.length; i ++ ) {
-
-				textures[ i ].setValue( null );
-
-			}
-
-		}
-
-		return this;
-
-	}
-
-	onChange( callback ) {
-
-		this.onChangeCallback = callback;
-
-		return this;
-
-	}
-
-}
-
 class UIOutliner extends UIDiv {
 class UIOutliner extends UIDiv {
 
 
 	constructor( editor ) {
 	constructor( editor ) {
@@ -980,4 +839,4 @@ function renderToCanvas( texture ) {
 
 
 }
 }
 
 
-export { UITexture, UICubeTexture, UIOutliner, UIPoints, UIPoints2, UIPoints3, UIBoolean };
+export { UITexture, UIOutliner, UIPoints, UIPoints2, UIPoints3, UIBoolean };

+ 1 - 3
editor/sw.js

@@ -149,7 +149,6 @@ const assets = [
 	'./js/Sidebar.Settings.js',
 	'./js/Sidebar.Settings.js',
 	'./js/Sidebar.Settings.History.js',
 	'./js/Sidebar.Settings.History.js',
 	'./js/Sidebar.Settings.Shortcuts.js',
 	'./js/Sidebar.Settings.Shortcuts.js',
-	'./js/Sidebar.Settings.Viewport.js',
 	'./js/Sidebar.Properties.js',
 	'./js/Sidebar.Properties.js',
 	'./js/Sidebar.Object.js',
 	'./js/Sidebar.Object.js',
 	'./js/Sidebar.Geometry.js',
 	'./js/Sidebar.Geometry.js',
@@ -184,8 +183,7 @@ const assets = [
 	'./js/Strings.js',
 	'./js/Strings.js',
 	'./js/Toolbar.js',
 	'./js/Toolbar.js',
 	'./js/Viewport.js',
 	'./js/Viewport.js',
-	'./js/Viewport.Camera.js',
-	'./js/Viewport.Shading.js',
+	'./js/Viewport.Controls.js',
 	'./js/Viewport.Info.js',
 	'./js/Viewport.Info.js',
 	'./js/Viewport.Selector.js',
 	'./js/Viewport.Selector.js',
 	'./js/Viewport.ViewHelper.js',
 	'./js/Viewport.ViewHelper.js',

+ 5 - 0
examples/files.json

@@ -117,6 +117,7 @@
 		"webgl_loader_texture_dds",
 		"webgl_loader_texture_dds",
 		"webgl_loader_texture_exr",
 		"webgl_loader_texture_exr",
 		"webgl_loader_texture_hdr",
 		"webgl_loader_texture_hdr",
+		"webgl_loader_texture_hdrjpg",
 		"webgl_loader_texture_ktx",
 		"webgl_loader_texture_ktx",
 		"webgl_loader_texture_ktx2",
 		"webgl_loader_texture_ktx2",
 		"webgl_loader_texture_logluv",
 		"webgl_loader_texture_logluv",
@@ -245,6 +246,7 @@
 		"webgl_postprocessing_fxaa",
 		"webgl_postprocessing_fxaa",
 		"webgl_postprocessing_glitch",
 		"webgl_postprocessing_glitch",
 		"webgl_postprocessing_godrays",
 		"webgl_postprocessing_godrays",
+		"webgl_postprocessing_hbao",
 		"webgl_postprocessing_rgb_halftone",
 		"webgl_postprocessing_rgb_halftone",
 		"webgl_postprocessing_masking",
 		"webgl_postprocessing_masking",
 		"webgl_postprocessing_ssaa",
 		"webgl_postprocessing_ssaa",
@@ -312,6 +314,7 @@
 	"webgpu (wip)": [
 	"webgpu (wip)": [
 		"webgpu_backdrop",
 		"webgpu_backdrop",
 		"webgpu_backdrop_area",
 		"webgpu_backdrop_area",
+		"webgpu_camera_logarithmicdepthbuffer",
 		"webgpu_clearcoat",
 		"webgpu_clearcoat",
 		"webgpu_compute_audio",
 		"webgpu_compute_audio",
 		"webgpu_compute_particles",
 		"webgpu_compute_particles",
@@ -340,6 +343,7 @@
 		"webgpu_materials_video",
 		"webgpu_materials_video",
 		"webgpu_multiple_rendertargets",
 		"webgpu_multiple_rendertargets",
 		"webgpu_morphtargets",
 		"webgpu_morphtargets",
+		"webgpu_morphtargets_face",
 		"webgpu_occlusion",
 		"webgpu_occlusion",
 		"webgpu_particles",
 		"webgpu_particles",
 		"webgpu_rtt",
 		"webgpu_rtt",
@@ -350,6 +354,7 @@
 		"webgpu_skinning_instancing",
 		"webgpu_skinning_instancing",
 		"webgpu_skinning_points",
 		"webgpu_skinning_points",
 		"webgpu_sprites",
 		"webgpu_sprites",
+		"webgpu_textures_2d-array",
 		"webgpu_tsl_editor",
 		"webgpu_tsl_editor",
 		"webgpu_tsl_transpiler",
 		"webgpu_tsl_transpiler",
 		"webgpu_video_panorama"
 		"webgpu_video_panorama"

+ 2 - 1
examples/jsm/Addons.js

@@ -60,6 +60,7 @@ export * from './helpers/LightProbeHelper.js';
 export * from './helpers/OctreeHelper.js';
 export * from './helpers/OctreeHelper.js';
 export * from './helpers/PositionalAudioHelper.js';
 export * from './helpers/PositionalAudioHelper.js';
 export * from './helpers/RectAreaLightHelper.js';
 export * from './helpers/RectAreaLightHelper.js';
+export * from './helpers/TextureHelper.js';
 export * from './helpers/VertexNormalsHelper.js';
 export * from './helpers/VertexNormalsHelper.js';
 export * from './helpers/VertexTangentsHelper.js';
 export * from './helpers/VertexTangentsHelper.js';
 export * from './helpers/ViewHelper.js';
 export * from './helpers/ViewHelper.js';
@@ -159,7 +160,6 @@ export * from './modifiers/EdgeSplitModifier.js';
 export * from './modifiers/SimplifyModifier.js';
 export * from './modifiers/SimplifyModifier.js';
 export * from './modifiers/TessellateModifier.js';
 export * from './modifiers/TessellateModifier.js';
 
 
-export * from './objects/BatchedMesh.js';
 export * from './objects/GroundProjectedSkybox.js';
 export * from './objects/GroundProjectedSkybox.js';
 export * from './objects/Lensflare.js';
 export * from './objects/Lensflare.js';
 export * from './objects/MarchingCubes.js';
 export * from './objects/MarchingCubes.js';
@@ -272,6 +272,7 @@ export * from './utils/PackedPhongMaterial.js';
 export * as SceneUtils from './utils/SceneUtils.js';
 export * as SceneUtils from './utils/SceneUtils.js';
 export * from './utils/ShadowMapViewer.js';
 export * from './utils/ShadowMapViewer.js';
 export * as SkeletonUtils from './utils/SkeletonUtils.js';
 export * as SkeletonUtils from './utils/SkeletonUtils.js';
+export * as SortUtils from './utils/SortUtils.js';
 export * from './utils/TextureUtils.js';
 export * from './utils/TextureUtils.js';
 export * from './utils/UVsDebug.js';
 export * from './utils/UVsDebug.js';
 export * from './utils/WorkerPool.js';
 export * from './utils/WorkerPool.js';

+ 0 - 2
examples/jsm/controls/OrbitControls.js

@@ -398,8 +398,6 @@ class OrbitControls extends EventDispatcher {
 					lastQuaternion.copy( scope.object.quaternion );
 					lastQuaternion.copy( scope.object.quaternion );
 					lastTargetPosition.copy( scope.target );
 					lastTargetPosition.copy( scope.target );
 
 
-					zoomChanged = false;
-
 					return true;
 					return true;
 
 
 				}
 				}

+ 79 - 1
examples/jsm/exporters/GLTFExporter.js

@@ -135,6 +135,12 @@ class GLTFExporter {
 
 
 		} );
 		} );
 
 
+		this.register( function ( writer ) {
+
+			return new GLTFMaterialsBumpExtension( writer );
+
+		} );
+
 		this.register( function ( writer ) {
 		this.register( function ( writer ) {
 
 
 			return new GLTFMeshGpuInstancing( writer );
 			return new GLTFMeshGpuInstancing( writer );
@@ -1829,6 +1835,24 @@ class GLTFWriter {
 
 
 		if ( isMultiMaterial && geometry.groups.length === 0 ) return null;
 		if ( isMultiMaterial && geometry.groups.length === 0 ) return null;
 
 
+		let didForceIndices = false;
+
+		if ( isMultiMaterial && geometry.index === null ) {
+
+			const indices = [];
+
+			for ( let i = 0, il = geometry.attributes.position.count; i < il; i ++ ) {
+
+				indices[ i ] = i;
+
+			}
+
+			geometry.setIndex( indices );
+
+			didForceIndices = true;
+
+		}
+
 		const materials = isMultiMaterial ? mesh.material : [ mesh.material ];
 		const materials = isMultiMaterial ? mesh.material : [ mesh.material ];
 		const groups = isMultiMaterial ? geometry.groups : [ { materialIndex: 0, start: undefined, count: undefined } ];
 		const groups = isMultiMaterial ? geometry.groups : [ { materialIndex: 0, start: undefined, count: undefined } ];
 
 
@@ -1876,6 +1900,12 @@ class GLTFWriter {
 
 
 		}
 		}
 
 
+		if ( didForceIndices === true ) {
+
+			geometry.setIndex( null );
+
+		}
+
 		meshDef.primitives = primitives;
 		meshDef.primitives = primitives;
 
 
 		if ( ! json.meshes ) json.meshes = [];
 		if ( ! json.meshes ) json.meshes = [];
@@ -2796,7 +2826,7 @@ class GLTFMaterialsSpecularExtension {
 
 
 		if ( ! material.isMeshPhysicalMaterial || ( material.specularIntensity === 1.0 &&
 		if ( ! material.isMeshPhysicalMaterial || ( material.specularIntensity === 1.0 &&
 		       material.specularColor.equals( DEFAULT_SPECULAR_COLOR ) &&
 		       material.specularColor.equals( DEFAULT_SPECULAR_COLOR ) &&
-		     ! material.specularIntensityMap && ! material.specularColorTexture ) ) return;
+		     ! material.specularIntensityMap && ! material.specularColorMap ) ) return;
 
 
 		const writer = this.writer;
 		const writer = this.writer;
 		const extensionsUsed = writer.extensionsUsed;
 		const extensionsUsed = writer.extensionsUsed;
@@ -2971,6 +3001,54 @@ class GLTFMaterialsEmissiveStrengthExtension {
 
 
 }
 }
 
 
+
+/**
+ * Materials bump Extension
+ *
+ * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/EXT_materials_bump
+ */
+class GLTFMaterialsBumpExtension {
+
+	constructor( writer ) {
+
+		this.writer = writer;
+		this.name = 'EXT_materials_bump';
+
+	}
+
+	writeMaterial( material, materialDef ) {
+
+		if ( ! material.isMeshStandardMaterial || (
+		       material.bumpScale === 1 &&
+		     ! material.bumpMap ) ) return;
+
+		const writer = this.writer;
+		const extensionsUsed = writer.extensionsUsed;
+
+		const extensionDef = {};
+
+		if ( material.bumpMap ) {
+
+			const bumpMapDef = {
+				index: writer.processTexture( material.bumpMap ),
+				texCoord: material.bumpMap.channel
+			};
+			writer.applyTextureTransform( bumpMapDef, material.bumpMap );
+			extensionDef.bumpTexture = bumpMapDef;
+
+		}
+
+		extensionDef.bumpFactor = material.bumpScale;
+
+		materialDef.extensions = materialDef.extensions || {};
+		materialDef.extensions[ this.name ] = extensionDef;
+
+		extensionsUsed[ this.name ] = true;
+
+	}
+
+}
+
 /**
 /**
  * GPU Instancing Extension
  * GPU Instancing Extension
  *
  *

+ 4 - 11
examples/jsm/exporters/USDZExporter.js

@@ -287,7 +287,7 @@ function buildMesh( geometry ) {
 			interpolation = "vertex"
 			interpolation = "vertex"
 		)
 		)
 		point3f[] points = [${ buildVector3Array( attributes.position, count )}]
 		point3f[] points = [${ buildVector3Array( attributes.position, count )}]
-${ buildPrimvars( attributes, count ) }
+${ buildPrimvars( attributes ) }
 		uniform token subdivisionScheme = "none"
 		uniform token subdivisionScheme = "none"
 	}
 	}
 `;
 `;
@@ -356,14 +356,7 @@ function buildVector3Array( attribute, count ) {
 
 
 }
 }
 
 
-function buildVector2Array( attribute, count ) {
-
-	if ( attribute === undefined ) {
-
-		console.warn( 'USDZExporter: UVs missing.' );
-		return Array( count ).fill( '(0, 0)' ).join( ', ' );
-
-	}
+function buildVector2Array( attribute ) {
 
 
 	const array = [];
 	const array = [];
 
 
@@ -380,7 +373,7 @@ function buildVector2Array( attribute, count ) {
 
 
 }
 }
 
 
-function buildPrimvars( attributes, count ) {
+function buildPrimvars( attributes ) {
 
 
 	let string = '';
 	let string = '';
 
 
@@ -392,7 +385,7 @@ function buildPrimvars( attributes, count ) {
 		if ( attribute !== undefined ) {
 		if ( attribute !== undefined ) {
 
 
 			string += `
 			string += `
-		texCoord2f[] primvars:st${ id } = [${ buildVector2Array( attribute, count )}] (
+		texCoord2f[] primvars:st${ id } = [${ buildVector2Array( attribute )}] (
 			interpolation = "vertex"
 			interpolation = "vertex"
 		)`;
 		)`;
 
 

+ 237 - 0
examples/jsm/helpers/TextureHelper.js

@@ -0,0 +1,237 @@
+import {
+	BoxGeometry,
+	BufferAttribute,
+	DoubleSide,
+	Mesh,
+	PlaneGeometry,
+	ShaderMaterial,
+	Vector3,
+} from 'three';
+import { mergeGeometries } from '../utils/BufferGeometryUtils.js';
+
+class TextureHelper extends Mesh {
+
+	constructor( texture, width = 1, height = 1, depth = 1 ) {
+
+		const material = new ShaderMaterial( {
+
+			type: 'TextureHelperMaterial',
+
+			side: DoubleSide,
+			transparent: true,
+
+			uniforms: {
+
+				map: { value: texture },
+				alpha: { value: getAlpha( texture ) },
+
+			},
+
+			vertexShader: [
+
+				'attribute vec3 uvw;',
+
+				'varying vec3 vUvw;',
+
+				'void main() {',
+
+				'	vUvw = uvw;',
+
+				'	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );',
+
+				'}',
+
+			].join( '\n' ),
+
+			fragmentShader: [
+
+				'precision highp float;',
+
+				'precision highp sampler2DArray;',
+
+				'precision highp sampler3D;',
+
+				'uniform {samplerType} map;',
+
+				'uniform float alpha;',
+
+				'varying vec3 vUvw;',
+
+				'vec4 textureHelper( in sampler2D map ) { return texture( map, vUvw.xy ); }',
+
+				'vec4 textureHelper( in sampler2DArray map ) { return texture( map, vUvw ); }',
+
+				'vec4 textureHelper( in sampler3D map ) { return texture( map, vUvw ); }',
+
+				'vec4 textureHelper( in samplerCube map ) { return texture( map, vUvw ); }',
+
+				'void main() {',
+
+				'	gl_FragColor = linearToOutputTexel( vec4( textureHelper( map ).xyz, alpha ) );',
+
+				'}'
+
+			].join( '\n' ).replace( '{samplerType}', getSamplerType( texture ) )
+
+		} );
+
+		const geometry = texture.isCubeTexture
+			? createCubeGeometry( width, height, depth )
+			: createSliceGeometry( texture, width, height, depth );
+
+		super( geometry, material );
+
+		this.texture = texture;
+		this.type = 'TextureHelper';
+
+	}
+
+	dispose() {
+
+		this.geometry.dispose();
+		this.material.dispose();
+
+	}
+
+}
+
+function getSamplerType( texture ) {
+
+	if ( texture.isCubeTexture ) {
+
+		return 'samplerCube';
+
+	} else if ( texture.isDataArrayTexture || texture.isCompressedArrayTexture ) {
+
+		return 'sampler2DArray';
+
+	} else if ( texture.isData3DTexture || texture.isCompressed3DTexture ) {
+
+		return 'sampler3D';
+
+	} else {
+
+		return 'sampler2D';
+
+	}
+
+}
+
+function getImageCount( texture ) {
+
+	if ( texture.isCubeTexture ) {
+
+		return 6;
+
+	} else if ( texture.isDataArrayTexture || texture.isCompressedArrayTexture ) {
+
+		return texture.image.depth;
+
+	} else if ( texture.isData3DTexture || texture.isCompressed3DTexture ) {
+
+		return texture.image.depth;
+
+	} else {
+
+		return 1;
+
+	}
+
+}
+
+function getAlpha( texture ) {
+
+	if ( texture.isCubeTexture ) {
+
+		return 1;
+
+	} else if ( texture.isDataArrayTexture || texture.isCompressedArrayTexture ) {
+
+		return Math.max( 1 / texture.image.depth, 0.25 );
+
+	} else if ( texture.isData3DTexture || texture.isCompressed3DTexture ) {
+
+		return Math.max( 1 / texture.image.depth, 0.25 );
+
+	} else {
+
+		return 1;
+
+	}
+
+}
+
+function createCubeGeometry( width, height, depth ) {
+
+	const geometry = new BoxGeometry( width, height, depth );
+
+	const position = geometry.attributes.position;
+	const uv = geometry.attributes.uv;
+	const uvw = new BufferAttribute( new Float32Array( uv.count * 3 ), 3 );
+
+	const _direction = new Vector3();
+
+	for ( let j = 0, jl = uv.count; j < jl; ++ j ) {
+
+		_direction.fromBufferAttribute( position, j ).normalize();
+
+		const u = _direction.x;
+		const v = _direction.y;
+		const w = _direction.z;
+
+		uvw.setXYZ( j, u, v, w );
+
+	}
+
+	geometry.deleteAttribute( 'uv' );
+	geometry.setAttribute( 'uvw', uvw );
+
+	return geometry;
+
+}
+
+function createSliceGeometry( texture, width, height, depth ) {
+
+	const sliceCount = getImageCount( texture );
+
+	const geometries = [];
+
+	for ( let i = 0; i < sliceCount; ++ i ) {
+
+		const geometry = new PlaneGeometry( width, height );
+
+		if ( sliceCount > 1 ) {
+
+			geometry.translate( 0, 0, depth * ( i / ( sliceCount - 1 ) - 0.5 ) );
+
+		}
+
+		const uv = geometry.attributes.uv;
+		const uvw = new BufferAttribute( new Float32Array( uv.count * 3 ), 3 );
+
+		for ( let j = 0, jl = uv.count; j < jl; ++ j ) {
+
+			const u = uv.getX( j );
+			const v = texture.flipY ? uv.getY( j ) : 1 - uv.getY( j );
+			const w = sliceCount === 1
+				? 1
+				: texture.isDataArrayTexture || texture.isCompressedArrayTexture
+				? i
+				: i / ( sliceCount - 1 );
+
+			uvw.setXYZ( j, u, v, w );
+
+		}
+
+		geometry.deleteAttribute( 'uv' );
+		geometry.setAttribute( 'uvw', uvw );
+
+		geometries.push( geometry );
+
+	}
+
+	return mergeGeometries( geometries );
+
+}
+
+export { TextureHelper };

+ 9 - 2
examples/jsm/interactive/HTMLMesh.js

@@ -267,10 +267,15 @@ function html2canvas( element ) {
 			// Canvas element
 			// Canvas element
 			if ( element.style.display === 'none' ) return;
 			if ( element.style.display === 'none' ) return;
 
 
-			context.save();
+			const rect = element.getBoundingClientRect();
+
+			x = rect.left - offset.left - 0.5;
+			y = rect.top - offset.top - 0.5;
+
+		        context.save();
 			const dpr = window.devicePixelRatio;
 			const dpr = window.devicePixelRatio;
 			context.scale( 1 / dpr, 1 / dpr );
 			context.scale( 1 / dpr, 1 / dpr );
-			context.drawImage( element, 0, 0 );
+			context.drawImage( element, x, y );
 			context.restore();
 			context.restore();
 
 
 		} else if ( element instanceof HTMLImageElement ) {
 		} else if ( element instanceof HTMLImageElement ) {
@@ -501,6 +506,8 @@ function html2canvas( element ) {
 
 
 	// console.time( 'drawElement' );
 	// console.time( 'drawElement' );
 
 
+	context.clearRect( 0, 0, canvas.width, canvas.height );
+
 	drawElement( element );
 	drawElement( element );
 
 
 	// console.timeEnd( 'drawElement' );
 	// console.timeEnd( 'drawElement' );

+ 0 - 6
examples/jsm/loaders/ColladaLoader.js

@@ -42,12 +42,6 @@ import { TGALoader } from '../loaders/TGALoader.js';
 
 
 class ColladaLoader extends Loader {
 class ColladaLoader extends Loader {
 
 
-	constructor( manager ) {
-
-		super( manager );
-
-	}
-
 	load( url, onLoad, onProgress, onError ) {
 	load( url, onLoad, onProgress, onError ) {
 
 
 		const scope = this;
 		const scope = this;

+ 294 - 124
examples/jsm/loaders/FBXLoader.js

@@ -36,10 +36,12 @@ import {
 	Texture,
 	Texture,
 	TextureLoader,
 	TextureLoader,
 	Uint16BufferAttribute,
 	Uint16BufferAttribute,
+	Vector2,
 	Vector3,
 	Vector3,
 	Vector4,
 	Vector4,
 	VectorKeyframeTrack,
 	VectorKeyframeTrack,
-	SRGBColorSpace
+	SRGBColorSpace,
+	ShapeUtils
 } from 'three';
 } from 'three';
 import * as fflate from '../libs/fflate.module.js';
 import * as fflate from '../libs/fflate.module.js';
 import { NURBSCurve } from '../curves/NURBSCurve.js';
 import { NURBSCurve } from '../curves/NURBSCurve.js';
@@ -443,6 +445,22 @@ class FBXTreeParser {
 
 
 			}
 			}
 
 
+		} else if ( extension === 'dds' ) {
+
+			const loader = this.manager.getHandler( '.dds' );
+
+			if ( loader === null ) {
+
+				console.warn( 'FBXLoader: DDS loader not found, creating placeholder texture for', textureNode.RelativeFilename );
+				texture = new Texture();
+
+			} else {
+
+				loader.setPath( this.textureLoader.path );
+				texture = loader.load( fileName );
+
+			}
+
 		} else if ( extension === 'psd' ) {
 		} else if ( extension === 'psd' ) {
 
 
 			console.warn( 'FBXLoader: PSD textures are not supported, creating placeholder texture for', textureNode.RelativeFilename );
 			console.warn( 'FBXLoader: PSD textures are not supported, creating placeholder texture for', textureNode.RelativeFilename );
@@ -883,7 +901,7 @@ class FBXTreeParser {
 
 
 		this.bindSkeleton( deformers.skeletons, geometryMap, modelMap );
 		this.bindSkeleton( deformers.skeletons, geometryMap, modelMap );
 
 
-		this.createAmbientLight();
+		this.addGlobalSceneSettings();
 
 
 		sceneGraph.traverse( function ( node ) {
 		sceneGraph.traverse( function ( node ) {
 
 
@@ -1466,20 +1484,31 @@ class FBXTreeParser {
 
 
 	}
 	}
 
 
-	// Parse ambient color in FBXTree.GlobalSettings - if it's not set to black (default), create an ambient light
-	createAmbientLight() {
+	addGlobalSceneSettings() {
+
+		if ( 'GlobalSettings' in fbxTree ) {
 
 
-		if ( 'GlobalSettings' in fbxTree && 'AmbientColor' in fbxTree.GlobalSettings ) {
+			if ( 'AmbientColor' in fbxTree.GlobalSettings ) {
 
 
-			const ambientColor = fbxTree.GlobalSettings.AmbientColor.value;
-			const r = ambientColor[ 0 ];
-			const g = ambientColor[ 1 ];
-			const b = ambientColor[ 2 ];
+				// Parse ambient color - if it's not set to black (default), create an ambient light
 
 
-			if ( r !== 0 || g !== 0 || b !== 0 ) {
+				const ambientColor = fbxTree.GlobalSettings.AmbientColor.value;
+				const r = ambientColor[ 0 ];
+				const g = ambientColor[ 1 ];
+				const b = ambientColor[ 2 ];
 
 
-				const color = new Color( r, g, b ).convertSRGBToLinear();
-				sceneGraph.add( new AmbientLight( color, 1 ) );
+				if ( r !== 0 || g !== 0 || b !== 0 ) {
+
+					const color = new Color( r, g, b ).convertSRGBToLinear();
+					sceneGraph.add( new AmbientLight( color, 1 ) );
+
+				}
+
+			}
+
+			if ( 'UnitScaleFactor' in fbxTree.GlobalSettings ) {
+
+				sceneGraph.userData.unitScaleFactor = fbxTree.GlobalSettings.UnitScaleFactor.value;
 
 
 			}
 			}
 
 
@@ -1944,8 +1973,6 @@ class GeometryParser {
 
 
 			if ( endOfFace ) {
 			if ( endOfFace ) {
 
 
-				if ( faceLength > 4 ) console.warn( 'THREE.FBXLoader: Polygons with more than four sides are not supported. Make sure to triangulate the geometry during export.' );
-
 				scope.genFace( buffers, geoInfo, facePositionIndexes, materialIndex, faceNormals, faceColors, faceUVs, faceWeights, faceWeightIndices, faceLength );
 				scope.genFace( buffers, geoInfo, facePositionIndexes, materialIndex, faceNormals, faceColors, faceUVs, faceWeights, faceWeightIndices, faceLength );
 
 
 				polygonIndex ++;
 				polygonIndex ++;
@@ -1967,70 +1994,153 @@ class GeometryParser {
 
 
 	}
 	}
 
 
+	// See https://www.khronos.org/opengl/wiki/Calculating_a_Surface_Normal
+	getNormalNewell( vertices ) {
+
+		const normal = new Vector3( 0.0, 0.0, 0.0 );
+
+		for ( let i = 0; i < vertices.length; i ++ ) {
+
+			const current = vertices[ i ];
+			const next = vertices[ ( i + 1 ) % vertices.length ];
+
+			normal.x += ( current.y - next.y ) * ( current.z + next.z );
+			normal.y += ( current.z - next.z ) * ( current.x + next.x );
+			normal.z += ( current.x - next.x ) * ( current.y + next.y );
+
+		}
+
+		normal.normalize();
+
+		return normal;
+
+	}
+
+	getNormalTangentAndBitangent( vertices ) {
+
+		const normalVector = this.getNormalNewell( vertices );
+		// Avoid up being equal or almost equal to normalVector
+		const up = Math.abs( normalVector.z ) > 0.5 ? new Vector3( 0.0, 1.0, 0.0 ) : new Vector3( 0.0, 0.0, 1.0 );
+		const tangent = up.cross( normalVector ).normalize();
+		const bitangent = normalVector.clone().cross( tangent ).normalize();
+
+		return {
+			normal: normalVector,
+			tangent: tangent,
+			bitangent: bitangent
+		};
+
+	}
+
+	flattenVertex( vertex, normalTangent, normalBitangent ) {
+
+		return new Vector2(
+			vertex.dot( normalTangent ),
+			vertex.dot( normalBitangent )
+		);
+
+	}
+
 	// Generate data for a single face in a geometry. If the face is a quad then split it into 2 tris
 	// Generate data for a single face in a geometry. If the face is a quad then split it into 2 tris
 	genFace( buffers, geoInfo, facePositionIndexes, materialIndex, faceNormals, faceColors, faceUVs, faceWeights, faceWeightIndices, faceLength ) {
 	genFace( buffers, geoInfo, facePositionIndexes, materialIndex, faceNormals, faceColors, faceUVs, faceWeights, faceWeightIndices, faceLength ) {
 
 
-		for ( let i = 2; i < faceLength; i ++ ) {
+		let triangles;
+
+		if ( faceLength > 3 ) {
+
+			// Triangulate n-gon using earcut
 
 
-			buffers.vertex.push( geoInfo.vertexPositions[ facePositionIndexes[ 0 ] ] );
-			buffers.vertex.push( geoInfo.vertexPositions[ facePositionIndexes[ 1 ] ] );
-			buffers.vertex.push( geoInfo.vertexPositions[ facePositionIndexes[ 2 ] ] );
+			const vertices = [];
 
 
-			buffers.vertex.push( geoInfo.vertexPositions[ facePositionIndexes[ ( i - 1 ) * 3 ] ] );
-			buffers.vertex.push( geoInfo.vertexPositions[ facePositionIndexes[ ( i - 1 ) * 3 + 1 ] ] );
-			buffers.vertex.push( geoInfo.vertexPositions[ facePositionIndexes[ ( i - 1 ) * 3 + 2 ] ] );
+			for ( let i = 0; i < facePositionIndexes.length; i += 3 ) {
+
+				vertices.push( new Vector3(
+					geoInfo.vertexPositions[ facePositionIndexes[ i ] ],
+					geoInfo.vertexPositions[ facePositionIndexes[ i + 1 ] ],
+					geoInfo.vertexPositions[ facePositionIndexes[ i + 2 ] ]
+				) );
+
+			}
 
 
-			buffers.vertex.push( geoInfo.vertexPositions[ facePositionIndexes[ i * 3 ] ] );
-			buffers.vertex.push( geoInfo.vertexPositions[ facePositionIndexes[ i * 3 + 1 ] ] );
-			buffers.vertex.push( geoInfo.vertexPositions[ facePositionIndexes[ i * 3 + 2 ] ] );
+			const { tangent, bitangent } = this.getNormalTangentAndBitangent( vertices );
+			const triangulationInput = [];
+
+			for ( const vertex of vertices ) {
+
+				triangulationInput.push( this.flattenVertex( vertex, tangent, bitangent ) );
+
+			}
+
+			triangles = ShapeUtils.triangulateShape( triangulationInput, [] );
+
+		} else {
+
+			// Regular triangle, skip earcut triangulation step
+			triangles = [[ 0, 1, 2 ]];
+
+		}
+
+		for ( const [ i0, i1, i2 ] of triangles ) {
+
+			buffers.vertex.push( geoInfo.vertexPositions[ facePositionIndexes[ i0 * 3 ] ] );
+			buffers.vertex.push( geoInfo.vertexPositions[ facePositionIndexes[ i0 * 3 + 1 ] ] );
+			buffers.vertex.push( geoInfo.vertexPositions[ facePositionIndexes[ i0 * 3 + 2 ] ] );
+
+			buffers.vertex.push( geoInfo.vertexPositions[ facePositionIndexes[ i1 * 3 ] ] );
+			buffers.vertex.push( geoInfo.vertexPositions[ facePositionIndexes[ i1 * 3 + 1 ] ] );
+			buffers.vertex.push( geoInfo.vertexPositions[ facePositionIndexes[ i1 * 3 + 2 ] ] );
+
+			buffers.vertex.push( geoInfo.vertexPositions[ facePositionIndexes[ i2 * 3 ] ] );
+			buffers.vertex.push( geoInfo.vertexPositions[ facePositionIndexes[ i2 * 3 + 1 ] ] );
+			buffers.vertex.push( geoInfo.vertexPositions[ facePositionIndexes[ i2 * 3 + 2 ] ] );
 
 
 			if ( geoInfo.skeleton ) {
 			if ( geoInfo.skeleton ) {
 
 
-				buffers.vertexWeights.push( faceWeights[ 0 ] );
-				buffers.vertexWeights.push( faceWeights[ 1 ] );
-				buffers.vertexWeights.push( faceWeights[ 2 ] );
-				buffers.vertexWeights.push( faceWeights[ 3 ] );
+				buffers.vertexWeights.push( faceWeights[ i0 * 4 ] );
+				buffers.vertexWeights.push( faceWeights[ i0 * 4 + 1 ] );
+				buffers.vertexWeights.push( faceWeights[ i0 * 4 + 2 ] );
+				buffers.vertexWeights.push( faceWeights[ i0 * 4 + 3 ] );
 
 
-				buffers.vertexWeights.push( faceWeights[ ( i - 1 ) * 4 ] );
-				buffers.vertexWeights.push( faceWeights[ ( i - 1 ) * 4 + 1 ] );
-				buffers.vertexWeights.push( faceWeights[ ( i - 1 ) * 4 + 2 ] );
-				buffers.vertexWeights.push( faceWeights[ ( i - 1 ) * 4 + 3 ] );
+				buffers.vertexWeights.push( faceWeights[ i1 * 4 ] );
+				buffers.vertexWeights.push( faceWeights[ i1 * 4 + 1 ] );
+				buffers.vertexWeights.push( faceWeights[ i1 * 4 + 2 ] );
+				buffers.vertexWeights.push( faceWeights[ i1 * 4 + 3 ] );
 
 
-				buffers.vertexWeights.push( faceWeights[ i * 4 ] );
-				buffers.vertexWeights.push( faceWeights[ i * 4 + 1 ] );
-				buffers.vertexWeights.push( faceWeights[ i * 4 + 2 ] );
-				buffers.vertexWeights.push( faceWeights[ i * 4 + 3 ] );
+				buffers.vertexWeights.push( faceWeights[ i2 * 4 ] );
+				buffers.vertexWeights.push( faceWeights[ i2 * 4 + 1 ] );
+				buffers.vertexWeights.push( faceWeights[ i2 * 4 + 2 ] );
+				buffers.vertexWeights.push( faceWeights[ i2 * 4 + 3 ] );
 
 
-				buffers.weightsIndices.push( faceWeightIndices[ 0 ] );
-				buffers.weightsIndices.push( faceWeightIndices[ 1 ] );
-				buffers.weightsIndices.push( faceWeightIndices[ 2 ] );
-				buffers.weightsIndices.push( faceWeightIndices[ 3 ] );
+				buffers.weightsIndices.push( faceWeightIndices[ i0 * 4 ] );
+				buffers.weightsIndices.push( faceWeightIndices[ i0 * 4 + 1 ] );
+				buffers.weightsIndices.push( faceWeightIndices[ i0 * 4 + 2 ] );
+				buffers.weightsIndices.push( faceWeightIndices[ i0 * 4 + 3 ] );
 
 
-				buffers.weightsIndices.push( faceWeightIndices[ ( i - 1 ) * 4 ] );
-				buffers.weightsIndices.push( faceWeightIndices[ ( i - 1 ) * 4 + 1 ] );
-				buffers.weightsIndices.push( faceWeightIndices[ ( i - 1 ) * 4 + 2 ] );
-				buffers.weightsIndices.push( faceWeightIndices[ ( i - 1 ) * 4 + 3 ] );
+				buffers.weightsIndices.push( faceWeightIndices[ i1 * 4 ] );
+				buffers.weightsIndices.push( faceWeightIndices[ i1 * 4 + 1 ] );
+				buffers.weightsIndices.push( faceWeightIndices[ i1 * 4 + 2 ] );
+				buffers.weightsIndices.push( faceWeightIndices[ i1 * 4 + 3 ] );
 
 
-				buffers.weightsIndices.push( faceWeightIndices[ i * 4 ] );
-				buffers.weightsIndices.push( faceWeightIndices[ i * 4 + 1 ] );
-				buffers.weightsIndices.push( faceWeightIndices[ i * 4 + 2 ] );
-				buffers.weightsIndices.push( faceWeightIndices[ i * 4 + 3 ] );
+				buffers.weightsIndices.push( faceWeightIndices[ i2 * 4 ] );
+				buffers.weightsIndices.push( faceWeightIndices[ i2 * 4 + 1 ] );
+				buffers.weightsIndices.push( faceWeightIndices[ i2 * 4 + 2 ] );
+				buffers.weightsIndices.push( faceWeightIndices[ i2 * 4 + 3 ] );
 
 
 			}
 			}
 
 
 			if ( geoInfo.color ) {
 			if ( geoInfo.color ) {
 
 
-				buffers.colors.push( faceColors[ 0 ] );
-				buffers.colors.push( faceColors[ 1 ] );
-				buffers.colors.push( faceColors[ 2 ] );
+				buffers.colors.push( faceColors[ i0 * 3 ] );
+				buffers.colors.push( faceColors[ i0 * 3 + 1 ] );
+				buffers.colors.push( faceColors[ i0 * 3 + 2 ] );
 
 
-				buffers.colors.push( faceColors[ ( i - 1 ) * 3 ] );
-				buffers.colors.push( faceColors[ ( i - 1 ) * 3 + 1 ] );
-				buffers.colors.push( faceColors[ ( i - 1 ) * 3 + 2 ] );
+				buffers.colors.push( faceColors[ i1 * 3 ] );
+				buffers.colors.push( faceColors[ i1 * 3 + 1 ] );
+				buffers.colors.push( faceColors[ i1 * 3 + 2 ] );
 
 
-				buffers.colors.push( faceColors[ i * 3 ] );
-				buffers.colors.push( faceColors[ i * 3 + 1 ] );
-				buffers.colors.push( faceColors[ i * 3 + 2 ] );
+				buffers.colors.push( faceColors[ i2 * 3 ] );
+				buffers.colors.push( faceColors[ i2 * 3 + 1 ] );
+				buffers.colors.push( faceColors[ i2 * 3 + 2 ] );
 
 
 			}
 			}
 
 
@@ -2044,17 +2154,17 @@ class GeometryParser {
 
 
 			if ( geoInfo.normal ) {
 			if ( geoInfo.normal ) {
 
 
-				buffers.normal.push( faceNormals[ 0 ] );
-				buffers.normal.push( faceNormals[ 1 ] );
-				buffers.normal.push( faceNormals[ 2 ] );
+				buffers.normal.push( faceNormals[ i0 * 3 ] );
+				buffers.normal.push( faceNormals[ i0 * 3 + 1 ] );
+				buffers.normal.push( faceNormals[ i0 * 3 + 2 ] );
 
 
-				buffers.normal.push( faceNormals[ ( i - 1 ) * 3 ] );
-				buffers.normal.push( faceNormals[ ( i - 1 ) * 3 + 1 ] );
-				buffers.normal.push( faceNormals[ ( i - 1 ) * 3 + 2 ] );
+				buffers.normal.push( faceNormals[ i1 * 3 ] );
+				buffers.normal.push( faceNormals[ i1 * 3 + 1 ] );
+				buffers.normal.push( faceNormals[ i1 * 3 + 2 ] );
 
 
-				buffers.normal.push( faceNormals[ i * 3 ] );
-				buffers.normal.push( faceNormals[ i * 3 + 1 ] );
-				buffers.normal.push( faceNormals[ i * 3 + 2 ] );
+				buffers.normal.push( faceNormals[ i2 * 3 ] );
+				buffers.normal.push( faceNormals[ i2 * 3 + 1 ] );
+				buffers.normal.push( faceNormals[ i2 * 3 + 2 ] );
 
 
 			}
 			}
 
 
@@ -2064,14 +2174,14 @@ class GeometryParser {
 
 
 					if ( buffers.uvs[ j ] === undefined ) buffers.uvs[ j ] = [];
 					if ( buffers.uvs[ j ] === undefined ) buffers.uvs[ j ] = [];
 
 
-					buffers.uvs[ j ].push( faceUVs[ j ][ 0 ] );
-					buffers.uvs[ j ].push( faceUVs[ j ][ 1 ] );
+					buffers.uvs[ j ].push( faceUVs[ j ][ i0 * 2 ] );
+					buffers.uvs[ j ].push( faceUVs[ j ][ i0 * 2 + 1 ] );
 
 
-					buffers.uvs[ j ].push( faceUVs[ j ][ ( i - 1 ) * 2 ] );
-					buffers.uvs[ j ].push( faceUVs[ j ][ ( i - 1 ) * 2 + 1 ] );
+					buffers.uvs[ j ].push( faceUVs[ j ][ i1 * 2 ] );
+					buffers.uvs[ j ].push( faceUVs[ j ][ i1 * 2 + 1 ] );
 
 
-					buffers.uvs[ j ].push( faceUVs[ j ][ i * 2 ] );
-					buffers.uvs[ j ].push( faceUVs[ j ][ i * 2 + 1 ] );
+					buffers.uvs[ j ].push( faceUVs[ j ][ i2 * 2 ] );
+					buffers.uvs[ j ].push( faceUVs[ j ][ i2 * 2 + 1 ] );
 
 
 				} );
 				} );
 
 
@@ -2648,13 +2758,11 @@ class AnimationParser {
 		const tracks = [];
 		const tracks = [];
 
 
 		let initialPosition = new Vector3();
 		let initialPosition = new Vector3();
-		let initialRotation = new Quaternion();
 		let initialScale = new Vector3();
 		let initialScale = new Vector3();
 
 
-		if ( rawTracks.transform ) rawTracks.transform.decompose( initialPosition, initialRotation, initialScale );
+		if ( rawTracks.transform ) rawTracks.transform.decompose( initialPosition, new Quaternion(), initialScale );
 
 
 		initialPosition = initialPosition.toArray();
 		initialPosition = initialPosition.toArray();
-		initialRotation = new Euler().setFromQuaternion( initialRotation, rawTracks.eulerOrder ).toArray();
 		initialScale = initialScale.toArray();
 		initialScale = initialScale.toArray();
 
 
 		if ( rawTracks.T !== undefined && Object.keys( rawTracks.T.curves ).length > 0 ) {
 		if ( rawTracks.T !== undefined && Object.keys( rawTracks.T.curves ).length > 0 ) {
@@ -2666,7 +2774,7 @@ class AnimationParser {
 
 
 		if ( rawTracks.R !== undefined && Object.keys( rawTracks.R.curves ).length > 0 ) {
 		if ( rawTracks.R !== undefined && Object.keys( rawTracks.R.curves ).length > 0 ) {
 
 
-			const rotationTrack = this.generateRotationTrack( rawTracks.modelName, rawTracks.R.curves, initialRotation, rawTracks.preRotation, rawTracks.postRotation, rawTracks.eulerOrder );
+			const rotationTrack = this.generateRotationTrack( rawTracks.modelName, rawTracks.R.curves, rawTracks.preRotation, rawTracks.postRotation, rawTracks.eulerOrder );
 			if ( rotationTrack !== undefined ) tracks.push( rotationTrack );
 			if ( rotationTrack !== undefined ) tracks.push( rotationTrack );
 
 
 		}
 		}
@@ -2698,32 +2806,20 @@ class AnimationParser {
 
 
 	}
 	}
 
 
-	generateRotationTrack( modelName, curves, initialValue, preRotation, postRotation, eulerOrder ) {
-
-		if ( curves.x !== undefined ) {
+	generateRotationTrack( modelName, curves, preRotation, postRotation, eulerOrder ) {
 
 
-			this.interpolateRotations( curves.x );
-			curves.x.values = curves.x.values.map( MathUtils.degToRad );
-
-		}
+		let times;
+		let values;
 
 
-		if ( curves.y !== undefined ) {
-
-			this.interpolateRotations( curves.y );
-			curves.y.values = curves.y.values.map( MathUtils.degToRad );
-
-		}
+		if ( curves.x !== undefined && curves.y !== undefined && curves.z !== undefined ) {
 
 
-		if ( curves.z !== undefined ) {
+			const result = this.interpolateRotations( curves.x, curves.y, curves.z, eulerOrder );
 
 
-			this.interpolateRotations( curves.z );
-			curves.z.values = curves.z.values.map( MathUtils.degToRad );
+			times = result[ 0 ];
+			values = result[ 1 ];
 
 
 		}
 		}
 
 
-		const times = this.getTimesForAllAxes( curves );
-		const values = this.getKeyframeTrackValues( times, curves, initialValue );
-
 		if ( preRotation !== undefined ) {
 		if ( preRotation !== undefined ) {
 
 
 			preRotation = preRotation.map( MathUtils.degToRad );
 			preRotation = preRotation.map( MathUtils.degToRad );
@@ -2749,15 +2845,32 @@ class AnimationParser {
 
 
 		const quaternionValues = [];
 		const quaternionValues = [];
 
 
+		if ( ! values || ! times ) return new QuaternionKeyframeTrack( modelName + '.quaternion', [], [] );
+
 		for ( let i = 0; i < values.length; i += 3 ) {
 		for ( let i = 0; i < values.length; i += 3 ) {
 
 
 			euler.set( values[ i ], values[ i + 1 ], values[ i + 2 ], eulerOrder );
 			euler.set( values[ i ], values[ i + 1 ], values[ i + 2 ], eulerOrder );
-
 			quaternion.setFromEuler( euler );
 			quaternion.setFromEuler( euler );
 
 
 			if ( preRotation !== undefined ) quaternion.premultiply( preRotation );
 			if ( preRotation !== undefined ) quaternion.premultiply( preRotation );
 			if ( postRotation !== undefined ) quaternion.multiply( postRotation );
 			if ( postRotation !== undefined ) quaternion.multiply( postRotation );
 
 
+			// Check unroll
+			if ( i > 2 ) {
+
+				const prevQuat = new Quaternion().fromArray(
+					quaternionValues,
+					( ( i - 3 ) / 3 ) * 4
+				);
+
+				if ( prevQuat.dot( quaternion ) < 0 ) {
+
+					quaternion.set( - quaternion.x, - quaternion.y, - quaternion.z, - quaternion.w );
+
+				}
+
+			}
+
 			quaternion.toArray( quaternionValues, ( i / 3 ) * 4 );
 			quaternion.toArray( quaternionValues, ( i / 3 ) * 4 );
 
 
 		}
 		}
@@ -2888,47 +3001,110 @@ class AnimationParser {
 	// Rotations are defined as Euler angles which can have values  of any size
 	// Rotations are defined as Euler angles which can have values  of any size
 	// These will be converted to quaternions which don't support values greater than
 	// These will be converted to quaternions which don't support values greater than
 	// PI, so we'll interpolate large rotations
 	// PI, so we'll interpolate large rotations
-	interpolateRotations( curve ) {
+	interpolateRotations( curvex, curvey, curvez, eulerOrder ) {
 
 
-		for ( let i = 1; i < curve.values.length; i ++ ) {
+		const times = [];
+		const values = [];
+
+		// Add first frame
+		times.push( curvex.times[ 0 ] );
+		values.push( MathUtils.degToRad( curvex.values[ 0 ] ) );
+		values.push( MathUtils.degToRad( curvey.values[ 0 ] ) );
+		values.push( MathUtils.degToRad( curvez.values[ 0 ] ) );
+
+		for ( let i = 1; i < curvex.values.length; i ++ ) {
+
+			const initialValue = [
+				curvex.values[ i - 1 ],
+				curvey.values[ i - 1 ],
+				curvez.values[ i - 1 ],
+			];
+
+			if ( isNaN( initialValue[ 0 ] ) || isNaN( initialValue[ 1 ] ) || isNaN( initialValue[ 2 ] ) ) {
+
+				continue;
+
+			}
+
+			const initialValueRad = initialValue.map( MathUtils.degToRad );
+
+			const currentValue = [
+				curvex.values[ i ],
+				curvey.values[ i ],
+				curvez.values[ i ],
+			];
+
+			if ( isNaN( currentValue[ 0 ] ) || isNaN( currentValue[ 1 ] ) || isNaN( currentValue[ 2 ] ) ) {
+
+				continue;
+
+			}
 
 
-			const initialValue = curve.values[ i - 1 ];
-			const valuesSpan = curve.values[ i ] - initialValue;
+			const currentValueRad = currentValue.map( MathUtils.degToRad );
 
 
-			const absoluteSpan = Math.abs( valuesSpan );
+			const valuesSpan = [
+				currentValue[ 0 ] - initialValue[ 0 ],
+				currentValue[ 1 ] - initialValue[ 1 ],
+				currentValue[ 2 ] - initialValue[ 2 ],
+			];
 
 
-			if ( absoluteSpan >= 180 ) {
+			const absoluteSpan = [
+				Math.abs( valuesSpan[ 0 ] ),
+				Math.abs( valuesSpan[ 1 ] ),
+				Math.abs( valuesSpan[ 2 ] ),
+			];
 
 
-				const numSubIntervals = absoluteSpan / 180;
+			if ( absoluteSpan[ 0 ] >= 180 || absoluteSpan[ 1 ] >= 180 || absoluteSpan[ 2 ] >= 180 ) {
 
 
-				const step = valuesSpan / numSubIntervals;
-				let nextValue = initialValue + step;
+				const maxAbsSpan = Math.max( ...absoluteSpan );
 
 
-				const initialTime = curve.times[ i - 1 ];
-				const timeSpan = curve.times[ i ] - initialTime;
-				const interval = timeSpan / numSubIntervals;
-				let nextTime = initialTime + interval;
+				const numSubIntervals = maxAbsSpan / 180;
 
 
-				const interpolatedTimes = [];
-				const interpolatedValues = [];
+				const E1 = new Euler( ...initialValueRad, eulerOrder );
+				const E2 = new Euler( ...currentValueRad, eulerOrder );
 
 
-				while ( nextTime < curve.times[ i ] ) {
+				const Q1 = new Quaternion().setFromEuler( E1 );
+				const Q2 = new Quaternion().setFromEuler( E2 );
 
 
-					interpolatedTimes.push( nextTime );
-					nextTime += interval;
+				// Check unroll
+				if ( Q1.dot( Q2 ) ) {
 
 
-					interpolatedValues.push( nextValue );
-					nextValue += step;
+					Q2.set( - Q2.x, - Q2.y, - Q2.z, - Q2.w );
 
 
 				}
 				}
 
 
-				curve.times = inject( curve.times, i, interpolatedTimes );
-				curve.values = inject( curve.values, i, interpolatedValues );
+				// Interpolate
+				const initialTime = curvex.times[ i - 1 ];
+				const timeSpan = curvex.times[ i ] - initialTime;
+
+				const Q = new Quaternion();
+				const E = new Euler();
+				for ( let t = 0; t < 1; t += 1 / numSubIntervals ) {
+
+					Q.copy( Q1.clone().slerp( Q2.clone(), t ) );
+
+					times.push( initialTime + t * timeSpan );
+					E.setFromQuaternion( Q, eulerOrder );
+
+					values.push( E.x );
+					values.push( E.y );
+					values.push( E.z );
+
+				}
+
+			} else {
+
+				times.push( curvex.times[ i ] );
+				values.push( MathUtils.degToRad( curvex.values[ i ] ) );
+				values.push( MathUtils.degToRad( curvey.values[ i ] ) );
+				values.push( MathUtils.degToRad( curvez.values[ i ] ) );
 
 
 			}
 			}
 
 
 		}
 		}
 
 
+		return [ times, values ];
+
 	}
 	}
 
 
 }
 }
@@ -4134,11 +4310,5 @@ function slice( a, b, from, to ) {
 
 
 }
 }
 
 
-// inject array a2 into array a1 at index
-function inject( a1, index, a2 ) {
-
-	return a1.slice( 0, index ).concat( a2 ).concat( a1.slice( index ) );
-
-}
 
 
 export { FBXLoader };
 export { FBXLoader };

+ 69 - 1
examples/jsm/loaders/GLTFLoader.js

@@ -151,6 +151,12 @@ class GLTFLoader extends Loader {
 
 
 		} );
 		} );
 
 
+		this.register( function ( parser ) {
+
+			return new GLTFMaterialsBumpExtension( parser );
+
+		} );
+
 		this.register( function ( parser ) {
 		this.register( function ( parser ) {
 
 
 			return new GLTFLightsExtension( parser );
 			return new GLTFLightsExtension( parser );
@@ -183,7 +189,13 @@ class GLTFLoader extends Loader {
 
 
 		} else if ( this.path !== '' ) {
 		} else if ( this.path !== '' ) {
 
 
-			resourcePath = this.path;
+			// If a base path is set, resources will be relative paths from that plus the relative path of the gltf file
+			// Example  path = 'https://my-cnd-server.com/', url = 'assets/models/model.gltf'
+			// resourcePath = 'https://my-cnd-server.com/assets/models/'
+			// referenced resource 'model.bin' will be loaded from 'https://my-cnd-server.com/assets/models/model.bin'
+			// referenced resource '../textures/texture.png' will be loaded from 'https://my-cnd-server.com/assets/textures/texture.png'
+			const relativeUrl = LoaderUtils.extractUrlBase( url );
+			resourcePath = LoaderUtils.resolveURL( relativeUrl, this.path );
 
 
 		} else {
 		} else {
 
 
@@ -491,6 +503,7 @@ const EXTENSIONS = {
 	KHR_TEXTURE_TRANSFORM: 'KHR_texture_transform',
 	KHR_TEXTURE_TRANSFORM: 'KHR_texture_transform',
 	KHR_MESH_QUANTIZATION: 'KHR_mesh_quantization',
 	KHR_MESH_QUANTIZATION: 'KHR_mesh_quantization',
 	KHR_MATERIALS_EMISSIVE_STRENGTH: 'KHR_materials_emissive_strength',
 	KHR_MATERIALS_EMISSIVE_STRENGTH: 'KHR_materials_emissive_strength',
+	EXT_MATERIALS_BUMP: 'EXT_materials_bump',
 	EXT_TEXTURE_WEBP: 'EXT_texture_webp',
 	EXT_TEXTURE_WEBP: 'EXT_texture_webp',
 	EXT_TEXTURE_AVIF: 'EXT_texture_avif',
 	EXT_TEXTURE_AVIF: 'EXT_texture_avif',
 	EXT_MESHOPT_COMPRESSION: 'EXT_meshopt_compression',
 	EXT_MESHOPT_COMPRESSION: 'EXT_meshopt_compression',
@@ -1201,6 +1214,61 @@ class GLTFMaterialsSpecularExtension {
 
 
 }
 }
 
 
+
+/**
+ * Materials bump Extension
+ *
+ * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/EXT_materials_bump
+ */
+class GLTFMaterialsBumpExtension {
+
+	constructor( parser ) {
+
+		this.parser = parser;
+		this.name = EXTENSIONS.EXT_MATERIALS_BUMP;
+
+	}
+
+	getMaterialType( materialIndex ) {
+
+		const parser = this.parser;
+		const materialDef = parser.json.materials[ materialIndex ];
+
+		if ( ! materialDef.extensions || ! materialDef.extensions[ this.name ] ) return null;
+
+		return MeshPhysicalMaterial;
+
+	}
+
+	extendMaterialParams( materialIndex, materialParams ) {
+
+		const parser = this.parser;
+		const materialDef = parser.json.materials[ materialIndex ];
+
+		if ( ! materialDef.extensions || ! materialDef.extensions[ this.name ] ) {
+
+			return Promise.resolve();
+
+		}
+
+		const pending = [];
+
+		const extension = materialDef.extensions[ this.name ];
+
+		materialParams.bumpScale = extension.bumpFactor !== undefined ? extension.bumpFactor : 1.0;
+
+		if ( extension.bumpTexture !== undefined ) {
+
+			pending.push( parser.assignTexture( materialParams, 'bumpMap', extension.bumpTexture ) );
+
+		}
+
+		return Promise.all( pending );
+
+	}
+
+}
+
 /**
 /**
  * Materials anisotropy Extension
  * Materials anisotropy Extension
  *
  *

+ 0 - 13
examples/jsm/loaders/NRRDLoader.js

@@ -76,12 +76,6 @@ class NRRDLoader extends Loader {
 
 
 		function scan( type, chunks ) {
 		function scan( type, chunks ) {
 
 
-			if ( chunks === undefined || chunks === null ) {
-
-				chunks = 1;
-
-			}
-
 			let _chunkSize = 1;
 			let _chunkSize = 1;
 			let _array_type = Uint8Array;
 			let _array_type = Uint8Array;
 
 
@@ -138,13 +132,6 @@ class NRRDLoader extends Loader {
 
 
 			}
 			}
 
 
-			if ( chunks == 1 ) {
-
-				// if only one chunk was requested, just return one value
-				return _bytes[ 0 ];
-
-			}
-
 			// return the byte array
 			// return the byte array
 			return _bytes;
 			return _bytes;
 
 

+ 4 - 4
examples/jsm/loaders/SVGLoader.js

@@ -2968,8 +2968,8 @@ class SVGLoader extends Loader {
 					// Bevel join triangle
 					// Bevel join triangle
 
 
 					addVertex( currentPointR, u, 1 );
 					addVertex( currentPointR, u, 1 );
-					addVertex( nextPointR, u, 0 );
-					addVertex( innerPoint, u, 0.5 );
+					addVertex( innerPoint, u, 0 );
+					addVertex( nextPointR, u, 1 );
 
 
 				}
 				}
 
 
@@ -3106,8 +3106,8 @@ class SVGLoader extends Loader {
 
 
 						} else {
 						} else {
 
 
-							tempV2_3.toArray( vertices, vl - 2 * 3 );
-							tempV2_4.toArray( vertices, vl - 1 * 3 );
+							tempV2_4.toArray( vertices, vl - 2 * 3 );
+							tempV2_3.toArray( vertices, vl - 1 * 3 );
 							tempV2_4.toArray( vertices, vl - 4 * 3 );
 							tempV2_4.toArray( vertices, vl - 4 * 3 );
 
 
 						}
 						}

+ 3 - 17
examples/jsm/loaders/USDZLoader.js

@@ -25,9 +25,7 @@ class USDAParser {
 		const data = {};
 		const data = {};
 
 
 		const lines = text.split( '\n' );
 		const lines = text.split( '\n' );
-		const length = lines.length;
 
 
-		let current = 0;
 		let string = null;
 		let string = null;
 		let target = data;
 		let target = data;
 
 
@@ -35,9 +33,7 @@ class USDAParser {
 
 
 		// debugger;
 		// debugger;
 
 
-		function parseNextLine() {
-
-			const line = lines[ current ];
+		for ( const line of lines ) {
 
 
 			// console.log( line );
 			// console.log( line );
 
 
@@ -74,7 +70,7 @@ class USDAParser {
 
 
 				stack.pop();
 				stack.pop();
 
 
-				if ( stack.length === 0 ) return;
+				if ( stack.length === 0 ) continue;
 
 
 				target = stack[ stack.length - 1 ];
 				target = stack[ stack.length - 1 ];
 
 
@@ -100,18 +96,8 @@ class USDAParser {
 
 
 			}
 			}
 
 
-			current ++;
-
-			if ( current < length ) {
-
-				parseNextLine();
-
-			}
-
 		}
 		}
 
 
-		parseNextLine();
-
 		return data;
 		return data;
 
 
 	}
 	}
@@ -640,7 +626,7 @@ class USDZLoader extends Loader {
 
 
 						}
 						}
 
 
-					} else  if ( 'float inputs:clearcoat' in surface ) {
+					} else if ( 'float inputs:clearcoat' in surface ) {
 
 
 						material.clearcoat = parseFloat( surface[ 'float inputs:clearcoat' ] );
 						material.clearcoat = parseFloat( surface[ 'float inputs:clearcoat' ] );
 
 

+ 15 - 4
examples/jsm/math/Octree.js

@@ -82,19 +82,18 @@ function lineToLineClosestPoints( line1, line2, target1 = null, target2 = null )
 
 
 class Octree {
 class Octree {
 
 
-
 	constructor( box ) {
 	constructor( box ) {
 
 
-		this.triangles = [];
 		this.box = box;
 		this.box = box;
+		this.bounds = new Box3();
+
 		this.subTrees = [];
 		this.subTrees = [];
+		this.triangles = [];
 
 
 	}
 	}
 
 
 	addTriangle( triangle ) {
 	addTriangle( triangle ) {
 
 
-		if ( ! this.bounds ) this.bounds = new Box3();
-
 		this.bounds.min.x = Math.min( this.bounds.min.x, triangle.a.x, triangle.b.x, triangle.c.x );
 		this.bounds.min.x = Math.min( this.bounds.min.x, triangle.a.x, triangle.b.x, triangle.c.x );
 		this.bounds.min.y = Math.min( this.bounds.min.y, triangle.a.y, triangle.b.y, triangle.c.y );
 		this.bounds.min.y = Math.min( this.bounds.min.y, triangle.a.y, triangle.b.y, triangle.c.y );
 		this.bounds.min.z = Math.min( this.bounds.min.z, triangle.a.z, triangle.b.z, triangle.c.z );
 		this.bounds.min.z = Math.min( this.bounds.min.z, triangle.a.z, triangle.b.z, triangle.c.z );
@@ -524,6 +523,18 @@ class Octree {
 
 
 	}
 	}
 
 
+	clear() {
+
+		this.box = null;
+		this.bounds.makeEmpty();
+
+		this.subTrees.length = 0;
+		this.triangles.length = 0;
+
+		return this;
+
+	}
+
 }
 }
 
 
 export { Octree };
 export { Octree };

+ 3 - 6
examples/jsm/misc/TubePainter.js

@@ -176,16 +176,13 @@ function TubePainter() {
 
 
 		if ( start === end ) return;
 		if ( start === end ) return;
 
 
-		positions.updateRange.offset = start * 3;
-		positions.updateRange.count = ( end - start ) * 3;
+		positions.addUpdateRange( start * 3, ( end - start ) * 3 );
 		positions.needsUpdate = true;
 		positions.needsUpdate = true;
 
 
-		normals.updateRange.offset = start * 3;
-		normals.updateRange.count = ( end - start ) * 3;
+		normals.addUpdateRange( start * 3, ( end - start ) * 3 );
 		normals.needsUpdate = true;
 		normals.needsUpdate = true;
 
 
-		colors.updateRange.offset = start * 3;
-		colors.updateRange.count = ( end - start ) * 3;
+		colors.addUpdateRange( start * 3, ( end - start ) * 3 );
 		colors.needsUpdate = true;
 		colors.needsUpdate = true;
 
 
 		count = geometry.drawRange.count;
 		count = geometry.drawRange.count;

+ 7 - 6
examples/jsm/nodes/Nodes.js

@@ -27,9 +27,10 @@ export { default as NodeUniform } from './core/NodeUniform.js';
 export { default as NodeVar } from './core/NodeVar.js';
 export { default as NodeVar } from './core/NodeVar.js';
 export { default as NodeVarying } from './core/NodeVarying.js';
 export { default as NodeVarying } from './core/NodeVarying.js';
 export { default as ParameterNode, parameter } from './core/ParameterNode.js';
 export { default as ParameterNode, parameter } from './core/ParameterNode.js';
-export { default as PropertyNode, property, output, diffuseColor, roughness, metalness, clearcoat, clearcoatRoughness, sheen, sheenRoughness, iridescence, iridescenceIOR, iridescenceThickness, specularColor, shininess, dashSize, gapSize, pointWidth } from './core/PropertyNode.js';
+export { default as PropertyNode, property, varyingProperty, output, diffuseColor, roughness, metalness, clearcoat, clearcoatRoughness, sheen, sheenRoughness, iridescence, iridescenceIOR, iridescenceThickness, specularColor, shininess, dashSize, gapSize, pointWidth } from './core/PropertyNode.js';
 export { default as StackNode, stack } from './core/StackNode.js';
 export { default as StackNode, stack } from './core/StackNode.js';
 export { default as TempNode } from './core/TempNode.js';
 export { default as TempNode } from './core/TempNode.js';
+export { default as UniformGroupNode, uniformGroup, objectGroup, renderGroup, frameGroup } from './core/UniformGroupNode.js';
 export { default as UniformNode, uniform } from './core/UniformNode.js';
 export { default as UniformNode, uniform } from './core/UniformNode.js';
 export { default as VaryingNode, varying } from './core/VaryingNode.js';
 export { default as VaryingNode, varying } from './core/VaryingNode.js';
 export { default as OutputStructNode, outputStruct } from './core/OutputStructNode.js';
 export { default as OutputStructNode, outputStruct } from './core/OutputStructNode.js';
@@ -70,7 +71,7 @@ export * from './shadernode/ShaderNode.js';
 export { default as BitangentNode, bitangentGeometry, bitangentLocal, bitangentView, bitangentWorld, transformedBitangentView, transformedBitangentWorld } from './accessors/BitangentNode.js';
 export { default as BitangentNode, bitangentGeometry, bitangentLocal, bitangentView, bitangentWorld, transformedBitangentView, transformedBitangentWorld } from './accessors/BitangentNode.js';
 export { default as BufferAttributeNode, bufferAttribute, dynamicBufferAttribute, instancedBufferAttribute, instancedDynamicBufferAttribute } from './accessors/BufferAttributeNode.js';
 export { default as BufferAttributeNode, bufferAttribute, dynamicBufferAttribute, instancedBufferAttribute, instancedDynamicBufferAttribute } from './accessors/BufferAttributeNode.js';
 export { default as BufferNode, buffer } from './accessors/BufferNode.js';
 export { default as BufferNode, buffer } from './accessors/BufferNode.js';
-export { default as CameraNode, cameraProjectionMatrix, cameraViewMatrix, cameraNormalMatrix, cameraWorldMatrix, cameraPosition, cameraNear, cameraFar } from './accessors/CameraNode.js';
+export { default as CameraNode, cameraProjectionMatrix, cameraViewMatrix, cameraNormalMatrix, cameraWorldMatrix, cameraPosition, cameraNear, cameraFar, cameraLogDepth } from './accessors/CameraNode.js';
 export { default as CubeTextureNode, cubeTexture } from './accessors/CubeTextureNode.js';
 export { default as CubeTextureNode, cubeTexture } from './accessors/CubeTextureNode.js';
 export { default as InstanceNode, instance } from './accessors/InstanceNode.js';
 export { default as InstanceNode, instance } from './accessors/InstanceNode.js';
 export { default as MaterialNode, materialAlphaTest, materialColor, materialShininess, materialEmissive, materialOpacity, materialSpecularColor, materialSpecularStrength, materialReflectivity, materialRoughness, materialMetalness, materialNormal, materialClearcoat, materialClearcoatRoughness, materialClearcoatNormal, materialRotation, materialSheen, materialSheenRoughness, materialIridescence, materialIridescenceIOR, materialIridescenceThickness, materialLineScale, materialLineDashSize, materialLineGapSize, materialLineWidth, materialLineDashOffset, materialPointWidth } from './accessors/MaterialNode.js';
 export { default as MaterialNode, materialAlphaTest, materialColor, materialShininess, materialEmissive, materialOpacity, materialSpecularColor, materialSpecularStrength, materialReflectivity, materialRoughness, materialMetalness, materialNormal, materialClearcoat, materialClearcoatRoughness, materialClearcoatNormal, materialRotation, materialSheen, materialSheenRoughness, materialIridescence, materialIridescenceIOR, materialIridescenceThickness, materialLineScale, materialLineDashSize, materialLineGapSize, materialLineWidth, materialLineDashOffset, materialPointWidth } from './accessors/MaterialNode.js';
@@ -83,13 +84,13 @@ export { default as NormalNode, normalGeometry, normalLocal, normalView, normalW
 export { default as Object3DNode, objectDirection, objectViewMatrix, objectNormalMatrix, objectWorldMatrix, objectPosition, objectScale, objectViewPosition } from './accessors/Object3DNode.js';
 export { default as Object3DNode, objectDirection, objectViewMatrix, objectNormalMatrix, objectWorldMatrix, objectPosition, objectScale, objectViewPosition } from './accessors/Object3DNode.js';
 export { default as PointUVNode, pointUV } from './accessors/PointUVNode.js';
 export { default as PointUVNode, pointUV } from './accessors/PointUVNode.js';
 export { default as PositionNode, positionGeometry, positionLocal, positionWorld, positionWorldDirection, positionView, positionViewDirection } from './accessors/PositionNode.js';
 export { default as PositionNode, positionGeometry, positionLocal, positionWorld, positionWorldDirection, positionView, positionViewDirection } from './accessors/PositionNode.js';
-export { default as ReferenceNode, reference } from './accessors/ReferenceNode.js';
+export { default as ReferenceNode, reference, referenceIndex } from './accessors/ReferenceNode.js';
 export { default as ReflectVectorNode, reflectVector } from './accessors/ReflectVectorNode.js';
 export { default as ReflectVectorNode, reflectVector } from './accessors/ReflectVectorNode.js';
 export { default as SkinningNode, skinning } from './accessors/SkinningNode.js';
 export { default as SkinningNode, skinning } from './accessors/SkinningNode.js';
 export { default as SceneNode, backgroundBlurriness, backgroundIntensity } from './accessors/SceneNode.js';
 export { default as SceneNode, backgroundBlurriness, backgroundIntensity } from './accessors/SceneNode.js';
 export { default as StorageBufferNode, storage } from './accessors/StorageBufferNode.js';
 export { default as StorageBufferNode, storage } from './accessors/StorageBufferNode.js';
 export { default as TangentNode, tangentGeometry, tangentLocal, tangentView, tangentWorld, transformedTangentView, transformedTangentWorld } from './accessors/TangentNode.js';
 export { default as TangentNode, tangentGeometry, tangentLocal, tangentView, tangentWorld, transformedTangentView, transformedTangentWorld } from './accessors/TangentNode.js';
-export { default as TextureNode, texture, /*textureLevel,*/ sampler } from './accessors/TextureNode.js';
+export { default as TextureNode, texture, textureLoad, /*textureLevel,*/ sampler } from './accessors/TextureNode.js';
 export { default as TextureStoreNode, textureStore } from './accessors/TextureStoreNode.js';
 export { default as TextureStoreNode, textureStore } from './accessors/TextureStoreNode.js';
 export { default as UVNode, uv } from './accessors/UVNode.js';
 export { default as UVNode, uv } from './accessors/UVNode.js';
 export { default as UserDataNode, userData } from './accessors/UserDataNode.js';
 export { default as UserDataNode, userData } from './accessors/UserDataNode.js';
@@ -107,7 +108,7 @@ export { default as ViewportNode, viewport, viewportCoordinate, viewportResoluti
 export { default as ViewportTextureNode, viewportTexture, viewportMipTexture } from './display/ViewportTextureNode.js';
 export { default as ViewportTextureNode, viewportTexture, viewportMipTexture } from './display/ViewportTextureNode.js';
 export { default as ViewportSharedTextureNode, viewportSharedTexture } from './display/ViewportSharedTextureNode.js';
 export { default as ViewportSharedTextureNode, viewportSharedTexture } from './display/ViewportSharedTextureNode.js';
 export { default as ViewportDepthTextureNode, viewportDepthTexture } from './display/ViewportDepthTextureNode.js';
 export { default as ViewportDepthTextureNode, viewportDepthTexture } from './display/ViewportDepthTextureNode.js';
-export { default as ViewportDepthNode, viewZToOrthographicDepth, orthographicDepthToViewZ, viewZToPerspectiveDepth, perspectiveDepthToViewZ, depth, depthTexture } from './display/ViewportDepthNode.js';
+export { default as ViewportDepthNode, viewZToOrthographicDepth, orthographicDepthToViewZ, viewZToPerspectiveDepth, perspectiveDepthToViewZ, depth, depthTexture, depthPixel } from './display/ViewportDepthNode.js';
 
 
 // code
 // code
 export { default as ExpressionNode, expression } from './code/ExpressionNode.js';
 export { default as ExpressionNode, expression } from './code/ExpressionNode.js';
@@ -135,7 +136,7 @@ export { default as DirectionalLightNode } from './lighting/DirectionalLightNode
 export { default as SpotLightNode } from './lighting/SpotLightNode.js';
 export { default as SpotLightNode } from './lighting/SpotLightNode.js';
 export { default as IESSpotLightNode } from './lighting/IESSpotLightNode.js';
 export { default as IESSpotLightNode } from './lighting/IESSpotLightNode.js';
 export { default as AmbientLightNode } from './lighting/AmbientLightNode.js';
 export { default as AmbientLightNode } from './lighting/AmbientLightNode.js';
-export { default as LightsNode, lights, lightsWithoutWrap, addLightNode } from './lighting/LightsNode.js';
+export { default as LightsNode, lights, lightNodes, addLightNode } from './lighting/LightsNode.js';
 export { default as LightingNode /* @TODO: lighting (abstract), light */ } from './lighting/LightingNode.js';
 export { default as LightingNode /* @TODO: lighting (abstract), light */ } from './lighting/LightingNode.js';
 export { default as LightingContextNode, lightingContext } from './lighting/LightingContextNode.js';
 export { default as LightingContextNode, lightingContext } from './lighting/LightingContextNode.js';
 export { default as HemisphereLightNode } from './lighting/HemisphereLightNode.js';
 export { default as HemisphereLightNode } from './lighting/HemisphereLightNode.js';

+ 18 - 2
examples/jsm/nodes/accessors/CameraNode.js

@@ -1,14 +1,22 @@
 import Object3DNode from './Object3DNode.js';
 import Object3DNode from './Object3DNode.js';
 import { addNodeClass } from '../core/Node.js';
 import { addNodeClass } from '../core/Node.js';
 import { label } from '../core/ContextNode.js';
 import { label } from '../core/ContextNode.js';
+import { NodeUpdateType } from '../core/constants.js';
+//import { sharedUniformGroup } from '../core/UniformGroupNode.js';
 import { nodeImmutable } from '../shadernode/ShaderNode.js';
 import { nodeImmutable } from '../shadernode/ShaderNode.js';
 
 
+//const cameraGroup = sharedUniformGroup( 'camera' );
+
 class CameraNode extends Object3DNode {
 class CameraNode extends Object3DNode {
 
 
 	constructor( scope = CameraNode.POSITION ) {
 	constructor( scope = CameraNode.POSITION ) {
 
 
 		super( scope );
 		super( scope );
 
 
+		this.updateType = NodeUpdateType.RENDER;
+
+		//this._uniformNode.groupNode = cameraGroup;
+
 	}
 	}
 
 
 	getNodeType( builder ) {
 	getNodeType( builder ) {
@@ -19,7 +27,7 @@ class CameraNode extends Object3DNode {
 
 
 			return 'mat4';
 			return 'mat4';
 
 
-		} else if ( scope === CameraNode.NEAR || scope === CameraNode.FAR ) {
+		} else if ( scope === CameraNode.NEAR || scope === CameraNode.FAR || scope === CameraNode.LOG_DEPTH ) {
 
 
 			return 'float';
 			return 'float';
 
 
@@ -35,6 +43,8 @@ class CameraNode extends Object3DNode {
 		const uniformNode = this._uniformNode;
 		const uniformNode = this._uniformNode;
 		const scope = this.scope;
 		const scope = this.scope;
 
 
+		//cameraGroup.needsUpdate = true;
+
 		if ( scope === CameraNode.VIEW_MATRIX ) {
 		if ( scope === CameraNode.VIEW_MATRIX ) {
 
 
 			uniformNode.value = camera.matrixWorldInverse;
 			uniformNode.value = camera.matrixWorldInverse;
@@ -51,6 +61,10 @@ class CameraNode extends Object3DNode {
 
 
 			uniformNode.value = camera.far;
 			uniformNode.value = camera.far;
 
 
+		} else if ( scope === CameraNode.LOG_DEPTH ) {
+
+			uniformNode.value = 2.0 / ( Math.log( camera.far + 1.0 ) / Math.LN2 );
+
 		} else {
 		} else {
 
 
 			this.object3d = camera;
 			this.object3d = camera;
@@ -69,7 +83,7 @@ class CameraNode extends Object3DNode {
 
 
 			this._uniformNode.nodeType = 'mat4';
 			this._uniformNode.nodeType = 'mat4';
 
 
-		} else if ( scope === CameraNode.NEAR || scope === CameraNode.FAR ) {
+		} else if ( scope === CameraNode.NEAR || scope === CameraNode.FAR || scope === CameraNode.LOG_DEPTH ) {
 
 
 			this._uniformNode.nodeType = 'float';
 			this._uniformNode.nodeType = 'float';
 
 
@@ -84,12 +98,14 @@ class CameraNode extends Object3DNode {
 CameraNode.PROJECTION_MATRIX = 'projectionMatrix';
 CameraNode.PROJECTION_MATRIX = 'projectionMatrix';
 CameraNode.NEAR = 'near';
 CameraNode.NEAR = 'near';
 CameraNode.FAR = 'far';
 CameraNode.FAR = 'far';
+CameraNode.LOG_DEPTH = 'logDepth';
 
 
 export default CameraNode;
 export default CameraNode;
 
 
 export const cameraProjectionMatrix = label( nodeImmutable( CameraNode, CameraNode.PROJECTION_MATRIX ), 'projectionMatrix' );
 export const cameraProjectionMatrix = label( nodeImmutable( CameraNode, CameraNode.PROJECTION_MATRIX ), 'projectionMatrix' );
 export const cameraNear = nodeImmutable( CameraNode, CameraNode.NEAR );
 export const cameraNear = nodeImmutable( CameraNode, CameraNode.NEAR );
 export const cameraFar = nodeImmutable( CameraNode, CameraNode.FAR );
 export const cameraFar = nodeImmutable( CameraNode, CameraNode.FAR );
+export const cameraLogDepth = nodeImmutable( CameraNode, CameraNode.LOG_DEPTH );
 export const cameraViewMatrix = nodeImmutable( CameraNode, CameraNode.VIEW_MATRIX );
 export const cameraViewMatrix = nodeImmutable( CameraNode, CameraNode.VIEW_MATRIX );
 export const cameraNormalMatrix = nodeImmutable( CameraNode, CameraNode.NORMAL_MATRIX );
 export const cameraNormalMatrix = nodeImmutable( CameraNode, CameraNode.NORMAL_MATRIX );
 export const cameraWorldMatrix = nodeImmutable( CameraNode, CameraNode.WORLD_MATRIX );
 export const cameraWorldMatrix = nodeImmutable( CameraNode, CameraNode.WORLD_MATRIX );

+ 3 - 76
examples/jsm/nodes/accessors/CubeTextureNode.js

@@ -1,9 +1,6 @@
 import TextureNode from './TextureNode.js';
 import TextureNode from './TextureNode.js';
-import UniformNode from '../core/UniformNode.js';
 import { reflectVector } from './ReflectVectorNode.js';
 import { reflectVector } from './ReflectVectorNode.js';
 import { addNodeClass } from '../core/Node.js';
 import { addNodeClass } from '../core/Node.js';
-import { colorSpaceToLinear } from '../display/ColorSpaceNode.js';
-import { expression } from '../code/ExpressionNode.js';
 import { addNodeElement, nodeProxy, vec3 } from '../shadernode/ShaderNode.js';
 import { addNodeElement, nodeProxy, vec3 } from '../shadernode/ShaderNode.js';
 
 
 class CubeTextureNode extends TextureNode {
 class CubeTextureNode extends TextureNode {
@@ -30,80 +27,10 @@ class CubeTextureNode extends TextureNode {
 
 
 	setUpdateMatrix( /*updateMatrix*/ ) { } // Ignore .updateMatrix for CubeTextureNode
 	setUpdateMatrix( /*updateMatrix*/ ) { } // Ignore .updateMatrix for CubeTextureNode
 
 
-	generate( builder, output ) {
+	generateUV( builder, uvNode ) {
 
 
-		const { uvNode, levelNode } = builder.getNodeProperties( this );
-
-		const texture = this.value;
-
-		if ( ! texture || texture.isCubeTexture !== true ) {
-
-			throw new Error( 'CubeTextureNode: Need a three.js cube texture.' );
-
-		}
-
-		const textureProperty = UniformNode.prototype.generate.call( this, builder, 'cubeTexture' );
-
-		if ( output === 'sampler' ) {
-
-			return textureProperty + '_sampler';
-
-		} else if ( builder.isReference( output ) ) {
-
-			return textureProperty;
-
-		} else {
-
-			const nodeData = builder.getDataFromNode( this );
-
-			let propertyName = nodeData.propertyName;
-
-			if ( propertyName === undefined ) {
-
-				const cubeUV = vec3( uvNode.x.negate(), uvNode.yz );
-				const uvSnippet = cubeUV.build( builder, 'vec3' );
-
-				const nodeVar = builder.getVarFromNode( this );
-
-				propertyName = builder.getPropertyName( nodeVar );
-
-				let snippet = null;
-
-				if ( levelNode && levelNode.isNode === true ) {
-
-					const levelSnippet = levelNode.build( builder, 'float' );
-
-					snippet = builder.getTextureLevel( this, textureProperty, uvSnippet, levelSnippet );
-
-				} else {
-
-					snippet = builder.getTexture( this, textureProperty, uvSnippet );
-
-				}
-
-				builder.addLineFlowCode( `${propertyName} = ${snippet}` );
-
-				if ( builder.context.tempWrite !== false ) {
-
-					nodeData.snippet = snippet;
-					nodeData.propertyName = propertyName;
-
-				}
-
-			}
-
-			let snippet = propertyName;
-			const nodeType = this.getNodeType( builder );
-
-			if ( builder.needsColorSpaceToLinear( this.value ) ) {
-
-				snippet = colorSpaceToLinear( expression( snippet, nodeType ), this.value.colorSpace ).setup( builder ).build( builder, nodeType );
-
-			}
-
-			return builder.format( snippet, nodeType, output );
-
-		}
+		const cubeUV = vec3( uvNode.x.negate(), uvNode.yz );
+		return cubeUV.build( builder, 'vec3' );
 
 
 	}
 	}
 
 

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