Sfoglia il codice sorgente

Merge remote-tracking branch 'upstream/dev' into dev29

Mugen87 5 anni fa
parent
commit
8824547318
100 ha cambiato i file con 3655 aggiunte e 5602 eliminazioni
  1. 103 106
      build/three.js
  2. 452 443
      build/three.min.js
  3. 103 106
      build/three.module.js
  4. 5 0
      docs/api/en/audio/Audio.html
  5. 1 1
      docs/api/en/constants/Renderer.html
  6. 0 7
      docs/api/en/core/BufferAttribute.html
  7. 0 1
      docs/api/en/loaders/managers/LoadingManager.html
  8. 7 2
      docs/api/en/materials/Material.html
  9. 0 1
      docs/api/en/textures/DataTexture.html
  10. 0 7
      docs/api/zh/core/BufferAttribute.html
  11. 0 1
      docs/api/zh/loaders/managers/LoadingManager.html
  12. 7 2
      docs/api/zh/materials/Material.html
  13. 89 0
      docs/examples/en/controls/DeviceOrientationControls.html
  14. 119 0
      docs/examples/en/controls/DragControls.html
  15. 166 0
      docs/examples/en/controls/FirstPersonControls.html
  16. 95 0
      docs/examples/en/controls/FlyControls.html
  17. 149 0
      docs/examples/en/controls/PointerLockControls.html
  18. 208 0
      docs/examples/en/controls/TrackballControls.html
  19. 225 0
      docs/examples/en/controls/TransformControls.html
  20. 0 96
      docs/examples/en/loaders/BabylonLoader.html
  21. 89 0
      docs/examples/zh/controls/DeviceOrientationControls.html
  22. 119 0
      docs/examples/zh/controls/DragControls.html
  23. 166 0
      docs/examples/zh/controls/FirstPersonControls.html
  24. 95 0
      docs/examples/zh/controls/FlyControls.html
  25. 149 0
      docs/examples/zh/controls/PointerLockControls.html
  26. 208 0
      docs/examples/zh/controls/TrackballControls.html
  27. 225 0
      docs/examples/zh/controls/TransformControls.html
  28. 0 96
      docs/examples/zh/loaders/BabylonLoader.html
  29. 16 4
      docs/list.js
  30. 24 0
      editor/css/dark.css
  31. 25 0
      editor/css/light.css
  32. 53 0
      editor/css/main.css
  33. 4 6
      editor/index.html
  34. 1 1
      editor/js/EditorControls.js
  35. 0 71
      editor/js/Loader.js
  36. 17 1
      editor/js/Menubar.Add.js
  37. 0 2
      editor/js/Sidebar.Geometry.BoxGeometry.js
  38. 0 2
      editor/js/Sidebar.Geometry.CircleGeometry.js
  39. 0 2
      editor/js/Sidebar.Geometry.CylinderGeometry.js
  40. 49 0
      editor/js/Sidebar.Geometry.DodecahedronGeometry.js
  41. 0 2
      editor/js/Sidebar.Geometry.ExtrudeGeometry.js
  42. 0 5
      editor/js/Sidebar.Geometry.IcosahedronGeometry.js
  43. 0 2
      editor/js/Sidebar.Geometry.LatheGeometry.js
  44. 0 4
      editor/js/Sidebar.Geometry.OctahedronGeometry.js
  45. 0 2
      editor/js/Sidebar.Geometry.PlaneGeometry.js
  46. 0 2
      editor/js/Sidebar.Geometry.RingGeometry.js
  47. 0 2
      editor/js/Sidebar.Geometry.ShapeGeometry.js
  48. 0 2
      editor/js/Sidebar.Geometry.SphereGeometry.js
  49. 0 4
      editor/js/Sidebar.Geometry.TetrahedronGeometry.js
  50. 0 2
      editor/js/Sidebar.Geometry.TorusGeometry.js
  51. 0 2
      editor/js/Sidebar.Geometry.TorusKnotGeometry.js
  52. 0 2
      editor/js/Sidebar.Geometry.TubeGeometry.js
  53. 36 0
      editor/js/Sidebar.Material.js
  54. 5 63
      editor/js/Sidebar.Properties.js
  55. 4 56
      editor/js/Sidebar.js
  56. 9 0
      editor/js/Strings.js
  57. 285 0
      editor/js/libs/ui.js
  58. 0 3
      editor/sw.js
  59. 2 6
      examples/files.js
  60. 6 2
      examples/js/controls/FirstPersonControls.js
  61. 0 644
      examples/js/controls/OrthographicTrackballControls.js
  62. 71 7
      examples/js/controls/TrackballControls.js
  63. 0 4
      examples/js/lights/RectAreaLightUniformsLib.js
  64. 0 1219
      examples/js/loaders/AWDLoader.js
  65. 0 248
      examples/js/loaders/BabylonLoader.js
  66. 27 5
      examples/js/loaders/DRACOLoader.js
  67. 22 16
      examples/js/loaders/FBXLoader.js
  68. 0 196
      examples/js/loaders/PlayCanvasLoader.js
  69. 2 5
      examples/js/misc/GPUComputationRenderer.js
  70. 0 1
      examples/js/misc/Ocean.js
  71. 0 2
      examples/js/objects/Lensflare.js
  72. 1 3
      examples/js/postprocessing/GlitchPass.js
  73. 4 4
      examples/js/postprocessing/OutlinePass.js
  74. 0 1
      examples/js/postprocessing/SSAOPass.js
  75. 1 3
      examples/jsm/controls/DeviceOrientationControls.d.ts
  76. 0 26
      examples/jsm/controls/EditorControls.d.ts
  77. 0 327
      examples/jsm/controls/EditorControls.js
  78. 1 1
      examples/jsm/controls/FirstPersonControls.d.ts
  79. 6 2
      examples/jsm/controls/FirstPersonControls.js
  80. 0 30
      examples/jsm/controls/OrthographicTrackballControls.d.ts
  81. 0 653
      examples/jsm/controls/OrthographicTrackballControls.js
  82. 0 2
      examples/jsm/controls/TrackballControls.d.ts
  83. 71 7
      examples/jsm/controls/TrackballControls.js
  84. 5 11
      examples/jsm/controls/TransformControls.d.ts
  85. 0 12
      examples/jsm/loaders/BabylonLoader.d.ts
  86. 0 266
      examples/jsm/loaders/BabylonLoader.js
  87. 27 5
      examples/jsm/loaders/DRACOLoader.js
  88. 22 16
      examples/jsm/loaders/FBXLoader.js
  89. 2 2
      examples/jsm/loaders/MMDLoader.d.ts
  90. 0 12
      examples/jsm/loaders/PlayCanvasLoader.d.ts
  91. 0 211
      examples/jsm/loaders/PlayCanvasLoader.js
  92. 1 1
      examples/jsm/loaders/VTKLoader.d.ts
  93. 7 7
      examples/jsm/loaders/obj2/utils/CodeSerializer.js
  94. 4 4
      examples/jsm/postprocessing/OutlinePass.js
  95. 2 2
      examples/jsm/renderers/WebGLDeferredRenderer.d.ts
  96. 9 19
      examples/misc_controls_drag.html
  97. 54 20
      examples/misc_controls_trackball.html
  98. 0 148
      examples/misc_controls_trackball_orthographic.html
  99. 0 341
      examples/misc_fps.html
  100. BIN
      examples/models/awd/simple/simple.awd

File diff suppressed because it is too large
+ 103 - 106
build/three.js


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


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


+ 5 - 0
docs/api/en/audio/Audio.html

@@ -192,7 +192,12 @@
 		<p>
 		Applies the given object of type [link:https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement HTMLMediaElement] as the source of this audio.<br />
 		Also sets [page:Audio.hasPlaybackControl hasPlaybackControl] to false.
+		</p>
 
+		<h3>[method:Audio setMediaStreamSource]( mediaStream )</h3>
+		<p>
+		Applies the given object of type [link:https://developer.mozilla.org/en-US/docs/Web/API/MediaStream MediaStream] as the source of this audio.<br />
+		Also sets [page:Audio.hasPlaybackControl hasPlaybackControl] to false.
 		</p>
 
 		<h3>[method:Audio setNodeSource]( audioNode )</h3>

+ 1 - 1
docs/api/en/constants/Renderer.html

@@ -47,7 +47,7 @@
 		[page:constant BasicShadowMap] gives unfiltered shadow maps - fastest, but lowest quality.<br />
 		[page:constant PCFShadowMap] filters shadow maps using the Percentage-Closer Filtering (PCF) algorithm (default).<br />
 		[page:constant PCFSoftShadowMap] filters shadow maps using the Percentage-Closer Soft Shadows (PCSS) algorithm.<br />
-		[page:constant VSMShadowMap] filters shadow maps using the Variance Shadow Map (VSM) algorithm.
+		[page:constant VSMShadowMap] filters shadow maps using the Variance Shadow Map (VSM) algorithm. When using VSMShadowMap all shadow receivers will also cast shadows.
 		</p>
 
 		<h2>Tone Mapping</h2>

+ 0 - 7
docs/api/en/core/BufferAttribute.html

@@ -174,13 +174,6 @@
 		being a [page:TypedArray].
 		</p>
 
-		<h3>[method:BufferAttribute setArray] ( [param:TypedArray array] ) </h3>
-		<p>
-		[page:BufferAttribute.array array] to the TypedArray passed in here.<br /><br />
-
-		After setting the array, [page:BufferAttribute.needsUpdate needsUpdate] should be set to true.
-		</p>
-
 		<h3>[method:BufferAttribute setUsage] ( [param:Usage value] ) </h3>
 		<p>Set [page:BufferAttribute.usage usage] to value.</p>
 

+ 0 - 1
docs/api/en/loaders/managers/LoadingManager.html

@@ -23,7 +23,6 @@
 		<h2>Example</h2>
 
 		<p>
-			[example:webgl_loader_babylon WebGL / loader / babylon]<br />
 			[example:webgl_loader_fbx WebGL / loader / fbx]<br />
 			[example:webgl_loader_obj WebGL / loader / obj]<br />
 			[example:webgl_materials_reflectivity WebGL / materials / reflectivity]<br />

+ 7 - 2
docs/api/en/materials/Material.html

@@ -128,6 +128,11 @@
 		Whether rendering this material has any effect on the stencil buffer. Default is *false*.
 		</p>
 
+		<h3>[property:Boolean stencilWriteMask]</h3>
+		<p>
+		The bit mask to use when writing to the stencil buffer. Default is *0xFF*.
+		</p>
+
 		<h3>[property:Boolean stencilFunc]</h3>
 		<p>
 		The stencil comparison function to use. Default is [page:Materials AlwaysStencilFunc]. See stencil function [page:Materials constants] for all possible values.
@@ -138,9 +143,9 @@
 		The value to use when performing stencil comparisons or stencil operations. Default is *0*.
 		</p>
 
-		<h3>[property:Boolean stencilMask]</h3>
+		<h3>[property:Boolean stencilFuncMask]</h3>
 		<p>
-		The bit mask to use when comparing against or writing to the stencil buffer. Default is *0xFF*.
+		The bit mask to use when comparing against the stencil buffer. Default is *0xFF*.
 		</p>
 
 		<h3>[property:Integer stencilFail]</h3>

+ 0 - 1
docs/api/en/textures/DataTexture.html

@@ -57,7 +57,6 @@
 		// used the buffer to create a [name]
 
 		var texture = new THREE.DataTexture( data, width, height, THREE.RGBFormat );
-		texture.needsUpdate = true
 		</code>
 
 		<h2>Properties</h2>

+ 0 - 7
docs/api/zh/core/BufferAttribute.html

@@ -155,13 +155,6 @@
 		特别的, 对将 [page:Array value] 转为  [page:TypedArray] 的要求详见上述链接。
 		</p>
 
-		<h3>[method:BufferAttribute setArray] ( [param:TypedArray array] ) </h3>
-		<p>
-		[page:BufferAttribute.array array] 被赋值的 TypedArray 队列。<br /><br />
-
-		队列被复制后,[page:BufferAttribute.needsUpdate needsUpdate] 应当被设置为 true。
-		</p>
-
 		<h3>[method:BufferAttribute setUsage] ( [param:Usage value] ) </h3>
 		<p>Set [page:BufferAttribute.usage usage] to value.</p>
 

+ 0 - 1
docs/api/zh/loaders/managers/LoadingManager.html

@@ -23,7 +23,6 @@
 		<h2>例子</h2>
 
 		<p>
-			[example:webgl_loader_babylon WebGL / loader / babylon]<br />
 			[example:webgl_loader_fbx WebGL / loader / fbx]<br />
 			[example:webgl_loader_obj WebGL / loader / obj]<br />
 			[example:webgl_materials_reflectivity WebGL / materials / reflectivity]<br />

+ 7 - 2
docs/api/zh/materials/Material.html

@@ -108,6 +108,11 @@
 Whether rendering this material has any effect on the stencil buffer. Default is *false*.
 </p>
 
+<h3>[property:Boolean stencilWriteMask]</h3>
+<p>
+The bit mask to use when writing to the stencil buffer. Default is *0xFF*.
+</p>
+
 <h3>[property:Boolean stencilFunc]</h3>
 <p>
 The stencil comparison function to use. Default is [page:Materials AlwaysStencilFunc]. See stencil function [page:Materials constants] for all possible values.
@@ -118,9 +123,9 @@ The stencil comparison function to use. Default is [page:Materials AlwaysStencil
 The value to use when performing stencil comparisons or stencil operations. Default is *0*.
 </p>
 
-<h3>[property:Boolean stencilMask]</h3>
+<h3>[property:Boolean stencilFuncMask]</h3>
 <p>
-The bit mask to use when comparing against or writing to the stencil buffer. Default is *0xFF*.
+The bit mask to use when comparing against the stencil buffer. Default is *0xFF*.
 </p>
 
 <h3>[property:Integer stencilFail]</h3>

+ 89 - 0
docs/examples/en/controls/DeviceOrientationControls.html

@@ -0,0 +1,89 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<meta charset="utf-8" />
+		<base href="../../../" />
+		<script src="list.js"></script>
+		<script src="page.js"></script>
+		<link type="text/css" rel="stylesheet" href="page.css" />
+	</head>
+	<body>
+
+		<h1>[name]</h1>
+
+		<p class="desc">
+			Can be used to orient the camera based on the mobile device's orientation.
+		</p>
+
+		<h2>Example</h2>
+
+		<p>[example:misc_controls_deviceorientation misc / controls / deviceorientation ]</p>
+
+		<h2>Constructor</h2>
+
+		<h3>[name]( [param:Camera object] )</h3>
+		<p>
+			<p>
+				[page:Camera object]: The camera to be controlled.
+			</p>
+			<p>
+				Creates a new instance of [name].
+			</p>
+		</p>
+
+		<h2>Properties</h2>
+
+		<h3>[property:Number alphaOffset]</h3>
+		<p>
+			The alpha offset in radians. Default is *0*.
+		</p>
+
+		<h3>[property:Object deviceOrientation]</h3>
+		<p>
+			The current *deviceorientation* event object.
+		</p>
+
+		<h3>[property:Boolean enabled]</h3>
+		<p>
+			Whether or not the controls are enabled.
+		</p>
+
+		<h3>[property:Camera object]</h3>
+		<p>
+			The camera to be controlled.
+		</p>
+
+		<h3>[property:Number screenOrientation]</h3>
+		<p>
+			The orientation in degrees (in 90-degree increments) of the viewport relative to the device's natural orientation. Default is *0*.
+		</p>
+
+		<h2>Methods</h2>
+
+		<h3>[method:null connect] ()</h3>
+		<p>
+			Adds the event listeners of the controls and enables it.
+		</p>
+
+		<h3>[method:null disconnect] ()</h3>
+		<p>
+			Removes the event listeners of the controls and disables it.
+		</p>
+
+		<h3>[method:null dispose] ()</h3>
+		<p>
+			Should be called if the controls is no longer required.
+		</p>
+
+		<h3>[method:null update] ()</h3>
+		<p>
+			Updates the controls. Usually called in the animation loop.
+		</p>
+
+		<h2>Source</h2>
+
+		<p>
+			[link:https://github.com/mrdoob/three.js/blob/master/examples/js/controls/DeviceOrientationControls.js examples/js/controls/DeviceOrientationControls.js]
+		</p>
+	</body>
+</html>

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

@@ -0,0 +1,119 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<meta charset="utf-8" />
+		<base href="../../../" />
+		<script src="list.js"></script>
+		<script src="page.js"></script>
+		<link type="text/css" rel="stylesheet" href="page.css" />
+	</head>
+	<body>
+		[page:EventDispatcher] &rarr;
+
+		<h1>[name]</h1>
+
+		<p class="desc">
+		This class can be used to provide a drag'n'drop interaction.
+		</p>
+
+		<h2>Example</h2>
+
+		<p>[example:misc_controls_drag misc / controls / drag ]</p>
+
+		<code>
+var controls = new THREE.DragControls( objects, camera, renderer.domElement );
+
+// add event listener to highlight dragged objects
+
+controls.addEventListener( 'dragstart', function ( event ) {
+
+	event.object.material.emissive.set( 0xaaaaaa );
+
+} );
+
+controls.addEventListener( 'dragend', function ( event ) {
+
+	event.object.material.emissive.set( 0x000000 );
+
+} );
+
+		</code>
+
+		<h2>Constructor</h2>
+
+		<h3>[name]( [param:Array objects], [param:Camera camera], [param:HTMLDOMElement domElement] )</h3>
+		<p>
+			<p>
+				[page:Array objects]: An array of draggable 3D objects.
+			</p>
+			<p>
+			[page:Camera camera]: The camera of the rendered scene.
+			</p>
+			<p>
+			[page:HTMLDOMElement domElement]: The HTML element used for event listeners.
+			</p>
+			<p>
+				Creates a new instance of [name].
+			</p>
+		</p>
+
+		<h2>Events</h2>
+
+		<h3>dragstart</h3>
+		<p>
+			Fires when the user starts to drag a 3D object.
+		</p>
+
+		<h3>drag</h3>
+		<p>
+			Fires when the user drags a 3D object.
+		</p>
+
+		<h3>dragend</h3>
+		<p>
+			Fires when the user has finished dragging a 3D object.
+		</p>
+
+		<h3>hoveron</h3>
+		<p>
+			Fires when the pointer is moved onto a 3D object, or onto one of its children.
+		</p>
+
+		<h3>hoveroff</h3>
+		<p>
+			Fires when the pointer is moved out of a 3D object.
+		</p>
+
+		<h2>Properties</h2>
+
+		<h3>[property:Boolean enabled]</h3>
+		<p>
+			Whether or not the controls are enabled.
+		</p>
+
+		<h2>Methods</h2>
+
+		<p>See the base [page:EventDispatcher] class for common methods.</p>
+
+		<h3>[method:null activate] ()</h3>
+		<p>
+			Adds the event listeners of the controls.
+		</p>
+
+		<h3>[method:null deactivate] ()</h3>
+		<p>
+			Removes the event listeners of the controls.
+		</p>
+
+		<h3>[method:null dispose] ()</h3>
+		<p>
+			Should be called if the controls is no longer required.
+		</p>
+
+		<h2>Source</h2>
+
+		<p>
+			[link:https://github.com/mrdoob/three.js/blob/master/examples/js/controls/DragControls.js examples/js/controls/DragControls.js]
+		</p>
+	</body>
+</html>

+ 166 - 0
docs/examples/en/controls/FirstPersonControls.html

@@ -0,0 +1,166 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<meta charset="utf-8" />
+		<base href="../../../" />
+		<script src="list.js"></script>
+		<script src="page.js"></script>
+		<link type="text/css" rel="stylesheet" href="page.css" />
+	</head>
+	<body>
+
+		<h1>[name]</h1>
+
+		<p class="desc">
+			This class is an alternative implementation of [page:FlyControls].
+		</p>
+
+		<h2>Example</h2>
+
+		<p>[example:webgl_geometry_terrain webgl / geometry / terrain ]</p>
+
+		<h2>Constructor</h2>
+
+		<h3>[name]( [param:Camera object], [param:HTMLDOMElement domElement] )</h3>
+		<p>
+			<p>
+				[page:Camera object]: The camera to be controlled.
+			</p>
+			<p>
+				[page:HTMLDOMElement domElement]: (optional) The HTML element used for event listeners. By default this is the whole document,
+				however if you only want the controls to work over a specific element (e.g. the canvas) you can specify that here.
+			</p>
+			<p>
+				Creates a new instance of [name].
+			</p>
+		</p>
+
+		<h2>Properties</h2>
+
+		<h3>[property:Boolean activeLook]</h3>
+		<p>
+			Whether or not it's possible to look around. Default is *true*.
+		</p>
+
+		<h3>[property:Boolean autoForward]</h3>
+		<p>
+			Whether or not the camera is automatically moved forward. Default is *false*.
+		</p>
+
+		<h3>[property:Boolean constrainVertical]</h3>
+		<p>
+			Whether or not looking around is vertically constrained by [[page:.verticalMin], [page:.verticalMax]]. Default is *false*.
+		</p>
+
+		<h3>[property:HTMLDOMElement domElement]</h3>
+		<p>
+			The HTMLDOMElement used to listen for mouse / touch events. This must be passed in the constructor; changing it here will
+			not set up new event listeners. Default is the whole document.
+		</p>
+
+		<h3>[property:Boolean enabled]</h3>
+		<p>
+			Whether or not the controls are enabled. Default is *true*.
+		</p>
+
+		<h3>[property:Number heightCoef]</h3>
+		<p>
+			Determines how much faster the camera moves when it's y-component is near [page:.heightMax]. Default is *1*.
+		</p>
+
+		<h3>[property:Number heightMax]</h3>
+		<p>
+			Upper camera height limit used for movement speed adjusment. Default is *1*.
+		</p>
+
+		<h3>[property:Number heightMin]</h3>
+		<p>
+			Lower camera height limit used for movement speed adjusment. Default is *0*.
+		</p>
+
+		<h3>[property:Boolean heightSpeed]</h3>
+		<p>
+			Whether or not the camera's height influences the forward movement speed. Default is *false*.
+			Use the properties [page:.heightCoef], [page:.heightMin] and [page:.heightMax] for configuration.
+		</p>
+
+		<h3>[property:Boolean lookVertical]</h3>
+		<p>
+			Whether or not it's possible to vertically look around. Default is *true*.
+		</p>
+
+		<h3>[property:Number lookSpeed]</h3>
+		<p>
+			The look around speed. Default is *0.005*.
+		</p>
+
+		<h3>[property:Boolean mouseDragOn]</h3>
+		<p>
+			Whether or not the mouse is pressed down. Read-only property.
+		</p>
+
+		<h3>[property:Number movementSpeed]</h3>
+		<p>
+			The movement speed. Default is *1*.
+		</p>
+
+		<h3>[property:Camera object]</h3>
+		<p>
+			The camera to be controlled.
+		</p>
+
+		<h3>[property:Number verticalMax]</h3>
+		<p>
+			How far you can vertically look around, upper limit. Range is 0 to Math.PI radians. Default is *Math.PI*.
+		</p>
+
+		<h3>[property:Number verticalMin]</h3>
+		<p>
+			How far you can vertically look around, lower limit. Range is 0 to Math.PI radians. Default is *0*.
+		</p>
+
+		<h2>Methods</h2>
+
+		<h3>[method:null dispose] ()</h3>
+		<p>
+			Should be called if the controls is no longer required.
+		</p>
+
+		<h3>[method:null handleResize] ()</h3>
+		<p>
+			Should be called if the application window is resized.
+		</p>
+
+		<h3>[method:FirstPersonControls lookAt]( [param:Vector3 vector] )<br />
+		[method:FirstPersonControls lookAt]( [param:Float x], [param:Float y], [param:Float z] )</h3>
+		<p>
+			<p>
+				<p>
+					vector - A vector representing the target position.
+				</p>
+				<p>
+					Optionally, the x, y, z components of the world space position.
+				</p>
+			</p>
+			<p>
+				Ensures the controls orient the camera towards the defined target position.
+			</p>
+		</p>
+
+		<h3>[method:null update] ( [param:Number delta] )</h3>
+		<p>
+			<p>
+				[page:Number delta]: Time delta value.
+			</p>
+			<p>
+				Updates the controls. Usually called in the animation loop.
+			</p>
+		</p>
+
+		<h2>Source</h2>
+
+		<p>
+			[link:https://github.com/mrdoob/three.js/blob/master/examples/js/controls/FirstPersonControls.js examples/js/controls/FirstPersonControls.js]
+		</p>
+	</body>
+</html>

+ 95 - 0
docs/examples/en/controls/FlyControls.html

@@ -0,0 +1,95 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<meta charset="utf-8" />
+		<base href="../../../" />
+		<script src="list.js"></script>
+		<script src="page.js"></script>
+		<link type="text/css" rel="stylesheet" href="page.css" />
+	</head>
+	<body>
+
+		<h1>[name]</h1>
+
+		<p class="desc">
+			[name] enables a navigation similar to fly modes in DCC tools like Blender. You can arbitrarily transform the camera in
+			3D space without any limitations (e.g. focus on a specific target).
+		</p>
+
+		<h2>Example</h2>
+
+		<p>[example:misc_controls_fly misc / controls / fly ]</p>
+
+		<h2>Constructor</h2>
+
+		<h3>[name]( [param:Camera object], [param:HTMLDOMElement domElement] )</h3>
+		<p>
+			<p>
+				[page:Camera object]: The camera to be controlled.
+			</p>
+			<p>
+				[page:HTMLDOMElement domElement]: (optional) The HTML element used for event listeners. By default this is the whole document,
+				however if you only want the controls to work over a specific element (e.g. the canvas) you can specify that here.
+			</p>
+			<p>
+				Creates a new instance of [name].
+			</p>
+		</p>
+
+		<h2>Properties</h2>
+
+		<h3>[property:Boolean autoForward]</h3>
+		<p>
+			If set to *true*, the camera automatically moves forward (and does not stop) when initially translated. Default is *false*.
+		</p>
+
+		<h3>[property:HTMLDOMElement domElement]</h3>
+		<p>
+			The HTMLDOMElement used to listen for mouse / touch events. This must be passed in the constructor; changing it here will
+			not set up new event listeners. Default is the whole document.
+		</p>
+
+		<h3>[property:Boolean dragToLook]</h3>
+		<p>
+			If set to *true*, you can only look around by performing a drag interaction. Default is *false*.
+		</p>
+
+		<h3>[property:Number movementSpeed]</h3>
+		<p>
+			The movement speed. Default is *1*.
+		</p>
+
+		<h3>[property:Camera object]</h3>
+		<p>
+			The camera to be controlled.
+		</p>
+
+		<h3>[property:Number rollSpeed]</h3>
+		<p>
+			The rotation speed. Default is *0.005*.
+		</p>
+
+		<h2>Methods</h2>
+
+		<h3>[method:null dispose] ()</h3>
+		<p>
+			Should be called if the controls is no longer required.
+		</p>
+
+		<h3>[method:null update] ( [param:Number delta] )</h3>
+		<p>
+			<p>
+				[page:Number delta]: Time delta value.
+			</p>
+			<p>
+				Updates the controls. Usually called in the animation loop.
+			</p>
+		</p>
+
+		<h2>Source</h2>
+
+		<p>
+			[link:https://github.com/mrdoob/three.js/blob/master/examples/js/controls/FlyControls.js examples/js/controls/FlyControls.js]
+		</p>
+	</body>
+</html>

+ 149 - 0
docs/examples/en/controls/PointerLockControls.html

@@ -0,0 +1,149 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<meta charset="utf-8" />
+		<base href="../../../" />
+		<script src="list.js"></script>
+		<script src="page.js"></script>
+		<link type="text/css" rel="stylesheet" href="page.css" />
+	</head>
+	<body>
+		[page:EventDispatcher] &rarr;
+
+		<h1>[name]</h1>
+
+		<p class="desc">
+		The implementation of this class is based on the [link:https://developer.mozilla.org/en-US/docs/Web/API/Pointer_Lock_API Pointer Lock API].
+		[name] is a perfect choice for first person 3D games.
+		</p>
+
+		<h2>Example</h2>
+
+		<p>[example:misc_controls_pointerlock misc / controls / pointerlock ]</p>
+
+		<code>
+var controls = new PointerLockControls( camera );
+
+// add event listener to show/hide a UI (e.g. the game's menu)
+
+controls.addEventListener( 'lock', function () {
+
+	menu.style.display = 'none';
+
+} );
+
+controls.addEventListener( 'unlock', function () {
+
+	menu.style.display = 'block';
+
+} );
+
+		</code>
+
+		<h2>Constructor</h2>
+
+		<h3>[name]( [param:Camera camera], [param:HTMLDOMElement domElement] )</h3>
+		<p>
+			<p>
+			[page:Camera camera]: The camera of the rendered scene.
+			</p>
+			<p>
+			[page:HTMLDOMElement domElement]: (optional) The HTML element used for event listeners. By default this is the document's body.
+			</p>
+			<p>
+				Creates a new instance of [name].
+			</p>
+		</p>
+
+		<h2>Events</h2>
+
+		<h3>change</h3>
+		<p>
+			Fires when the user moves the mouse.
+		</p>
+
+		<h3>lock</h3>
+		<p>
+			Fires when the pointer lock status is "locked" (in other words: the mouse is captured).
+		</p>
+
+		<h3>unlock</h3>
+		<p>
+			Fires when the pointer lock status is "unlocked" (in other words: the mouse is not captured anymore).
+		</p>
+
+		<h2>Properties</h2>
+
+		<h3>[property:HTMLDOMElement domElement]</h3>
+		<p>
+			The HTMLDOMElement used to listen for mouse / touch events. This must be passed in the constructor; changing it here will
+			not set up new event listeners. Default is the document's body.
+		</p>
+
+
+		<h3>[property:Boolean isLocked]</h3>
+		<p>
+			Whether or not the controls are locked.
+		</p>
+
+		<h2>Methods</h2>
+
+		<p>See the base [page:EventDispatcher] class for common methods.</p>
+
+		<h3>[method:null connect] ()</h3>
+		<p>
+			Adds the event listeners of the controls.
+		</p>
+
+		<h3>[method:null disconnect] ()</h3>
+		<p>
+			Removes the event listeners of the controls.
+		</p>
+
+		<h3>[method:Vector3 getDirection] ( [param:Vector3 target] )</h3>
+		<p>
+			<p>
+				[page:Vector3 target]: The target vector.
+			</p>
+			<p>
+				Returns the look direction of the camera.
+			</p>
+		</p>
+
+		<h3>[method:null lock] ()</h3>
+		<p>
+			Activates the pointer lock.
+		</p>
+
+		<h3>[method:null moveForward] ( [param:Number distance] )</h3>
+		<p>
+			<p>
+				[page:Number distance]: The signed distance.
+			</p>
+			<p>
+				Moves the camera forward parallel to the xz-plane. Assumes camera.up is y-up.
+			</p>
+		</p>
+
+		<h3>[method:null moveRight] ( [param:Number distance] )</h3>
+		<p>
+			<p>
+				[page:Number distance]: The signed distance.
+			</p>
+			<p>
+				Moves the camera sidewards parallel to the xz-plane.
+			</p>
+		</p>
+
+		<h3>[method:null unlock] ()</h3>
+		<p>
+			Exits the pointer lock.
+		</p>
+
+		<h2>Source</h2>
+
+		<p>
+			[link:https://github.com/mrdoob/three.js/blob/master/examples/js/controls/PointerLockControls.js examples/js/controls/PointerLockControls.js]
+		</p>
+	</body>
+</html>

+ 208 - 0
docs/examples/en/controls/TrackballControls.html

@@ -0,0 +1,208 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<meta charset="utf-8" />
+		<base href="../../../" />
+		<script src="list.js"></script>
+		<script src="page.js"></script>
+		<link type="text/css" rel="stylesheet" href="page.css" />
+	</head>
+	<body>
+		[page:EventDispatcher] &rarr;
+
+		<h1>[name]</h1>
+
+		<p class="desc">
+			<p>
+				[name] is similar to [page:OrbitControls]. However, it does not maintain a constant camera [page:Object3D.up up] vector.
+				That means if the camera orbits over the “north” and “south” poles, it does not flip to stay "right side up".
+			</p>
+		</p>
+
+		<h2>Example</h2>
+
+		<p>[example:misc_controls_trackball misc / controls / trackball ]</p>
+
+		<h2>Constructor</h2>
+
+		<h3>[name]( [param:Camera camera], [param:HTMLDOMElement domElement] )</h3>
+		<p>
+			<p>
+				[page:Camera camera]: The camera of the rendered scene.
+			</p>
+			<p>
+				[page:HTMLDOMElement domElement]: (optional) The HTML element used for event listeners. By default this is the whole document,
+				however if you only want the controls to work over a specific element (e.g. the canvas) you can specify that here.
+			</p>
+			<p>
+				Creates a new instance of [name].
+			</p>
+		</p>
+
+		<h2>Events</h2>
+
+		<h3>change</h3>
+		<p>
+			Fires when the camera has been transformed by the controls.
+		</p>
+
+		<h3>start</h3>
+		<p>
+			Fires when an interaction (e.g. touch) was initiated.
+		</p>
+
+		<h3>end</h3>
+		<p>
+			Fires when an interaction has finished.
+		</p>
+
+		<h2>Properties</h2>
+
+		<h3>[property:HTMLDOMElement domElement]</h3>
+		<p>
+			The HTMLDOMElement used to listen for mouse / touch events. This must be passed in the constructor; changing it here will
+			not set up new event listeners. Default is the whole document.
+		</p>
+
+		<h3>[property:Number dynamicDampingFactor]</h3>
+		<p>
+			Defines the intensity of damping. Only considered if [page:.staticMoving staticMoving] is set to *false*. Default is *0.2*.
+		</p>
+
+		<h3>[property:Boolean enabled]</h3>
+		<p>
+			Whether or not the controls are enabled.
+		</p>
+
+		<h3>[property:Array keys]</h3>
+		<p>
+			This array holds keycodes for controlling interactions.
+			<ul>
+				<li>When the first defined key is pressed, all mouse interactions (left, middle, right) performs orbiting.</li>
+				<li>When the second defined key is pressed, all mouse interactions (left, middle, right) performs zooming.</li>
+				<li>When the third defined key is pressed, all mouse interactions (left, middle, right) performs panning.</li>
+			</ul>
+			Default is *65, 83, 68* which represents A, S, D.
+		</p>
+
+		<h3>[property:Number maxDistance]</h3>
+		<p>
+			 How far you can zoom in. Default is *Infinity*.
+		</p>
+
+		<h3>[property:Number minDistance]</h3>
+		<p>
+			 How far you can zoom in. Default is *0*.
+		</p>
+
+		<h3>
+			[property:Object mouseButtons]</h3>
+		<p>
+			This object contains references to the mouse actions used by the controls.
+			<ul>
+				<li>.LEFT is assinged with *THREE.MOUSE.ROTATE*</li>
+				<li>.MIDDLE is assinged with *THREE.MOUSE.ZOOM*</li>
+				<li>.RIGHT is assinged with *THREE.MOUSE.PAN*</li>
+			</ul>
+		</p>
+
+		<h3>[property:Boolean noPan]</h3>
+		<p>
+			Whether or not panning is disabled. Default is *false*.
+		</p>
+
+		<h3>[property:Boolean noRotate]</h3>
+		<p>
+			Whether or not rotation is disabled. Default is *false*.
+		</p>
+
+		<h3>[property:Boolean noZoom]</h3>
+		<p>
+			Whether or not zooming is disabled. Default is *false*.
+		</p>
+
+		<h3>[property:Camera object]</h3>
+		<p>
+			The camera being controlled.
+		</p>
+
+		<h3>[property:Number panSpeed]</h3>
+		<p>
+			The zoom speed. Default is *0.3*.
+		</p>
+
+		<h3>[property:Number rotateSpeed]</h3>
+		<p>
+			The rotation speed. Default is *1.0*.
+		</p>
+
+		<h3>[property:Object screen]</h3>
+		<p>
+			Represents the properties of the screen. Automatically set when [page:.handleResize handleResize]() is called.
+			<ul>
+				<li>left: Represents the offset in pixels to the screen's left boundary.</li>
+				<li>top: Represents the offset in pixels to the screen's top boundary.</li>
+				<li>width: Represents the screen width in pixels.</li>
+				<li>height: Represents the screen height in pixels.</li>
+			</ul>
+		</p>
+
+		<h3>[property:Boolean staticMoving]</h3>
+		<p>
+			Whether or not damping is disabled. Default is *false*.
+		</p>
+
+		<h3>[property:Number zoomSpeed]</h3>
+		<p>
+			The zoom speed. Default is *1.2*.
+		</p>
+
+		<h2>Methods</h2>
+
+		<h3>[method:null checkDistances] ()</h3>
+		<p>
+			Ensures the controls stay in the range [minDistance, maxDistance]. Called by [page:.update update]().
+		</p>
+
+		<h3>[method:null dispose] ()</h3>
+		<p>
+			Should be called if the controls is no longer required.
+		</p>
+
+		<h3>[method:null handleResize] ()</h3>
+		<p>
+			Should be called if the application window is resized.
+		</p>
+
+		<h3>[method:null panCamera] ()</h3>
+		<p>
+			Performs panning if necessary. Called by [page:.update update]().
+		</p>
+
+		<h3>[method:null reset] ()</h3>
+		<p>
+			Resets the controls to its initial state.
+		</p>
+
+		<h3>[method:null rotateCamera] ()</h3>
+		<p>
+			Rotates the camera if necessary. Called by [page:.update update]().
+		</p>
+
+		<h3>[method:null update] ()</h3>
+		<p>
+			Updates the controls. Usually called in the animation loop.
+		</p>
+
+		<h3>[method:null zoomCamera] ()</h3>
+		<p>
+			Performs zooming if necessary. Called by [page:.update update]().
+		</p>
+
+		<h2>Source</h2>
+
+		<p>
+			[link:https://github.com/mrdoob/three.js/blob/master/examples/js/controls/TrackballControls.js examples/js/controls/TrackballControls.js]
+		</p>
+	</body>
+</html>

+ 225 - 0
docs/examples/en/controls/TransformControls.html

@@ -0,0 +1,225 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<meta charset="utf-8" />
+		<base href="../../../" />
+		<script src="list.js"></script>
+		<script src="page.js"></script>
+		<link type="text/css" rel="stylesheet" href="page.css" />
+	</head>
+	<body>
+		[page:Object3D] &rarr;
+
+		<h1>[name]</h1>
+
+		<p class="desc">
+			This class can be used to transform objects in 3D space by adapting a similar interaction model of DCC tools like Blender.
+			Unlike other controls, it is not intended to transform the scene's camera.
+		</p>
+
+		<h2>Example</h2>
+
+		<p>[example:misc_controls_transform misc / controls / transform ]</p>
+
+		<h2>Constructor</h2>
+
+		<h3>[name]( [param:Camera camera], [param:HTMLDOMElement domElement] )</h3>
+		<p>
+			<p>
+				[page:Camera camera]: The camera of the rendered scene.
+			</p>
+			<p>
+				[page:HTMLDOMElement domElement]: (optional) The HTML element used for event listeners. By default this is the whole document,
+				however if you only want the controls to work over a specific element (e.g. the canvas) you can specify that here.
+			</p>
+			<p>
+				Creates a new instance of [name].
+			</p>
+		</p>
+
+		<h2>Events</h2>
+
+		<h3>change</h3>
+		<p>
+			Fires if any type of change (object or property change) is performed. Property changes
+			are separate events you can add event listeners to. The event type is "propertyname-changed".
+		</p>
+
+		<h3>mouseDown</h3>
+		<p>
+			Fires if a pointer (mouse/touch) becomes active.
+		</p>
+
+		<h3>mouseUp</h3>
+		<p>
+			Fires if a pointer (mouse/touch) is no longer active.
+		</p>
+
+		<h3>objectChange</h3>
+		<p>
+			Fires if the controlled 3D object is changed.
+		</p>
+
+		<h2>Properties</h2>
+
+		<p>See the base [page:Object3D] class for common properties.</p>
+
+		<h3>[property:String axis]</h3>
+		<p>
+			The current transformation axis.
+		</p>
+
+		<h3>[property:Camera camera]</h3>
+		<p>
+			The camera of the rendered scene.
+		</p>
+
+		<h3>[property:HTMLDOMElement domElement]</h3>
+		<p>
+			The HTMLDOMElement used to listen for mouse / touch events. This must be passed in the constructor; changing it here will
+			not set up new event listeners. Default is the whole document.
+		</p>
+
+		<h3>[property:Boolean dragging]</h3>
+		<p>
+			Whether or not dragging is currently performed. Read-only property.
+		</p>
+
+		<h3>[property:Boolean enabled]</h3>
+		<p>
+			Whether or not the controls are enabled.
+		</p>
+
+		<h3>[property:String mode]</h3>
+		<p>
+			The current transformation mode. Possible values are "translate", "rotate" and "scale". Default is *translate*.
+		</p>
+
+		<h3>[property:Object3D object]</h3>
+		<p>
+			The 3D object being controlled.
+		</p>
+
+		<h3>[property:Number rotationSnap]</h3>
+		<p>
+			By default, 3D objects are continously rotated. If you set this property to a numeric value (radians), you can define in which
+			steps the 3D object should be rotated. Deault is *null*.
+		</p>
+
+		<h3>[property:Boolean showX]</h3>
+		<p>
+			Whether or not the x-axis helper should be visible. Default is *true*.
+		</p>
+
+		<h3>[property:Boolean showY]</h3>
+		<p>
+			Whether or not the y-axis helper should be visible. Default is *true*.
+		</p>
+
+		<h3>[property:Boolean showZ]</h3>
+		<p>
+			Whether or not the z-axis helper should be visible. Default is *true*.
+		</p>
+
+		<h3>[property:Number size]</h3>
+		<p>
+			The size of the helper UI (axes/planes). Default is *1*.
+		</p>
+
+		<h3>[property:String space]</h3>
+		<p>
+			Defines in which coordinate space transformations should be performed. Possible values are "world" and "local". Default is *world*.
+		</p>
+
+		<h3>[property:Number translationSnap]</h3>
+		<p>
+			By default, 3D objects are continously translated. If you set this property to a numeric value (world units), you can define in which
+			steps the 3D object should be translated. Deault is *null*.
+		</p>
+
+		<h2>Methods</h2>
+
+		<p>See the base [page:Object3D] class for common methods.</p>
+
+		<h3>[method:TransformControls attach] ( [param:Object3D object] )</h3>
+		<p>
+			<p>
+				[page:Object3D object]: The 3D object that should be transformed.
+			</p>
+			<p>
+				Sets the 3D object that should be transformed and ensures the controls UI is visible.
+			</p>
+		</p>
+
+		<h3>[method:TransformControls detach] ()</h3>
+		<p>
+			Removes the current 3D object from the controls and makes the helper UI is invisible.
+		</p>
+
+		<h3>[method:null dispose] ()</h3>
+		<p>
+			Should be called if the controls is no longer required.
+		</p>
+
+		<h3>[method:String getMode] ()</h3>
+		<p>
+			Returns the transformation mode.
+		</p>
+
+		<h3>[method:null setMode] ( [param:String mode] )</h3>
+		<p>
+			<p>
+				[page:String mode]: The transformation mode.
+			</p>
+			<p>
+				Sets the transformation mode.
+			</p>
+		</p>
+
+		<h3>[method:null setRotationSnap] ( [param:Number rotationSnap] )</h3>
+		<p>
+			<p>
+				[page:Number rotationSnap]: The rotation snap.
+			</p>
+			<p>
+				Sets the rotation snap.
+			</p>
+		</p>
+
+		<h3>[method:null setSize] ( [param:Number size] )</h3>
+		<p>
+			<p>
+				[page:Number size]: The size of the helper UI.
+			</p>
+			<p>
+				Sets the size of the helper UI.
+			</p>
+		</p>
+
+		<h3>[method:null setSpace] ( [param:String space] )</h3>
+		<p>
+			<p>
+				[page:String space]: The coordinate space in which transformations are applied.
+			</p>
+			<p>
+				Sets the coordinate space in which transformations are applied.
+			</p>
+		</p>
+
+		<h3>[method:null setTranslationSnap] ( [param:Number translationSnap] )</h3>
+		<p>
+			<p>
+				[page:Number translationSnap]: The translation snap.
+			</p>
+			<p>
+				Sets the translation snap.
+			</p>
+		</p>
+
+		<h2>Source</h2>
+
+		<p>
+			[link:https://github.com/mrdoob/three.js/blob/master/examples/js/controls/TransformControls.js examples/js/controls/TransformControls.js]
+		</p>
+	</body>
+</html>

+ 0 - 96
docs/examples/en/loaders/BabylonLoader.html

@@ -1,96 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-	<head>
-		<meta charset="utf-8" />
-		<base href="../../../" />
-		<script src="list.js"></script>
-		<script src="page.js"></script>
-		<link type="text/css" rel="stylesheet" href="page.css" />
-	</head>
-	<body>
-		[page:Loader] &rarr;
-
-		<h1>[name]</h1>
-
-		<p class="desc">A loader for loading a <em>.babylon</em> resource. <br />
-		The <a href="https://doc.babylonjs.com/generals/file_format_map_(.babylon)"> .babylon </a> file format used by
-		<a href="https://www.babylonjs.com/">Babylon.js</a>.
-		</p>
-
-		<h2>Example</h2>
-
-		<code>
-		// instantiate a loader
-		var loader = new THREE.BabylonLoader();
-
-		// load a Babylon resource
-		loader.load(
-			// resource URL
-			'models/babylon/skull.babylon',
-			// called when resource is loaded
-			function ( object ) {
-
-				scene.add( object );
-
-			},
-			// called when loading is in progress
-			function ( xhr ) {
-
-				console.log( ( xhr.loaded / xhr.total * 100 ) + '% loaded' );
-
-			},
-			// called when loading has errors
-			function ( xhr ) {
-
-				console.log( 'An error happened' );
-
-			}
-		);
-		</code>
-
-		[example:webgl_loader_babylon]
-
-		<h2>Constructor</h2>
-
-		<h3>[name]( [param:LoadingManager manager] )</h3>
-		<p>
-		[page:LoadingManager manager] — The [page:LoadingManager loadingManager] for the loader to use. Default is [page:LoadingManager THREE.DefaultLoadingManager].
-		</p>
-		<p>
-		Creates a new [name].
-		</p>
-
-		<h2>Properties</h2>
-		<p>See the base [page:Loader] class for common properties.</p>
-
-		<h2>Methods</h2>
-		<p>See the base [page:Loader] class for common methods.</p>
-
-		<h3>[method:null load]( [param:String url], [param:Function onLoad], [param:Function onProgress], [param:Function onError] )</h3>
-		<p>
-		[page:String url] — A string containing the path/URL of the <em>.babylon</em> file.<br />
-		[page:function onLoad] — (optional) A function to be called after loading is successfully completed. The function receives the loaded [page:Object3D] as an argument.<br />
-		[page:function onProgress] — (optional) A function to be called while the loading is in progress. The argument will be the XMLHttpRequest instance, which contains [page:Integer total] and [page:Integer loaded] bytes.<br />
-		[page:function onError] — (optional) A function to be called if an error occurs during loading. The function receives the error as an argument.<br />
-		</p>
-		<p>
-		Begin loading from url and call onLoad with the parsed response content.
-		</p>
-
-		<h3>[method:Object3D parse]( [param:Object json] )</h3>
-		<p>
-		[page:Object json] — The <em>JSON</em> structure to parse.
-		</p>
-		<p>
-		Parse a <em>JSON</em> structure and return an [page:Object3D object] or a [page:Scene scene].<br />
-		Found objects are converted to [page:Mesh] with a [page:BufferGeometry] and a default [page:MeshPhongMaterial].<br />
-		Lights are parsed accordingly.
-		</p>
-
-		<h2>Source</h2>
-
-		<p>
-			[link:https://github.com/mrdoob/three.js/blob/master/examples/js/loaders/BabylonLoader.js examples/js/loaders/BabylonLoader.js]
-		</p>
-	</body>
-</html>

+ 89 - 0
docs/examples/zh/controls/DeviceOrientationControls.html

@@ -0,0 +1,89 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<meta charset="utf-8" />
+		<base href="../../../" />
+		<script src="list.js"></script>
+		<script src="page.js"></script>
+		<link type="text/css" rel="stylesheet" href="page.css" />
+	</head>
+	<body>
+
+		<h1>[name]</h1>
+
+		<p class="desc">
+			Can be used to orient the camera based on the mobile device's orientation.
+		</p>
+
+		<h2>Example</h2>
+
+		<p>[example:misc_controls_deviceorientation misc / controls / deviceorientation ]</p>
+
+		<h2>Constructor</h2>
+
+		<h3>[name]( [param:Camera object] )</h3>
+		<p>
+			<p>
+				[page:Camera object]: The camera to be controlled.
+			</p>
+			<p>
+				Creates a new instance of [name].
+			</p>
+		</p>
+
+		<h2>Properties</h2>
+
+		<h3>[property:Number alphaOffset]</h3>
+		<p>
+			The alpha offset in radians. Default is *0*.
+		</p>
+
+		<h3>[property:Object deviceOrientation]</h3>
+		<p>
+			The current *deviceorientation* event object.
+		</p>
+
+		<h3>[property:Boolean enabled]</h3>
+		<p>
+			Whether or not the controls are enabled.
+		</p>
+
+		<h3>[property:Camera object]</h3>
+		<p>
+			The camera to be controlled.
+		</p>
+
+		<h3>[property:Number screenOrientation]</h3>
+		<p>
+			The orientation in degrees (in 90-degree increments) of the viewport relative to the device's natural orientation. Default is *0*.
+		</p>
+
+		<h2>Methods</h2>
+
+		<h3>[method:null connect] ()</h3>
+		<p>
+			Adds the event listeners of the controls and enables it.
+		</p>
+
+		<h3>[method:null disconnect] ()</h3>
+		<p>
+			Removes the event listeners of the controls and disables it.
+		</p>
+
+		<h3>[method:null dispose] ()</h3>
+		<p>
+			Should be called if the controls is no longer required.
+		</p>
+
+		<h3>[method:null update] ()</h3>
+		<p>
+			Updates the controls. Usually called in the animation loop.
+		</p>
+
+		<h2>Source</h2>
+
+		<p>
+			[link:https://github.com/mrdoob/three.js/blob/master/examples/js/controls/DeviceOrientationControls.js examples/js/controls/DeviceOrientationControls.js]
+		</p>
+	</body>
+</html>

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

@@ -0,0 +1,119 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<meta charset="utf-8" />
+		<base href="../../../" />
+		<script src="list.js"></script>
+		<script src="page.js"></script>
+		<link type="text/css" rel="stylesheet" href="page.css" />
+	</head>
+	<body>
+		[page:EventDispatcher] &rarr;
+
+		<h1>[name]</h1>
+
+		<p class="desc">
+		This class can be used to provide a drag'n'drop interaction.
+		</p>
+
+		<h2>Example</h2>
+
+		<p>[example:misc_controls_drag misc / controls / drag ]</p>
+
+		<code>
+var controls = new THREE.DragControls( objects, camera, renderer.domElement );
+
+// add event listener to highlight dragged objects
+
+controls.addEventListener( 'dragstart', function ( event ) {
+
+	event.object.material.emissive.set( 0xaaaaaa );
+
+} );
+
+controls.addEventListener( 'dragend', function ( event ) {
+
+	event.object.material.emissive.set( 0x000000 );
+
+} );
+
+		</code>
+
+		<h2>Constructor</h2>
+
+		<h3>[name]( [param:Array objects], [param:Camera camera], [param:HTMLDOMElement domElement] )</h3>
+		<p>
+			<p>
+				[page:Array objects]: An array of draggable 3D objects.
+			</p>
+			<p>
+			[page:Camera camera]: The camera of the rendered scene.
+			</p>
+			<p>
+			[page:HTMLDOMElement domElement]: The HTML element used for event listeners.
+			</p>
+			<p>
+				Creates a new instance of [name].
+			</p>
+		</p>
+
+		<h2>Events</h2>
+
+		<h3>dragstart</h3>
+		<p>
+			Fires when the user starts to drag a 3D object.
+		</p>
+
+		<h3>drag</h3>
+		<p>
+			Fires when the user drags a 3D object.
+		</p>
+
+		<h3>dragend</h3>
+		<p>
+			Fires when the user has finished dragging a 3D object.
+		</p>
+
+		<h3>hoveron</h3>
+		<p>
+			Fires when the pointer is moved onto a 3D object, or onto one of its children.
+		</p>
+
+		<h3>hoveroff</h3>
+		<p>
+			Fires when the pointer is moved out of a 3D object.
+		</p>
+
+		<h2>Properties</h2>
+
+		<h3>[property:Boolean enabled]</h3>
+		<p>
+			Whether or not the controls are enabled.
+		</p>
+
+		<h2>Methods</h2>
+
+		<p>See the base [page:EventDispatcher] class for common methods.</p>
+
+		<h3>[method:null activate] ()</h3>
+		<p>
+			Adds the event listeners of the controls.
+		</p>
+
+		<h3>[method:null deactivate] ()</h3>
+		<p>
+			Removes the event listeners of the controls.
+		</p>
+
+		<h3>[method:null dispose] ()</h3>
+		<p>
+			Should be called if the controls is no longer required.
+		</p>
+
+		<h2>Source</h2>
+
+		<p>
+			[link:https://github.com/mrdoob/three.js/blob/master/examples/js/controls/DragControls.js examples/js/controls/DragControls.js]
+		</p>
+	</body>
+</html>

+ 166 - 0
docs/examples/zh/controls/FirstPersonControls.html

@@ -0,0 +1,166 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<meta charset="utf-8" />
+		<base href="../../../" />
+		<script src="list.js"></script>
+		<script src="page.js"></script>
+		<link type="text/css" rel="stylesheet" href="page.css" />
+	</head>
+	<body>
+
+		<h1>[name]</h1>
+
+		<p class="desc">
+			This class is an alternative implementation of [page:FlyControls].
+		</p>
+
+		<h2>Example</h2>
+
+		<p>[example:webgl_geometry_terrain webgl / geometry / terrain ]</p>
+
+		<h2>Constructor</h2>
+
+		<h3>[name]( [param:Camera object], [param:HTMLDOMElement domElement] )</h3>
+		<p>
+			<p>
+				[page:Camera object]: The camera to be controlled.
+			</p>
+			<p>
+				[page:HTMLDOMElement domElement]: (optional) The HTML element used for event listeners. By default this is the whole document,
+				however if you only want the controls to work over a specific element (e.g. the canvas) you can specify that here.
+			</p>
+			<p>
+				Creates a new instance of [name].
+			</p>
+		</p>
+
+		<h2>Properties</h2>
+
+		<h3>[property:Boolean activeLook]</h3>
+		<p>
+			Whether or not it's possible to look around. Default is *true*.
+		</p>
+
+		<h3>[property:Boolean autoForward]</h3>
+		<p>
+			Whether or not the camera is automatically moved forward. Default is *false*.
+		</p>
+
+		<h3>[property:Boolean constrainVertical]</h3>
+		<p>
+			Whether or not looking around is vertically constrained by [[page:.verticalMin], [page:.verticalMax]]. Default is *false*.
+		</p>
+
+		<h3>[property:HTMLDOMElement domElement]</h3>
+		<p>
+			The HTMLDOMElement used to listen for mouse / touch events. This must be passed in the constructor; changing it here will
+			not set up new event listeners. Default is the whole document.
+		</p>
+
+		<h3>[property:Boolean enabled]</h3>
+		<p>
+			Whether or not the controls are enabled. Default is *true*.
+		</p>
+
+		<h3>[property:Number heightCoef]</h3>
+		<p>
+			Determines how much faster the camera moves when it's y-component is near [page:.heightMax]. Default is *1*.
+		</p>
+
+		<h3>[property:Number heightMax]</h3>
+		<p>
+			Upper camera height limit used for movement speed adjusment. Default is *1*.
+		</p>
+
+		<h3>[property:Number heightMin]</h3>
+		<p>
+			Lower camera height limit used for movement speed adjusment. Default is *0*.
+		</p>
+
+		<h3>[property:Boolean heightSpeed]</h3>
+		<p>
+			Whether or not the camera's height influences the forward movement speed. Default is *false*.
+			Use the properties [page:.heightCoef], [page:.heightMin] and [page:.heightMax] for configuration.
+		</p>
+
+		<h3>[property:Boolean lookVertical]</h3>
+		<p>
+			Whether or not it's possible to vertically look around. Default is *true*.
+		</p>
+
+		<h3>[property:Number lookSpeed]</h3>
+		<p>
+			The look around speed. Default is *0.005*.
+		</p>
+
+		<h3>[property:Boolean mouseDragOn]</h3>
+		<p>
+			Whether or not the mouse is pressed down. Read-only property.
+		</p>
+
+		<h3>[property:Number movementSpeed]</h3>
+		<p>
+			The movement speed. Default is *1*.
+		</p>
+
+		<h3>[property:Camera object]</h3>
+		<p>
+			The camera to be controlled.
+		</p>
+
+		<h3>[property:Number verticalMax]</h3>
+		<p>
+			How far you can vertically look around, upper limit. Range is 0 to Math.PI radians. Default is *Math.PI*.
+		</p>
+
+		<h3>[property:Number verticalMin]</h3>
+		<p>
+			How far you can vertically look around, lower limit. Range is 0 to Math.PI radians. Default is *0*.
+		</p>
+
+		<h2>Methods</h2>
+
+		<h3>[method:null dispose] ()</h3>
+		<p>
+			Should be called if the controls is no longer required.
+		</p>
+
+		<h3>[method:null handleResize] ()</h3>
+		<p>
+			Should be called if the application window is resized.
+		</p>
+
+		<h3>[method:FirstPersonControls lookAt]( [param:Vector3 vector] )<br />
+		[method:FirstPersonControls lookAt]( [param:Float x], [param:Float y], [param:Float z] )</h3>
+		<p>
+			<p>
+				<p>
+					vector - A vector representing the target position.
+				</p>
+				<p>
+					Optionally, the x, y, z components of the world space position.
+				</p>
+			</p>
+			<p>
+				Ensures the controls orient the camera towards the defined target position.
+			</p>
+		</p>
+
+		<h3>[method:null update] ( [param:Number delta] )</h3>
+		<p>
+			<p>
+				[page:Number delta]: Time delta value.
+			</p>
+			<p>
+				Updates the controls. Usually called in the animation loop.
+			</p>
+		</p>
+
+		<h2>Source</h2>
+
+		<p>
+			[link:https://github.com/mrdoob/three.js/blob/master/examples/js/controls/FirstPersonControls.js examples/js/controls/FirstPersonControls.js]
+		</p>
+	</body>
+</html>

+ 95 - 0
docs/examples/zh/controls/FlyControls.html

@@ -0,0 +1,95 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<meta charset="utf-8" />
+		<base href="../../../" />
+		<script src="list.js"></script>
+		<script src="page.js"></script>
+		<link type="text/css" rel="stylesheet" href="page.css" />
+	</head>
+	<body>
+
+		<h1>[name]</h1>
+
+		<p class="desc">
+			[name] enables a navigation similar to fly modes in DCC tools like Blender. You can arbitrarily transform the camera in
+			3D space without any limitations (e.g. focus on a specific target).
+		</p>
+
+		<h2>Example</h2>
+
+		<p>[example:misc_controls_fly misc / controls / fly ]</p>
+
+		<h2>Constructor</h2>
+
+		<h3>[name]( [param:Camera object], [param:HTMLDOMElement domElement] )</h3>
+		<p>
+			<p>
+				[page:Camera object]: The camera to be controlled.
+			</p>
+			<p>
+				[page:HTMLDOMElement domElement]: (optional) The HTML element used for event listeners. By default this is the whole document,
+				however if you only want the controls to work over a specific element (e.g. the canvas) you can specify that here.
+			</p>
+			<p>
+				Creates a new instance of [name].
+			</p>
+		</p>
+
+		<h2>Properties</h2>
+
+		<h3>[property:Boolean autoForward]</h3>
+		<p>
+			If set to *true*, the camera automatically moves forward (and does not stop) when initially translated. Default is *false*.
+		</p>
+
+		<h3>[property:HTMLDOMElement domElement]</h3>
+		<p>
+			The HTMLDOMElement used to listen for mouse / touch events. This must be passed in the constructor; changing it here will
+			not set up new event listeners. Default is the whole document.
+		</p>
+
+		<h3>[property:Boolean dragToLook]</h3>
+		<p>
+			If set to *true*, you can only look around by performing a drag interaction. Default is *false*.
+		</p>
+
+		<h3>[property:Number movementSpeed]</h3>
+		<p>
+			The movement speed. Default is *1*.
+		</p>
+
+		<h3>[property:Camera object]</h3>
+		<p>
+			The camera to be controlled.
+		</p>
+
+		<h3>[property:Number rollSpeed]</h3>
+		<p>
+			The rotation speed. Default is *0.005*.
+		</p>
+
+		<h2>Methods</h2>
+
+		<h3>[method:null dispose] ()</h3>
+		<p>
+			Should be called if the controls is no longer required.
+		</p>
+
+		<h3>[method:null update] ( [param:Number delta] )</h3>
+		<p>
+			<p>
+				[page:Number delta]: Time delta value.
+			</p>
+			<p>
+				Updates the controls. Usually called in the animation loop.
+			</p>
+		</p>
+
+		<h2>Source</h2>
+
+		<p>
+			[link:https://github.com/mrdoob/three.js/blob/master/examples/js/controls/FlyControls.js examples/js/controls/FlyControls.js]
+		</p>
+	</body>
+</html>

+ 149 - 0
docs/examples/zh/controls/PointerLockControls.html

@@ -0,0 +1,149 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<meta charset="utf-8" />
+		<base href="../../../" />
+		<script src="list.js"></script>
+		<script src="page.js"></script>
+		<link type="text/css" rel="stylesheet" href="page.css" />
+	</head>
+	<body>
+		[page:EventDispatcher] &rarr;
+
+		<h1>[name]</h1>
+
+		<p class="desc">
+		The implementation of this class is based on the [link:https://developer.mozilla.org/en-US/docs/Web/API/Pointer_Lock_API Pointer Lock API].
+		[name] is a perfect choice for first person 3D games.
+		</p>
+
+		<h2>Example</h2>
+
+		<p>[example:misc_controls_pointerlock misc / controls / pointerlock ]</p>
+
+		<code>
+var controls = new PointerLockControls( camera );
+
+// add event listener to show/hide a UI (e.g. the game's menu)
+
+controls.addEventListener( 'lock', function () {
+
+	menu.style.display = 'none';
+
+} );
+
+controls.addEventListener( 'unlock', function () {
+
+	menu.style.display = 'block';
+
+} );
+
+		</code>
+
+		<h2>Constructor</h2>
+
+		<h3>[name]( [param:Camera camera], [param:HTMLDOMElement domElement] )</h3>
+		<p>
+			<p>
+			[page:Camera camera]: The camera of the rendered scene.
+			</p>
+			<p>
+			[page:HTMLDOMElement domElement]: (optional) The HTML element used for event listeners. By default this is the document's body.
+			</p>
+			<p>
+				Creates a new instance of [name].
+			</p>
+		</p>
+
+		<h2>Events</h2>
+
+		<h3>change</h3>
+		<p>
+			Fires when the user moves the mouse.
+		</p>
+
+		<h3>lock</h3>
+		<p>
+			Fires when the pointer lock status is "locked" (in other words: the mouse is captured).
+		</p>
+
+		<h3>unlock</h3>
+		<p>
+			Fires when the pointer lock status is "unlocked" (in other words: the mouse is not captured anymore).
+		</p>
+
+		<h2>Properties</h2>
+
+		<h3>[property:HTMLDOMElement domElement]</h3>
+		<p>
+			The HTMLDOMElement used to listen for mouse / touch events. This must be passed in the constructor; changing it here will
+			not set up new event listeners. Default is the document's body.
+		</p>
+
+
+		<h3>[property:Boolean isLocked]</h3>
+		<p>
+			Whether or not the controls are locked.
+		</p>
+
+		<h2>Methods</h2>
+
+		<p>See the base [page:EventDispatcher] class for common methods.</p>
+
+		<h3>[method:null connect] ()</h3>
+		<p>
+			Adds the event listeners of the controls.
+		</p>
+
+		<h3>[method:null disconnect] ()</h3>
+		<p>
+			Removes the event listeners of the controls.
+		</p>
+
+		<h3>[method:Vector3 getDirection] ( [param:Vector3 target] )</h3>
+		<p>
+			<p>
+				[page:Vector3 target]: The target vector.
+			</p>
+			<p>
+				Returns the look direction of the camera.
+			</p>
+		</p>
+
+		<h3>[method:null lock] ()</h3>
+		<p>
+			Activates the pointer lock.
+		</p>
+
+		<h3>[method:null moveForward] ( [param:Number distance] )</h3>
+		<p>
+			<p>
+				[page:Number distance]: The signed distance.
+			</p>
+			<p>
+				Moves the camera forward parallel to the xz-plane. Assumes camera.up is y-up.
+			</p>
+		</p>
+
+		<h3>[method:null moveRight] ( [param:Number distance] )</h3>
+		<p>
+			<p>
+				[page:Number distance]: The signed distance.
+			</p>
+			<p>
+				Moves the camera sidewards parallel to the xz-plane.
+			</p>
+		</p>
+
+		<h3>[method:null unlock] ()</h3>
+		<p>
+			Exits the pointer lock.
+		</p>
+
+		<h2>Source</h2>
+
+		<p>
+			[link:https://github.com/mrdoob/three.js/blob/master/examples/js/controls/PointerLockControls.js examples/js/controls/PointerLockControls.js]
+		</p>
+	</body>
+</html>

+ 208 - 0
docs/examples/zh/controls/TrackballControls.html

@@ -0,0 +1,208 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<meta charset="utf-8" />
+		<base href="../../../" />
+		<script src="list.js"></script>
+		<script src="page.js"></script>
+		<link type="text/css" rel="stylesheet" href="page.css" />
+	</head>
+	<body>
+		[page:EventDispatcher] &rarr;
+
+		<h1>[name]</h1>
+
+		<p class="desc">
+			<p>
+				[name] is similar to [page:OrbitControls]. However, it does not maintain a constant camera [page:Object3D.up up] vector.
+				That means if the camera orbits over the “north” and “south” poles, it does not flip to stay "right side up".
+			</p>
+		</p>
+
+		<h2>Example</h2>
+
+		<p>[example:misc_controls_trackball misc / controls / trackball ]</p>
+
+		<h2>Constructor</h2>
+
+		<h3>[name]( [param:Camera camera], [param:HTMLDOMElement domElement] )</h3>
+		<p>
+			<p>
+				[page:Camera camera]: The camera of the rendered scene.
+			</p>
+			<p>
+				[page:HTMLDOMElement domElement]: (optional) The HTML element used for event listeners. By default this is the whole document,
+				however if you only want the controls to work over a specific element (e.g. the canvas) you can specify that here.
+			</p>
+			<p>
+				Creates a new instance of [name].
+			</p>
+		</p>
+
+		<h2>Events</h2>
+
+		<h3>change</h3>
+		<p>
+			Fires when the camera has been transformed by the controls.
+		</p>
+
+		<h3>start</h3>
+		<p>
+			Fires when an interaction (e.g. touch) was initiated.
+		</p>
+
+		<h3>end</h3>
+		<p>
+			Fires when an interaction has finished.
+		</p>
+
+		<h2>Properties</h2>
+
+		<h3>[property:HTMLDOMElement domElement]</h3>
+		<p>
+			The HTMLDOMElement used to listen for mouse / touch events. This must be passed in the constructor; changing it here will
+			not set up new event listeners. Default is the whole document.
+		</p>
+
+		<h3>[property:Number dynamicDampingFactor]</h3>
+		<p>
+			Defines the intensity of damping. Only considered if [page:.staticMoving staticMoving] is set to *false*. Default is *0.2*.
+		</p>
+
+		<h3>[property:Boolean enabled]</h3>
+		<p>
+			Whether or not the controls are enabled.
+		</p>
+
+		<h3>[property:Array keys]</h3>
+		<p>
+			This array holds keycodes for controlling interactions.
+			<ul>
+				<li>When the first defined key is pressed, all mouse interactions (left, middle, right) performs orbiting.</li>
+				<li>When the second defined key is pressed, all mouse interactions (left, middle, right) performs zooming.</li>
+				<li>When the third defined key is pressed, all mouse interactions (left, middle, right) performs panning.</li>
+			</ul>
+			Default is *65, 83, 68* which represents A, S, D.
+		</p>
+
+		<h3>[property:Number maxDistance]</h3>
+		<p>
+			 How far you can zoom in. Default is *Infinity*.
+		</p>
+
+		<h3>[property:Number minDistance]</h3>
+		<p>
+			 How far you can zoom in. Default is *0*.
+		</p>
+
+		<h3>
+			[property:Object mouseButtons]</h3>
+		<p>
+			This object contains references to the mouse actions used by the controls.
+			<ul>
+				<li>.LEFT is assinged with *THREE.MOUSE.ROTATE*</li>
+				<li>.MIDDLE is assinged with *THREE.MOUSE.ZOOM*</li>
+				<li>.RIGHT is assinged with *THREE.MOUSE.PAN*</li>
+			</ul>
+		</p>
+
+		<h3>[property:Boolean noPan]</h3>
+		<p>
+			Whether or not panning is disabled. Default is *false*.
+		</p>
+
+		<h3>[property:Boolean noRotate]</h3>
+		<p>
+			Whether or not rotation is disabled. Default is *false*.
+		</p>
+
+		<h3>[property:Boolean noZoom]</h3>
+		<p>
+			Whether or not zooming is disabled. Default is *false*.
+		</p>
+
+		<h3>[property:Camera object]</h3>
+		<p>
+			The camera being controlled.
+		</p>
+
+		<h3>[property:Number panSpeed]</h3>
+		<p>
+			The zoom speed. Default is *0.3*.
+		</p>
+
+		<h3>[property:Number rotateSpeed]</h3>
+		<p>
+			The rotation speed. Default is *1.0*.
+		</p>
+
+		<h3>[property:Object screen]</h3>
+		<p>
+			Represents the properties of the screen. Automatically set when [page:.handleResize handleResize]() is called.
+			<ul>
+				<li>left: Represents the offset in pixels to the screen's left boundary.</li>
+				<li>top: Represents the offset in pixels to the screen's top boundary.</li>
+				<li>width: Represents the screen width in pixels.</li>
+				<li>height: Represents the screen height in pixels.</li>
+			</ul>
+		</p>
+
+		<h3>[property:Boolean staticMoving]</h3>
+		<p>
+			Whether or not damping is disabled. Default is *false*.
+		</p>
+
+		<h3>[property:Number zoomSpeed]</h3>
+		<p>
+			The zoom speed. Default is *1.2*.
+		</p>
+
+		<h2>Methods</h2>
+
+		<h3>[method:null checkDistances] ()</h3>
+		<p>
+			Ensures the controls stay in the range [minDistance, maxDistance]. Called by [page:.update update]().
+		</p>
+
+		<h3>[method:null dispose] ()</h3>
+		<p>
+			Should be called if the controls is no longer required.
+		</p>
+
+		<h3>[method:null handleResize] ()</h3>
+		<p>
+			Should be called if the application window is resized.
+		</p>
+
+		<h3>[method:null panCamera] ()</h3>
+		<p>
+			Performs panning if necessary. Called by [page:.update update]().
+		</p>
+
+		<h3>[method:null reset] ()</h3>
+		<p>
+			Resets the controls to its initial state.
+		</p>
+
+		<h3>[method:null rotateCamera] ()</h3>
+		<p>
+			Rotates the camera if necessary. Called by [page:.update update]().
+		</p>
+
+		<h3>[method:null update] ()</h3>
+		<p>
+			Updates the controls. Usually called in the animation loop.
+		</p>
+
+		<h3>[method:null zoomCamera] ()</h3>
+		<p>
+			Performs zooming if necessary. Called by [page:.update update]().
+		</p>
+
+		<h2>Source</h2>
+
+		<p>
+			[link:https://github.com/mrdoob/three.js/blob/master/examples/js/controls/TrackballControls.js examples/js/controls/TrackballControls.js]
+		</p>
+	</body>
+</html>

+ 225 - 0
docs/examples/zh/controls/TransformControls.html

@@ -0,0 +1,225 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<meta charset="utf-8" />
+		<base href="../../../" />
+		<script src="list.js"></script>
+		<script src="page.js"></script>
+		<link type="text/css" rel="stylesheet" href="page.css" />
+	</head>
+	<body>
+		[page:Object3D] &rarr;
+
+		<h1>[name]</h1>
+
+		<p class="desc">
+			This class can be used to transform objects in 3D space by adapting a similar interaction model of DCC tools like Blender.
+			Unlike other controls, it is not intended to transform the scene's camera.
+		</p>
+
+		<h2>Example</h2>
+
+		<p>[example:misc_controls_transform misc / controls / transform ]</p>
+
+		<h2>Constructor</h2>
+
+		<h3>[name]( [param:Camera camera], [param:HTMLDOMElement domElement] )</h3>
+		<p>
+			<p>
+				[page:Camera camera]: The camera of the rendered scene.
+			</p>
+			<p>
+				[page:HTMLDOMElement domElement]: (optional) The HTML element used for event listeners. By default this is the whole document,
+				however if you only want the controls to work over a specific element (e.g. the canvas) you can specify that here.
+			</p>
+			<p>
+				Creates a new instance of [name].
+			</p>
+		</p>
+
+		<h2>Events</h2>
+
+		<h3>change</h3>
+		<p>
+			Fires if any type of change (object or property change) is performed. Property changes
+			are separate events you can add event listeners to. The event type is "propertyname-changed".
+		</p>
+
+		<h3>mouseDown</h3>
+		<p>
+			Fires if a pointer (mouse/touch) becomes active.
+		</p>
+
+		<h3>mouseUp</h3>
+		<p>
+			Fires if a pointer (mouse/touch) is no longer active.
+		</p>
+
+		<h3>objectChange</h3>
+		<p>
+			Fires if the controlled 3D object is changed.
+		</p>
+
+		<h2>Properties</h2>
+
+		<p>See the base [page:Object3D] class for common properties.</p>
+
+		<h3>[property:String axis]</h3>
+		<p>
+			The current transformation axis.
+		</p>
+
+		<h3>[property:Camera camera]</h3>
+		<p>
+			The camera of the rendered scene.
+		</p>
+
+		<h3>[property:HTMLDOMElement domElement]</h3>
+		<p>
+			The HTMLDOMElement used to listen for mouse / touch events. This must be passed in the constructor; changing it here will
+			not set up new event listeners. Default is the whole document.
+		</p>
+
+		<h3>[property:Boolean dragging]</h3>
+		<p>
+			Whether or not dragging is currently performed. Read-only property.
+		</p>
+
+		<h3>[property:Boolean enabled]</h3>
+		<p>
+			Whether or not the controls are enabled.
+		</p>
+
+		<h3>[property:String mode]</h3>
+		<p>
+			The current transformation mode. Possible values are "translate", "rotate" and "scale". Default is *translate*.
+		</p>
+
+		<h3>[property:Object3D object]</h3>
+		<p>
+			The 3D object being controlled.
+		</p>
+
+		<h3>[property:Number rotationSnap]</h3>
+		<p>
+			By default, 3D objects are continously rotated. If you set this property to a numeric value (radians), you can define in which
+			steps the 3D object should be rotated. Deault is *null*.
+		</p>
+
+		<h3>[property:Boolean showX]</h3>
+		<p>
+			Whether or not the x-axis helper should be visible. Default is *true*.
+		</p>
+
+		<h3>[property:Boolean showY]</h3>
+		<p>
+			Whether or not the y-axis helper should be visible. Default is *true*.
+		</p>
+
+		<h3>[property:Boolean showZ]</h3>
+		<p>
+			Whether or not the z-axis helper should be visible. Default is *true*.
+		</p>
+
+		<h3>[property:Number size]</h3>
+		<p>
+			The size of the helper UI (axes/planes). Default is *1*.
+		</p>
+
+		<h3>[property:String space]</h3>
+		<p>
+			Defines in which coordinate space transformations should be performed. Possible values are "world" and "local". Default is *world*.
+		</p>
+
+		<h3>[property:Number translationSnap]</h3>
+		<p>
+			By default, 3D objects are continously translated. If you set this property to a numeric value (world units), you can define in which
+			steps the 3D object should be translated. Deault is *null*.
+		</p>
+
+		<h2>Methods</h2>
+
+		<p>See the base [page:Object3D] class for common methods.</p>
+
+		<h3>[method:TransformControls attach] ( [param:Object3D object] )</h3>
+		<p>
+			<p>
+				[page:Object3D object]: The 3D object that should be transformed.
+			</p>
+			<p>
+				Sets the 3D object that should be transformed and ensures the controls UI is visible.
+			</p>
+		</p>
+
+		<h3>[method:TransformControls detach] ()</h3>
+		<p>
+			Removes the current 3D object from the controls and makes the helper UI is invisible.
+		</p>
+
+		<h3>[method:null dispose] ()</h3>
+		<p>
+			Should be called if the controls is no longer required.
+		</p>
+
+		<h3>[method:String getMode] ()</h3>
+		<p>
+			Returns the transformation mode.
+		</p>
+
+		<h3>[method:null setMode] ( [param:String mode] )</h3>
+		<p>
+			<p>
+				[page:String mode]: The transformation mode.
+			</p>
+			<p>
+				Sets the transformation mode.
+			</p>
+		</p>
+
+		<h3>[method:null setRotationSnap] ( [param:Number rotationSnap] )</h3>
+		<p>
+			<p>
+				[page:Number rotationSnap]: The rotation snap.
+			</p>
+			<p>
+				Sets the rotation snap.
+			</p>
+		</p>
+
+		<h3>[method:null setSize] ( [param:Number size] )</h3>
+		<p>
+			<p>
+				[page:Number size]: The size of the helper UI.
+			</p>
+			<p>
+				Sets the size of the helper UI.
+			</p>
+		</p>
+
+		<h3>[method:null setSpace] ( [param:String space] )</h3>
+		<p>
+			<p>
+				[page:String space]: The coordinate space in which transformations are applied.
+			</p>
+			<p>
+				Sets the coordinate space in which transformations are applied.
+			</p>
+		</p>
+
+		<h3>[method:null setTranslationSnap] ( [param:Number translationSnap] )</h3>
+		<p>
+			<p>
+				[page:Number translationSnap]: The translation snap.
+			</p>
+			<p>
+				Sets the translation snap.
+			</p>
+		</p>
+
+		<h2>Source</h2>
+
+		<p>
+			[link:https://github.com/mrdoob/three.js/blob/master/examples/js/controls/TransformControls.js examples/js/controls/TransformControls.js]
+		</p>
+	</body>
+</html>

+ 0 - 96
docs/examples/zh/loaders/BabylonLoader.html

@@ -1,96 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-	<head>
-		<meta charset="utf-8" />
-		<base href="../../../" />
-		<script src="list.js"></script>
-		<script src="page.js"></script>
-		<link type="text/css" rel="stylesheet" href="page.css" />
-	</head>
-	<body>
-		[page:Loader] &rarr;
-
-		<h1>[name]</h1>
-
-		<p class="desc">A loader for loading a <em>.babylon</em> resource. <br />
-		The <a href="https://doc.babylonjs.com/generals/file_format_map_(.babylon)"> .babylon </a> file format used by
-		<a href="https://www.babylonjs.com/">Babylon.js</a>.
-		</p>
-
-		<h2>Example</h2>
-
-		<code>
-		// instantiate a loader
-		var loader = new THREE.BabylonLoader();
-
-		// load a Babylon resource
-		loader.load(
-			// resource URL
-			'models/babylon/skull.babylon',
-			// called when resource is loaded
-			function ( object ) {
-
-				scene.add( object );
-
-			},
-			// called when loading is in progress
-			function ( xhr ) {
-
-				console.log( ( xhr.loaded / xhr.total * 100 ) + '% loaded' );
-
-			},
-			// called when loading has errors
-			function ( xhr ) {
-
-				console.log( 'An error happened' );
-
-			}
-		);
-		</code>
-
-		[example:webgl_loader_babylon]
-
-		<h2>Constructor</h2>
-
-		<h3>[name]( [param:LoadingManager manager] )</h3>
-		<p>
-		[page:LoadingManager manager] — The [page:LoadingManager loadingManager] for the loader to use. Default is [page:LoadingManager THREE.DefaultLoadingManager].
-		</p>
-		<p>
-		Creates a new [name].
-		</p>
-
-		<h2>Properties</h2>
-		<p>See the base [page:Loader] class for common properties.</p>
-
-		<h2>Methods</h2>
-		<p>See the base [page:Loader] class for common methods.</p>
-
-		<h3>[method:null load]( [param:String url], [param:Function onLoad], [param:Function onProgress], [param:Function onError] )</h3>
-		<p>
-		[page:String url] — A string containing the path/URL of the <em>.babylon</em> file.<br />
-		[page:function onLoad] — (optional) A function to be called after loading is successfully completed. The function receives the loaded [page:Object3D] as an argument.<br />
-		[page:function onProgress] — (optional) A function to be called while the loading is in progress. The argument will be the XMLHttpRequest instance, which contains [page:Integer total] and [page:Integer loaded] bytes.<br />
-		[page:function onError] — (optional) A function to be called if an error occurs during loading. The function receives the error as an argument.<br />
-		</p>
-		<p>
-		Begin loading from url and call onLoad with the parsed response content.
-		</p>
-
-		<h3>[method:Object3D parse]( [param:Object json] )</h3>
-		<p>
-		[page:Object json] — The <em>JSON</em> structure to parse.
-		</p>
-		<p>
-		Parse a <em>JSON</em> structure and return an [page:Object3D object] or a [page:Scene scene].<br />
-		Found objects are converted to [page:Mesh] with a [page:BufferGeometry] and a default [page:MeshPhongMaterial].<br />
-		Lights are parsed accordingly.
-		</p>
-
-		<h2>Source</h2>
-
-		<p>
-			[link:https://github.com/mrdoob/three.js/blob/master/examples/js/loaders/BabylonLoader.js examples/js/loaders/BabylonLoader.js]
-		</p>
-	</body>
-</html>

+ 16 - 4
docs/list.js

@@ -354,7 +354,14 @@ var list = {
 			},
 
 			"Controls": {
-				"OrbitControls": "examples/en/controls/OrbitControls"
+				"DeviceOrientationControls": "examples/en/controls/DeviceOrientationControls",
+				"DragControls": "examples/en/controls/DragControls",
+				"FirstPersonControls": "examples/en/controls/FirstPersonControls",
+				"FlyControls": "examples/en/controls/FlyControls",
+				"OrbitControls": "examples/en/controls/OrbitControls",
+				"PointerLockControls": "examples/en/controls/PointerLockControls",
+				"TrackballControls": "examples/en/controls/TrackballControls",
+				"TransformControls": "examples/en/controls/TransformControls"
 			},
 
 			"Geometries": {
@@ -364,7 +371,6 @@ var list = {
 			},
 
 			"Loaders": {
-				"BabylonLoader": "examples/en/loaders/BabylonLoader",
 				"BasisTextureLoader": "examples/en/loaders/BasisTextureLoader",
 				"DRACOLoader": "examples/en/loaders/DRACOLoader",
 				"GLTFLoader": "examples/en/loaders/GLTFLoader",
@@ -790,7 +796,14 @@ var list = {
 			},
 
 			"控制": {
-				"OrbitControls": "examples/zh/controls/OrbitControls"
+				"DeviceOrientationControls": "examples/zh/controls/DeviceOrientationControls",
+				"DragControls": "examples/zh/controls/DragControls",
+				"FirstPersonControls": "examples/zh/controls/FirstPersonControls",
+				"FlyControls": "examples/zh/controls/FlyControls",
+				"OrbitControls": "examples/zh/controls/OrbitControls",
+				"PointerLockControls": "examples/zh/controls/PointerLockControls",
+				"TrackballControls": "examples/zh/controls/TrackballControls",
+				"TransformControls": "examples/zh/controls/TransformControls"
 			},
 
 			"几何体": {
@@ -800,7 +813,6 @@ var list = {
 			},
 
 			"加载器": {
-				"BabylonLoader": "examples/zh/loaders/BabylonLoader",
 				"BasisTextureLoader": "examples/zh/loaders/BasisTextureLoader",
 				"DRACOLoader": "examples/zh/loaders/DRACOLoader",
 				"GLTFLoader": "examples/zh/loaders/GLTFLoader",

+ 24 - 0
editor/css/dark.css

@@ -251,6 +251,30 @@ select {
 		background-color: rgba(21,60,94,1);
 	}
 
+.TabbedPanel .Tabs {
+	background-color: #1b1b1b;
+	border-top: 1px solid #222;
+}
+
+	.TabbedPanel .Tab {
+		color: #555;
+		border-right: 1px solid #222;
+	}
+
+	.TabbedPanel .Tab.selected {
+		color: #888;
+		background-color: #111;
+	}
+
+.Listbox {
+	color: #888;
+	background: #222;
+}
+
+.Panel {
+	color: #888;
+	border-top: 1px solid #222;
+}
 /* */
 
 @media all and ( max-width: 600px ) {

+ 25 - 0
editor/css/light.css

@@ -244,6 +244,31 @@ select {
 		background-color: rgba(0,0,0,0.04);
 	}
 
+
+.TabbedPanel .Tabs {
+	background-color: #ddd;
+	border-top: 1px solid #ccc;
+}
+
+	.TabbedPanel .Tab {
+		color: #aaa;
+		border-right: 1px solid #ccc;
+	}
+
+	.TabbedPanel .Tab.selected {
+		color: #888;
+		background-color: #eee;
+	}
+
+.Listbox {
+	color: #444;
+	background-color: #fff;
+}
+
+.Panel {
+	color: #888;
+	border-top: 1px solid #ccc;
+}
 /* */
 
 @media all and ( max-width: 600px ) {

+ 53 - 0
editor/css/main.css

@@ -41,6 +41,59 @@ textarea, input { outline: none; } /* osx */
 	user-select: none;
 }
 
+.TabbedPanel {
+	-moz-user-select: none;
+	-webkit-user-select: none;
+	-ms-user-select: none;
+
+	/* No support for these yet */
+	-o-user-select: none;
+	user-select: none;
+	position: relative;
+	display: block;
+	width: 100%;
+}
+
+.TabbedPanel .Tabs {
+	position: relative;
+	display: block;
+	width: 100%;
+}
+
+.TabbedPanel .Tabs .Tab {
+	padding: 10px;
+	vertical-align: middle;
+}
+
+.TabbedPanel .Tabs .Panels {
+	position: relative;
+	display: block;
+	width: 100%;
+	height: 100%;
+}
+
+/* Listbox */
+.Listbox {
+	color: #444;
+	background-color: #fff;
+	padding: 0;
+	width: 100%;
+	min-height: 140px;
+	font-size: 12px;
+	cursor: default;
+	overflow: auto;
+}
+
+.Listbox .ListboxItem {
+	padding: 6px;
+	color: #666;
+	white-space: nowrap;
+}
+
+.Listbox .ListboxItem.active {
+	background-color: rgba(0, 0, 0, 0.04);
+}
+
 /* CodeMirror */
 
 .CodeMirror {

+ 4 - 6
editor/index.html

@@ -7,8 +7,8 @@
 		<link rel="apple-touch-icon" href="images/icon.png">
 		<link rel="manifest" href="manifest.json">
 		<link rel="shortcut icon" href="../files/favicon.ico" />
-		<!-- WebXR Device API (For Chrome M76+), expires 09/09/2019 -->
-		<meta http-equiv="origin-trial" content="Ai1/G787sugfmWtk1xQExa8N6OqwDsJyNn+OwpA1J4PozR1lixRYIQ4Tmp00vrGWS8FQQ2iDyqjwaewrOfYvPAUAAABTeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJYUkRldmljZU03NiIsImV4cGlyeSI6MTU2ODAyMzQ3OH0=">
+		<!-- WebXR Device API (For Chrome M76+), expires 10/16/2019 -->
+		<meta http-equiv="origin-trial" content="AtWCPo0cZgy0zJDSYftemy7eZvmcwR5qy/4osFkMkLZ0ar6OYyKfbu93pjpxiOVzcWNIVxgoWoK8YtxCXeFSqgIAAABTeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJYUkRldmljZU03NiIsImV4cGlyeSI6MTU3MTE4Mzk5OX0=">
 	</head>
 	<body ontouchstart="">
 		<link rel="stylesheet" href="css/main.css">
@@ -16,7 +16,6 @@
 
 		<script src="../build/three.js"></script>
 
-		<script src="../examples/js/controls/EditorControls.js"></script>
 		<script src="../examples/js/controls/TransformControls.js"></script>
 
 		<script src="../examples/js/libs/chevrotain.min.js"></script> <!-- VRML -->
@@ -24,8 +23,6 @@
 		<script src="../examples/js/libs/inflate.min.js"></script> <!-- FBX -->
 
 		<script src="../examples/js/loaders/AMFLoader.js"></script>
-		<script src="../examples/js/loaders/AWDLoader.js"></script>
-		<script src="../examples/js/loaders/BabylonLoader.js"></script>
 		<script src="../examples/js/loaders/ColladaLoader.js"></script>
 		<script src="../examples/js/loaders/DRACOLoader.js"></script>
 		<script src="../examples/js/loaders/FBXLoader.js"></script>
@@ -35,7 +32,6 @@
 		<script src="../examples/js/loaders/MD2Loader.js"></script>
 		<script src="../examples/js/loaders/OBJLoader.js"></script>
 		<script src="../examples/js/loaders/MTLLoader.js"></script>
-		<script src="../examples/js/loaders/PlayCanvasLoader.js"></script>
 		<script src="../examples/js/loaders/PLYLoader.js"></script>
 		<script src="../examples/js/loaders/STLLoader.js"></script>
 		<script src="../examples/js/loaders/SVGLoader.js"></script>
@@ -96,6 +92,7 @@
 
 		<script src="../examples/js/vr/WebVR.js"></script>
 
+		<script src="js/EditorControls.js"></script>
 		<script src="js/Storage.js"></script>
 
 		<script src="js/Editor.js"></script>
@@ -126,6 +123,7 @@
 		<script src="js/Sidebar.Geometry.BoxGeometry.js"></script>
 		<script src="js/Sidebar.Geometry.CircleGeometry.js"></script>
 		<script src="js/Sidebar.Geometry.CylinderGeometry.js"></script>
+		<script src="js/Sidebar.Geometry.DodecahedronGeometry.js"></script>
 		<script src="js/Sidebar.Geometry.ExtrudeGeometry.js"></script>
 		<script src="js/Sidebar.Geometry.IcosahedronGeometry.js"></script>
 		<script src="js/Sidebar.Geometry.OctahedronGeometry.js"></script>

+ 1 - 1
examples/js/controls/EditorControls.js → editor/js/EditorControls.js

@@ -175,7 +175,7 @@ THREE.EditorControls = function ( object, domElement ) {
 
 	}
 
-	function onMouseUp( event ) {
+	function onMouseUp( /* event */ ) {
 
 		domElement.removeEventListener( 'mousemove', onMouseMove, false );
 		domElement.removeEventListener( 'mouseup', onMouseUp, false );

+ 0 - 71
editor/js/Loader.js

@@ -5,7 +5,6 @@
 var Loader = function ( editor ) {
 
 	var scope = this;
-	var signals = editor.signals;
 
 	this.texturePath = '';
 
@@ -87,59 +86,6 @@ var Loader = function ( editor ) {
 
 				break;
 
-			case 'awd':
-
-				reader.addEventListener( 'load', function ( event ) {
-
-					var loader = new THREE.AWDLoader();
-					var scene = loader.parse( event.target.result );
-
-					editor.execute( new SetSceneCommand( editor, scene ) );
-
-				}, false );
-				reader.readAsArrayBuffer( file );
-
-				break;
-
-			case 'babylon':
-
-				reader.addEventListener( 'load', function ( event ) {
-
-					var contents = event.target.result;
-					var json = JSON.parse( contents );
-
-					var loader = new THREE.BabylonLoader();
-					var scene = loader.parse( json );
-
-					editor.execute( new SetSceneCommand( editor, scene ) );
-
-				}, false );
-				reader.readAsText( file );
-
-				break;
-
-			case 'babylonmeshdata':
-
-				reader.addEventListener( 'load', function ( event ) {
-
-					var contents = event.target.result;
-					var json = JSON.parse( contents );
-
-					var loader = new THREE.BabylonLoader();
-
-					var geometry = loader.parseGeometry( json );
-					var material = new THREE.MeshStandardMaterial();
-
-					var mesh = new THREE.Mesh( geometry, material );
-					mesh.name = filename;
-
-					editor.execute( new AddObjectCommand( editor, mesh ) );
-
-				}, false );
-				reader.readAsText( file );
-
-				break;
-
 			case 'dae':
 
 				reader.addEventListener( 'load', function ( event ) {
@@ -348,23 +294,6 @@ var Loader = function ( editor ) {
 
 				break;
 
-			case 'playcanvas':
-
-				reader.addEventListener( 'load', function ( event ) {
-
-					var contents = event.target.result;
-					var json = JSON.parse( contents );
-
-					var loader = new THREE.PlayCanvasLoader();
-					var object = loader.parse( json );
-
-					editor.execute( new AddObjectCommand( editor, object ) );
-
-				}, false );
-				reader.readAsText( file );
-
-				break;
-
 			case 'ply':
 
 				reader.addEventListener( 'load', function ( event ) {

+ 17 - 1
editor/js/Menubar.Add.js

@@ -85,6 +85,22 @@ Menubar.Add = function ( editor ) {
 	} );
 	options.add( option );
 
+	// Dodecahedron
+
+	var option = new UI.Row();
+	option.setClass( 'option' );
+	option.setTextContent( strings.getKey( 'menubar/add/dodecahedron' ) );
+	option.onClick( function () {
+
+		var geometry = new THREE.DodecahedronBufferGeometry( 1, 0 );
+		var mesh = new THREE.Mesh( geometry, new THREE.MeshStandardMaterial() );
+		mesh.name = 'Dodecahedron';
+
+		editor.execute( new AddObjectCommand( editor, mesh ) );
+
+	} );
+	options.add( option );
+
 	// Icosahedron
 
 	var option = new UI.Row();
@@ -162,7 +178,7 @@ Menubar.Add = function ( editor ) {
 		editor.execute( new AddObjectCommand( editor, mesh ) );
 
 	} );
-	options.add( option )
+	options.add( option );
 
 	// Ring
 

+ 0 - 2
editor/js/Sidebar.Geometry.BoxGeometry.js

@@ -6,8 +6,6 @@ Sidebar.Geometry.BoxGeometry = function ( editor, object ) {
 
 	var strings = editor.strings;
 
-	var signals = editor.signals;
-
 	var container = new UI.Row();
 
 	var geometry = object.geometry;

+ 0 - 2
editor/js/Sidebar.Geometry.CircleGeometry.js

@@ -6,8 +6,6 @@ Sidebar.Geometry.CircleGeometry = function ( editor, object ) {
 
 	var strings = editor.strings;
 
-	var signals = editor.signals;
-
 	var container = new UI.Row();
 
 	var geometry = object.geometry;

+ 0 - 2
editor/js/Sidebar.Geometry.CylinderGeometry.js

@@ -6,8 +6,6 @@ Sidebar.Geometry.CylinderGeometry = function ( editor, object ) {
 
 	var strings = editor.strings;
 
-	var signals = editor.signals;
-
 	var container = new UI.Row();
 
 	var geometry = object.geometry;

+ 49 - 0
editor/js/Sidebar.Geometry.DodecahedronGeometry.js

@@ -0,0 +1,49 @@
+/**
+ * @author mrdoob / http://mrdoob.com/
+ */
+
+Sidebar.Geometry.DodecahedronGeometry = function ( editor, object ) {
+
+	var strings = editor.strings;
+
+	var container = new UI.Row();
+
+	var geometry = object.geometry;
+	var parameters = geometry.parameters;
+
+	// radius
+
+	var radiusRow = new UI.Row();
+	var radius = new UI.Number( parameters.radius ).onChange( update );
+
+	radiusRow.add( new UI.Text( strings.getKey( 'sidebar/geometry/dodecahedron_geometry/radius' ) ).setWidth( '90px' ) );
+	radiusRow.add( radius );
+
+	container.add( radiusRow );
+
+	// detail
+
+	var detailRow = new UI.Row();
+	var detail = new UI.Integer( parameters.detail ).setRange( 0, Infinity ).onChange( update );
+
+	detailRow.add( new UI.Text( strings.getKey( 'sidebar/geometry/dodecahedron_geometry/detail' ) ).setWidth( '90px' ) );
+	detailRow.add( detail );
+
+	container.add( detailRow );
+
+	//
+
+	function update() {
+
+		editor.execute( new SetGeometryCommand( editor, object, new THREE[ geometry.type ](
+			radius.getValue(),
+			detail.getValue()
+		) ) );
+
+	}
+
+	return container;
+
+};
+
+Sidebar.Geometry.DodecahedronBufferGeometry = Sidebar.Geometry.DodecahedronGeometry;

+ 0 - 2
editor/js/Sidebar.Geometry.ExtrudeGeometry.js

@@ -6,8 +6,6 @@ Sidebar.Geometry.ExtrudeGeometry = function ( editor, object ) {
 
 	var strings = editor.strings;
 
-	var signals = editor.signals;
-
 	var container = new UI.Row();
 
 	var geometry = object.geometry;

+ 0 - 5
editor/js/Sidebar.Geometry.IcosahedronGeometry.js

@@ -6,8 +6,6 @@ Sidebar.Geometry.IcosahedronGeometry = function ( editor, object ) {
 
 	var strings = editor.strings;
 
-	var signals = editor.signals;
-
 	var container = new UI.Row();
 
 	var geometry = object.geometry;
@@ -33,7 +31,6 @@ Sidebar.Geometry.IcosahedronGeometry = function ( editor, object ) {
 
 	container.add( detailRow );
 
-
 	//
 
 	function update() {
@@ -43,8 +40,6 @@ Sidebar.Geometry.IcosahedronGeometry = function ( editor, object ) {
 			detail.getValue()
 		) ) );
 
-		signals.objectChanged.dispatch( object );
-
 	}
 
 	return container;

+ 0 - 2
editor/js/Sidebar.Geometry.LatheGeometry.js

@@ -6,8 +6,6 @@ Sidebar.Geometry.LatheGeometry = function ( editor, object ) {
 
 	var strings = editor.strings;
 
-	var signals = editor.signals;
-
 	var container = new UI.Row();
 
 	var geometry = object.geometry;

+ 0 - 4
editor/js/Sidebar.Geometry.OctahedronGeometry.js

@@ -6,8 +6,6 @@ Sidebar.Geometry.OctahedronGeometry = function ( editor, object ) {
 
 	var strings = editor.strings;
 
-	var signals = editor.signals;
-
 	var container = new UI.Row();
 
 	var geometry = object.geometry;
@@ -43,8 +41,6 @@ Sidebar.Geometry.OctahedronGeometry = function ( editor, object ) {
 			detail.getValue()
 		) ) );
 
-		signals.objectChanged.dispatch( object );
-
 	}
 
 	return container;

+ 0 - 2
editor/js/Sidebar.Geometry.PlaneGeometry.js

@@ -6,8 +6,6 @@ Sidebar.Geometry.PlaneGeometry = function ( editor, object ) {
 
 	var strings = editor.strings;
 
-	var signals = editor.signals;
-
 	var container = new UI.Row();
 
 	var geometry = object.geometry;

+ 0 - 2
editor/js/Sidebar.Geometry.RingGeometry.js

@@ -6,8 +6,6 @@ Sidebar.Geometry.RingGeometry = function ( editor, object ) {
 
 	var strings = editor.strings;
 
-	var signals = editor.signals;
-
 	var container = new UI.Row();
 
 	var geometry = object.geometry;

+ 0 - 2
editor/js/Sidebar.Geometry.ShapeGeometry.js

@@ -6,8 +6,6 @@ Sidebar.Geometry.ShapeGeometry = function ( editor, object ) {
 
 	var strings = editor.strings;
 
-	var signals = editor.signals;
-
 	var container = new UI.Row();
 
 	var geometry = object.geometry;

+ 0 - 2
editor/js/Sidebar.Geometry.SphereGeometry.js

@@ -6,8 +6,6 @@ Sidebar.Geometry.SphereGeometry = function ( editor, object ) {
 
 	var strings = editor.strings;
 
-	var signals = editor.signals;
-
 	var container = new UI.Row();
 
 	var geometry = object.geometry;

+ 0 - 4
editor/js/Sidebar.Geometry.TetrahedronGeometry.js

@@ -7,8 +7,6 @@ Sidebar.Geometry.TetrahedronGeometry = function ( editor, object ) {
 
 	var strings = editor.strings;
 
-	var signals = editor.signals;
-
 	var container = new UI.Row();
 
 	var geometry = object.geometry;
@@ -44,8 +42,6 @@ Sidebar.Geometry.TetrahedronGeometry = function ( editor, object ) {
 			detail.getValue()
 		) ) );
 
-		signals.objectChanged.dispatch( object );
-
 	}
 
 	return container;

+ 0 - 2
editor/js/Sidebar.Geometry.TorusGeometry.js

@@ -6,8 +6,6 @@ Sidebar.Geometry.TorusGeometry = function ( editor, object ) {
 
 	var strings = editor.strings;
 
-	var signals = editor.signals;
-
 	var container = new UI.Row();
 
 	var geometry = object.geometry;

+ 0 - 2
editor/js/Sidebar.Geometry.TorusKnotGeometry.js

@@ -6,8 +6,6 @@ Sidebar.Geometry.TorusKnotGeometry = function ( editor, object ) {
 
 	var strings = editor.strings;
 
-	var signals = editor.signals;
-
 	var container = new UI.Row();
 
 	var geometry = object.geometry;

+ 0 - 2
editor/js/Sidebar.Geometry.TubeGeometry.js

@@ -6,8 +6,6 @@ Sidebar.Geometry.TubeGeometry = function ( editor, object ) {
 
 	var strings = editor.strings;
 
-	var signals = editor.signals;
-
 	var container = new UI.Row();
 
 	var geometry = object.geometry;

+ 36 - 0
editor/js/Sidebar.Material.js

@@ -195,6 +195,18 @@ Sidebar.Material = function ( editor ) {
 
 	container.add( materialMetalnessRow );
 
+	// sheen
+
+	var materialSheenRow = new UI.Row();
+	var materialSheenEnabled = new UI.Checkbox( false ).onChange( update );
+	var materialSheen = new UI.Color().setHexValue(0x000000).onChange( update );
+
+	materialSheenRow.add( new UI.Text( strings.getKey( 'sidebar/material/sheen' ) ).setWidth( '90px' ) )
+	materialSheenRow.add( materialSheenEnabled );
+	materialSheenRow.add( materialSheen );
+
+	container.add( materialSheenRow );
+
 	// emissive
 
 	var materialEmissiveRow = new UI.Row();
@@ -636,6 +648,22 @@ Sidebar.Material = function ( editor ) {
 
 			}
 
+			if ( material.sheen !== undefined ) {
+
+				var sheenEnabled = materialSheenEnabled.getValue() === true;
+
+				var sheen = sheenEnabled ? new THREE.Color(materialSheen.getHexValue()) : null;
+
+				editor.execute( new SetMaterialValueCommand( editor, currentObject, 'sheen', sheen, currentMaterialSlot ) );
+				
+			}
+			
+			if ( material.sheen !== undefined && material.sheen !== null && material.sheen.getHex() !== materialSheen.getHexValue() ) {
+
+				editor.execute( new SetMaterialColorCommand( editor, currentObject, 'sheen', materialSheen.getHexValue(), currentMaterialSlot ) );
+
+			}
+
 			if ( material.emissive !== undefined && material.emissive.getHex() !== materialEmissive.getHexValue() ) {
 
 				editor.execute( new SetMaterialColorCommand( editor, currentObject, 'emissive', materialEmissive.getHexValue(), currentMaterialSlot ) );
@@ -1157,6 +1185,7 @@ Sidebar.Material = function ( editor ) {
 			'roughness': materialRoughnessRow,
 			'metalness': materialMetalnessRow,
 			'emissive': materialEmissiveRow,
+			'sheen': materialSheenRow,
 			'specular': materialSpecularRow,
 			'shininess': materialShininessRow,
 			'clearcoat': materialClearcoatRow,
@@ -1268,6 +1297,13 @@ Sidebar.Material = function ( editor ) {
 			materialMetalness.setValue( material.metalness );
 
 		}
+		
+		if ( material.sheen !== undefined && material.sheen !== null ) {
+			
+			materialSheenEnabled.setValue( true );
+			materialSheen.setHexValue( material.sheen.getHexString() );
+
+		}
 
 		if ( material.emissive !== undefined ) {
 

+ 5 - 63
editor/js/Sidebar.Properties.js

@@ -4,72 +4,14 @@
 
 Sidebar.Properties = function ( editor ) {
 
-	var signals = editor.signals;
 	var strings = editor.strings;
 
-	var container = new UI.Span();
+	var container = new UI.TabbedPanel();
+	container.setId( 'properties' );
 
-	var objectTab = new UI.Text( strings.getKey( 'sidebar/properties/object' ) ).setTextTransform( 'uppercase' );
-	objectTab.onClick( function () { select( 'OBJECT' ) } );
-
-	var geometryTab = new UI.Text( strings.getKey( 'sidebar/properties/geometry' ) ).setTextTransform( 'uppercase' );
-	geometryTab.onClick( function () { select( 'GEOMETRY' ) } );
-
-	var materialTab = new UI.Text( strings.getKey( 'sidebar/properties/material' ) ).setTextTransform( 'uppercase' );
-	materialTab.onClick( function () { select( 'MATERIAL' ) } );
-
-	var tabs = new UI.Div();
-	tabs.setId( 'tabs' );
-	tabs.add( objectTab, geometryTab, materialTab );
-	container.add( tabs );
-
-	//
-
-	var object = new UI.Span().add(
-		new Sidebar.Object( editor )
-	);
-	container.add( object );
-
-	var geometry = new UI.Span().add(
-		new Sidebar.Geometry( editor )
-	);
-	container.add( geometry );
-
-	var material = new UI.Span().add(
-		new Sidebar.Material( editor )
-	);
-	container.add( material );
-
-	//
-
-	function select( section ) {
-
-		objectTab.setClass( '' );
-		geometryTab.setClass( '' );
-		materialTab.setClass( '' );
-
-		object.setDisplay( 'none' );
-		geometry.setDisplay( 'none' );
-		material.setDisplay( 'none' );
-
-		switch ( section ) {
-			case 'OBJECT':
-				objectTab.setClass( 'selected' );
-				object.setDisplay( '' );
-				break;
-			case 'GEOMETRY':
-				geometryTab.setClass( 'selected' );
-				geometry.setDisplay( '' );
-				break;
-			case 'MATERIAL':
-				materialTab.setClass( 'selected' );
-				material.setDisplay( '' );
-				break;
-		}
-
-	}
-
-	select( 'OBJECT' );
+	container.addTab( 'object', strings.getKey( 'sidebar/properties/object' ), new Sidebar.Object( editor ) );
+	container.addTab( 'geometry', strings.getKey( 'sidebar/properties/geometry' ), new Sidebar.Geometry( editor ) );
+	container.addTab( 'material', strings.getKey( 'sidebar/properties/material' ), new Sidebar.Material( editor ) );
 
 	return container;
 

+ 4 - 56
editor/js/Sidebar.js

@@ -6,76 +6,24 @@ var Sidebar = function ( editor ) {
 
 	var strings = editor.strings;
 
-	var container = new UI.Panel();
+	var container = new UI.TabbedPanel();
 	container.setId( 'sidebar' );
 
-	//
-
-	var sceneTab = new UI.Text( strings.getKey( 'sidebar/scene' ) ).setTextTransform( 'uppercase' );
-	sceneTab.onClick( function () { select( 'SCENE' ) } );
-
-	var projectTab = new UI.Text( strings.getKey( 'sidebar/project' ) ).setTextTransform( 'uppercase' );
-	projectTab.onClick( function () { select( 'PROJECT' ) } );
-
-	var settingsTab = new UI.Text( strings.getKey( 'sidebar/settings' ) ).setTextTransform( 'uppercase' );
-	settingsTab.onClick( function () { select( 'SETTINGS' ) } );
-
-	var tabs = new UI.Div();
-	tabs.setId( 'tabs' );
-	tabs.add( sceneTab, projectTab, settingsTab );
-	container.add( tabs );
-
-	//
-
 	var scene = new UI.Span().add(
 		new Sidebar.Scene( editor ),
 		new Sidebar.Properties( editor ),
 		new Sidebar.Animation( editor ),
 		new Sidebar.Script( editor )
 	);
-	container.add( scene );
-
-	var project = new UI.Span().add(
-		new Sidebar.Project( editor )
-	);
-	container.add( project );
 
 	var settings = new UI.Span().add(
 		new Sidebar.Settings( editor ),
 		new Sidebar.History( editor )
 	);
-	container.add( settings );
-
-	//
-
-	function select( section ) {
-
-		sceneTab.setClass( '' );
-		projectTab.setClass( '' );
-		settingsTab.setClass( '' );
-
-		scene.setDisplay( 'none' );
-		project.setDisplay( 'none' );
-		settings.setDisplay( 'none' );
-
-		switch ( section ) {
-			case 'SCENE':
-				sceneTab.setClass( 'selected' );
-				scene.setDisplay( '' );
-				break;
-			case 'PROJECT':
-				projectTab.setClass( 'selected' );
-				project.setDisplay( '' );
-				break;
-			case 'SETTINGS':
-				settingsTab.setClass( 'selected' );
-				settings.setDisplay( '' );
-				break;
-		}
-
-	}
 
-	select( 'SCENE' );
+	container.addTab( 'scene', strings.getKey( 'sidebar/scene' ), scene );
+	container.addTab( 'project', strings.getKey( 'sidebar/project' ), new Sidebar.Project( editor ) );
+	container.addTab( 'settings', strings.getKey( 'sidebar/settings' ), settings );
 
 	return container;
 

+ 9 - 0
editor/js/Strings.js

@@ -41,6 +41,7 @@ var Strings = function ( config ) {
 			'menubar/add/cylinder': 'Cylinder',
 			'menubar/add/ring': 'Ring',
 			'menubar/add/sphere': 'Sphere',
+			'menubar/add/dodecahedron': 'Dodecahedron',
 			'menubar/add/icosahedron': 'Icosahedron',
 			'menubar/add/octahedron': 'Octahedron',
 			'menubar/add/tetrahedron': 'Tetrahedron',
@@ -148,6 +149,9 @@ var Strings = function ( config ) {
 			'sidebar/geometry/geometry/vertices': 'Vertices',
 			'sidebar/geometry/geometry/faces': 'Faces',
 
+			'sidebar/geometry/dodecahedron_geometry/radius': 'Radius',
+			'sidebar/geometry/dodecahedron_geometry/detail': 'Detail',
+
 			'sidebar/geometry/icosahedron_geometry/radius': 'Radius',
 			'sidebar/geometry/icosahedron_geometry/detail': 'Detail',
 
@@ -221,6 +225,7 @@ var Strings = function ( config ) {
 			'sidebar/material/depthPacking': 'Depth Packing',
 			'sidebar/material/roughness': 'Roughness',
 			'sidebar/material/metalness': 'Metalness',
+			'sidebar/material/sheen': 'Sheen',
 			'sidebar/material/emissive': 'Emissive',
 			'sidebar/material/specular': 'Specular',
 			'sidebar/material/shininess': 'Shininess',
@@ -337,6 +342,7 @@ var Strings = function ( config ) {
 			'menubar/add/cylinder': '圆柱体',
 			'menubar/add/ring': '环',
 			'menubar/add/sphere': '球体',
+			'menubar/add/dodecahedron': 'Dodecahedron',
 			'menubar/add/icosahedron': '二十面体',
 			'menubar/add/octahedron': '八面体',
 			'menubar/add/tetrahedron': '四面体',
@@ -434,6 +440,9 @@ var Strings = function ( config ) {
 			'sidebar/geometry/geometry/vertices': '顶点',
 			'sidebar/geometry/geometry/faces': '面',
 
+			'sidebar/geometry/dodecahedron_geometry/radius': '半径',
+			'sidebar/geometry/dodecahedron_geometry/detail': '面片分段',
+
 			'sidebar/geometry/icosahedron_geometry/radius': '半径',
 			'sidebar/geometry/icosahedron_geometry/detail': '面片分段',
 

+ 285 - 0
editor/js/libs/ui.js

@@ -74,6 +74,12 @@ UI.Element.prototype = {
 
 	},
 
+	getId: function ( id ) {
+
+		return this.dom.id;
+
+	},
+
 	setClass: function ( name ) {
 
 		this.dom.className = name;
@@ -82,6 +88,22 @@ UI.Element.prototype = {
 
 	},
 
+	addClass: function ( name ) {
+
+		this.dom.classList.add( name );
+
+		return this;
+
+	},
+
+	removeClass: function ( name ) {
+
+		this.dom.classList.remove( name );
+
+		return this;
+
+	},
+
 	setStyle: function ( style, array ) {
 
 		for ( var i = 0; i < array.length; i ++ ) {
@@ -995,3 +1017,266 @@ UI.Button.prototype.setLabel = function ( value ) {
 	return this;
 
 };
+
+
+// TabbedPanel
+
+UI.TabbedPanel = function ( ) {
+
+	UI.Element.call( this );
+
+	var dom = document.createElement('div');
+	
+	this.dom = dom;
+
+	this.setClass( 'TabbedPanel' );
+
+	this.tabs = [];
+	this.panels = [];
+
+	this.tabsDiv = new UI.Div();
+	this.tabsDiv.setClass( 'Tabs' );
+
+	this.panelsDiv = new UI.Div();
+	this.panelsDiv.setClass( 'Panels' );
+
+	this.add( this.tabsDiv );
+	this.add( this.panelsDiv );
+
+	this.selected = '';
+
+	return this;
+
+}
+
+UI.TabbedPanel.prototype = Object.create( UI.Element.prototype );
+UI.TabbedPanel.prototype.constructor = UI.TabbedPanel;
+
+UI.TabbedPanel.prototype.select = function ( id ) {
+
+	var tab;
+	var panel;
+	var scope = this;
+	
+	// Deselect current selection
+	if ( this.selected && this.selected.length ) {
+		tab = this.tabs.find( function ( item ) { return item.dom.id === scope.selected } );
+		panel = this.panels.find( function ( item ) { return item.dom.id === scope.selected } );
+
+		if ( tab ) {
+
+			tab.removeClass( 'selected' );
+
+		}
+
+		if( panel ) {
+
+			panel.setDisplay( 'none' );
+
+		}
+
+	}
+
+	tab = this.tabs.find( function ( item ) { return item.dom.id === id } );
+	panel = this.panels.find( function ( item ) { return item.dom.id === id } );
+	
+	if ( tab ) {
+
+		tab.addClass( 'selected' );
+
+	}
+
+	if( panel ) {
+
+		panel.setDisplay( '' );
+
+	}
+
+	this.selected = id;
+
+	return this;
+
+}
+
+UI.TabbedPanel.prototype.addTab = function ( id, label, items ) {
+
+	var tab = new UI.TabbedPanel.Tab( label, this );
+	tab.setId( id );
+	this.tabs.push( tab );
+	this.tabsDiv.add( tab );
+
+	var panel = new UI.Div();
+	panel.setId( id );
+	panel.add( items );
+	panel.setDisplay( 'none' );
+	this.panels.push( panel );
+	this.panelsDiv.add( panel );
+
+	this.select( id );
+
+}
+
+UI.TabbedPanel.Tab = function ( text, parent ) {
+
+	UI.Text.call( this, text );
+	this.parent = parent;
+
+	this.setClass( 'Tab' );
+
+	var scope = this;
+	this.dom.addEventListener( 'click', function ( event ) {
+
+		scope.parent.select( scope.dom.id );
+
+	} )
+
+	return this;
+
+}
+
+UI.TabbedPanel.Tab.prototype = Object.create( UI.Text.prototype );
+UI.TabbedPanel.Tab.prototype.constructor = UI.TabbedPanel.Tab;
+
+// Listbox
+UI.Listbox = function ( ) {
+
+	UI.Element.call( this );
+
+	var dom = document.createElement( 'div' );
+	dom.className = 'Listbox';
+	dom.tabIndex = 0;
+
+	this.dom = dom;
+	this.items = [];
+	this.listitems = [];
+	this.selectedIndex = 0;
+	this.selectedValue = null;
+
+	return this;
+
+}
+
+UI.Listbox.prototype = Object.create( UI.Element.prototype );
+UI.Listbox.prototype.constructor = UI.ListboxItem;
+
+UI.Listbox.prototype.setItems = function ( items ) {
+
+	if ( Array.isArray( items ) ) {
+
+		this.items = items;
+
+	}
+
+	this.render( );
+
+}
+
+UI.Listbox.prototype.render = function ( ) {
+
+	while( this.listitems.length ) {
+
+		var item = this.listitems[0];
+
+		item.dom.remove();
+
+		this.listitems.splice(0, 1);
+
+	}
+
+	for ( var i = 0; i < this.items.length; i ++ ) {
+
+		var item = this.items[i];
+
+		var listitem = new UI.Listbox.ListboxItem( this );
+		listitem.setId( item.id || `Listbox-${i}` );
+		listitem.setTextContent( item.name || item.type );
+		this.add( listitem );
+
+	}
+
+}
+
+// Assuming user passes valid list items
+UI.Listbox.prototype.add = function (  ) {
+
+	var items = Array.from( arguments );
+
+	this.listitems = this.listitems.concat( items );
+
+	UI.Element.prototype.add.apply( this, items );
+
+}
+
+UI.Listbox.prototype.selectIndex = function ( index ) {
+
+	if ( index >= 0 && index < this.items.length ) {
+
+		this.setValue( this.listitems[ index ].getId(  ) );
+
+	}
+
+	this.selectIndex = index;
+
+}
+
+UI.Listbox.prototype.getValue = function ( index ) {
+
+	return this.selectedValue;
+
+}
+
+UI.Listbox.prototype.setValue = function ( value ) {
+
+	for ( var i = 0; i < this.listitems.length; i ++ ) {
+
+		var element = this.listitems[ i ];
+
+		if ( element.getId( ) === value ) {
+
+			element.addClass( 'active' );
+
+		} else {
+			
+			element.removeClass( 'active' );
+
+		}
+
+	}
+
+	this.selectedValue = value;
+
+	var changeEvent = document.createEvent( 'HTMLEvents' );
+	changeEvent.initEvent( 'change', true, true );
+	this.dom.dispatchEvent( changeEvent );
+
+}
+
+// Listbox Item
+UI.Listbox.ListboxItem = function ( parent ) {
+
+	UI.Element.call( this );
+
+	var dom = document.createElement( 'div' );
+	dom.className = 'ListboxItem';
+
+	this.parent = parent;
+	this.dom = dom;
+
+	var scope = this;
+
+	function onClick ( ) {
+		
+		if( scope.parent ) {
+			scope.parent.setValue( scope.getId( ) );
+		}
+
+	}
+
+	dom.addEventListener( 'click', onClick, false );
+
+	return this;
+
+}
+
+UI.Listbox.ListboxItem.prototype = Object.create( UI.Element.prototype );
+UI.Listbox.ListboxItem.prototype.constructor = UI.Listbox.ListboxItem;

+ 0 - 3
editor/sw.js

@@ -15,8 +15,6 @@ const staticAssets = [
 	'../examples/js/libs/inflate.min.js',
 
 	'../examples/js/loaders/AMFLoader.js',
-	'../examples/js/loaders/AWDLoader.js',
-	'../examples/js/loaders/BabylonLoader.js',
 	'../examples/js/loaders/ColladaLoader.js',
 	'../examples/js/loaders/DRACOLoader.js',
 	'../examples/js/loaders/FBXLoader.js',
@@ -26,7 +24,6 @@ const staticAssets = [
 	'../examples/js/loaders/MD2Loader.js',
 	'../examples/js/loaders/OBJLoader.js',
 	'../examples/js/loaders/MTLLoader.js',
-	'../examples/js/loaders/PlayCanvasLoader.js',
 	'../examples/js/loaders/PLYLoader.js',
 	'../examples/js/loaders/STLLoader.js',
 	'../examples/js/loaders/SVGLoader.js',

+ 2 - 6
examples/files.js

@@ -52,7 +52,6 @@ var files = {
 		"webgl_interactive_cubes_gpu",
 		"webgl_interactive_instances_gpu",
 		"webgl_interactive_cubes_ortho",
-		"webgl_interactive_draggablecubes",
 		"webgl_interactive_lines",
 		"webgl_interactive_points",
 		"webgl_interactive_raycasting_points",
@@ -79,8 +78,6 @@ var files = {
 		"webgl_loader_amf",
 		"webgl_loader_assimp",
 		"webgl_loader_assimp2json",
-		"webgl_loader_awd",
-		"webgl_loader_babylon",
 		"webgl_loader_bvh",
 		"webgl_loader_collada",
 		"webgl_loader_collada_kinematics",
@@ -108,7 +105,6 @@ var files = {
 		"webgl_loader_obj2_options",
 		"webgl_loader_pcd",
 		"webgl_loader_pdb",
-		"webgl_loader_playcanvas",
 		"webgl_loader_ply",
 		"webgl_loader_prwm",
 		"webgl_loader_sea3d",
@@ -338,6 +334,7 @@ var files = {
 		"webvr_cubes",
 		"webvr_dragging",
 		"webvr_lorenzattractor",
+		"webvr_multiview",
 		"webvr_panorama",
 		"webvr_paint",
 		"webvr_rollercoaster",
@@ -360,19 +357,18 @@ var files = {
 		"misc_animation_keys",
 		"misc_boxselection",
 		"misc_controls_deviceorientation",
+		"misc_controls_drag",
 		"misc_controls_fly",
 		"misc_controls_map",
 		"misc_controls_orbit",
 		"misc_controls_pointerlock",
 		"misc_controls_trackball",
-		"misc_controls_trackball_orthographic",
 		"misc_controls_transform",
 		"misc_exporter_collada",
 		"misc_exporter_draco",
 		"misc_exporter_gltf",
 		"misc_exporter_obj",
 		"misc_exporter_stl",
-		"misc_fps",
 		"misc_lookat",
 	],
 	"css2d": [

+ 6 - 2
examples/js/controls/FirstPersonControls.js

@@ -10,6 +10,8 @@ THREE.FirstPersonControls = function ( object, domElement ) {
 
 	this.domElement = ( domElement !== undefined ) ? domElement : document;
 
+	// API
+
 	this.enabled = true;
 
 	this.movementSpeed = 1.0;
@@ -29,6 +31,10 @@ THREE.FirstPersonControls = function ( object, domElement ) {
 	this.verticalMin = 0;
 	this.verticalMax = Math.PI;
 
+	this.mouseDragOn = false;
+
+	// internals
+
 	this.autoSpeedFactor = 0.0;
 
 	this.mouseX = 0;
@@ -39,8 +45,6 @@ THREE.FirstPersonControls = function ( object, domElement ) {
 	this.moveLeft = false;
 	this.moveRight = false;
 
-	this.mouseDragOn = false;
-
 	this.viewHalfX = 0;
 	this.viewHalfY = 0;
 

+ 0 - 644
examples/js/controls/OrthographicTrackballControls.js

@@ -1,644 +0,0 @@
-/**
- * @author Eberhard Graether / http://egraether.com/
- * @author Mark Lundin 	/ http://mark-lundin.com
- * @author Patrick Fuller / http://patrick-fuller.com
- * @author Max Smolens / https://github.com/msmolens
- */
-
-THREE.OrthographicTrackballControls = function ( object, domElement ) {
-
-	var _this = this;
-	var STATE = { NONE: - 1, ROTATE: 0, ZOOM: 1, PAN: 2, TOUCH_ROTATE: 3, TOUCH_ZOOM_PAN: 4 };
-
-	this.object = object;
-	this.domElement = ( domElement !== undefined ) ? domElement : document;
-
-	// API
-
-	this.enabled = true;
-
-	this.screen = { left: 0, top: 0, width: 0, height: 0 };
-
-	this.radius = 0;
-
-	this.rotateSpeed = 1.0;
-	this.zoomSpeed = 1.2;
-
-	this.noRotate = false;
-	this.noZoom = false;
-	this.noPan = false;
-	this.noRoll = false;
-
-	this.staticMoving = false;
-	this.dynamicDampingFactor = 0.2;
-
-	this.keys = [ 65 /*A*/, 83 /*S*/, 68 /*D*/ ];
-
-	// internals
-
-	this.target = new THREE.Vector3();
-
-	var EPS = 0.000001;
-
-	var _changed = true;
-
-	var _state = STATE.NONE,
-		_prevState = STATE.NONE,
-
-		_eye = new THREE.Vector3(),
-
-		_rotateStart = new THREE.Vector3(),
-		_rotateEnd = new THREE.Vector3(),
-
-		_zoomStart = new THREE.Vector2(),
-		_zoomEnd = new THREE.Vector2(),
-
-		_touchZoomDistanceStart = 0,
-		_touchZoomDistanceEnd = 0,
-
-		_panStart = new THREE.Vector2(),
-		_panEnd = new THREE.Vector2();
-
-	// for reset
-
-	this.target0 = this.target.clone();
-	this.position0 = this.object.position.clone();
-	this.up0 = this.object.up.clone();
-
-	this.left0 = this.object.left;
-	this.right0 = this.object.right;
-	this.top0 = this.object.top;
-	this.bottom0 = this.object.bottom;
-
-	// events
-
-	var changeEvent = { type: 'change' };
-	var startEvent = { type: 'start' };
-	var endEvent = { type: 'end' };
-
-
-	// methods
-
-	this.handleResize = function () {
-
-		if ( this.domElement === document ) {
-
-			this.screen.left = 0;
-			this.screen.top = 0;
-			this.screen.width = window.innerWidth;
-			this.screen.height = window.innerHeight;
-
-		} else {
-
-			var box = this.domElement.getBoundingClientRect();
-			// adjustments come from similar code in the jquery offset() function
-			var d = this.domElement.ownerDocument.documentElement;
-			this.screen.left = box.left + window.pageXOffset - d.clientLeft;
-			this.screen.top = box.top + window.pageYOffset - d.clientTop;
-			this.screen.width = box.width;
-			this.screen.height = box.height;
-
-		}
-
-		this.radius = 0.5 * Math.min( this.screen.width, this.screen.height );
-
-		this.left0 = this.object.left;
-		this.right0 = this.object.right;
-		this.top0 = this.object.top;
-		this.bottom0 = this.object.bottom;
-
-	};
-
-	var getMouseOnScreen = ( function () {
-
-		var vector = new THREE.Vector2();
-
-		return function getMouseOnScreen( pageX, pageY ) {
-
-			vector.set(
-				( pageX - _this.screen.left ) / _this.screen.width,
-				( pageY - _this.screen.top ) / _this.screen.height
-			);
-
-			return vector;
-
-		};
-
-	}() );
-
-	var getMouseProjectionOnBall = ( function () {
-
-		var vector = new THREE.Vector3();
-		var objectUp = new THREE.Vector3();
-		var mouseOnBall = new THREE.Vector3();
-
-		return function getMouseProjectionOnBall( pageX, pageY ) {
-
-			mouseOnBall.set(
-				( pageX - _this.screen.width * 0.5 - _this.screen.left ) / _this.radius,
-				( _this.screen.height * 0.5 + _this.screen.top - pageY ) / _this.radius,
-				0.0
-			);
-
-			var length = mouseOnBall.length();
-
-			if ( _this.noRoll ) {
-
-				if ( length < Math.SQRT1_2 ) {
-
-					mouseOnBall.z = Math.sqrt( 1.0 - length * length );
-
-				} else {
-
-					mouseOnBall.z = .5 / length;
-
-				}
-
-			} else if ( length > 1.0 ) {
-
-				mouseOnBall.normalize();
-
-			} else {
-
-				mouseOnBall.z = Math.sqrt( 1.0 - length * length );
-
-			}
-
-			_eye.copy( _this.object.position ).sub( _this.target );
-
-			vector.copy( _this.object.up ).setLength( mouseOnBall.y );
-			vector.add( objectUp.copy( _this.object.up ).cross( _eye ).setLength( mouseOnBall.x ) );
-			vector.add( _eye.setLength( mouseOnBall.z ) );
-
-			return vector;
-
-		};
-
-	}() );
-
-	this.rotateCamera = ( function () {
-
-		var axis = new THREE.Vector3(),
-			quaternion = new THREE.Quaternion();
-
-
-		return function rotateCamera() {
-
-			var angle = Math.acos( _rotateStart.dot( _rotateEnd ) / _rotateStart.length() / _rotateEnd.length() );
-
-			if ( angle ) {
-
-				axis.crossVectors( _rotateStart, _rotateEnd ).normalize();
-
-				angle *= _this.rotateSpeed;
-
-				quaternion.setFromAxisAngle( axis, - angle );
-
-				_eye.applyQuaternion( quaternion );
-				_this.object.up.applyQuaternion( quaternion );
-
-				_rotateEnd.applyQuaternion( quaternion );
-
-				if ( _this.staticMoving ) {
-
-					_rotateStart.copy( _rotateEnd );
-
-				} else {
-
-					quaternion.setFromAxisAngle( axis, angle * ( _this.dynamicDampingFactor - 1.0 ) );
-					_rotateStart.applyQuaternion( quaternion );
-
-				}
-
-				_changed = true;
-
-			}
-
-		};
-
-	}() );
-
-	this.zoomCamera = function () {
-
-		if ( _state === STATE.TOUCH_ZOOM_PAN ) {
-
-			var factor = _touchZoomDistanceEnd / _touchZoomDistanceStart;
-			_touchZoomDistanceStart = _touchZoomDistanceEnd;
-
-			_this.object.zoom *= factor;
-
-			_changed = true;
-
-		} else {
-
-			var factor = 1.0 + ( _zoomEnd.y - _zoomStart.y ) * _this.zoomSpeed;
-
-			if ( Math.abs( factor - 1.0 ) > EPS && factor > 0.0 ) {
-
-				_this.object.zoom /= factor;
-
-				if ( _this.staticMoving ) {
-
-					_zoomStart.copy( _zoomEnd );
-
-				} else {
-
-					_zoomStart.y += ( _zoomEnd.y - _zoomStart.y ) * this.dynamicDampingFactor;
-
-				}
-
-				_changed = true;
-
-			}
-
-		}
-
-	};
-
-	this.panCamera = ( function () {
-
-		var mouseChange = new THREE.Vector2(),
-			objectUp = new THREE.Vector3(),
-			pan = new THREE.Vector3();
-
-		return function panCamera() {
-
-			mouseChange.copy( _panEnd ).sub( _panStart );
-
-			if ( mouseChange.lengthSq() > EPS ) {
-
-				// Scale movement to keep clicked/dragged position under cursor
-				var scale_x = ( _this.object.right - _this.object.left ) / _this.object.zoom;
-				var scale_y = ( _this.object.top - _this.object.bottom ) / _this.object.zoom;
-				mouseChange.x *= scale_x;
-				mouseChange.y *= scale_y;
-
-				pan.copy( _eye ).cross( _this.object.up ).setLength( mouseChange.x );
-				pan.add( objectUp.copy( _this.object.up ).setLength( mouseChange.y ) );
-
-				_this.object.position.add( pan );
-				_this.target.add( pan );
-
-				if ( _this.staticMoving ) {
-
-					_panStart.copy( _panEnd );
-
-				} else {
-
-					_panStart.add( mouseChange.subVectors( _panEnd, _panStart ).multiplyScalar( _this.dynamicDampingFactor ) );
-
-				}
-
-				_changed = true;
-
-			}
-
-		};
-
-	}() );
-
-	this.update = function () {
-
-		_eye.subVectors( _this.object.position, _this.target );
-
-		if ( ! _this.noRotate ) {
-
-			_this.rotateCamera();
-
-		}
-
-		if ( ! _this.noZoom ) {
-
-			_this.zoomCamera();
-
-			if ( _changed ) {
-
-				_this.object.updateProjectionMatrix();
-
-			}
-
-		}
-
-		if ( ! _this.noPan ) {
-
-			_this.panCamera();
-
-		}
-
-		_this.object.position.addVectors( _this.target, _eye );
-
-		_this.object.lookAt( _this.target );
-
-		if ( _changed ) {
-
-			_this.dispatchEvent( changeEvent );
-
-			_changed = false;
-
-		}
-
-	};
-
-	this.reset = function () {
-
-		_state = STATE.NONE;
-		_prevState = STATE.NONE;
-
-		_this.target.copy( _this.target0 );
-		_this.object.position.copy( _this.position0 );
-		_this.object.up.copy( _this.up0 );
-
-		_eye.subVectors( _this.object.position, _this.target );
-
-		_this.object.left = _this.left0;
-		_this.object.right = _this.right0;
-		_this.object.top = _this.top0;
-		_this.object.bottom = _this.bottom0;
-
-		_this.object.lookAt( _this.target );
-
-		_this.dispatchEvent( changeEvent );
-
-		_changed = false;
-
-	};
-
-	// listeners
-
-	function keydown( event ) {
-
-		if ( _this.enabled === false ) return;
-
-		window.removeEventListener( 'keydown', keydown );
-
-		_prevState = _state;
-
-		if ( _state !== STATE.NONE ) {
-
-			return;
-
-		} else if ( event.keyCode === _this.keys[ STATE.ROTATE ] && ! _this.noRotate ) {
-
-			_state = STATE.ROTATE;
-
-		} else if ( event.keyCode === _this.keys[ STATE.ZOOM ] && ! _this.noZoom ) {
-
-			_state = STATE.ZOOM;
-
-		} else if ( event.keyCode === _this.keys[ STATE.PAN ] && ! _this.noPan ) {
-
-			_state = STATE.PAN;
-
-		}
-
-	}
-
-	function keyup() {
-
-		if ( _this.enabled === false ) return;
-
-		_state = _prevState;
-
-		window.addEventListener( 'keydown', keydown, false );
-
-	}
-
-	function mousedown( event ) {
-
-		if ( _this.enabled === false ) return;
-
-		event.preventDefault();
-		event.stopPropagation();
-
-		if ( _state === STATE.NONE ) {
-
-			_state = event.button;
-
-		}
-
-		if ( _state === STATE.ROTATE && ! _this.noRotate ) {
-
-			_rotateStart.copy( getMouseProjectionOnBall( event.pageX, event.pageY ) );
-			_rotateEnd.copy( _rotateStart );
-
-		} else if ( _state === STATE.ZOOM && ! _this.noZoom ) {
-
-			_zoomStart.copy( getMouseOnScreen( event.pageX, event.pageY ) );
-			_zoomEnd.copy( _zoomStart );
-
-		} else if ( _state === STATE.PAN && ! _this.noPan ) {
-
-			_panStart.copy( getMouseOnScreen( event.pageX, event.pageY ) );
-			_panEnd.copy( _panStart );
-
-		}
-
-		document.addEventListener( 'mousemove', mousemove, false );
-		document.addEventListener( 'mouseup', mouseup, false );
-
-		_this.dispatchEvent( startEvent );
-
-	}
-
-	function mousemove( event ) {
-
-		if ( _this.enabled === false ) return;
-
-		event.preventDefault();
-		event.stopPropagation();
-
-		if ( _state === STATE.ROTATE && ! _this.noRotate ) {
-
-			_rotateEnd.copy( getMouseProjectionOnBall( event.pageX, event.pageY ) );
-
-		} else if ( _state === STATE.ZOOM && ! _this.noZoom ) {
-
-			_zoomEnd.copy( getMouseOnScreen( event.pageX, event.pageY ) );
-
-		} else if ( _state === STATE.PAN && ! _this.noPan ) {
-
-			_panEnd.copy( getMouseOnScreen( event.pageX, event.pageY ) );
-
-		}
-
-	}
-
-	function mouseup( event ) {
-
-		if ( _this.enabled === false ) return;
-
-		event.preventDefault();
-		event.stopPropagation();
-
-		_state = STATE.NONE;
-
-		document.removeEventListener( 'mousemove', mousemove );
-		document.removeEventListener( 'mouseup', mouseup );
-		_this.dispatchEvent( endEvent );
-
-	}
-
-	function mousewheel( event ) {
-
-		if ( _this.enabled === false ) return;
-
-		event.preventDefault();
-		event.stopPropagation();
-
-		switch ( event.deltaMode ) {
-
-			case 2:
-				// Zoom in pages
-				_zoomStart.y -= event.deltaY * 0.025;
-				break;
-
-			case 1:
-				// Zoom in lines
-				_zoomStart.y -= event.deltaY * 0.01;
-				break;
-
-			default:
-				// undefined, 0, assume pixels
-				_zoomStart.y -= event.deltaY * 0.00025;
-				break;
-
-		}
-
-		_this.dispatchEvent( startEvent );
-		_this.dispatchEvent( endEvent );
-
-	}
-
-	function touchstart( event ) {
-
-		if ( _this.enabled === false ) return;
-
-		switch ( event.touches.length ) {
-
-			case 1:
-				_state = STATE.TOUCH_ROTATE;
-				_rotateStart.copy( getMouseProjectionOnBall( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY ) );
-				_rotateEnd.copy( _rotateStart );
-				break;
-
-			case 2:
-				_state = STATE.TOUCH_ZOOM_PAN;
-				var dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX;
-				var dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY;
-				_touchZoomDistanceEnd = _touchZoomDistanceStart = Math.sqrt( dx * dx + dy * dy );
-
-				var x = ( event.touches[ 0 ].pageX + event.touches[ 1 ].pageX ) / 2;
-				var y = ( event.touches[ 0 ].pageY + event.touches[ 1 ].pageY ) / 2;
-				_panStart.copy( getMouseOnScreen( x, y ) );
-				_panEnd.copy( _panStart );
-				break;
-
-			default:
-				_state = STATE.NONE;
-
-		}
-		_this.dispatchEvent( startEvent );
-
-	}
-
-	function touchmove( event ) {
-
-		if ( _this.enabled === false ) return;
-
-		event.preventDefault();
-		event.stopPropagation();
-
-		switch ( event.touches.length ) {
-
-			case 1:
-				_rotateEnd.copy( getMouseProjectionOnBall( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY ) );
-				break;
-
-			case 2:
-				var dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX;
-				var dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY;
-				_touchZoomDistanceEnd = Math.sqrt( dx * dx + dy * dy );
-
-				var x = ( event.touches[ 0 ].pageX + event.touches[ 1 ].pageX ) / 2;
-				var y = ( event.touches[ 0 ].pageY + event.touches[ 1 ].pageY ) / 2;
-				_panEnd.copy( getMouseOnScreen( x, y ) );
-				break;
-
-			default:
-				_state = STATE.NONE;
-
-		}
-
-	}
-
-	function touchend( event ) {
-
-		if ( _this.enabled === false ) return;
-
-		switch ( event.touches.length ) {
-
-			case 1:
-				_rotateEnd.copy( getMouseProjectionOnBall( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY ) );
-				_rotateStart.copy( _rotateEnd );
-				break;
-
-			case 2:
-				_touchZoomDistanceStart = _touchZoomDistanceEnd = 0;
-
-				var x = ( event.touches[ 0 ].pageX + event.touches[ 1 ].pageX ) / 2;
-				var y = ( event.touches[ 0 ].pageY + event.touches[ 1 ].pageY ) / 2;
-				_panEnd.copy( getMouseOnScreen( x, y ) );
-				_panStart.copy( _panEnd );
-				break;
-
-		}
-
-		_state = STATE.NONE;
-		_this.dispatchEvent( endEvent );
-
-	}
-
-	function contextmenu( event ) {
-
-		event.preventDefault();
-
-	}
-
-	this.dispose = function () {
-
-		this.domElement.removeEventListener( 'contextmenu', contextmenu, false );
-		this.domElement.removeEventListener( 'mousedown', mousedown, false );
-		this.domElement.removeEventListener( 'wheel', mousewheel, false );
-
-		this.domElement.removeEventListener( 'touchstart', touchstart, false );
-		this.domElement.removeEventListener( 'touchend', touchend, false );
-		this.domElement.removeEventListener( 'touchmove', touchmove, false );
-
-		document.removeEventListener( 'mousemove', mousemove, false );
-		document.removeEventListener( 'mouseup', mouseup, false );
-
-		window.removeEventListener( 'keydown', keydown, false );
-		window.removeEventListener( 'keyup', keyup, false );
-
-	};
-
-	this.domElement.addEventListener( 'contextmenu', contextmenu, false );
-	this.domElement.addEventListener( 'mousedown', mousedown, false );
-	this.domElement.addEventListener( 'wheel', mousewheel, false );
-
-	this.domElement.addEventListener( 'touchstart', touchstart, false );
-	this.domElement.addEventListener( 'touchend', touchend, false );
-	this.domElement.addEventListener( 'touchmove', touchmove, false );
-
-	window.addEventListener( 'keydown', keydown, false );
-	window.addEventListener( 'keyup', keyup, false );
-
-	this.handleResize();
-
-	// force an update at start
-	this.update();
-
-};
-
-THREE.OrthographicTrackballControls.prototype = Object.create( THREE.EventDispatcher.prototype );
-THREE.OrthographicTrackballControls.prototype.constructor = THREE.OrthographicTrackballControls;

+ 71 - 7
examples/js/controls/TrackballControls.js

@@ -44,6 +44,7 @@ THREE.TrackballControls = function ( object, domElement ) {
 	var EPS = 0.000001;
 
 	var lastPosition = new THREE.Vector3();
+	var lastZoom = 1;
 
 	var _state = STATE.NONE,
 		_keyState = STATE.NONE,
@@ -70,6 +71,7 @@ THREE.TrackballControls = function ( object, domElement ) {
 	this.target0 = this.target.clone();
 	this.position0 = this.object.position.clone();
 	this.up0 = this.object.up.clone();
+	this.zoom0 = this.object.zoom;
 
 	// events
 
@@ -201,7 +203,21 @@ THREE.TrackballControls = function ( object, domElement ) {
 
 			factor = _touchZoomDistanceStart / _touchZoomDistanceEnd;
 			_touchZoomDistanceStart = _touchZoomDistanceEnd;
-			_eye.multiplyScalar( factor );
+
+			if ( _this.object.isPerspectiveCamera ) {
+
+				_eye.multiplyScalar( factor );
+
+			} else if ( _this.object.isOrthographicCamera ) {
+
+				_this.object.zoom *= factor;
+				_this.object.updateProjectionMatrix();
+
+			} else {
+
+				console.warn( 'THREE.TrackballControls: Unsupported camera type' );
+
+			}
 
 		} else {
 
@@ -209,7 +225,20 @@ THREE.TrackballControls = function ( object, domElement ) {
 
 			if ( factor !== 1.0 && factor > 0.0 ) {
 
-				_eye.multiplyScalar( factor );
+				if ( _this.object.isPerspectiveCamera ) {
+
+					_eye.multiplyScalar( factor );
+
+				} else if ( _this.object.isOrthographicCamera ) {
+
+					_this.object.zoom /= factor;
+					_this.object.updateProjectionMatrix();
+
+				} else {
+
+					console.warn( 'THREE.TrackballControls: Unsupported camera type' );
+
+				}
 
 			}
 
@@ -239,6 +268,16 @@ THREE.TrackballControls = function ( object, domElement ) {
 
 			if ( mouseChange.lengthSq() ) {
 
+				if ( _this.object.isOrthographicCamera ) {
+
+					var scale_x = ( _this.object.right - _this.object.left ) / _this.object.zoom / _this.domElement.clientWidth;
+					var scale_y = ( _this.object.top - _this.object.bottom ) / _this.object.zoom / _this.domElement.clientWidth;
+
+					mouseChange.x *= scale_x;
+					mouseChange.y *= scale_y;
+
+				}
+
 				mouseChange.multiplyScalar( _eye.length() * _this.panSpeed );
 
 				pan.copy( _eye ).cross( _this.object.up ).setLength( mouseChange.x );
@@ -309,15 +348,36 @@ THREE.TrackballControls = function ( object, domElement ) {
 
 		_this.object.position.addVectors( _this.target, _eye );
 
-		_this.checkDistances();
+		if ( _this.object.isPerspectiveCamera ) {
 
-		_this.object.lookAt( _this.target );
+			_this.checkDistances();
 
-		if ( lastPosition.distanceToSquared( _this.object.position ) > EPS ) {
+			_this.object.lookAt( _this.target );
+
+			if ( lastPosition.distanceToSquared( _this.object.position ) > EPS ) {
+
+				_this.dispatchEvent( changeEvent );
+
+				lastPosition.copy( _this.object.position );
+
+			}
 
-			_this.dispatchEvent( changeEvent );
+		} else if ( _this.object.isOrthographicCamera ) {
 
-			lastPosition.copy( _this.object.position );
+			_this.object.lookAt( _this.target );
+
+			if ( lastPosition.distanceToSquared( _this.object.position ) > EPS || lastZoom !== _this.object.zoom ) {
+
+				_this.dispatchEvent( changeEvent );
+
+				lastPosition.copy( _this.object.position );
+				lastZoom = _this.object.zoom;
+
+			}
+
+		} else {
+
+			console.warn( 'THREE.TrackballControls: Unsupported camera type' );
 
 		}
 
@@ -331,6 +391,9 @@ THREE.TrackballControls = function ( object, domElement ) {
 		_this.target.copy( _this.target0 );
 		_this.object.position.copy( _this.position0 );
 		_this.object.up.copy( _this.up0 );
+		_this.object.zoom = _this.zoom0;
+
+		_this.object.updateProjectionMatrix();
 
 		_eye.subVectors( _this.object.position, _this.target );
 
@@ -339,6 +402,7 @@ THREE.TrackballControls = function ( object, domElement ) {
 		_this.dispatchEvent( changeEvent );
 
 		lastPosition.copy( _this.object.position );
+		lastZoom = _this.object.zoom;
 
 	};
 

+ 0 - 4
examples/js/lights/RectAreaLightUniformsLib.js

@@ -30,12 +30,8 @@ THREE.RectAreaLightUniformsLib = {
 		// data textures
 
 		var ltc_1 = new THREE.DataTexture( new Float32Array( LTC_MAT_1 ), 64, 64, THREE.RGBAFormat, THREE.FloatType, THREE.UVMapping, THREE.ClampToEdgeWrapping, THREE.ClampToEdgeWrapping, THREE.LinearFilter, THREE.NearestFilter, 1 );
-
 		var ltc_2 = new THREE.DataTexture( new Float32Array( LTC_MAT_2 ), 64, 64, THREE.RGBAFormat, THREE.FloatType, THREE.UVMapping, THREE.ClampToEdgeWrapping, THREE.ClampToEdgeWrapping, THREE.LinearFilter, THREE.NearestFilter, 1 );
 
-		ltc_1.needsUpdate = true;
-		ltc_2.needsUpdate = true;
-
 		THREE.UniformsLib.LTC_1 = ltc_1;
 		THREE.UniformsLib.LTC_2 = ltc_2;
 

+ 0 - 1219
examples/js/loaders/AWDLoader.js

@@ -1,1219 +0,0 @@
-/**
- * Author: Pierre Lepers
- * Date: 09/12/2013 17:21
- */
-
-THREE.AWDLoader = ( function () {
-
-	var //UNCOMPRESSED = 0,
-		//DEFLATE = 1,
-		//LZMA = 2,
-
-		AWD_FIELD_INT8 = 1,
-		AWD_FIELD_INT16 = 2,
-		AWD_FIELD_INT32 = 3,
-		AWD_FIELD_UINT8 = 4,
-		AWD_FIELD_UINT16 = 5,
-		AWD_FIELD_UINT32 = 6,
-		AWD_FIELD_FLOAT32 = 7,
-		AWD_FIELD_FLOAT64 = 8,
-		AWD_FIELD_BOOL = 21,
-		//AWD_FIELD_COLOR = 22,
-		AWD_FIELD_BADDR = 23,
-		//AWD_FIELD_STRING = 31,
-		//AWD_FIELD_BYTEARRAY = 32,
-		AWD_FIELD_VECTOR2x1 = 41,
-		AWD_FIELD_VECTOR3x1 = 42,
-		AWD_FIELD_VECTOR4x1 = 43,
-		AWD_FIELD_MTX3x2 = 44,
-		AWD_FIELD_MTX3x3 = 45,
-		AWD_FIELD_MTX4x3 = 46,
-		AWD_FIELD_MTX4x4 = 47,
-
-		BOOL = 21,
-		//COLOR = 22,
-		BADDR = 23,
-
-		//INT8 = 1,
-		//INT16 = 2,
-		//INT32 = 3,
-		UINT8 = 4,
-		UINT16 = 5,
-		//UINT32 = 6,
-		FLOAT32 = 7,
-		FLOAT64 = 8;
-
-	var littleEndian = true;
-
-	function Block() {
-
-		this.id = 0;
-		this.data = null;
-		this.namespace = 0;
-		this.flags = 0;
-
-	}
-
-	function AWDProperties() {}
-
-	AWDProperties.prototype = {
-		set: function ( key, value ) {
-
-			this[ key ] = value;
-
-		},
-
-		get: function ( key, fallback ) {
-
-			if ( this.hasOwnProperty( key ) ) {
-
-				return this[ key ];
-
-			} else {
-
-				return fallback;
-
-			}
-
-		}
-	};
-
-	var AWDLoader = function ( manager ) {
-
-		THREE.Loader.call( this, manager );
-
-		this.trunk = new THREE.Object3D();
-
-		this.materialFactory = undefined;
-
-		this._url = '';
-		this._baseDir = '';
-
-		this._data = undefined;
-		this._ptr = 0;
-
-		this._version = [];
-		this._streaming = false;
-		this._optimized_for_accuracy = false;
-		this._compression = 0;
-		this._bodylen = 0xFFFFFFFF;
-
-		this._blocks = [ new Block() ];
-
-		this._accuracyMatrix = false;
-		this._accuracyGeo = false;
-		this._accuracyProps = false;
-
-	};
-
-	AWDLoader.prototype = Object.assign( Object.create( THREE.Loader.prototype ), {
-
-		constructor: AWDLoader,
-
-		load: function ( url, onLoad, onProgress, onError ) {
-
-			var scope = this;
-
-			this._url = url;
-			this._baseDir = url.substr( 0, url.lastIndexOf( '/' ) + 1 );
-
-			var loader = new THREE.FileLoader( this.manager );
-			loader.setPath( this.path );
-			loader.setResponseType( 'arraybuffer' );
-			loader.load( url, function ( text ) {
-
-				onLoad( scope.parse( text ) );
-
-			}, onProgress, onError );
-
-		},
-
-		parse: function ( data ) {
-
-			var blen = data.byteLength;
-
-			this._ptr = 0;
-			this._data = new DataView( data );
-
-			this._parseHeader( );
-
-			if ( this._compression != 0 ) {
-
-				console.error( 'compressed AWD not supported' );
-
-			}
-
-			if ( ! this._streaming && this._bodylen != data.byteLength - this._ptr ) {
-
-				console.error( 'AWDLoader: body len does not match file length', this._bodylen, blen - this._ptr );
-
-			}
-
-			while ( this._ptr < blen ) {
-
-				this.parseNextBlock();
-
-			}
-
-			return this.trunk;
-
-		},
-
-		parseNextBlock: function () {
-
-			var assetData,
-				block,
-				blockId = this.readU32(),
-				ns = this.readU8(),
-				type = this.readU8(),
-				flags = this.readU8(),
-				len = this.readU32();
-
-
-			switch ( type ) {
-
-				case 1:
-					assetData = this.parseMeshData();
-					break;
-
-				case 22:
-					assetData = this.parseContainer();
-					break;
-
-				case 23:
-					assetData = this.parseMeshInstance();
-					break;
-
-				case 81:
-					assetData = this.parseMaterial();
-					break;
-
-				case 82:
-					assetData = this.parseTexture();
-					break;
-
-				case 101:
-					assetData = this.parseSkeleton();
-					break;
-
-				case 112:
-					assetData = this.parseMeshPoseAnimation( false );
-					break;
-
-				case 113:
-					assetData = this.parseVertexAnimationSet();
-					break;
-
-				case 102:
-					assetData = this.parseSkeletonPose();
-					break;
-
-				case 103:
-					assetData = this.parseSkeletonAnimation();
-					break;
-
-				case 122:
-					assetData = this.parseAnimatorSet();
-					break;
-
-				default:
-					//debug('Ignoring block!',type, len);
-					this._ptr += len;
-					break;
-
-			}
-
-
-			// Store block reference for later use
-			this._blocks[ blockId ] = block = new Block();
-			block.data = assetData;
-			block.id = blockId;
-			block.namespace = ns;
-			block.flags = flags;
-
-
-		},
-
-		_parseHeader: function () {
-
-			var version = this._version,
-				awdmagic = ( this.readU8() << 16 ) | ( this.readU8() << 8 ) | this.readU8();
-
-			if ( awdmagic != 4282180 )
-				throw new Error( "AWDLoader - bad magic" );
-
-			version[ 0 ] = this.readU8();
-			version[ 1 ] = this.readU8();
-
-			var flags = this.readU16();
-
-			this._streaming = ( flags & 0x1 ) == 0x1;
-
-			if ( ( version[ 0 ] === 2 ) && ( version[ 1 ] === 1 ) ) {
-
-				this._accuracyMatrix = ( flags & 0x2 ) === 0x2;
-				this._accuracyGeo = ( flags & 0x4 ) === 0x4;
-				this._accuracyProps = ( flags & 0x8 ) === 0x8;
-
-			}
-
-			this._geoNrType = this._accuracyGeo ? FLOAT64 : FLOAT32;
-			this._matrixNrType = this._accuracyMatrix ? FLOAT64 : FLOAT32;
-			this._propsNrType = this._accuracyProps ? FLOAT64 : FLOAT32;
-
-			this._optimized_for_accuracy = ( flags & 0x2 ) === 0x2;
-
-			this._compression = this.readU8();
-			this._bodylen = this.readU32();
-
-		},
-
-		parseContainer: function () {
-
-			var parent,
-				ctr = new THREE.Object3D(),
-				par_id = this.readU32(),
-				mtx = this.parseMatrix4();
-
-			ctr.name = this.readUTF();
-			ctr.applyMatrix( mtx );
-
-			parent = this._blocks[ par_id ].data || this.trunk;
-			parent.add( ctr );
-
-			this.parseProperties( {
-				1: this._matrixNrType,
-				2: this._matrixNrType,
-				3: this._matrixNrType,
-				4: UINT8
-			} );
-
-			ctr.extra = this.parseUserAttributes();
-
-			return ctr;
-
-		},
-
-		parseMeshInstance: function () {
-
-			var name,
-				mesh, geometries, meshLen, meshes,
-				par_id, data_id,
-				mtx,
-				materials, mat, mat_id,
-				num_materials,
-				parent,
-				i;
-
-			par_id = this.readU32();
-			mtx = this.parseMatrix4();
-			name = this.readUTF();
-			data_id = this.readU32();
-			num_materials = this.readU16();
-
-			geometries = this.getBlock( data_id );
-
-			materials = [];
-
-			for ( i = 0; i < num_materials; i ++ ) {
-
-				mat_id = this.readU32();
-				mat = this.getBlock( mat_id );
-				materials.push( mat );
-
-			}
-
-			meshLen = geometries.length;
-			meshes = [];
-
-			// TODO : BufferGeometry don't support "geometryGroups" for now.
-			// so we create sub meshes for each groups
-			if ( meshLen > 1 ) {
-
-				mesh = new THREE.Object3D();
-				for ( i = 0; i < meshLen; i ++ ) {
-
-					var sm = new THREE.Mesh( geometries[ i ] );
-					meshes.push( sm );
-					mesh.add( sm );
-
-				}
-
-			} else {
-
-				mesh = new THREE.Mesh( geometries[ 0 ] );
-				meshes.push( mesh );
-
-			}
-
-			mesh.applyMatrix( mtx );
-			mesh.name = name;
-
-
-			parent = this.getBlock( par_id ) || this.trunk;
-			parent.add( mesh );
-
-
-			var matLen = materials.length;
-			var maxLen = Math.max( meshLen, matLen );
-			for ( i = 0; i < maxLen; i ++ )
-				meshes[ i % meshLen ].material = materials[ i % matLen ];
-
-
-			// Ignore for now
-			this.parseProperties( null );
-			mesh.extra = this.parseUserAttributes();
-
-			return mesh;
-
-		},
-
-		parseMaterial: function () {
-
-			var name,
-				type,
-				props,
-				mat,
-				attributes,
-				num_methods,
-				methods_parsed;
-
-			name = this.readUTF();
-			type = this.readU8();
-			num_methods = this.readU8();
-
-			//log( "AWDLoader parseMaterial ",name )
-
-			// Read material numerical properties
-			// (1=color, 2=bitmap url, 11=alpha_blending, 12=alpha_threshold, 13=repeat)
-			props = this.parseProperties( {
-				1: AWD_FIELD_INT32,
-				2: AWD_FIELD_BADDR,
-				11: AWD_FIELD_BOOL,
-				12: AWD_FIELD_FLOAT32,
-				13: AWD_FIELD_BOOL
-			} );
-
-			methods_parsed = 0;
-
-			while ( methods_parsed < num_methods ) {
-
-				// read method_type before
-				this.readU16();
-				this.parseProperties( null );
-				this.parseUserAttributes();
-
-			}
-
-			attributes = this.parseUserAttributes();
-
-			if ( this.materialFactory !== undefined ) {
-
-				mat = this.materialFactory( name );
-				if ( mat ) return mat;
-
-			}
-
-			mat = new THREE.MeshPhongMaterial();
-
-			if ( type === 1 ) {
-
-				// Color material
-				mat.color.setHex( props.get( 1, 0xcccccc ) );
-
-			} else if ( type === 2 ) {
-
-				// Bitmap material
-				var tex_addr = props.get( 2, 0 );
-				mat.map = this.getBlock( tex_addr );
-
-			}
-
-			mat.extra = attributes;
-			mat.alphaThreshold = props.get( 12, 0.0 );
-			mat.repeat = props.get( 13, false );
-
-
-			return mat;
-
-		},
-
-		parseTexture: function () {
-
-			var name = this.readUTF(),
-				type = this.readU8(),
-				asset,
-				data_len;
-
-			// External
-			if ( type === 0 ) {
-
-				data_len = this.readU32();
-				var url = this.readUTFBytes( data_len );
-				console.log( url );
-
-				asset = this.loadTexture( url );
-				asset.userData = {};
-				asset.userData.name = name;
-
-			} else {
-				// embed texture not supported
-			}
-			// Ignore for now
-			this.parseProperties( null );
-
-			this.parseUserAttributes();
-			return asset;
-
-		},
-
-		loadTexture: function ( url ) {
-
-			var tex = new THREE.Texture();
-
-			var loader = new THREE.ImageLoader( this.manager );
-
-			loader.load( this._baseDir + url, function ( image ) {
-
-				tex.image = image;
-				tex.needsUpdate = true;
-
-			} );
-
-			return tex;
-
-		},
-
-		parseSkeleton: function () {
-
-			// Array<Bone>
-			//
-			this.readUTF();
-			var	num_joints = this.readU16(),
-				skeleton = [],
-				joints_parsed = 0;
-
-			this.parseProperties( null );
-
-			while ( joints_parsed < num_joints ) {
-
-				var joint, ibp;
-
-				// Ignore joint id
-				this.readU16();
-
-				joint = new THREE.Bone();
-				joint.parent = this.readU16() - 1; // 0=null in AWD
-				joint.name = this.readUTF();
-
-				ibp = this.parseMatrix4();
-				joint.skinMatrix = ibp;
-
-				// Ignore joint props/attributes for now
-				this.parseProperties( null );
-				this.parseUserAttributes();
-
-				skeleton.push( joint );
-				joints_parsed ++;
-
-			}
-
-			// Discard attributes for now
-			this.parseUserAttributes();
-
-
-			return skeleton;
-
-		},
-
-		parseSkeletonPose: function () {
-
-			var name = this.readUTF();
-
-			var num_joints = this.readU16();
-			this.parseProperties( null );
-
-			// debug( 'parse Skeleton Pose. joints : ' + num_joints);
-
-			var pose = [];
-
-			var joints_parsed = 0;
-
-			while ( joints_parsed < num_joints ) {
-
-				var has_transform; //:uint;
-				var mtx_data;
-
-				has_transform = this.readU8();
-
-				if ( has_transform === 1 ) {
-
-					mtx_data = this.parseMatrix4();
-
-				} else {
-
-					mtx_data = new THREE.Matrix4();
-
-				}
-				pose[ joints_parsed ] = mtx_data;
-				joints_parsed ++;
-
-			}
-
-			// Skip attributes for now
-			this.parseUserAttributes();
-
-			return pose;
-
-		},
-
-		parseSkeletonAnimation: function () {
-
-			var frame_dur;
-			var pose_addr;
-			var pose;
-
-			var name = this.readUTF();
-
-			var clip = [];
-
-			var num_frames = this.readU16();
-			this.parseProperties( null );
-
-			var frames_parsed = 0;
-
-			// debug( 'parse Skeleton Animation. frames : ' + num_frames);
-
-			while ( frames_parsed < num_frames ) {
-
-				pose_addr = this.readU32();
-				frame_dur = this.readU16();
-
-				pose = this._blocks[ pose_addr ].data;
-				// debug( 'pose address ',pose[2].elements[12],pose[2].elements[13],pose[2].elements[14] );
-				clip.push( {
-					pose: pose,
-					duration: frame_dur
-				} );
-
-				frames_parsed ++;
-
-			}
-
-			if ( clip.length === 0 ) {
-
-				// debug("Could not this SkeletonClipNode, because no Frames where set.");
-				return;
-
-			}
-			// Ignore attributes for now
-			this.parseUserAttributes();
-			return clip;
-
-		},
-
-		parseVertexAnimationSet: function () {
-
-			var poseBlockAdress,
-				name = this.readUTF(),
-				num_frames = this.readU16(),
-				props = this.parseProperties( { 1: UINT16 } ),
-				frames_parsed = 0,
-				skeletonFrames = [];
-
-			while ( frames_parsed < num_frames ) {
-
-				poseBlockAdress = this.readU32();
-				skeletonFrames.push( this._blocks[ poseBlockAdress ].data );
-				frames_parsed ++;
-
-			}
-
-			this.parseUserAttributes();
-
-
-			return skeletonFrames;
-
-		},
-
-		parseAnimatorSet: function () {
-
-			var animSetBlockAdress; //:int
-
-			var targetAnimationSet; //:AnimationSetBase;
-			var name = this.readUTF();
-			var type = this.readU16();
-
-			var props = this.parseProperties( { 1: BADDR } );
-
-			animSetBlockAdress = this.readU32();
-			var targetMeshLength = this.readU16();
-
-			var meshAdresses = []; //:Vector.<uint> = new Vector.<uint>;
-
-			for ( var i = 0; i < targetMeshLength; i ++ )
-				meshAdresses.push( this.readU32() );
-
-			var activeState = this.readU16();
-			var autoplay = Boolean( this.readU8() );
-			this.parseUserAttributes();
-			this.parseUserAttributes();
-
-			var targetMeshes = []; //:Vector.<Mesh> = new Vector.<Mesh>;
-
-			for ( i = 0; i < meshAdresses.length; i ++ ) {
-
-				//			returnedArray = getAssetByID(meshAdresses[i], [AssetType.MESH]);
-				//			if (returnedArray[0])
-				targetMeshes.push( this._blocks[ meshAdresses[ i ] ].data );
-
-			}
-
-			targetAnimationSet = this._blocks[ animSetBlockAdress ].data;
-			var thisAnimator;
-
-			if ( type == 1 ) {
-
-
-				thisAnimator = {
-					animationSet: targetAnimationSet,
-					skeleton: this._blocks[ props.get( 1, 0 ) ].data
-				};
-
-			} else if ( type == 2 ) {
-				// debug( "vertex Anim???");
-			}
-
-
-			for ( i = 0; i < targetMeshes.length; i ++ ) {
-
-				targetMeshes[ i ].animator = thisAnimator;
-
-			}
-			// debug("Parsed a Animator: Name = " + name);
-
-			return thisAnimator;
-
-		},
-
-		parseMeshData: function () {
-
-			var name = this.readUTF(),
-				num_subs = this.readU16(),
-				geom,
-				subs_parsed = 0,
-				buffer,
-				geometries = [];
-
-			// Ignore for now
-			this.parseProperties( { 1: this._geoNrType, 2: this._geoNrType } );
-
-			// Loop through sub meshes
-			while ( subs_parsed < num_subs ) {
-
-				var sm_len, sm_end, attrib;
-
-				geom = new THREE.BufferGeometry();
-				geom.name = name;
-				geometries.push( geom );
-
-
-				sm_len = this.readU32();
-				sm_end = this._ptr + sm_len;
-
-
-				// Ignore for now
-				this.parseProperties( { 1: this._geoNrType, 2: this._geoNrType } );
-
-				// Loop through data streams
-				while ( this._ptr < sm_end ) {
-
-					var idx = 0,
-						str_type = this.readU8(),
-						str_ftype = this.readU8(),
-						str_len = this.readU32(),
-						str_end = str_len + this._ptr;
-
-					if ( str_type === 1 ) {
-
-						// VERTICES
-
-						buffer = new Float32Array( ( str_len / 12 ) * 3 );
-						attrib = new THREE.BufferAttribute( buffer, 3 );
-
-						geom.addAttribute( 'position', attrib );
-						idx = 0;
-
-						while ( this._ptr < str_end ) {
-
-							buffer[ idx ] = - this.readF32();
-							buffer[ idx + 1 ] = this.readF32();
-							buffer[ idx + 2 ] = this.readF32();
-							idx += 3;
-
-						}
-
-					} else if ( str_type === 2 ) {
-
-						// INDICES
-
-						buffer = new Uint16Array( str_len / 2 );
-						attrib = new THREE.BufferAttribute( buffer, 1 );
-						geom.setIndex( attrib );
-
-						idx = 0;
-
-						while ( this._ptr < str_end ) {
-
-							buffer[ idx + 1 ] = this.readU16();
-							buffer[ idx ] = this.readU16();
-							buffer[ idx + 2 ] = this.readU16();
-							idx += 3;
-
-						}
-
-					} else if ( str_type === 3 ) {
-
-						// UVS
-
-						buffer = new Float32Array( ( str_len / 8 ) * 2 );
-						attrib = new THREE.BufferAttribute( buffer, 2 );
-
-						geom.addAttribute( 'uv', attrib );
-						idx = 0;
-
-						while ( this._ptr < str_end ) {
-
-							buffer[ idx ] = this.readF32();
-							buffer[ idx + 1 ] = 1.0 - this.readF32();
-							idx += 2;
-
-						}
-
-					} else if ( str_type === 4 ) {
-
-						// NORMALS
-
-						buffer = new Float32Array( ( str_len / 12 ) * 3 );
-						attrib = new THREE.BufferAttribute( buffer, 3 );
-						geom.addAttribute( 'normal', attrib );
-						idx = 0;
-
-						while ( this._ptr < str_end ) {
-
-							buffer[ idx ] = - this.readF32();
-							buffer[ idx + 1 ] = this.readF32();
-							buffer[ idx + 2 ] = this.readF32();
-							idx += 3;
-
-						}
-
-					} else {
-
-						this._ptr = str_end;
-
-					}
-
-				}
-
-				this.parseUserAttributes();
-
-				geom.computeBoundingSphere();
-				subs_parsed ++;
-
-			}
-
-			//geom.computeFaceNormals();
-
-			this.parseUserAttributes();
-			//finalizeAsset(geom, name);
-
-			return geometries;
-
-		},
-
-		parseMeshPoseAnimation: function ( poseOnly ) {
-
-			var num_frames = 1,
-				num_submeshes,
-				frames_parsed,
-				subMeshParsed,
-
-				str_len,
-				str_end,
-				geom,
-				idx = 0,
-				clip = {},
-				num_Streams,
-				streamsParsed,
-				streamtypes = [],
-
-				props,
-				name = this.readUTF(),
-				geoAdress = this.readU32();
-
-			var mesh = this.getBlock( geoAdress );
-
-			if ( mesh === null ) {
-
-				console.log( "parseMeshPoseAnimation target mesh not found at:", geoAdress );
-				return;
-
-			}
-
-			geom = mesh.geometry;
-			geom.morphTargets = [];
-
-			if ( ! poseOnly )
-				num_frames = this.readU16();
-
-			num_submeshes = this.readU16();
-			num_Streams = this.readU16();
-
-			// debug("VA num_frames : ", num_frames );
-			// debug("VA num_submeshes : ", num_submeshes );
-			// debug("VA numstreams : ", num_Streams );
-
-			streamsParsed = 0;
-			while ( streamsParsed < num_Streams ) {
-
-				streamtypes.push( this.readU16() );
-				streamsParsed ++;
-
-			}
-			props = this.parseProperties( { 1: BOOL, 2: BOOL } );
-
-			clip.looping = props.get( 1, true );
-			clip.stitchFinalFrame = props.get( 2, false );
-
-			frames_parsed = 0;
-
-			while ( frames_parsed < num_frames ) {
-
-				this.readU16();
-				subMeshParsed = 0;
-
-				while ( subMeshParsed < num_submeshes ) {
-
-					streamsParsed = 0;
-					str_len = this.readU32();
-					str_end = this._ptr + str_len;
-
-					while ( streamsParsed < num_Streams ) {
-
-						if ( streamtypes[ streamsParsed ] === 1 ) {
-
-							//geom.addAttribute( 'morphTarget'+frames_parsed, Float32Array, str_len/12, 3 );
-							var buffer = new Float32Array( str_len / 4 );
-							geom.morphTargets.push( {
-								array: buffer
-							} );
-
-							//buffer = geom.attributes['morphTarget'+frames_parsed].array
-							idx = 0;
-
-							while ( this._ptr < str_end ) {
-
-								buffer[ idx ] = this.readF32();
-								buffer[ idx + 1 ] = this.readF32();
-								buffer[ idx + 2 ] = this.readF32();
-								idx += 3;
-
-							}
-
-
-							subMeshParsed ++;
-
-						} else
-							this._ptr = str_end;
-						streamsParsed ++;
-
-					}
-
-				}
-
-
-				frames_parsed ++;
-
-			}
-
-			this.parseUserAttributes();
-
-			return null;
-
-		},
-
-		getBlock: function ( id ) {
-
-			return this._blocks[ id ].data;
-
-		},
-
-		parseMatrix4: function () {
-
-			var mtx = new THREE.Matrix4();
-			var e = mtx.elements;
-
-			e[ 0 ] = this.readF32();
-			e[ 1 ] = this.readF32();
-			e[ 2 ] = this.readF32();
-			e[ 3 ] = 0.0;
-			//e[3] = 0.0;
-
-			e[ 4 ] = this.readF32();
-			e[ 5 ] = this.readF32();
-			e[ 6 ] = this.readF32();
-			//e[7] = this.readF32();
-			e[ 7 ] = 0.0;
-
-			e[ 8 ] = this.readF32();
-			e[ 9 ] = this.readF32();
-			e[ 10 ] = this.readF32();
-			//e[11] = this.readF32();
-			e[ 11 ] = 0.0;
-
-			e[ 12 ] = - this.readF32();
-			e[ 13 ] = this.readF32();
-			e[ 14 ] = this.readF32();
-			//e[15] = this.readF32();
-			e[ 15 ] = 1.0;
-			return mtx;
-
-		},
-
-		parseProperties: function ( expected ) {
-
-			var list_len = this.readU32();
-			var list_end = this._ptr + list_len;
-
-			var props = new AWDProperties();
-
-			if ( expected ) {
-
-				while ( this._ptr < list_end ) {
-
-					var key = this.readU16();
-					var len = this.readU32();
-					var type;
-
-					if ( expected.hasOwnProperty( key ) ) {
-
-						type = expected[ key ];
-						props.set( key, this.parseAttrValue( type, len ) );
-
-					} else {
-
-						this._ptr += len;
-
-					}
-
-				}
-
-			}
-
-			return props;
-
-		},
-
-		parseUserAttributes: function () {
-
-			// skip for now
-			this._ptr = this.readU32() + this._ptr;
-			return null;
-
-		},
-
-		parseAttrValue: function ( type, len ) {
-
-			var elem_len;
-			var read_func;
-
-			switch ( type ) {
-
-				case AWD_FIELD_INT8:
-					elem_len = 1;
-					read_func = this.readI8;
-					break;
-
-				case AWD_FIELD_INT16:
-					elem_len = 2;
-					read_func = this.readI16;
-					break;
-
-				case AWD_FIELD_INT32:
-					elem_len = 4;
-					read_func = this.readI32;
-					break;
-
-				case AWD_FIELD_BOOL:
-				case AWD_FIELD_UINT8:
-					elem_len = 1;
-					read_func = this.readU8;
-					break;
-
-				case AWD_FIELD_UINT16:
-					elem_len = 2;
-					read_func = this.readU16;
-					break;
-
-				case AWD_FIELD_UINT32:
-				case AWD_FIELD_BADDR:
-					elem_len = 4;
-					read_func = this.readU32;
-					break;
-
-				case AWD_FIELD_FLOAT32:
-					elem_len = 4;
-					read_func = this.readF32;
-					break;
-
-				case AWD_FIELD_FLOAT64:
-					elem_len = 8;
-					read_func = this.readF64;
-					break;
-
-				case AWD_FIELD_VECTOR2x1:
-				case AWD_FIELD_VECTOR3x1:
-				case AWD_FIELD_VECTOR4x1:
-				case AWD_FIELD_MTX3x2:
-				case AWD_FIELD_MTX3x3:
-				case AWD_FIELD_MTX4x3:
-				case AWD_FIELD_MTX4x4:
-					elem_len = 8;
-					read_func = this.readF64;
-					break;
-
-			}
-
-			if ( elem_len < len ) {
-
-				var list;
-				var num_read;
-				var num_elems;
-
-				list = [];
-				num_read = 0;
-				num_elems = len / elem_len;
-
-				while ( num_read < num_elems ) {
-
-					list.push( read_func.call( this ) );
-					num_read ++;
-
-				}
-
-				return list;
-
-			} else {
-
-				return read_func.call( this );
-
-			}
-
-		},
-
-		readU8: function () {
-
-			return this._data.getUint8( this._ptr ++ );
-
-		},
-		readI8: function () {
-
-			return this._data.getInt8( this._ptr ++ );
-
-		},
-		readU16: function () {
-
-			var a = this._data.getUint16( this._ptr, littleEndian );
-			this._ptr += 2;
-			return a;
-
-		},
-		readI16: function () {
-
-			var a = this._data.getInt16( this._ptr, littleEndian );
-			this._ptr += 2;
-			return a;
-
-		},
-		readU32: function () {
-
-			var a = this._data.getUint32( this._ptr, littleEndian );
-			this._ptr += 4;
-			return a;
-
-		},
-		readI32: function () {
-
-			var a = this._data.getInt32( this._ptr, littleEndian );
-			this._ptr += 4;
-			return a;
-
-		},
-		readF32: function () {
-
-			var a = this._data.getFloat32( this._ptr, littleEndian );
-			this._ptr += 4;
-			return a;
-
-		},
-		readF64: function () {
-
-			var a = this._data.getFloat64( this._ptr, littleEndian );
-			this._ptr += 8;
-			return a;
-
-		},
-
-		/**
-	 * Converts a UTF-8 byte array to JavaScript's 16-bit Unicode.
-	 * @param {Array.<number>} bytes UTF-8 byte array.
-	 * @return {string} 16-bit Unicode string.
-	 */
-		readUTF: function () {
-
-			var len = this.readU16();
-			return this.readUTFBytes( len );
-
-		},
-
-		/**
-		 * Converts a UTF-8 byte array to JavaScript's 16-bit Unicode.
-		 * @param {Array.<number>} bytes UTF-8 byte array.
-		 * @return {string} 16-bit Unicode string.
-		 */
-		readUTFBytes: function ( len ) {
-
-			// TODO(user): Use native implementations if/when available
-			var out = [], c = 0;
-
-			while ( out.length < len ) {
-
-				var c1 = this._data.getUint8( this._ptr ++, littleEndian );
-				if ( c1 < 128 ) {
-
-					out[ c ++ ] = String.fromCharCode( c1 );
-
-				} else if ( c1 > 191 && c1 < 224 ) {
-
-					var c2 = this._data.getUint8( this._ptr ++, littleEndian );
-					out[ c ++ ] = String.fromCharCode( ( c1 & 31 ) << 6 | c2 & 63 );
-
-				} else {
-
-					var c2 = this._data.getUint8( this._ptr ++, littleEndian );
-					var c3 = this._data.getUint8( this._ptr ++, littleEndian );
-					out[ c ++ ] = String.fromCharCode( ( c1 & 15 ) << 12 | ( c2 & 63 ) << 6 | c3 & 63 );
-
-				}
-
-			}
-			return out.join( '' );
-
-		}
-
-	} );
-
-	return AWDLoader;
-
-} )();

+ 0 - 248
examples/js/loaders/BabylonLoader.js

@@ -1,248 +0,0 @@
-/**
- * @author mrdoob / http://mrdoob.com/
- * @author Mugen87 / https://github.com/Mugen87
- */
-
-THREE.BabylonLoader = function ( manager ) {
-
-	THREE.Loader.call( this, manager );
-
-};
-
-THREE.BabylonLoader.prototype = Object.assign( Object.create( THREE.Loader.prototype ), {
-
-	constructor: THREE.BabylonLoader,
-
-	load: function ( url, onLoad, onProgress, onError ) {
-
-		var scope = this;
-
-		var loader = new THREE.FileLoader( scope.manager );
-		loader.setPath( scope.path );
-		loader.load( url, function ( text ) {
-
-			onLoad( scope.parse( JSON.parse( text ) ) );
-
-		}, onProgress, onError );
-
-	},
-
-	parse: function ( json ) {
-
-		function parseMaterials( json ) {
-
-			var materials = {};
-
-			for ( var i = 0, l = json.materials.length; i < l; i ++ ) {
-
-				var data = json.materials[ i ];
-
-				var material = new THREE.MeshPhongMaterial();
-				material.name = data.name;
-				material.color.fromArray( data.diffuse );
-				material.emissive.fromArray( data.emissive );
-				material.specular.fromArray( data.specular );
-				material.shininess = data.specularPower;
-				material.opacity = data.alpha;
-
-				materials[ data.id ] = material;
-
-			}
-
-			if ( json.multiMaterials ) {
-
-				for ( var i = 0, l = json.multiMaterials.length; i < l; i ++ ) {
-
-					var data = json.multiMaterials[ i ];
-
-					console.warn( 'THREE.BabylonLoader: Multi materials not yet supported.' );
-
-					materials[ data.id ] = new THREE.MeshPhongMaterial();
-
-				}
-
-			}
-
-			return materials;
-
-		}
-
-		function parseGeometry( json ) {
-
-			var geometry = new THREE.BufferGeometry();
-
-			var indices = json.indices;
-			var positions = json.positions;
-			var normals = json.normals;
-			var uvs = json.uvs;
-
-			// indices
-
-			geometry.setIndex( indices );
-
-			// positions
-
-			for ( var j = 2, jl = positions.length; j < jl; j += 3 ) {
-
-				positions[ j ] = - positions[ j ];
-
-			}
-
-			geometry.addAttribute( 'position', new THREE.Float32BufferAttribute( positions, 3 ) );
-
-			// normals
-
-			if ( normals ) {
-
-				for ( var j = 2, jl = normals.length; j < jl; j += 3 ) {
-
-					normals[ j ] = - normals[ j ];
-
-				}
-
-				geometry.addAttribute( 'normal', new THREE.Float32BufferAttribute( normals, 3 ) );
-
-			}
-
-			// uvs
-
-			if ( uvs ) {
-
-				geometry.addAttribute( 'uv', new THREE.Float32BufferAttribute( uvs, 2 ) );
-
-			}
-
-			// offsets
-
-			var subMeshes = json.subMeshes;
-
-			if ( subMeshes ) {
-
-				for ( var j = 0, jl = subMeshes.length; j < jl; j ++ ) {
-
-					var subMesh = subMeshes[ j ];
-
-					geometry.addGroup( subMesh.indexStart, subMesh.indexCount );
-
-				}
-
-			}
-
-			return geometry;
-
-		}
-
-		function parseObjects( json, materials ) {
-
-			var objects = {};
-			var scene = new THREE.Scene();
-
-			var cameras = json.cameras;
-
-			for ( var i = 0, l = cameras.length; i < l; i ++ ) {
-
-				var data = cameras[ i ];
-
-				var camera = new THREE.PerspectiveCamera( ( data.fov / Math.PI ) * 180, 1.33, data.minZ, data.maxZ );
-
-				camera.name = data.name;
-				camera.position.fromArray( data.position );
-				if ( data.rotation ) camera.rotation.fromArray( data.rotation );
-
-				objects[ data.id ] = camera;
-
-			}
-
-			var lights = json.lights;
-
-			for ( var i = 0, l = lights.length; i < l; i ++ ) {
-
-				var data = lights[ i ];
-
-				var light;
-
-				switch ( data.type ) {
-
-					case 0:
-						light = new THREE.PointLight();
-						break;
-
-					case 1:
-						light = new THREE.DirectionalLight();
-						break;
-
-					case 2:
-						light = new THREE.SpotLight();
-						break;
-
-					case 3:
-						light = new THREE.HemisphereLight();
-						break;
-
-				}
-
-				light.name = data.name;
-				if ( data.position ) light.position.set( data.position[ 0 ], data.position[ 1 ], - data.position[ 2 ] );
-				light.color.fromArray( data.diffuse );
-				if ( data.groundColor ) light.groundColor.fromArray( data.groundColor );
-				if ( data.intensity ) light.intensity = data.intensity;
-
-				objects[ data.id ] = light;
-
-				scene.add( light );
-
-			}
-
-			var meshes = json.meshes;
-
-			for ( var i = 0, l = meshes.length; i < l; i ++ ) {
-
-				var data = meshes[ i ];
-
-				var object;
-
-				if ( data.indices ) {
-
-					var geometry = parseGeometry( data );
-
-					object = new THREE.Mesh( geometry, materials[ data.materialId ] );
-
-				} else {
-
-					object = new THREE.Group();
-
-				}
-
-				object.name = data.name;
-				object.position.set( data.position[ 0 ], data.position[ 1 ], - data.position[ 2 ] );
-				object.rotation.fromArray( data.rotation );
-				if ( data.rotationQuaternion ) object.quaternion.fromArray( data.rotationQuaternion );
-				object.scale.fromArray( data.scaling );
-				// object.visible = data.isVisible;
-
-				if ( data.parentId ) {
-
-					objects[ data.parentId ].add( object );
-
-				} else {
-
-					scene.add( object );
-
-				}
-
-				objects[ data.id ] = object;
-
-			}
-
-			return scene;
-
-		}
-
-		var materials = parseMaterials( json );
-		var scene = parseObjects( json, materials );
-
-		return scene;
-
-	}
-
-} );

+ 27 - 5
examples/js/loaders/DRACOLoader.js

@@ -97,7 +97,8 @@ THREE.DRACOLoader.prototype = Object.assign( Object.create( THREE.Loader.prototy
 
 			var taskConfig = {
 				attributeIDs: this.defaultAttributeIDs,
-				attributeTypes: this.defaultAttributeTypes
+				attributeTypes: this.defaultAttributeTypes,
+				useUniqueIDs: false
 			};
 
 			this.decodeGeometry( buffer, taskConfig )
@@ -113,7 +114,8 @@ THREE.DRACOLoader.prototype = Object.assign( Object.create( THREE.Loader.prototy
 
 		var taskConfig = {
 			attributeIDs: attributeIDs || this.defaultAttributeIDs,
-			attributeTypes: attributeTypes || this.defaultAttributeTypes
+			attributeTypes: attributeTypes || this.defaultAttributeTypes,
+			useUniqueIDs: !! attributeIDs
 		};
 
 		this.decodeGeometry( buffer, taskConfig ).then( callback );
@@ -454,12 +456,32 @@ THREE.DRACOLoader.DRACOWorker = function () {
 
 		var geometry = { index: null, attributes: [] };
 
-		// Add attributes of user specified unique id.
+		// Gather all vertex attributes.
 		for ( var attributeName in attributeIDs ) {
 
 			var attributeType = self[ attributeTypes[ attributeName ] ];
-			var attributeId = attributeIDs[ attributeName ];
-			var attribute = decoder.GetAttributeByUniqueId( dracoGeometry, attributeId );
+
+			var attribute;
+			var attributeID;
+
+			// A Draco file may be created with default vertex attributes, whose attribute IDs
+			// are mapped 1:1 from their semantic name (POSITION, NORMAL, ...). Alternatively,
+			// a Draco file may contain a custom set of attributes, identified by known unique
+			// IDs. glTF files always do the latter, and `.drc` files typically do the former.
+			if ( taskConfig.useUniqueIDs ) {
+
+				attributeID = attributeIDs[ attributeName ];
+				attribute = decoder.GetAttributeByUniqueId( dracoGeometry, attributeID );
+
+			} else {
+
+				attributeID = decoder.GetAttributeId( dracoGeometry, draco[ attributeIDs[ attributeName ] ] );
+
+				if ( attributeID === -1 ) continue;
+
+				attribute = decoder.GetAttribute( dracoGeometry, attributeID );
+
+			}
 
 			geometry.attributes.push( decodeAttribute( draco, decoder, dracoGeometry, attributeName, attributeType, attribute ) );
 

+ 22 - 16
examples/js/loaders/FBXLoader.js

@@ -1529,7 +1529,7 @@ THREE.FBXLoader = ( function () {
 		parseMeshGeometry: function ( relationships, geoNode, deformers ) {
 
 			var skeletons = deformers.skeletons;
-			var morphTargets = deformers.morphTargets;
+			var morphTargets = [];
 
 			var modelNodes = relationships.parents.map( function ( parent ) {
 
@@ -1548,13 +1548,15 @@ THREE.FBXLoader = ( function () {
 
 			}, null );
 
-			var morphTarget = relationships.children.reduce( function ( morphTarget, child ) {
+			relationships.children.forEach( function( child ) {
 
-				if ( morphTargets[ child.ID ] !== undefined ) morphTarget = morphTargets[ child.ID ];
+				if ( deformers.morphTargets[ child.ID ] !== undefined ) {
 
-				return morphTarget;
+					morphTargets.push( deformers.morphTargets[ child.ID ] );
 
-			}, null );
+				}
+
+			} );
 
 			// Assume one model and get the preRotation from that
 			// if there is more than one model associated with the geometry this may cause problems
@@ -1571,12 +1573,12 @@ THREE.FBXLoader = ( function () {
 
 			var transform = generateTransform( transformData );
 
-			return this.genGeometry( geoNode, skeleton, morphTarget, transform );
+			return this.genGeometry( geoNode, skeleton, morphTargets, transform );
 
 		},
 
 		// Generate a THREE.BufferGeometry from a node in FBXTree.Objects.Geometry
-		genGeometry: function ( geoNode, skeleton, morphTarget, preTransform ) {
+		genGeometry: function ( geoNode, skeleton, morphTargets, preTransform ) {
 
 			var geo = new THREE.BufferGeometry();
 			if ( geoNode.attrName ) geo.name = geoNode.attrName;
@@ -1677,7 +1679,7 @@ THREE.FBXLoader = ( function () {
 
 			}
 
-			this.addMorphTargets( geo, geoNode, morphTarget, preTransform );
+			this.addMorphTargets( geo, geoNode, morphTargets, preTransform );
 
 			return geo;
 
@@ -2050,23 +2052,27 @@ THREE.FBXLoader = ( function () {
 
 		},
 
-		addMorphTargets: function ( parentGeo, parentGeoNode, morphTarget, preTransform ) {
+		addMorphTargets: function ( parentGeo, parentGeoNode, morphTargets, preTransform ) {
 
-			if ( morphTarget === null ) return;
+			if ( morphTargets.length === 0 ) return;
 
 			parentGeo.morphAttributes.position = [];
 			// parentGeo.morphAttributes.normal = []; // not implemented
 
-			var self = this;
-			morphTarget.rawTargets.forEach( function ( rawTarget ) {
+			 var self = this;
+			morphTargets.forEach( function( morphTarget ) {
 
-				var morphGeoNode = fbxTree.Objects.Geometry[ rawTarget.geoID ];
+				morphTarget.rawTargets.forEach( function ( rawTarget ) {
 
-				if ( morphGeoNode !== undefined ) {
+					var morphGeoNode = fbxTree.Objects.Geometry[ rawTarget.geoID ];
 
-					self.genMorphGeometry( parentGeo, parentGeoNode, morphGeoNode, preTransform, rawTarget.name );
+					if ( morphGeoNode !== undefined ) {
 
-				}
+						self.genMorphGeometry( parentGeo, parentGeoNode, morphGeoNode, preTransform, rawTarget.name );
+
+					}
+
+				} );
 
 			} );
 

+ 0 - 196
examples/js/loaders/PlayCanvasLoader.js

@@ -1,196 +0,0 @@
-/**
- * @author mrdoob / http://mrdoob.com/
- * @author Mugen87 / https://github.com/Mugen87
- */
-
-THREE.PlayCanvasLoader = function ( manager ) {
-
-	THREE.Loader.call( this, manager );
-
-};
-
-THREE.PlayCanvasLoader.prototype = Object.assign( Object.create( THREE.Loader.prototype ), {
-
-	constructor: THREE.PlayCanvasLoader,
-
-	load: function ( url, onLoad, onProgress, onError ) {
-
-		var scope = this;
-
-		var loader = new THREE.FileLoader( scope.manager );
-		loader.setPath( scope.path );
-		loader.load( url, function ( text ) {
-
-			onLoad( scope.parse( JSON.parse( text ) ) );
-
-		}, onProgress, onError );
-
-	},
-
-	parse: function ( json ) {
-
-		function parseVertices( data ) {
-
-			var attributes = {};
-
-			// create a buffer attribute for each array that contains vertex information
-
-			for ( var name in data ) {
-
-				var array = data[ name ];
-
-				var type = array.type;
-				var size = array.components;
-
-				var attribute;
-
-				switch ( type ) {
-
-					case 'float32':
-						attribute = new THREE.Float32BufferAttribute( array.data, size );
-						break;
-
-					case 'uint8':
-						attribute = new THREE.Uint8BufferAttribute( array.data, size );
-						break;
-
-					case 'uint16':
-						attribute = new THREE.Uint16BufferAttribute( array.data, size );
-						break;
-
-					default:
-						console.log( 'THREE.PlayCanvasLoader: Array type "%s" not yet supported.', type );
-
-				}
-
-				attributes[ name ] = attribute;
-
-			}
-
-			data._attributes = attributes;
-
-		}
-
-		function parseMeshes( data ) {
-
-			// create buffer geometry
-
-			var geometry = new THREE.BufferGeometry();
-
-			geometry.setIndex( data.indices );
-
-			var attributes = model.vertices[ data.vertices ]._attributes;
-
-			for ( var name in attributes ) {
-
-				var attribute = attributes[ name ];
-
-				if ( name === 'texCoord0' ) name = 'uv';
-
-				geometry.addAttribute( name, attribute );
-
-			}
-
-			data._geometry = geometry;
-
-		}
-
-		function parseMeshInstances( data ) {
-
-			var node = model.nodes[ data.node ];
-			var mesh = model.meshes[ data.mesh ];
-
-			if ( node._geometries === undefined ) {
-
-				node._geometries = [];
-
-			}
-
-			node._geometries.push( mesh._geometry );
-
-		}
-
-		function parseNodes( data ) {
-
-			var object = new THREE.Group();
-
-			var geometries = data._geometries;
-
-			if ( geometries !== undefined ) {
-
-				var material = new THREE.MeshPhongMaterial();
-
-				for ( var i = 0, l = geometries.length; i < l; i ++ ) {
-
-					var geometry = geometries[ i ];
-
-					object.add( new THREE.Mesh( geometry, material ) );
-
-				}
-
-			}
-
-			for ( var i = 0, l = data.rotation.length; i < l; i ++ ) {
-
-				data.rotation[ i ] *= Math.PI / 180;
-
-			}
-
-			//
-
-			object.name = data.name;
-
-			object.position.fromArray( data.position );
-			object.quaternion.setFromEuler( new THREE.Euler().fromArray( data.rotation ) );
-			object.scale.fromArray( data.scale );
-
-			data._object = object;
-
-		}
-
-		//
-
-		var model = json.model;
-
-		for ( var i = 0, l = model.vertices.length; i < l; i ++ ) {
-
-			parseVertices( model.vertices[ i ] );
-
-		}
-
-		for ( var i = 0, l = model.meshes.length; i < l; i ++ ) {
-
-			parseMeshes( model.meshes[ i ] );
-
-		}
-
-		for ( var i = 0, l = model.meshInstances.length; i < l; i ++ ) {
-
-			parseMeshInstances( model.meshInstances[ i ] );
-
-		}
-
-		for ( var i = 0, l = model.nodes.length; i < l; i ++ ) {
-
-			parseNodes( model.nodes[ i ] );
-
-		}
-
-		// setup scene hierarchy
-
-		for ( var i = 0, l = model.parents.length; i < l; i ++ ) {
-
-			var parent = model.parents[ i ];
-
-			if ( parent === - 1 ) continue;
-
-			model.nodes[ parent ]._object.add( model.nodes[ i ]._object );
-
-
-		}
-
-		return model.nodes[ 0 ]._object;
-
-	}
-
-} );

+ 2 - 5
examples/js/misc/GPUComputationRenderer.js

@@ -318,11 +318,8 @@ THREE.GPUComputationRenderer = function ( sizeX, sizeY, renderer ) {
 
 	this.createTexture = function () {
 
-		var a = new Float32Array( sizeX * sizeY * 4 );
-		var texture = new THREE.DataTexture( a, sizeX, sizeY, THREE.RGBAFormat, THREE.FloatType );
-		texture.needsUpdate = true;
-
-		return texture;
+		var data = new Float32Array( sizeX * sizeY * 4 );
+		return new THREE.DataTexture( data, sizeX, sizeY, THREE.RGBAFormat, THREE.FloatType );
 
 	};
 

+ 0 - 1
examples/js/misc/Ocean.js

@@ -255,7 +255,6 @@ THREE.Ocean.prototype.generateSeedPhaseTexture = function () {
 	this.pingPhaseTexture.wrapS = THREE.ClampToEdgeWrapping;
 	this.pingPhaseTexture.wrapT = THREE.ClampToEdgeWrapping;
 	this.pingPhaseTexture.type = THREE.FloatType;
-	this.pingPhaseTexture.needsUpdate = true;
 
 };
 

+ 0 - 2
examples/js/objects/Lensflare.js

@@ -23,14 +23,12 @@ THREE.Lensflare = function () {
 	tempMap.magFilter = THREE.NearestFilter;
 	tempMap.wrapS = THREE.ClampToEdgeWrapping;
 	tempMap.wrapT = THREE.ClampToEdgeWrapping;
-	tempMap.needsUpdate = true;
 
 	var occlusionMap = new THREE.DataTexture( new Uint8Array( 16 * 16 * 3 ), 16, 16, THREE.RGBFormat );
 	occlusionMap.minFilter = THREE.NearestFilter;
 	occlusionMap.magFilter = THREE.NearestFilter;
 	occlusionMap.wrapS = THREE.ClampToEdgeWrapping;
 	occlusionMap.wrapT = THREE.ClampToEdgeWrapping;
-	occlusionMap.needsUpdate = true;
 
 	// material
 

+ 1 - 3
examples/js/postprocessing/GlitchPass.js

@@ -104,9 +104,7 @@ THREE.GlitchPass.prototype = Object.assign( Object.create( THREE.Pass.prototype
 
 		}
 
-		var texture = new THREE.DataTexture( data_arr, dt_size, dt_size, THREE.RGBFormat, THREE.FloatType );
-		texture.needsUpdate = true;
-		return texture;
+		return new THREE.DataTexture( data_arr, dt_size, dt_size, THREE.RGBFormat, THREE.FloatType );
 
 	}
 

+ 4 - 4
examples/js/postprocessing/OutlinePass.js

@@ -510,18 +510,18 @@ THREE.OutlinePass.prototype = Object.assign( Object.create( THREE.Pass.prototype
 				void main() {\
 					vec2 invSize = 1.0 / texSize;\
 					float weightSum = gaussianPdf(0.0, kernelRadius);\
-					vec3 diffuseSum = texture2D( colorTexture, vUv).rgb * weightSum;\
+					vec4 diffuseSum = texture2D( colorTexture, vUv) * weightSum;\
 					vec2 delta = direction * invSize * kernelRadius/float(MAX_RADIUS);\
 					vec2 uvOffset = delta;\
 					for( int i = 1; i <= MAX_RADIUS; i ++ ) {\
 						float w = gaussianPdf(uvOffset.x, kernelRadius);\
-						vec3 sample1 = texture2D( colorTexture, vUv + uvOffset).rgb;\
-						vec3 sample2 = texture2D( colorTexture, vUv - uvOffset).rgb;\
+						vec4 sample1 = texture2D( colorTexture, vUv + uvOffset);\
+						vec4 sample2 = texture2D( colorTexture, vUv - uvOffset);\
 						diffuseSum += ((sample1 + sample2) * w);\
 						weightSum += (2.0 * w);\
 						uvOffset += delta;\
 					}\
-					gl_FragColor = vec4(diffuseSum/weightSum, 1.0);\
+					gl_FragColor = diffuseSum/weightSum;\
 				}"
 		} );
 

+ 0 - 1
examples/js/postprocessing/SSAOPass.js

@@ -388,7 +388,6 @@ THREE.SSAOPass.prototype = Object.assign( Object.create( THREE.Pass.prototype ),
 		this.noiseTexture = new THREE.DataTexture( data, width, height, THREE.RGBAFormat, THREE.FloatType );
 		this.noiseTexture.wrapS = THREE.RepeatWrapping;
 		this.noiseTexture.wrapT = THREE.RepeatWrapping;
-		this.noiseTexture.needsUpdate = true;
 
 	}
 

+ 1 - 3
examples/jsm/controls/DeviceOrientationControls.d.ts

@@ -1,6 +1,5 @@
 import {
-  Camera,
-  Vector3
+  Camera
 } from '../../../src/Three';
 
 export class DeviceOrientationControls {
@@ -14,7 +13,6 @@ export class DeviceOrientationControls {
   deviceOrientation: any;
   enabled: boolean;
   screenOrientation: number;
-  target: Vector3;
 
   connect(): void;
   disconnect(): void;

+ 0 - 26
examples/jsm/controls/EditorControls.d.ts

@@ -1,26 +0,0 @@
-import {
-  Camera,
-  EventDispatcher,
-  Vector3,
-  Object3D
-} from '../../../src/Three';
-
-export class EditorControls extends EventDispatcher {
-  constructor(object: Camera, domElement?: HTMLElement);
-
-  object: Camera;
-  domElement: HTMLElement | HTMLDocument;
-
-  enabled: boolean;
-  center: Vector3;
-  panSpeed: number;
-  zoomSpeed: number;
-  rotationSpeed: number;
-
-  focus(target: Object3D): void;
-  pan(delta: Vector3): void;
-  zoom(delta: Vector3): void;
-  rotate(delta: Vector3): void;
-  dispose(): void;
-
-}

+ 0 - 327
examples/jsm/controls/EditorControls.js

@@ -1,327 +0,0 @@
-/**
- * @author qiao / https://github.com/qiao
- * @author mrdoob / http://mrdoob.com
- * @author alteredq / http://alteredqualia.com/
- * @author WestLangley / http://github.com/WestLangley
- */
-
-import {
-	Box3,
-	EventDispatcher,
-	Matrix3,
-	Sphere,
-	Spherical,
-	Vector2,
-	Vector3
-} from "../../../build/three.module.js";
-
-var EditorControls = function ( object, domElement ) {
-
-	domElement = ( domElement !== undefined ) ? domElement : document;
-
-	// API
-
-	this.enabled = true;
-	this.center = new Vector3();
-	this.panSpeed = 0.002;
-	this.zoomSpeed = 0.1;
-	this.rotationSpeed = 0.005;
-
-	// internals
-
-	var scope = this;
-	var vector = new Vector3();
-	var delta = new Vector3();
-	var box = new Box3();
-
-	var STATE = { NONE: - 1, ROTATE: 0, ZOOM: 1, PAN: 2 };
-	var state = STATE.NONE;
-
-	var center = this.center;
-	var normalMatrix = new Matrix3();
-	var pointer = new Vector2();
-	var pointerOld = new Vector2();
-	var spherical = new Spherical();
-	var sphere = new Sphere();
-
-	// events
-
-	var changeEvent = { type: 'change' };
-
-	this.focus = function ( target ) {
-
-		var distance;
-
-		box.setFromObject( target );
-
-		if ( box.isEmpty() === false ) {
-
-			box.getCenter( center );
-			distance = box.getBoundingSphere( sphere ).radius;
-
-		} else {
-
-			// Focusing on an Group, AmbientLight, etc
-
-			center.setFromMatrixPosition( target.matrixWorld );
-			distance = 0.1;
-
-		}
-
-		delta.set( 0, 0, 1 );
-		delta.applyQuaternion( object.quaternion );
-		delta.multiplyScalar( distance * 4 );
-
-		object.position.copy( center ).add( delta );
-
-		scope.dispatchEvent( changeEvent );
-
-	};
-
-	this.pan = function ( delta ) {
-
-		var distance = object.position.distanceTo( center );
-
-		delta.multiplyScalar( distance * scope.panSpeed );
-		delta.applyMatrix3( normalMatrix.getNormalMatrix( object.matrix ) );
-
-		object.position.add( delta );
-		center.add( delta );
-
-		scope.dispatchEvent( changeEvent );
-
-	};
-
-	this.zoom = function ( delta ) {
-
-		var distance = object.position.distanceTo( center );
-
-		delta.multiplyScalar( distance * scope.zoomSpeed );
-
-		if ( delta.length() > distance ) return;
-
-		delta.applyMatrix3( normalMatrix.getNormalMatrix( object.matrix ) );
-
-		object.position.add( delta );
-
-		scope.dispatchEvent( changeEvent );
-
-	};
-
-	this.rotate = function ( delta ) {
-
-		vector.copy( object.position ).sub( center );
-
-		spherical.setFromVector3( vector );
-
-		spherical.theta += delta.x * scope.rotationSpeed;
-		spherical.phi += delta.y * scope.rotationSpeed;
-
-		spherical.makeSafe();
-
-		vector.setFromSpherical( spherical );
-
-		object.position.copy( center ).add( vector );
-
-		object.lookAt( center );
-
-		scope.dispatchEvent( changeEvent );
-
-	};
-
-	// mouse
-
-	function onMouseDown( event ) {
-
-		if ( scope.enabled === false ) return;
-
-		if ( event.button === 0 ) {
-
-			state = STATE.ROTATE;
-
-		} else if ( event.button === 1 ) {
-
-			state = STATE.ZOOM;
-
-		} else if ( event.button === 2 ) {
-
-			state = STATE.PAN;
-
-		}
-
-		pointerOld.set( event.clientX, event.clientY );
-
-		domElement.addEventListener( 'mousemove', onMouseMove, false );
-		domElement.addEventListener( 'mouseup', onMouseUp, false );
-		domElement.addEventListener( 'mouseout', onMouseUp, false );
-		domElement.addEventListener( 'dblclick', onMouseUp, false );
-
-	}
-
-	function onMouseMove( event ) {
-
-		if ( scope.enabled === false ) return;
-
-		pointer.set( event.clientX, event.clientY );
-
-		var movementX = pointer.x - pointerOld.x;
-		var movementY = pointer.y - pointerOld.y;
-
-		if ( state === STATE.ROTATE ) {
-
-			scope.rotate( delta.set( - movementX, - movementY, 0 ) );
-
-		} else if ( state === STATE.ZOOM ) {
-
-			scope.zoom( delta.set( 0, 0, movementY ) );
-
-		} else if ( state === STATE.PAN ) {
-
-			scope.pan( delta.set( - movementX, movementY, 0 ) );
-
-		}
-
-		pointerOld.set( event.clientX, event.clientY );
-
-	}
-
-	function onMouseUp( event ) {
-
-		domElement.removeEventListener( 'mousemove', onMouseMove, false );
-		domElement.removeEventListener( 'mouseup', onMouseUp, false );
-		domElement.removeEventListener( 'mouseout', onMouseUp, false );
-		domElement.removeEventListener( 'dblclick', onMouseUp, false );
-
-		state = STATE.NONE;
-
-	}
-
-	function onMouseWheel( event ) {
-
-		event.preventDefault();
-
-		// Normalize deltaY due to https://bugzilla.mozilla.org/show_bug.cgi?id=1392460
-		scope.zoom( delta.set( 0, 0, event.deltaY > 0 ? 1 : - 1 ) );
-
-	}
-
-	function contextmenu( event ) {
-
-		event.preventDefault();
-
-	}
-
-	this.dispose = function () {
-
-		domElement.removeEventListener( 'contextmenu', contextmenu, false );
-		domElement.removeEventListener( 'mousedown', onMouseDown, false );
-		domElement.removeEventListener( 'wheel', onMouseWheel, false );
-
-		domElement.removeEventListener( 'mousemove', onMouseMove, false );
-		domElement.removeEventListener( 'mouseup', onMouseUp, false );
-		domElement.removeEventListener( 'mouseout', onMouseUp, false );
-		domElement.removeEventListener( 'dblclick', onMouseUp, false );
-
-		domElement.removeEventListener( 'touchstart', touchStart, false );
-		domElement.removeEventListener( 'touchmove', touchMove, false );
-
-	};
-
-	domElement.addEventListener( 'contextmenu', contextmenu, false );
-	domElement.addEventListener( 'mousedown', onMouseDown, false );
-	domElement.addEventListener( 'wheel', onMouseWheel, false );
-
-	// touch
-
-	var touches = [ new Vector3(), new Vector3(), new Vector3() ];
-	var prevTouches = [ new Vector3(), new Vector3(), new Vector3() ];
-
-	var prevDistance = null;
-
-	function touchStart( event ) {
-
-		if ( scope.enabled === false ) return;
-
-		switch ( event.touches.length ) {
-
-			case 1:
-				touches[ 0 ].set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY, 0 ).divideScalar( window.devicePixelRatio );
-				touches[ 1 ].set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY, 0 ).divideScalar( window.devicePixelRatio );
-				break;
-
-			case 2:
-				touches[ 0 ].set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY, 0 ).divideScalar( window.devicePixelRatio );
-				touches[ 1 ].set( event.touches[ 1 ].pageX, event.touches[ 1 ].pageY, 0 ).divideScalar( window.devicePixelRatio );
-				prevDistance = touches[ 0 ].distanceTo( touches[ 1 ] );
-				break;
-
-		}
-
-		prevTouches[ 0 ].copy( touches[ 0 ] );
-		prevTouches[ 1 ].copy( touches[ 1 ] );
-
-	}
-
-
-	function touchMove( event ) {
-
-		if ( scope.enabled === false ) return;
-
-		event.preventDefault();
-		event.stopPropagation();
-
-		function getClosest( touch, touches ) {
-
-			var closest = touches[ 0 ];
-
-			for ( var i in touches ) {
-
-				if ( closest.distanceTo( touch ) > touches[ i ].distanceTo( touch ) ) closest = touches[ i ];
-
-			}
-
-			return closest;
-
-		}
-
-		switch ( event.touches.length ) {
-
-			case 1:
-				touches[ 0 ].set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY, 0 ).divideScalar( window.devicePixelRatio );
-				touches[ 1 ].set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY, 0 ).divideScalar( window.devicePixelRatio );
-				scope.rotate( touches[ 0 ].sub( getClosest( touches[ 0 ], prevTouches ) ).multiplyScalar( - 1 ) );
-				break;
-
-			case 2:
-				touches[ 0 ].set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY, 0 ).divideScalar( window.devicePixelRatio );
-				touches[ 1 ].set( event.touches[ 1 ].pageX, event.touches[ 1 ].pageY, 0 ).divideScalar( window.devicePixelRatio );
-				var distance = touches[ 0 ].distanceTo( touches[ 1 ] );
-				scope.zoom( delta.set( 0, 0, prevDistance - distance ) );
-				prevDistance = distance;
-
-
-				var offset0 = touches[ 0 ].clone().sub( getClosest( touches[ 0 ], prevTouches ) );
-				var offset1 = touches[ 1 ].clone().sub( getClosest( touches[ 1 ], prevTouches ) );
-				offset0.x = - offset0.x;
-				offset1.x = - offset1.x;
-
-				scope.pan( offset0.add( offset1 ) );
-
-				break;
-
-		}
-
-		prevTouches[ 0 ].copy( touches[ 0 ] );
-		prevTouches[ 1 ].copy( touches[ 1 ] );
-
-	}
-
-	domElement.addEventListener( 'touchstart', touchStart, false );
-	domElement.addEventListener( 'touchmove', touchMove, false );
-
-};
-
-EditorControls.prototype = Object.create( EventDispatcher.prototype );
-EditorControls.prototype.constructor = EditorControls;
-
-export { EditorControls };

+ 1 - 1
examples/jsm/controls/FirstPersonControls.d.ts

@@ -22,7 +22,7 @@ export class FirstPersonControls {
   constrainVertical: boolean;
   verticalMin: number;
   verticalMax: number;
-  autoSpeedFactor: number;
+	mouseDragOn: boolean;
 
   handleResize(): void;
   lookAt(x: number | Vector3, y: number, z: number): this;

+ 6 - 2
examples/jsm/controls/FirstPersonControls.js

@@ -16,6 +16,8 @@ var FirstPersonControls = function ( object, domElement ) {
 
 	this.domElement = ( domElement !== undefined ) ? domElement : document;
 
+	// API
+
 	this.enabled = true;
 
 	this.movementSpeed = 1.0;
@@ -35,6 +37,10 @@ var FirstPersonControls = function ( object, domElement ) {
 	this.verticalMin = 0;
 	this.verticalMax = Math.PI;
 
+	this.mouseDragOn = false;
+
+	// internals
+
 	this.autoSpeedFactor = 0.0;
 
 	this.mouseX = 0;
@@ -45,8 +51,6 @@ var FirstPersonControls = function ( object, domElement ) {
 	this.moveLeft = false;
 	this.moveRight = false;
 
-	this.mouseDragOn = false;
-
 	this.viewHalfX = 0;
 	this.viewHalfY = 0;
 

+ 0 - 30
examples/jsm/controls/OrthographicTrackballControls.d.ts

@@ -1,30 +0,0 @@
-import { Camera, EventDispatcher } from '../../../src/Three';
-
-export class OrthographicTrackballControls extends EventDispatcher {
-  constructor(object: Camera, domElement?: HTMLElement);
-
-  object: Camera;
-  domElement: HTMLElement;
-
-  enabled: boolean;
-  screen: {left: number; top: number; width: number; height: number};
-  radius: number;
-  rotateSpeed: number;
-  zoomSpeed: number;
-  noRotate: boolean;
-  noZoom: boolean;
-  noPan: boolean;
-  noRoll: boolean;
-  staticMoving: boolean;
-  dynamicDampingFactor: number;
-  keys: number[];
-
-  handleResize(): void;
-  rotateCamera(): void;
-  zoomCamera(): void;
-  panCamera(): void;
-  update(): void;
-  reset(): void;
-  dispose(): void;
-
-}

+ 0 - 653
examples/jsm/controls/OrthographicTrackballControls.js

@@ -1,653 +0,0 @@
-/**
- * @author Eberhard Graether / http://egraether.com/
- * @author Mark Lundin 	/ http://mark-lundin.com
- * @author Patrick Fuller / http://patrick-fuller.com
- * @author Max Smolens / https://github.com/msmolens
- */
-
-import {
-	EventDispatcher,
-	Quaternion,
-	Vector2,
-	Vector3
-} from "../../../build/three.module.js";
-
-var OrthographicTrackballControls = function ( object, domElement ) {
-
-	var _this = this;
-	var STATE = { NONE: - 1, ROTATE: 0, ZOOM: 1, PAN: 2, TOUCH_ROTATE: 3, TOUCH_ZOOM_PAN: 4 };
-
-	this.object = object;
-	this.domElement = ( domElement !== undefined ) ? domElement : document;
-
-	// API
-
-	this.enabled = true;
-
-	this.screen = { left: 0, top: 0, width: 0, height: 0 };
-
-	this.radius = 0;
-
-	this.rotateSpeed = 1.0;
-	this.zoomSpeed = 1.2;
-
-	this.noRotate = false;
-	this.noZoom = false;
-	this.noPan = false;
-	this.noRoll = false;
-
-	this.staticMoving = false;
-	this.dynamicDampingFactor = 0.2;
-
-	this.keys = [ 65 /*A*/, 83 /*S*/, 68 /*D*/ ];
-
-	// internals
-
-	this.target = new Vector3();
-
-	var EPS = 0.000001;
-
-	var _changed = true;
-
-	var _state = STATE.NONE,
-		_prevState = STATE.NONE,
-
-		_eye = new Vector3(),
-
-		_rotateStart = new Vector3(),
-		_rotateEnd = new Vector3(),
-
-		_zoomStart = new Vector2(),
-		_zoomEnd = new Vector2(),
-
-		_touchZoomDistanceStart = 0,
-		_touchZoomDistanceEnd = 0,
-
-		_panStart = new Vector2(),
-		_panEnd = new Vector2();
-
-	// for reset
-
-	this.target0 = this.target.clone();
-	this.position0 = this.object.position.clone();
-	this.up0 = this.object.up.clone();
-
-	this.left0 = this.object.left;
-	this.right0 = this.object.right;
-	this.top0 = this.object.top;
-	this.bottom0 = this.object.bottom;
-
-	// events
-
-	var changeEvent = { type: 'change' };
-	var startEvent = { type: 'start' };
-	var endEvent = { type: 'end' };
-
-
-	// methods
-
-	this.handleResize = function () {
-
-		if ( this.domElement === document ) {
-
-			this.screen.left = 0;
-			this.screen.top = 0;
-			this.screen.width = window.innerWidth;
-			this.screen.height = window.innerHeight;
-
-		} else {
-
-			var box = this.domElement.getBoundingClientRect();
-			// adjustments come from similar code in the jquery offset() function
-			var d = this.domElement.ownerDocument.documentElement;
-			this.screen.left = box.left + window.pageXOffset - d.clientLeft;
-			this.screen.top = box.top + window.pageYOffset - d.clientTop;
-			this.screen.width = box.width;
-			this.screen.height = box.height;
-
-		}
-
-		this.radius = 0.5 * Math.min( this.screen.width, this.screen.height );
-
-		this.left0 = this.object.left;
-		this.right0 = this.object.right;
-		this.top0 = this.object.top;
-		this.bottom0 = this.object.bottom;
-
-	};
-
-	var getMouseOnScreen = ( function () {
-
-		var vector = new Vector2();
-
-		return function getMouseOnScreen( pageX, pageY ) {
-
-			vector.set(
-				( pageX - _this.screen.left ) / _this.screen.width,
-				( pageY - _this.screen.top ) / _this.screen.height
-			);
-
-			return vector;
-
-		};
-
-	}() );
-
-	var getMouseProjectionOnBall = ( function () {
-
-		var vector = new Vector3();
-		var objectUp = new Vector3();
-		var mouseOnBall = new Vector3();
-
-		return function getMouseProjectionOnBall( pageX, pageY ) {
-
-			mouseOnBall.set(
-				( pageX - _this.screen.width * 0.5 - _this.screen.left ) / _this.radius,
-				( _this.screen.height * 0.5 + _this.screen.top - pageY ) / _this.radius,
-				0.0
-			);
-
-			var length = mouseOnBall.length();
-
-			if ( _this.noRoll ) {
-
-				if ( length < Math.SQRT1_2 ) {
-
-					mouseOnBall.z = Math.sqrt( 1.0 - length * length );
-
-				} else {
-
-					mouseOnBall.z = .5 / length;
-
-				}
-
-			} else if ( length > 1.0 ) {
-
-				mouseOnBall.normalize();
-
-			} else {
-
-				mouseOnBall.z = Math.sqrt( 1.0 - length * length );
-
-			}
-
-			_eye.copy( _this.object.position ).sub( _this.target );
-
-			vector.copy( _this.object.up ).setLength( mouseOnBall.y );
-			vector.add( objectUp.copy( _this.object.up ).cross( _eye ).setLength( mouseOnBall.x ) );
-			vector.add( _eye.setLength( mouseOnBall.z ) );
-
-			return vector;
-
-		};
-
-	}() );
-
-	this.rotateCamera = ( function () {
-
-		var axis = new Vector3(),
-			quaternion = new Quaternion();
-
-
-		return function rotateCamera() {
-
-			var angle = Math.acos( _rotateStart.dot( _rotateEnd ) / _rotateStart.length() / _rotateEnd.length() );
-
-			if ( angle ) {
-
-				axis.crossVectors( _rotateStart, _rotateEnd ).normalize();
-
-				angle *= _this.rotateSpeed;
-
-				quaternion.setFromAxisAngle( axis, - angle );
-
-				_eye.applyQuaternion( quaternion );
-				_this.object.up.applyQuaternion( quaternion );
-
-				_rotateEnd.applyQuaternion( quaternion );
-
-				if ( _this.staticMoving ) {
-
-					_rotateStart.copy( _rotateEnd );
-
-				} else {
-
-					quaternion.setFromAxisAngle( axis, angle * ( _this.dynamicDampingFactor - 1.0 ) );
-					_rotateStart.applyQuaternion( quaternion );
-
-				}
-
-				_changed = true;
-
-			}
-
-		};
-
-	}() );
-
-	this.zoomCamera = function () {
-
-		if ( _state === STATE.TOUCH_ZOOM_PAN ) {
-
-			var factor = _touchZoomDistanceEnd / _touchZoomDistanceStart;
-			_touchZoomDistanceStart = _touchZoomDistanceEnd;
-
-			_this.object.zoom *= factor;
-
-			_changed = true;
-
-		} else {
-
-			var factor = 1.0 + ( _zoomEnd.y - _zoomStart.y ) * _this.zoomSpeed;
-
-			if ( Math.abs( factor - 1.0 ) > EPS && factor > 0.0 ) {
-
-				_this.object.zoom /= factor;
-
-				if ( _this.staticMoving ) {
-
-					_zoomStart.copy( _zoomEnd );
-
-				} else {
-
-					_zoomStart.y += ( _zoomEnd.y - _zoomStart.y ) * this.dynamicDampingFactor;
-
-				}
-
-				_changed = true;
-
-			}
-
-		}
-
-	};
-
-	this.panCamera = ( function () {
-
-		var mouseChange = new Vector2(),
-			objectUp = new Vector3(),
-			pan = new Vector3();
-
-		return function panCamera() {
-
-			mouseChange.copy( _panEnd ).sub( _panStart );
-
-			if ( mouseChange.lengthSq() > EPS ) {
-
-				// Scale movement to keep clicked/dragged position under cursor
-				var scale_x = ( _this.object.right - _this.object.left ) / _this.object.zoom;
-				var scale_y = ( _this.object.top - _this.object.bottom ) / _this.object.zoom;
-				mouseChange.x *= scale_x;
-				mouseChange.y *= scale_y;
-
-				pan.copy( _eye ).cross( _this.object.up ).setLength( mouseChange.x );
-				pan.add( objectUp.copy( _this.object.up ).setLength( mouseChange.y ) );
-
-				_this.object.position.add( pan );
-				_this.target.add( pan );
-
-				if ( _this.staticMoving ) {
-
-					_panStart.copy( _panEnd );
-
-				} else {
-
-					_panStart.add( mouseChange.subVectors( _panEnd, _panStart ).multiplyScalar( _this.dynamicDampingFactor ) );
-
-				}
-
-				_changed = true;
-
-			}
-
-		};
-
-	}() );
-
-	this.update = function () {
-
-		_eye.subVectors( _this.object.position, _this.target );
-
-		if ( ! _this.noRotate ) {
-
-			_this.rotateCamera();
-
-		}
-
-		if ( ! _this.noZoom ) {
-
-			_this.zoomCamera();
-
-			if ( _changed ) {
-
-				_this.object.updateProjectionMatrix();
-
-			}
-
-		}
-
-		if ( ! _this.noPan ) {
-
-			_this.panCamera();
-
-		}
-
-		_this.object.position.addVectors( _this.target, _eye );
-
-		_this.object.lookAt( _this.target );
-
-		if ( _changed ) {
-
-			_this.dispatchEvent( changeEvent );
-
-			_changed = false;
-
-		}
-
-	};
-
-	this.reset = function () {
-
-		_state = STATE.NONE;
-		_prevState = STATE.NONE;
-
-		_this.target.copy( _this.target0 );
-		_this.object.position.copy( _this.position0 );
-		_this.object.up.copy( _this.up0 );
-
-		_eye.subVectors( _this.object.position, _this.target );
-
-		_this.object.left = _this.left0;
-		_this.object.right = _this.right0;
-		_this.object.top = _this.top0;
-		_this.object.bottom = _this.bottom0;
-
-		_this.object.lookAt( _this.target );
-
-		_this.dispatchEvent( changeEvent );
-
-		_changed = false;
-
-	};
-
-	// listeners
-
-	function keydown( event ) {
-
-		if ( _this.enabled === false ) return;
-
-		window.removeEventListener( 'keydown', keydown );
-
-		_prevState = _state;
-
-		if ( _state !== STATE.NONE ) {
-
-			return;
-
-		} else if ( event.keyCode === _this.keys[ STATE.ROTATE ] && ! _this.noRotate ) {
-
-			_state = STATE.ROTATE;
-
-		} else if ( event.keyCode === _this.keys[ STATE.ZOOM ] && ! _this.noZoom ) {
-
-			_state = STATE.ZOOM;
-
-		} else if ( event.keyCode === _this.keys[ STATE.PAN ] && ! _this.noPan ) {
-
-			_state = STATE.PAN;
-
-		}
-
-	}
-
-	function keyup() {
-
-		if ( _this.enabled === false ) return;
-
-		_state = _prevState;
-
-		window.addEventListener( 'keydown', keydown, false );
-
-	}
-
-	function mousedown( event ) {
-
-		if ( _this.enabled === false ) return;
-
-		event.preventDefault();
-		event.stopPropagation();
-
-		if ( _state === STATE.NONE ) {
-
-			_state = event.button;
-
-		}
-
-		if ( _state === STATE.ROTATE && ! _this.noRotate ) {
-
-			_rotateStart.copy( getMouseProjectionOnBall( event.pageX, event.pageY ) );
-			_rotateEnd.copy( _rotateStart );
-
-		} else if ( _state === STATE.ZOOM && ! _this.noZoom ) {
-
-			_zoomStart.copy( getMouseOnScreen( event.pageX, event.pageY ) );
-			_zoomEnd.copy( _zoomStart );
-
-		} else if ( _state === STATE.PAN && ! _this.noPan ) {
-
-			_panStart.copy( getMouseOnScreen( event.pageX, event.pageY ) );
-			_panEnd.copy( _panStart );
-
-		}
-
-		document.addEventListener( 'mousemove', mousemove, false );
-		document.addEventListener( 'mouseup', mouseup, false );
-
-		_this.dispatchEvent( startEvent );
-
-	}
-
-	function mousemove( event ) {
-
-		if ( _this.enabled === false ) return;
-
-		event.preventDefault();
-		event.stopPropagation();
-
-		if ( _state === STATE.ROTATE && ! _this.noRotate ) {
-
-			_rotateEnd.copy( getMouseProjectionOnBall( event.pageX, event.pageY ) );
-
-		} else if ( _state === STATE.ZOOM && ! _this.noZoom ) {
-
-			_zoomEnd.copy( getMouseOnScreen( event.pageX, event.pageY ) );
-
-		} else if ( _state === STATE.PAN && ! _this.noPan ) {
-
-			_panEnd.copy( getMouseOnScreen( event.pageX, event.pageY ) );
-
-		}
-
-	}
-
-	function mouseup( event ) {
-
-		if ( _this.enabled === false ) return;
-
-		event.preventDefault();
-		event.stopPropagation();
-
-		_state = STATE.NONE;
-
-		document.removeEventListener( 'mousemove', mousemove );
-		document.removeEventListener( 'mouseup', mouseup );
-		_this.dispatchEvent( endEvent );
-
-	}
-
-	function mousewheel( event ) {
-
-		if ( _this.enabled === false ) return;
-
-		event.preventDefault();
-		event.stopPropagation();
-
-		switch ( event.deltaMode ) {
-
-			case 2:
-				// Zoom in pages
-				_zoomStart.y -= event.deltaY * 0.025;
-				break;
-
-			case 1:
-				// Zoom in lines
-				_zoomStart.y -= event.deltaY * 0.01;
-				break;
-
-			default:
-				// undefined, 0, assume pixels
-				_zoomStart.y -= event.deltaY * 0.00025;
-				break;
-
-		}
-
-		_this.dispatchEvent( startEvent );
-		_this.dispatchEvent( endEvent );
-
-	}
-
-	function touchstart( event ) {
-
-		if ( _this.enabled === false ) return;
-
-		switch ( event.touches.length ) {
-
-			case 1:
-				_state = STATE.TOUCH_ROTATE;
-				_rotateStart.copy( getMouseProjectionOnBall( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY ) );
-				_rotateEnd.copy( _rotateStart );
-				break;
-
-			case 2:
-				_state = STATE.TOUCH_ZOOM_PAN;
-				var dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX;
-				var dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY;
-				_touchZoomDistanceEnd = _touchZoomDistanceStart = Math.sqrt( dx * dx + dy * dy );
-
-				var x = ( event.touches[ 0 ].pageX + event.touches[ 1 ].pageX ) / 2;
-				var y = ( event.touches[ 0 ].pageY + event.touches[ 1 ].pageY ) / 2;
-				_panStart.copy( getMouseOnScreen( x, y ) );
-				_panEnd.copy( _panStart );
-				break;
-
-			default:
-				_state = STATE.NONE;
-
-		}
-		_this.dispatchEvent( startEvent );
-
-	}
-
-	function touchmove( event ) {
-
-		if ( _this.enabled === false ) return;
-
-		event.preventDefault();
-		event.stopPropagation();
-
-		switch ( event.touches.length ) {
-
-			case 1:
-				_rotateEnd.copy( getMouseProjectionOnBall( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY ) );
-				break;
-
-			case 2:
-				var dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX;
-				var dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY;
-				_touchZoomDistanceEnd = Math.sqrt( dx * dx + dy * dy );
-
-				var x = ( event.touches[ 0 ].pageX + event.touches[ 1 ].pageX ) / 2;
-				var y = ( event.touches[ 0 ].pageY + event.touches[ 1 ].pageY ) / 2;
-				_panEnd.copy( getMouseOnScreen( x, y ) );
-				break;
-
-			default:
-				_state = STATE.NONE;
-
-		}
-
-	}
-
-	function touchend( event ) {
-
-		if ( _this.enabled === false ) return;
-
-		switch ( event.touches.length ) {
-
-			case 1:
-				_rotateEnd.copy( getMouseProjectionOnBall( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY ) );
-				_rotateStart.copy( _rotateEnd );
-				break;
-
-			case 2:
-				_touchZoomDistanceStart = _touchZoomDistanceEnd = 0;
-
-				var x = ( event.touches[ 0 ].pageX + event.touches[ 1 ].pageX ) / 2;
-				var y = ( event.touches[ 0 ].pageY + event.touches[ 1 ].pageY ) / 2;
-				_panEnd.copy( getMouseOnScreen( x, y ) );
-				_panStart.copy( _panEnd );
-				break;
-
-		}
-
-		_state = STATE.NONE;
-		_this.dispatchEvent( endEvent );
-
-	}
-
-	function contextmenu( event ) {
-
-		event.preventDefault();
-
-	}
-
-	this.dispose = function () {
-
-		this.domElement.removeEventListener( 'contextmenu', contextmenu, false );
-		this.domElement.removeEventListener( 'mousedown', mousedown, false );
-		this.domElement.removeEventListener( 'wheel', mousewheel, false );
-
-		this.domElement.removeEventListener( 'touchstart', touchstart, false );
-		this.domElement.removeEventListener( 'touchend', touchend, false );
-		this.domElement.removeEventListener( 'touchmove', touchmove, false );
-
-		document.removeEventListener( 'mousemove', mousemove, false );
-		document.removeEventListener( 'mouseup', mouseup, false );
-
-		window.removeEventListener( 'keydown', keydown, false );
-		window.removeEventListener( 'keyup', keyup, false );
-
-	};
-
-	this.domElement.addEventListener( 'contextmenu', contextmenu, false );
-	this.domElement.addEventListener( 'mousedown', mousedown, false );
-	this.domElement.addEventListener( 'wheel', mousewheel, false );
-
-	this.domElement.addEventListener( 'touchstart', touchstart, false );
-	this.domElement.addEventListener( 'touchend', touchend, false );
-	this.domElement.addEventListener( 'touchmove', touchmove, false );
-
-	window.addEventListener( 'keydown', keydown, false );
-	window.addEventListener( 'keyup', keyup, false );
-
-	this.handleResize();
-
-	// force an update at start
-	this.update();
-
-};
-
-OrthographicTrackballControls.prototype = Object.create( EventDispatcher.prototype );
-OrthographicTrackballControls.prototype.constructor = OrthographicTrackballControls;
-
-export { OrthographicTrackballControls };

+ 0 - 2
examples/jsm/controls/TrackballControls.d.ts

@@ -42,6 +42,4 @@ export class TrackballControls extends EventDispatcher {
   rotateCamera(): void;
 
   handleResize(): void;
-
-  handleEvent(event: any): void;
 }

+ 71 - 7
examples/jsm/controls/TrackballControls.js

@@ -52,6 +52,7 @@ var TrackballControls = function ( object, domElement ) {
 	var EPS = 0.000001;
 
 	var lastPosition = new Vector3();
+	var lastZoom = 1;
 
 	var _state = STATE.NONE,
 		_keyState = STATE.NONE,
@@ -78,6 +79,7 @@ var TrackballControls = function ( object, domElement ) {
 	this.target0 = this.target.clone();
 	this.position0 = this.object.position.clone();
 	this.up0 = this.object.up.clone();
+	this.zoom0 = this.object.zoom;
 
 	// events
 
@@ -209,7 +211,21 @@ var TrackballControls = function ( object, domElement ) {
 
 			factor = _touchZoomDistanceStart / _touchZoomDistanceEnd;
 			_touchZoomDistanceStart = _touchZoomDistanceEnd;
-			_eye.multiplyScalar( factor );
+
+			if ( _this.object.isPerspectiveCamera ) {
+
+				_eye.multiplyScalar( factor );
+
+			} else if ( _this.object.isOrthographicCamera ) {
+
+				_this.object.zoom *= factor;
+				_this.object.updateProjectionMatrix();
+
+			} else {
+
+				console.warn( 'THREE.TrackballControls: Unsupported camera type' );
+
+			}
 
 		} else {
 
@@ -217,7 +233,20 @@ var TrackballControls = function ( object, domElement ) {
 
 			if ( factor !== 1.0 && factor > 0.0 ) {
 
-				_eye.multiplyScalar( factor );
+				if ( _this.object.isPerspectiveCamera ) {
+
+					_eye.multiplyScalar( factor );
+
+				} else if ( _this.object.isOrthographicCamera ) {
+
+					_this.object.zoom /= factor;
+					_this.object.updateProjectionMatrix();
+
+				} else {
+
+					console.warn( 'THREE.TrackballControls: Unsupported camera type' );
+
+				}
 
 			}
 
@@ -247,6 +276,16 @@ var TrackballControls = function ( object, domElement ) {
 
 			if ( mouseChange.lengthSq() ) {
 
+				if ( _this.object.isOrthographicCamera ) {
+
+					var scale_x = ( _this.object.right - _this.object.left ) / _this.object.zoom / _this.domElement.clientWidth;
+					var scale_y = ( _this.object.top - _this.object.bottom ) / _this.object.zoom / _this.domElement.clientWidth;
+
+					mouseChange.x *= scale_x;
+					mouseChange.y *= scale_y;
+
+				}
+
 				mouseChange.multiplyScalar( _eye.length() * _this.panSpeed );
 
 				pan.copy( _eye ).cross( _this.object.up ).setLength( mouseChange.x );
@@ -317,15 +356,36 @@ var TrackballControls = function ( object, domElement ) {
 
 		_this.object.position.addVectors( _this.target, _eye );
 
-		_this.checkDistances();
+		if ( _this.object.isPerspectiveCamera ) {
 
-		_this.object.lookAt( _this.target );
+			_this.checkDistances();
 
-		if ( lastPosition.distanceToSquared( _this.object.position ) > EPS ) {
+			_this.object.lookAt( _this.target );
+
+			if ( lastPosition.distanceToSquared( _this.object.position ) > EPS ) {
+
+				_this.dispatchEvent( changeEvent );
+
+				lastPosition.copy( _this.object.position );
+
+			}
 
-			_this.dispatchEvent( changeEvent );
+		} else if ( _this.object.isOrthographicCamera ) {
 
-			lastPosition.copy( _this.object.position );
+			_this.object.lookAt( _this.target );
+
+			if ( lastPosition.distanceToSquared( _this.object.position ) > EPS || lastZoom !== _this.object.zoom ) {
+
+				_this.dispatchEvent( changeEvent );
+
+				lastPosition.copy( _this.object.position );
+				lastZoom = _this.object.zoom;
+
+			}
+
+		} else {
+
+			console.warn( 'THREE.TrackballControls: Unsupported camera type' );
 
 		}
 
@@ -339,6 +399,9 @@ var TrackballControls = function ( object, domElement ) {
 		_this.target.copy( _this.target0 );
 		_this.object.position.copy( _this.position0 );
 		_this.object.up.copy( _this.up0 );
+		_this.object.zoom = _this.zoom0;
+
+		_this.object.updateProjectionMatrix();
 
 		_eye.subVectors( _this.object.position, _this.target );
 
@@ -347,6 +410,7 @@ var TrackballControls = function ( object, domElement ) {
 		_this.dispatchEvent( changeEvent );
 
 		lastPosition.copy( _this.object.position );
+		lastZoom = _this.object.zoom;
 
 	};
 

+ 5 - 11
examples/jsm/controls/TransformControls.d.ts

@@ -14,12 +14,12 @@ export class TransformControls extends Object3D {
   // API
 
   camera: Camera;
-  object: Object3D;
+  object: Object3D | undefined;
   enabled: boolean;
-  axis: string;
+  axis: string | null;
   mode: string;
-  translationSnap: Vector3;
-  rotationSnap: Vector3;
+  translationSnap: number | null;
+  rotationSnap: number | null;
   space: string;
   size: number;
   dragging: boolean;
@@ -27,19 +27,14 @@ export class TransformControls extends Object3D {
   showY: boolean;
   showZ: boolean;
   isTransformControls: boolean;
-  visible: boolean;
   mouseButtons: {
-    LEFT: MOUSE; 
+    LEFT: MOUSE;
     MIDDLE: MOUSE;
     RIGHT: MOUSE;
   };
 
   attach(object: Object3D): this;
   detach(): this;
-  pointerHover(pointer: Object): void;
-  pointerDown(pointer: Object): void;
-  pointerMove(pointer: Object): void;
-  pointerUp(pointer: Object): void;
   getMode(): string;
   setMode(mode: string): void;
   setTranslationSnap(translationSnap: Number | null): void;
@@ -47,6 +42,5 @@ export class TransformControls extends Object3D {
   setSize(size: number): void;
   setSpace(space: string): void;
   dispose(): void;
-  update(): void;
 
 }

+ 0 - 12
examples/jsm/loaders/BabylonLoader.d.ts

@@ -1,12 +0,0 @@
-import {
-  Loader,
-  LoadingManager,
-  Scene
-} from '../../../src/Three';
-
-export class BabylonLoader extends Loader {
-  constructor(manager?: LoadingManager);
-
-  load(url: string, onLoad: (scene: Scene) => void, onProgress?: (event: ProgressEvent) => void, onError?: (event: ErrorEvent) => void): void;
-  parse(json: object): Scene;
-}

+ 0 - 266
examples/jsm/loaders/BabylonLoader.js

@@ -1,266 +0,0 @@
-/**
- * @author mrdoob / http://mrdoob.com/
- * @author Mugen87 / https://github.com/Mugen87
- */
-
-import {
-	BufferGeometry,
-	DirectionalLight,
-	FileLoader,
-	Float32BufferAttribute,
-	Group,
-	HemisphereLight,
-	Loader,
-	Mesh,
-	MeshPhongMaterial,
-	PerspectiveCamera,
-	PointLight,
-	Scene,
-	SpotLight
-} from "../../../build/three.module.js";
-
-var BabylonLoader = function ( manager ) {
-
-	Loader.call( this, manager );
-
-};
-
-BabylonLoader.prototype = Object.assign( Object.create( Loader.prototype ), {
-
-	constructor: BabylonLoader,
-
-	load: function ( url, onLoad, onProgress, onError ) {
-
-		var scope = this;
-
-		var loader = new FileLoader( scope.manager );
-		loader.setPath( scope.path );
-		loader.load( url, function ( text ) {
-
-			onLoad( scope.parse( JSON.parse( text ) ) );
-
-		}, onProgress, onError );
-
-	},
-
-	parse: function ( json ) {
-
-		function parseMaterials( json ) {
-
-			var materials = {};
-
-			for ( var i = 0, l = json.materials.length; i < l; i ++ ) {
-
-				var data = json.materials[ i ];
-
-				var material = new MeshPhongMaterial();
-				material.name = data.name;
-				material.color.fromArray( data.diffuse );
-				material.emissive.fromArray( data.emissive );
-				material.specular.fromArray( data.specular );
-				material.shininess = data.specularPower;
-				material.opacity = data.alpha;
-
-				materials[ data.id ] = material;
-
-			}
-
-			if ( json.multiMaterials ) {
-
-				for ( var i = 0, l = json.multiMaterials.length; i < l; i ++ ) {
-
-					var data = json.multiMaterials[ i ];
-
-					console.warn( 'THREE.BabylonLoader: Multi materials not yet supported.' );
-
-					materials[ data.id ] = new MeshPhongMaterial();
-
-				}
-
-			}
-
-			return materials;
-
-		}
-
-		function parseGeometry( json ) {
-
-			var geometry = new BufferGeometry();
-
-			var indices = json.indices;
-			var positions = json.positions;
-			var normals = json.normals;
-			var uvs = json.uvs;
-
-			// indices
-
-			geometry.setIndex( indices );
-
-			// positions
-
-			for ( var j = 2, jl = positions.length; j < jl; j += 3 ) {
-
-				positions[ j ] = - positions[ j ];
-
-			}
-
-			geometry.addAttribute( 'position', new Float32BufferAttribute( positions, 3 ) );
-
-			// normals
-
-			if ( normals ) {
-
-				for ( var j = 2, jl = normals.length; j < jl; j += 3 ) {
-
-					normals[ j ] = - normals[ j ];
-
-				}
-
-				geometry.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );
-
-			}
-
-			// uvs
-
-			if ( uvs ) {
-
-				geometry.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );
-
-			}
-
-			// offsets
-
-			var subMeshes = json.subMeshes;
-
-			if ( subMeshes ) {
-
-				for ( var j = 0, jl = subMeshes.length; j < jl; j ++ ) {
-
-					var subMesh = subMeshes[ j ];
-
-					geometry.addGroup( subMesh.indexStart, subMesh.indexCount );
-
-				}
-
-			}
-
-			return geometry;
-
-		}
-
-		function parseObjects( json, materials ) {
-
-			var objects = {};
-			var scene = new Scene();
-
-			var cameras = json.cameras;
-
-			for ( var i = 0, l = cameras.length; i < l; i ++ ) {
-
-				var data = cameras[ i ];
-
-				var camera = new PerspectiveCamera( ( data.fov / Math.PI ) * 180, 1.33, data.minZ, data.maxZ );
-
-				camera.name = data.name;
-				camera.position.fromArray( data.position );
-				if ( data.rotation ) camera.rotation.fromArray( data.rotation );
-
-				objects[ data.id ] = camera;
-
-			}
-
-			var lights = json.lights;
-
-			for ( var i = 0, l = lights.length; i < l; i ++ ) {
-
-				var data = lights[ i ];
-
-				var light;
-
-				switch ( data.type ) {
-
-					case 0:
-						light = new PointLight();
-						break;
-
-					case 1:
-						light = new DirectionalLight();
-						break;
-
-					case 2:
-						light = new SpotLight();
-						break;
-
-					case 3:
-						light = new HemisphereLight();
-						break;
-
-				}
-
-				light.name = data.name;
-				if ( data.position ) light.position.set( data.position[ 0 ], data.position[ 1 ], - data.position[ 2 ] );
-				light.color.fromArray( data.diffuse );
-				if ( data.groundColor ) light.groundColor.fromArray( data.groundColor );
-				if ( data.intensity ) light.intensity = data.intensity;
-
-				objects[ data.id ] = light;
-
-				scene.add( light );
-
-			}
-
-			var meshes = json.meshes;
-
-			for ( var i = 0, l = meshes.length; i < l; i ++ ) {
-
-				var data = meshes[ i ];
-
-				var object;
-
-				if ( data.indices ) {
-
-					var geometry = parseGeometry( data );
-
-					object = new Mesh( geometry, materials[ data.materialId ] );
-
-				} else {
-
-					object = new Group();
-
-				}
-
-				object.name = data.name;
-				object.position.set( data.position[ 0 ], data.position[ 1 ], - data.position[ 2 ] );
-				object.rotation.fromArray( data.rotation );
-				if ( data.rotationQuaternion ) object.quaternion.fromArray( data.rotationQuaternion );
-				object.scale.fromArray( data.scaling );
-				// object.visible = data.isVisible;
-
-				if ( data.parentId ) {
-
-					objects[ data.parentId ].add( object );
-
-				} else {
-
-					scene.add( object );
-
-				}
-
-				objects[ data.id ] = object;
-
-			}
-
-			return scene;
-
-		}
-
-		var materials = parseMaterials( json );
-		var scene = parseObjects( json, materials );
-
-		return scene;
-
-	}
-
-} );
-
-export { BabylonLoader };

+ 27 - 5
examples/jsm/loaders/DRACOLoader.js

@@ -104,7 +104,8 @@ DRACOLoader.prototype = Object.assign( Object.create( Loader.prototype ), {
 
 			var taskConfig = {
 				attributeIDs: this.defaultAttributeIDs,
-				attributeTypes: this.defaultAttributeTypes
+				attributeTypes: this.defaultAttributeTypes,
+				useUniqueIDs: false
 			};
 
 			this.decodeGeometry( buffer, taskConfig )
@@ -120,7 +121,8 @@ DRACOLoader.prototype = Object.assign( Object.create( Loader.prototype ), {
 
 		var taskConfig = {
 			attributeIDs: attributeIDs || this.defaultAttributeIDs,
-			attributeTypes: attributeTypes || this.defaultAttributeTypes
+			attributeTypes: attributeTypes || this.defaultAttributeTypes,
+			useUniqueIDs: !! attributeIDs
 		};
 
 		this.decodeGeometry( buffer, taskConfig ).then( callback );
@@ -461,12 +463,32 @@ DRACOLoader.DRACOWorker = function () {
 
 		var geometry = { index: null, attributes: [] };
 
-		// Add attributes of user specified unique id.
+		// Gather all vertex attributes.
 		for ( var attributeName in attributeIDs ) {
 
 			var attributeType = self[ attributeTypes[ attributeName ] ];
-			var attributeId = attributeIDs[ attributeName ];
-			var attribute = decoder.GetAttributeByUniqueId( dracoGeometry, attributeId );
+
+			var attribute;
+			var attributeID;
+
+			// A Draco file may be created with default vertex attributes, whose attribute IDs
+			// are mapped 1:1 from their semantic name (POSITION, NORMAL, ...). Alternatively,
+			// a Draco file may contain a custom set of attributes, identified by known unique
+			// IDs. glTF files always do the latter, and `.drc` files typically do the former.
+			if ( taskConfig.useUniqueIDs ) {
+
+				attributeID = attributeIDs[ attributeName ];
+				attribute = decoder.GetAttributeByUniqueId( dracoGeometry, attributeID );
+
+			} else {
+
+				attributeID = decoder.GetAttributeId( dracoGeometry, draco[ attributeIDs[ attributeName ] ] );
+
+				if ( attributeID === -1 ) continue;
+
+				attribute = decoder.GetAttribute( dracoGeometry, attributeID );
+
+			}
 
 			geometry.attributes.push( decodeAttribute( draco, decoder, dracoGeometry, attributeName, attributeType, attribute ) );
 

+ 22 - 16
examples/jsm/loaders/FBXLoader.js

@@ -1577,7 +1577,7 @@ var FBXLoader = ( function () {
 		parseMeshGeometry: function ( relationships, geoNode, deformers ) {
 
 			var skeletons = deformers.skeletons;
-			var morphTargets = deformers.morphTargets;
+			var morphTargets = [];
 
 			var modelNodes = relationships.parents.map( function ( parent ) {
 
@@ -1596,13 +1596,15 @@ var FBXLoader = ( function () {
 
 			}, null );
 
-			var morphTarget = relationships.children.reduce( function ( morphTarget, child ) {
+			relationships.children.forEach( function( child ) {
 
-				if ( morphTargets[ child.ID ] !== undefined ) morphTarget = morphTargets[ child.ID ];
+				if ( deformers.morphTargets[ child.ID ] !== undefined ) {
 
-				return morphTarget;
+					morphTargets.push( deformers.morphTargets[ child.ID ] );
 
-			}, null );
+				}
+
+			} );
 
 			// Assume one model and get the preRotation from that
 			// if there is more than one model associated with the geometry this may cause problems
@@ -1619,12 +1621,12 @@ var FBXLoader = ( function () {
 
 			var transform = generateTransform( transformData );
 
-			return this.genGeometry( geoNode, skeleton, morphTarget, transform );
+			return this.genGeometry( geoNode, skeleton, morphTargets, transform );
 
 		},
 
 		// Generate a BufferGeometry from a node in FBXTree.Objects.Geometry
-		genGeometry: function ( geoNode, skeleton, morphTarget, preTransform ) {
+		genGeometry: function ( geoNode, skeleton, morphTargets, preTransform ) {
 
 			var geo = new BufferGeometry();
 			if ( geoNode.attrName ) geo.name = geoNode.attrName;
@@ -1725,7 +1727,7 @@ var FBXLoader = ( function () {
 
 			}
 
-			this.addMorphTargets( geo, geoNode, morphTarget, preTransform );
+			this.addMorphTargets( geo, geoNode, morphTargets, preTransform );
 
 			return geo;
 
@@ -2098,23 +2100,27 @@ var FBXLoader = ( function () {
 
 		},
 
-		addMorphTargets: function ( parentGeo, parentGeoNode, morphTarget, preTransform ) {
+		addMorphTargets: function ( parentGeo, parentGeoNode, morphTargets, preTransform ) {
 
-			if ( morphTarget === null ) return;
+			if ( morphTargets.length === 0 ) return;
 
 			parentGeo.morphAttributes.position = [];
 			// parentGeo.morphAttributes.normal = []; // not implemented
 
-			var self = this;
-			morphTarget.rawTargets.forEach( function ( rawTarget ) {
+			 var self = this;
+			morphTargets.forEach( function( morphTarget ) {
 
-				var morphGeoNode = fbxTree.Objects.Geometry[ rawTarget.geoID ];
+				morphTarget.rawTargets.forEach( function ( rawTarget ) {
 
-				if ( morphGeoNode !== undefined ) {
+					var morphGeoNode = fbxTree.Objects.Geometry[ rawTarget.geoID ];
 
-					self.genMorphGeometry( parentGeo, parentGeoNode, morphGeoNode, preTransform, rawTarget.name );
+					if ( morphGeoNode !== undefined ) {
 
-				}
+						self.genMorphGeometry( parentGeo, parentGeoNode, morphGeoNode, preTransform, rawTarget.name );
+
+					}
+
+				} );
 
 			} );
 

+ 2 - 2
examples/jsm/loaders/MMDLoader.d.ts

@@ -20,11 +20,11 @@ export class MMDLoader extends Loader {
   parser: object | null;
 
   load(url: string, onLoad: (mesh: SkinnedMesh) => void, onProgress?: (event: ProgressEvent) => void, onError?: (event: ErrorEvent) => void): void;
-  loadAnimation(url: string, onLoad: (object: SkinnedMesh | AnimationClip) => void, onProgress?: (event: ProgressEvent) => void, onError?: (event: ErrorEvent) => void): void;
+  loadAnimation(url: string, object: SkinnedMesh | THREE.Camera, onLoad: (object: SkinnedMesh | AnimationClip) => void, onProgress?: (event: ProgressEvent) => void, onError?: (event: ErrorEvent) => void): void;
   loadPMD(url: string, onLoad: (object: object) => void, onProgress?: (event: ProgressEvent) => void, onError?: (event: ErrorEvent) => void): void;
   loadPMX(url: string, onLoad: (object: object) => void, onProgress?: (event: ProgressEvent) => void, onError?: (event: ErrorEvent) => void): void;
   loadVMD(url: string, onLoad: (object: object) => void, onProgress?: (event: ProgressEvent) => void, onError?: (event: ErrorEvent) => void): void;
-  loadVPD(url: string, onLoad: (object: object) => void, onProgress?: (event: ProgressEvent) => void, onError?: (event: ErrorEvent) => void): void;
+  loadVPD(url: string, isUnicode: boolean, onLoad: (object: object) => void, onProgress?: (event: ProgressEvent) => void, onError?: (event: ErrorEvent) => void): void;
   loadWithAnimation(url: string, vmdUrl: string | string[], onLoad: (object: MMDLoaderAnimationObject) => void, onProgress?: (event: ProgressEvent) => void, onError?: (event: ErrorEvent) => void): void;
   setAnimationPath(animationPath: string): this;
 }

+ 0 - 12
examples/jsm/loaders/PlayCanvasLoader.d.ts

@@ -1,12 +0,0 @@
-import {
-  Loader,
-  LoadingManager,
-  Group
-} from '../../../src/Three';
-
-export class PlayCanvasLoader extends Loader {
-  constructor(manager?: LoadingManager);
-
-  load(url: string, onLoad: (group: Group) => void, onProgress?: (event: ProgressEvent) => void, onError?: (event: ErrorEvent) => void): void;
-  parse(json: object): Group;
-}

+ 0 - 211
examples/jsm/loaders/PlayCanvasLoader.js

@@ -1,211 +0,0 @@
-/**
- * @author mrdoob / http://mrdoob.com/
- * @author Mugen87 / https://github.com/Mugen87
- */
-
-import {
-	BufferGeometry,
-	Euler,
-	FileLoader,
-	Float32BufferAttribute,
-	Group,
-	Loader,
-	Mesh,
-	MeshPhongMaterial,
-	Uint16BufferAttribute,
-	Uint8BufferAttribute
-} from "../../../build/three.module.js";
-
-var PlayCanvasLoader = function ( manager ) {
-
-	Loader.call( this, manager );
-
-};
-
-PlayCanvasLoader.prototype = Object.assign( Object.create( Loader.prototype ), {
-
-	constructor: PlayCanvasLoader,
-
-	load: function ( url, onLoad, onProgress, onError ) {
-
-		var scope = this;
-
-		var loader = new FileLoader( scope.manager );
-		loader.setPath( scope.path );
-		loader.load( url, function ( text ) {
-
-			onLoad( scope.parse( JSON.parse( text ) ) );
-
-		}, onProgress, onError );
-
-	},
-
-	parse: function ( json ) {
-
-		function parseVertices( data ) {
-
-			var attributes = {};
-
-			// create a buffer attribute for each array that contains vertex information
-
-			for ( var name in data ) {
-
-				var array = data[ name ];
-
-				var type = array.type;
-				var size = array.components;
-
-				var attribute;
-
-				switch ( type ) {
-
-					case 'float32':
-						attribute = new Float32BufferAttribute( array.data, size );
-						break;
-
-					case 'uint8':
-						attribute = new Uint8BufferAttribute( array.data, size );
-						break;
-
-					case 'uint16':
-						attribute = new Uint16BufferAttribute( array.data, size );
-						break;
-
-					default:
-						console.log( 'THREE.PlayCanvasLoader: Array type "%s" not yet supported.', type );
-
-				}
-
-				attributes[ name ] = attribute;
-
-			}
-
-			data._attributes = attributes;
-
-		}
-
-		function parseMeshes( data ) {
-
-			// create buffer geometry
-
-			var geometry = new BufferGeometry();
-
-			geometry.setIndex( data.indices );
-
-			var attributes = model.vertices[ data.vertices ]._attributes;
-
-			for ( var name in attributes ) {
-
-				var attribute = attributes[ name ];
-
-				if ( name === 'texCoord0' ) name = 'uv';
-
-				geometry.addAttribute( name, attribute );
-
-			}
-
-			data._geometry = geometry;
-
-		}
-
-		function parseMeshInstances( data ) {
-
-			var node = model.nodes[ data.node ];
-			var mesh = model.meshes[ data.mesh ];
-
-			if ( node._geometries === undefined ) {
-
-				node._geometries = [];
-
-			}
-
-			node._geometries.push( mesh._geometry );
-
-		}
-
-		function parseNodes( data ) {
-
-			var object = new Group();
-
-			var geometries = data._geometries;
-
-			if ( geometries !== undefined ) {
-
-				var material = new MeshPhongMaterial();
-
-				for ( var i = 0, l = geometries.length; i < l; i ++ ) {
-
-					var geometry = geometries[ i ];
-
-					object.add( new Mesh( geometry, material ) );
-
-				}
-
-			}
-
-			for ( var i = 0, l = data.rotation.length; i < l; i ++ ) {
-
-				data.rotation[ i ] *= Math.PI / 180;
-
-			}
-
-			//
-
-			object.name = data.name;
-
-			object.position.fromArray( data.position );
-			object.quaternion.setFromEuler( new Euler().fromArray( data.rotation ) );
-			object.scale.fromArray( data.scale );
-
-			data._object = object;
-
-		}
-
-		//
-
-		var model = json.model;
-
-		for ( var i = 0, l = model.vertices.length; i < l; i ++ ) {
-
-			parseVertices( model.vertices[ i ] );
-
-		}
-
-		for ( var i = 0, l = model.meshes.length; i < l; i ++ ) {
-
-			parseMeshes( model.meshes[ i ] );
-
-		}
-
-		for ( var i = 0, l = model.meshInstances.length; i < l; i ++ ) {
-
-			parseMeshInstances( model.meshInstances[ i ] );
-
-		}
-
-		for ( var i = 0, l = model.nodes.length; i < l; i ++ ) {
-
-			parseNodes( model.nodes[ i ] );
-
-		}
-
-		// setup scene hierarchy
-
-		for ( var i = 0, l = model.parents.length; i < l; i ++ ) {
-
-			var parent = model.parents[ i ];
-
-			if ( parent === - 1 ) continue;
-
-			model.nodes[ parent ]._object.add( model.nodes[ i ]._object );
-
-
-		}
-
-		return model.nodes[ 0 ]._object;
-
-	}
-
-} );
-
-export { PlayCanvasLoader };

+ 1 - 1
examples/jsm/loaders/VTKLoader.d.ts

@@ -4,7 +4,7 @@ import {
   LoadingManager
 } from '../../../src/Three';
 
-export class VRMLLoader extends Loader {
+export class VTKLoader extends Loader {
   constructor(manager?: LoadingManager);
 
   load(url: string, onLoad: (geometry: BufferGeometry) => void, onProgress?: (event: ProgressEvent) => void, onError?: (event: ErrorEvent) => void): void;

+ 7 - 7
examples/jsm/loaders/obj2/utils/CodeSerializer.js

@@ -21,8 +21,8 @@ const CodeSerializer = {
 			part = serializationTarget[ name ];
 			if ( typeof ( part ) === 'string' || part instanceof String ) {
 
-				part = part.replace( '\n', '\\n' );
-				part = part.replace( '\r', '\\r' );
+				part = part.replace( /\n/g, '\\n' );
+				part = part.replace( /\r/g, '\\r' );
 				objectString += '\t' + name + ': "' + part + '",\n';
 
 			} else if ( part instanceof Array ) {
@@ -31,7 +31,7 @@ const CodeSerializer = {
 
 			} else if ( typeof part === 'object' ) {
 
-				console.log( 'Omitting object "' + name + '" and replace it with empty object.');
+				console.log( 'Omitting object "' + name + '" and replace it with empty object.' );
 				objectString += '\t' + name + ': {},\n';
 
 			} else {
@@ -75,7 +75,7 @@ const CodeSerializer = {
 
 			if ( name === 'constructor' ) {
 
-				if ( !funcInstructions.isRemoveCode() ) {
+				if ( ! funcInstructions.isRemoveCode() ) {
 
 					constructorString = fullObjectName + ' = ' + funcInstructions.getCode() + ';\n\n';
 
@@ -89,7 +89,7 @@ const CodeSerializer = {
 					funcInstructions = funcTemp;
 
 				}
-				if ( !funcInstructions.isRemoveCode() ) {
+				if ( ! funcInstructions.isRemoveCode() ) {
 
 					if ( isExtended ) {
 
@@ -136,7 +136,7 @@ const CodeSerializer = {
 
 				} else if ( typeof objectPart === 'object' ) {
 
-					console.log( 'Omitting object "' + funcInstructions.getName() + '" and replace it with empty object.');
+					console.log( 'Omitting object "' + funcInstructions.getName() + '" and replace it with empty object.' );
 					funcInstructions.setCode( "{}" );
 
 				} else {
@@ -257,7 +257,7 @@ CodeSerializationInstruction.prototype = {
 	 * Returns the serialized function code
 	 * @return {String}
 	 */
-	getCode: function() {
+	getCode: function () {
 
 		return this.code;
 

+ 4 - 4
examples/jsm/postprocessing/OutlinePass.js

@@ -530,18 +530,18 @@ OutlinePass.prototype = Object.assign( Object.create( Pass.prototype ), {
 				void main() {\
 					vec2 invSize = 1.0 / texSize;\
 					float weightSum = gaussianPdf(0.0, kernelRadius);\
-					vec3 diffuseSum = texture2D( colorTexture, vUv).rgb * weightSum;\
+					vec4 diffuseSum = texture2D( colorTexture, vUv) * weightSum;\
 					vec2 delta = direction * invSize * kernelRadius/float(MAX_RADIUS);\
 					vec2 uvOffset = delta;\
 					for( int i = 1; i <= MAX_RADIUS; i ++ ) {\
 						float w = gaussianPdf(uvOffset.x, kernelRadius);\
-						vec3 sample1 = texture2D( colorTexture, vUv + uvOffset).rgb;\
-						vec3 sample2 = texture2D( colorTexture, vUv - uvOffset).rgb;\
+						vec4 sample1 = texture2D( colorTexture, vUv + uvOffset);\
+						vec4 sample2 = texture2D( colorTexture, vUv - uvOffset);\
 						diffuseSum += ((sample1 + sample2) * w);\
 						weightSum += (2.0 * w);\
 						uvOffset += delta;\
 					}\
-					gl_FragColor = vec4(diffuseSum/weightSum, 1.0);\
+					gl_FragColor = diffuseSum/weightSum;\
 				}"
 		} );
 

+ 2 - 2
examples/jsm/renderers/WebGLDeferredRenderer.d.ts

@@ -8,9 +8,9 @@ import {
 export interface WebGLDeferredRendererParameters {
   antialias?: boolean;
   cacheKeepAlive?: boolean;
-  height?: Vector2;
+  height?: number;
   renderer?: WebGLRenderer;
-  width?: Vector2;
+  width?: number;
 }
 
 export class WebGLDeferredRenderer {

+ 9 - 19
examples/webgl_interactive_draggablecubes.html → examples/misc_controls_drag.html

@@ -1,7 +1,7 @@
 <!DOCTYPE html>
 <html lang="en">
 	<head>
-		<title>three.js webgl - draggable cubes</title>
+		<title>three.js webgl - drag controls</title>
 		<meta charset="utf-8">
 		<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
 		<link type="text/css" rel="stylesheet" href="main.css">
@@ -18,7 +18,7 @@
 	<body>
 
 		<div id="info">
-			<a href="http://threejs.org" target="_blank" rel="noopener">three.js</a> webgl - draggable cubes
+			<a href="https://threejs.org" target="_blank" rel="noopener">three.js</a> webgl - drag controls
 		</div>
 
 		<script type="module">
@@ -27,11 +27,10 @@
 
 			import Stats from './jsm/libs/stats.module.js';
 
-			import { TrackballControls } from './jsm/controls/TrackballControls.js';
 			import { DragControls } from './jsm/controls/DragControls.js';
 
 			var container, stats;
-			var camera, controls, scene, renderer;
+			var camera, scene, renderer;
 			var objects = [];
 
 			init();
@@ -98,24 +97,17 @@
 
 				container.appendChild( renderer.domElement );
 
-				controls = new TrackballControls( camera, renderer.domElement );
-				controls.rotateSpeed = 1.0;
-				controls.zoomSpeed = 1.2;
-				controls.panSpeed = 0.8;
-				controls.noZoom = false;
-				controls.noPan = false;
-				controls.staticMoving = true;
-				controls.dynamicDampingFactor = 0.3;
+				var controls = new DragControls( objects, camera, renderer.domElement );
 
-				var dragControls = new DragControls( objects, camera, renderer.domElement );
-				dragControls.addEventListener( 'dragstart', function () {
+				controls.addEventListener( 'dragstart', function ( event ) {
 
-					controls.enabled = false;
+					event.object.material.emissive.set( 0xaaaaaa );
 
 				} );
-				dragControls.addEventListener( 'dragend', function () {
 
-					controls.enabled = true;
+				controls.addEventListener( 'dragend', function ( event ) {
+
+					event.object.material.emissive.set( 0x000000 );
 
 				} );
 
@@ -150,8 +142,6 @@
 
 			function render() {
 
-				controls.update();
-
 				renderer.render( scene, camera );
 
 			}

+ 54 - 20
examples/misc_controls_trackball.html

@@ -27,19 +27,30 @@
 			import * as THREE from '../build/three.module.js';
 
 			import Stats from './jsm/libs/stats.module.js';
+			import { GUI } from './jsm/libs/dat.gui.module.js';
 
 			import { TrackballControls } from './jsm/controls/TrackballControls.js';
 
+			var perspectiveCamera, orthographicCamera, controls, scene, renderer, stats;
 
-			var camera, controls, scene, renderer, stats;
+			var params = {
+				orthographicCamera: false
+			};
+
+			var frustumSize = 400;
 
 			init();
 			animate();
 
 			function init() {
 
-				camera = new THREE.PerspectiveCamera( 60, window.innerWidth / window.innerHeight, 1, 1000 );
-				camera.position.z = 500;
+				var aspect = window.innerWidth / window.innerHeight;
+
+				perspectiveCamera = new THREE.PerspectiveCamera( 60, aspect, 1, 1000 );
+				perspectiveCamera.position.z = 500;
+
+				orthographicCamera = new THREE.OrthographicCamera( frustumSize * aspect / - 2, frustumSize * aspect / 2, frustumSize / 2, frustumSize / - 2, 1, 1000 );
+				orthographicCamera.position.z = 500;
 
 				// world
 
@@ -62,7 +73,6 @@
 
 				}
 
-
 				// lights
 
 				var light = new THREE.DirectionalLight( 0xffffff );
@@ -76,7 +86,6 @@
 				var light = new THREE.AmbientLight( 0x222222 );
 				scene.add( light );
 
-
 				// renderer
 
 				renderer = new THREE.WebGLRenderer( { antialias: true } );
@@ -84,38 +93,61 @@
 				renderer.setSize( window.innerWidth, window.innerHeight );
 				document.body.appendChild( renderer.domElement );
 
-				controls = new TrackballControls( camera, renderer.domElement );
+				stats = new Stats();
+				document.body.appendChild( stats.dom );
 
-				controls.rotateSpeed = 1.0;
-				controls.zoomSpeed = 1.2;
-				controls.panSpeed = 0.8;
+				//
 
-				controls.noZoom = false;
-				controls.noPan = false;
+				var gui = new GUI();
+				gui.add( params, 'orthographicCamera' ).name( 'use orthographic' ).onChange( function ( value ) {
 
-				controls.staticMoving = true;
-				controls.dynamicDampingFactor = 0.3;
+					controls.dispose();
 
-				controls.keys = [ 65, 83, 68 ];
+					createControls( value ? orthographicCamera : perspectiveCamera );
 
-				controls.addEventListener( 'change', render );
+					render();
 
-				stats = new Stats();
-				document.body.appendChild( stats.dom );
+				} );
 
 				//
 
 				window.addEventListener( 'resize', onWindowResize, false );
-				//
+
+				createControls( perspectiveCamera );
 
 				render();
 
 			}
 
+			function createControls( camera ) {
+
+				controls = new TrackballControls( camera, renderer.domElement );
+
+				controls.rotateSpeed = 1.0;
+				controls.zoomSpeed = 1.2;
+				controls.panSpeed = 0.8;
+
+				controls.staticMoving = true;
+				controls.dynamicDampingFactor = 0.3;
+
+				controls.keys = [ 65, 83, 68 ];
+
+				controls.addEventListener( 'change', render );
+
+			}
+
 			function onWindowResize() {
 
-				camera.aspect = window.innerWidth / window.innerHeight;
-				camera.updateProjectionMatrix();
+				var aspect = window.innerWidth / window.innerHeight;
+
+				perspectiveCamera.aspect = aspect;
+				perspectiveCamera.updateProjectionMatrix();
+
+				orthographicCamera.left = - frustumSize * aspect / 2;
+				orthographicCamera.right = frustumSize * aspect / 2;
+				orthographicCamera.top = frustumSize / 2;
+				orthographicCamera.bottom = - frustumSize / 2;
+				orthographicCamera.updateProjectionMatrix();
 
 				renderer.setSize( window.innerWidth, window.innerHeight );
 
@@ -137,6 +169,8 @@
 
 			function render() {
 
+				var camera = ( params.orthographicCamera ) ? orthographicCamera : perspectiveCamera;
+
 				renderer.render( scene, camera );
 
 			}

+ 0 - 148
examples/misc_controls_trackball_orthographic.html

@@ -1,148 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-	<head>
-		<title>three.js webgl - orthographic trackball controls</title>
-		<meta charset="utf-8">
-		<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
-		<link type="text/css" rel="stylesheet" href="main.css">
-		<style>
-			body {
-				background-color: #ccc;
-				color: #000;
-			}
-			a {
-				color: #f00;
-			}
-		</style>
-	</head>
-
-	<body>
-		<div id="info">
-			<a href="https://threejs.org" target="_blank" rel="noopener">three.js</a> - orthographic trackball controls<br />
-			MOVE mouse &amp; press LEFT: rotate, MIDDLE: zoom, RIGHT: pan
-		</div>
-
-		<script type="module">
-
-			import * as THREE from '../build/three.module.js';
-
-			import Stats from './jsm/libs/stats.module.js';
-
-			import { OrthographicTrackballControls } from './jsm/controls/OrthographicTrackballControls.js';
-
-			var camera, controls, scene, renderer, stats;
-
-			init();
-			animate();
-
-			function init() {
-
-				camera = new THREE.OrthographicCamera( window.innerWidth / - 2, window.innerWidth / 2, window.innerHeight / 2, window.innerHeight / - 2, 1, 2000 );
-				camera.position.z = 1000;
-
-				// world
-
-				scene = new THREE.Scene();
-				scene.background = new THREE.Color( 0xcccccc );
-				scene.fog = new THREE.FogExp2( 0xcccccc, 0.001 );
-
-				var geometry = new THREE.CylinderBufferGeometry( 0, 10, 30, 4, 1 );
-				var material = new THREE.MeshPhongMaterial( { color: 0xffffff, flatShading: true } );
-
-				for ( var i = 0; i < 500; i ++ ) {
-
-					var mesh = new THREE.Mesh( geometry, material );
-					mesh.position.x = ( Math.random() - 0.5 ) * 1000;
-					mesh.position.y = ( Math.random() - 0.5 ) * 1000;
-					mesh.position.z = ( Math.random() - 0.5 ) * 1000;
-					mesh.updateMatrix();
-					mesh.matrixAutoUpdate = false;
-					scene.add( mesh );
-
-				}
-
-				// lights
-
-				var light = new THREE.DirectionalLight( 0xffffff );
-				light.position.set( 1, 1, 1 );
-				scene.add( light );
-
-				var light = new THREE.DirectionalLight( 0x002288 );
-				light.position.set( - 1, - 1, - 1 );
-				scene.add( light );
-
-				var light = new THREE.AmbientLight( 0x222222 );
-				scene.add( light );
-
-
-				// renderer
-
-				renderer = new THREE.WebGLRenderer( { antialias: true } );
-				renderer.setPixelRatio( window.devicePixelRatio );
-				renderer.setSize( window.innerWidth, window.innerHeight );
-				document.body.appendChild( renderer.domElement );
-
-				controls = new OrthographicTrackballControls( camera, renderer.domElement );
-
-				controls.rotateSpeed = 1.0;
-				controls.zoomSpeed = 1.2;
-
-				controls.noZoom = false;
-				controls.noPan = false;
-
-				controls.staticMoving = true;
-				controls.dynamicDampingFactor = 0.3;
-
-				controls.keys = [ 65, 83, 68 ];
-
-				controls.addEventListener( 'change', render );
-
-				stats = new Stats();
-				document.body.appendChild( stats.dom );
-
-				//
-
-				window.addEventListener( 'resize', onWindowResize, false );
-				//
-
-				render();
-
-			}
-
-			function onWindowResize() {
-
-				camera.left = window.innerWidth / - 2;
-				camera.right = window.innerWidth / 2;
-				camera.top = window.innerHeight / 2;
-				camera.bottom = window.innerHeight / - 2;
-				camera.updateProjectionMatrix();
-
-				renderer.setSize( window.innerWidth, window.innerHeight );
-
-				controls.handleResize();
-
-				render();
-
-			}
-
-			function animate() {
-
-				requestAnimationFrame( animate );
-
-				controls.update();
-
-				stats.update();
-
-			}
-
-			function render() {
-
-				renderer.render( scene, camera );
-
-			}
-
-
-		</script>
-
-	</body>
-</html>

+ 0 - 341
examples/misc_fps.html

@@ -1,341 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-	<head>
-		<title>three.js - platformer demo</title>
-		<meta charset="utf-8">
-		<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
-		<link type="text/css" rel="stylesheet" href="main.css">
-	</head>
-	<body>
-
-		<div id="info"><a href="http://threejs.org" target="_blank" rel="noopener">three.js</a> - platformer demo. cubemap by <a href="http://www.zfight.com/" target="_blank" rel="noopener">Jochum Skoglund</a>.<br />Use arrow keys to look around, WASD to move and SPACE to jump.</div>
-
-		<script type="module">
-
-			import * as THREE from '../build/three.module.js';
-
-			// player motion parameters
-
-			var motion = {
-				airborne: false,
-				position: new THREE.Vector3(), velocity: new THREE.Vector3(),
-				rotation: new THREE.Vector2(), spinning: new THREE.Vector2()
-			};
-
-			motion.position.y = - 150;
-
-
-			// game systems code
-
-			var resetPlayer = function () {
-
-				if ( motion.position.y < - 123 ) {
-
-					motion.position.set( - 2, 7.7, 25 );
-					motion.velocity.multiplyScalar( 0 );
-
-				}
-
-			};
-
-			var keyboardControls = ( function () {
-
-				var keys = { SP: 32, W: 87, A: 65, S: 83, D: 68, UP: 38, LT: 37, DN: 40, RT: 39 };
-
-				var keysPressed = {};
-
-				( function ( watchedKeyCodes ) {
-
-					var handler = function ( down ) {
-
-						return function ( e ) {
-
-							var index = watchedKeyCodes.indexOf( e.keyCode );
-							if ( index >= 0 ) {
-
-								keysPressed[ watchedKeyCodes[ index ] ] = down;
-								e.preventDefault();
-
-							}
-
-						};
-
-					};
-					window.addEventListener( "keydown", handler( true ), false );
-					window.addEventListener( "keyup", handler( false ), false );
-
-				} )( [
-					keys.SP, keys.W, keys.A, keys.S, keys.D, keys.UP, keys.LT, keys.DN, keys.RT
-				] );
-
-				var forward = new THREE.Vector3();
-				var sideways = new THREE.Vector3();
-
-				return function () {
-
-					if ( ! motion.airborne ) {
-
-						// look around
-						var sx = keysPressed[ keys.UP ] ? 0.03 : ( keysPressed[ keys.DN ] ? - 0.03 : 0 );
-						var sy = keysPressed[ keys.LT ] ? 0.03 : ( keysPressed[ keys.RT ] ? - 0.03 : 0 );
-
-						if ( Math.abs( sx ) >= Math.abs( motion.spinning.x ) ) motion.spinning.x = sx;
-						if ( Math.abs( sy ) >= Math.abs( motion.spinning.y ) ) motion.spinning.y = sy;
-
-						// move around
-						forward.set( Math.sin( motion.rotation.y ), 0, Math.cos( motion.rotation.y ) );
-						sideways.set( forward.z, 0, - forward.x );
-
-						forward.multiplyScalar( keysPressed[ keys.W ] ? - 0.1 : ( keysPressed[ keys.S ] ? 0.1 : 0 ) );
-						sideways.multiplyScalar( keysPressed[ keys.A ] ? - 0.1 : ( keysPressed[ keys.D ] ? 0.1 : 0 ) );
-
-						var combined = forward.add( sideways );
-						if ( Math.abs( combined.x ) >= Math.abs( motion.velocity.x ) ) motion.velocity.x = combined.x;
-						if ( Math.abs( combined.y ) >= Math.abs( motion.velocity.y ) ) motion.velocity.y = combined.y;
-						if ( Math.abs( combined.z ) >= Math.abs( motion.velocity.z ) ) motion.velocity.z = combined.z;
-
-						//jump
- 						var vy = keysPressed[ keys.SP ] ? 0.7 : 0;
- 						motion.velocity.y += vy;
-
-					}
-
-				};
-
-			} )();
-
-			var jumpPads = ( function () {
-
-				var pads = [ new THREE.Vector3( - 17.5, 8, - 10 ), new THREE.Vector3( 17.5, 8, - 10 ), new THREE.Vector3( 0, 8, 21 ) ];
-				var temp = new THREE.Vector3();
-
-				return function () {
-
-					if ( ! motion.airborne ) {
-
-						for ( var j = 0, n = pads.length; j < n; j ++ ) {
-
-							if ( pads[ j ].distanceToSquared( motion.position ) < 2.3 ) {
-
-								// calculate velocity towards another side of platform from jump pad position
-								temp.copy( pads[ j ] );
-								temp.y = 0;
-								temp.setLength( - 0.8 );
-								temp.y = 0.7;
-
-								motion.airborne = true;
-								motion.velocity.copy( temp );
-								break;
-
-							}
-
-						}
-
-					}
-
-				};
-
-			} )();
-
-			var applyPhysics = ( function () {
-
-				var timeStep = 5;
-				var timeLeft = timeStep + 1;
-
-				var birdsEye = 100;
-				var kneeDeep = 0.4;
-
-				var raycaster = new THREE.Raycaster();
-				raycaster.ray.direction.set( 0, - 1, 0 );
-
-				var angles = new THREE.Vector2();
-				var displacement = new THREE.Vector3();
-
-				return function ( dt ) {
-
-					var platform = scene.getObjectByName( "platform", true );
-					if ( platform ) {
-
-						timeLeft += dt;
-
-						// run several fixed-step iterations to approximate varying-step
-
-						dt = 5;
-						while ( timeLeft >= dt ) {
-
-							var time = 0.3, damping = 0.93, gravity = 0.01, tau = 2 * Math.PI;
-
-							raycaster.ray.origin.copy( motion.position );
-							raycaster.ray.origin.y += birdsEye;
-
-							var hits = raycaster.intersectObject( platform );
-
-							motion.airborne = true;
-
-							// are we above, or at most knee deep in, the platform?
-
-							if ( ( hits.length > 0 ) && ( hits[ 0 ].face.normal.y > 0 ) ) {
-
-								var actualHeight = hits[ 0 ].distance - birdsEye;
-
-								// collision: stick to the surface if landing on it
-
-								if ( ( motion.velocity.y <= 0 ) && ( Math.abs( actualHeight ) < kneeDeep ) ) {
-
-									motion.position.y -= actualHeight;
-									motion.velocity.y = 0;
-									motion.airborne = false;
-
-								}
-
-							}
-
-							if ( motion.airborne ) motion.velocity.y -= gravity;
-
-							angles.copy( motion.spinning ).multiplyScalar( time );
-							if ( ! motion.airborne ) motion.spinning.multiplyScalar( damping );
-
-							displacement.copy( motion.velocity ).multiplyScalar( time );
-							if ( ! motion.airborne ) motion.velocity.multiplyScalar( damping );
-
-							motion.rotation.add( angles );
-							motion.position.add( displacement );
-
-							// limit the tilt at ±0.4 radians
-
-							motion.rotation.x = Math.max( - 0.4, Math.min( + 0.4, motion.rotation.x ) );
-
-							// wrap horizontal rotation to 0...2π
-
-							motion.rotation.y += tau;
-							motion.rotation.y %= tau;
-
-							timeLeft -= dt;
-
-						}
-
-					}
-
-				};
-
-			} )();
-
-			var updateCamera = ( function () {
-
-				var euler = new THREE.Euler( 0, 0, 0, 'YXZ' );
-
-				return function () {
-
-					euler.x = motion.rotation.x;
-					euler.y = motion.rotation.y;
-					camera.quaternion.setFromEuler( euler );
-
-					camera.position.copy( motion.position );
-
-					camera.position.y += 3.0;
-
-				};
-
-			} )();
-
-
-			// init 3D stuff
-
-			function makePlatform( url ) {
-
-				var placeholder = new THREE.Object3D();
-
-				var loader = new THREE.ObjectLoader();
-				loader.load( url, function ( platform ) {
-
-					placeholder.add( platform );
-
-				} );
-
-				return placeholder;
-
-			}
-
-			var renderer = new THREE.WebGLRenderer( { antialias: true } );
-			renderer.setPixelRatio( window.devicePixelRatio );
-			document.body.appendChild( renderer.domElement );
-
-			var camera = new THREE.PerspectiveCamera( 60, 1, 0.1, 9000 );
-
-			var scene = new THREE.Scene();
-
-			var envMap = new THREE.CubeTextureLoader().load( [
-				'textures/cube/skybox/px.jpg', // right
-				'textures/cube/skybox/nx.jpg', // left
-				'textures/cube/skybox/py.jpg', // top
-				'textures/cube/skybox/ny.jpg', // bottom
-				'textures/cube/skybox/pz.jpg', // back
-				'textures/cube/skybox/nz.jpg' // front
-			] );
-			envMap.format = THREE.RGBFormat;
-
-			scene.background = envMap;
-
-			scene.add( makePlatform(
-				'models/json/platform/platform.json'
-			) );
-
-			// start the game
-
-			var start = function ( gameLoop, gameViewportSize ) {
-
-				var resize = function () {
-
-					var viewport = gameViewportSize();
-					renderer.setSize( viewport.width, viewport.height );
-					camera.aspect = viewport.width / viewport.height;
-					camera.updateProjectionMatrix();
-
-				};
-
-				window.addEventListener( 'resize', resize, false );
-				resize();
-
-				var lastTimeStamp;
-				var render = function ( timeStamp ) {
-
-					var timeElapsed = lastTimeStamp ? timeStamp - lastTimeStamp : 0;
-					lastTimeStamp = timeStamp;
-
-					// call our game loop with the time elapsed since last rendering, in ms
-					gameLoop( timeElapsed );
-
-					renderer.render( scene, camera );
-					requestAnimationFrame( render );
-
-				};
-
-				requestAnimationFrame( render );
-
-			};
-
-
-			var gameLoop = function ( dt ) {
-
-				resetPlayer();
-				keyboardControls();
-				jumpPads();
-				applyPhysics( dt );
-				updateCamera();
-
-			};
-
-			var gameViewportSize = function () {
-
-				return {
-
-					width: window.innerWidth, height: window.innerHeight
-
-				};
-
-			};
-
-			start( gameLoop, gameViewportSize );
-		</script>
-	</body>
-</html>

BIN
examples/models/awd/simple/simple.awd


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