Browse Source

Merge branch 'dev-fix-warnings' of https://github.com/sunag/three.js into dev-fix-warnings

sunag 6 years ago
parent
commit
de4ec95f8c
100 changed files with 3520 additions and 2021 deletions
  1. 15 0
      .editorconfig
  2. 1 1
      .github/ISSUE_TEMPLATE.md
  3. 0 1
      .npmignore
  4. 1 1
      README.md
  5. 325 624
      build/three.js
  6. 411 410
      build/three.min.js
  7. 323 622
      build/three.module.js
  8. 1 1
      docs/api/en/audio/Audio.html
  9. 1 1
      docs/api/en/audio/AudioAnalyser.html
  10. 4 4
      docs/api/en/audio/AudioListener.html
  11. 2 2
      docs/api/en/audio/PositionalAudio.html
  12. 1 0
      docs/api/en/constants/Renderer.html
  13. 4 2
      docs/api/en/core/Object3D.html
  14. 4 1
      docs/api/en/extras/core/ShapePath.html
  15. 73 0
      docs/api/en/helpers/PositionalAudioHelper.html
  16. 4 5
      docs/api/en/loaders/AnimationLoader.html
  17. 10 0
      docs/api/en/loaders/ImageBitmapLoader.html
  18. 1 1
      docs/api/en/loaders/ImageLoader.html
  19. 24 0
      docs/api/en/loaders/Loader.html
  20. 8 1
      docs/api/en/materials/Material.html
  21. 131 0
      docs/api/en/materials/MeshDistanceMaterial.html
  22. 150 0
      docs/api/en/materials/MeshMatcapMaterial.html
  23. 61 1
      docs/api/en/materials/MeshNormalMaterial.html
  24. 1 1
      docs/api/en/math/Matrix3.html
  25. 1 1
      docs/api/en/math/Matrix4.html
  26. 7 0
      docs/api/en/math/Quaternion.html
  27. 1 1
      docs/api/en/objects/Mesh.html
  28. 0 6
      docs/api/en/renderers/WebGLRenderTargetCube.html
  29. 65 47
      docs/api/en/renderers/WebGLRenderer.html
  30. 10 2
      docs/api/en/textures/DataTexture3D.html
  31. 15 3
      docs/api/en/textures/Texture.html
  32. 1 1
      docs/api/zh/audio/Audio.html
  33. 1 1
      docs/api/zh/audio/AudioAnalyser.html
  34. 4 4
      docs/api/zh/audio/AudioListener.html
  35. 2 2
      docs/api/zh/audio/PositionalAudio.html
  36. 2 2
      docs/api/zh/core/Object3D.html
  37. 73 0
      docs/api/zh/helpers/PositionalAudioHelper.html
  38. 4 7
      docs/api/zh/loaders/AnimationLoader.html
  39. 10 0
      docs/api/zh/loaders/ImageBitmapLoader.html
  40. 20 0
      docs/api/zh/loaders/Loader.html
  41. 5 1
      docs/api/zh/materials/Material.html
  42. 112 0
      docs/api/zh/materials/MeshDistanceMaterial.html
  43. 120 0
      docs/api/zh/materials/MeshMatcapMaterial.html
  44. 42 1
      docs/api/zh/materials/MeshNormalMaterial.html
  45. 3 3
      docs/api/zh/math/Matrix3.html
  46. 5 5
      docs/api/zh/math/Matrix4.html
  47. 8 1
      docs/api/zh/math/Quaternion.html
  48. 1 1
      docs/api/zh/objects/Mesh.html
  49. 0 5
      docs/api/zh/renderers/WebGLRenderTargetCube.html
  50. 6 27
      docs/api/zh/renderers/WebGLRenderer.html
  51. 13 1
      docs/api/zh/textures/Texture.html
  52. 1 0
      docs/examples/exporters/GLTFExporter.html
  53. 145 0
      docs/examples/loaders/DRACOLoader.html
  54. 3 0
      docs/examples/loaders/GLTFLoader.html
  55. 1 1
      docs/examples/loaders/OBJLoader2.html
  56. 2 1
      docs/examples/loaders/SVGLoader.html
  57. 2 3
      docs/examples/objects/Lensflare.html
  58. 60 0
      docs/examples/utils/SkeletonUtils.html
  59. 15 0
      docs/index.html
  60. 13 2
      docs/list.js
  61. 133 0
      docs/manual/en/introduction/How-to-dispose-of-objects.html
  62. 1 0
      docs/manual/en/introduction/Loading-3D-models.html
  63. 7 7
      docs/manual/en/introduction/Matrix-transformations.html
  64. 4 0
      docs/manual/en/introduction/Useful-links.html
  65. 1 1
      docs/manual/zh/introduction/Creating-a-scene.html
  66. 125 0
      docs/manual/zh/introduction/How-to-dispose-of-objects.html
  67. 7 7
      docs/manual/zh/introduction/Matrix-transformations.html
  68. 118 49
      docs/scenes/js/material.js
  69. 48 0
      editor/css/dark.css
  70. 48 0
      editor/css/light.css
  71. 0 2
      editor/examples/arkanoid.app.json
  72. 0 2
      editor/examples/camera.app.json
  73. 0 2
      editor/examples/particles.app.json
  74. 0 2
      editor/examples/pong.app.json
  75. 0 2
      editor/examples/shaders.app.json
  76. BIN
      editor/images/icon.png
  77. BIN
      editor/images/icon.xcf
  78. 25 20
      editor/index.html
  79. 0 2
      editor/js/Config.js
  80. 76 15
      editor/js/Editor.js
  81. 26 11
      editor/js/Loader.js
  82. 42 19
      editor/js/Menubar.Add.js
  83. 1 1
      editor/js/Menubar.Edit.js
  84. 65 5
      editor/js/Sidebar.Animation.js
  85. 1 1
      editor/js/Sidebar.Geometry.BufferGeometry.js
  86. 1 1
      editor/js/Sidebar.Geometry.Geometry.js
  87. 1 1
      editor/js/Sidebar.Geometry.Modifiers.js
  88. 185 0
      editor/js/Sidebar.Geometry.TubeGeometry.js
  89. 3 1
      editor/js/Sidebar.Geometry.js
  90. 139 6
      editor/js/Sidebar.Material.js
  91. 2 2
      editor/js/Sidebar.Object.js
  92. 5 28
      editor/js/Sidebar.Project.js
  93. 3 3
      editor/js/Sidebar.Scene.js
  94. 1 1
      editor/js/Sidebar.Settings.js
  95. 14 4
      editor/js/Strings.js
  96. 48 0
      editor/js/Viewport.Camera.js
  97. 3 3
      editor/js/Viewport.Info.js
  98. 56 12
      editor/js/Viewport.js
  99. 1 2
      editor/js/libs/app.js
  100. 1 1
      editor/js/libs/codemirror/mode/glsl.js

+ 15 - 0
.editorconfig

@@ -0,0 +1,15 @@
+# http://editorconfig.org
+
+root = true
+
+[*]
+end_of_line = lf
+insert_final_newline = true
+
+[*.{js,ts,html}]
+charset = utf-8
+indent_style = tab
+indent_size = 2
+
+[*.{js,ts}]
+trim_trailing_whitespace = true

+ 1 - 1
.github/ISSUE_TEMPLATE.md

@@ -19,7 +19,7 @@ Please also include a live example if possible. You can start from these templat
 ##### Three.js version
 
 - [ ] Dev
-- [ ] r100
+- [ ] r103
 - [ ] ...
 
 ##### Browser

+ 0 - 1
.npmignore

@@ -1,6 +1,5 @@
 examples/*
 !examples/js/
-src/
 test/
 utils/
 docs/

+ 1 - 1
README.md

@@ -10,7 +10,7 @@ three.js
 
 #### JavaScript 3D library ####
 
-The aim of the project is to create an easy to use, lightweight, 3D library. The library provides Canvas 2D, SVG, CSS3D and WebGL renderers.
+The aim of the project is to create an easy to use, lightweight, 3D library with a default WebGL renderer. The library also provides Canvas 2D, SVG and CSS3D renderers in the examples.
 
 [Examples](http://threejs.org/examples/) —
 [Documentation](http://threejs.org/docs/) —

File diff suppressed because it is too large
+ 325 - 624
build/three.js


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


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


+ 1 - 1
docs/api/en/audio/Audio.html

@@ -22,7 +22,7 @@
 		<h2>Example</h2>
 
 		<p>
-			[example:webaudio_sandbox webaudio / sandbox ]</br>
+			[example:webaudio_sandbox webaudio / sandbox ]<br />
 			[example:webaudio_visualizer webaudio / visualizer ]
 		</p>
 

+ 1 - 1
docs/api/en/audio/AudioAnalyser.html

@@ -22,7 +22,7 @@
 		<h2>Example</h2>
 
 		<p>
-			[example:webaudio_sandbox webaudio / sandbox ]</br>
+			[example:webaudio_sandbox webaudio / sandbox ]<br />
 			[example:webaudio_visualizer webaudio / visualizer ]
 		</p>
 

+ 4 - 4
docs/api/en/audio/AudioListener.html

@@ -13,8 +13,8 @@
 		<h1>[name]</h1>
 
 		<p class="desc">
-			The [name] represents a virtual [link:https://developer.mozilla.org/de/docs/Web/API/AudioListener listener] of the all positional and non-positional audio effects in the scene.</br>
-			A three.js application usually creates a single instance of [name]. It is a mandatory construtor parameter for audios entities like [page:Audio Audio] and [page:PositionalAudio PositionalAudio].</br>
+			The [name] represents a virtual [link:https://developer.mozilla.org/de/docs/Web/API/AudioListener listener] of the all positional and non-positional audio effects in the scene.<br />
+			A three.js application usually creates a single instance of [name]. It is a mandatory construtor parameter for audios entities like [page:Audio Audio] and [page:PositionalAudio PositionalAudio].<br />
 			In most cases, the listener object is a child of the camera. So the 3D transformation of the camera represents the 3D transformation of the listener.
 		</p>
 
@@ -22,8 +22,8 @@
 		<h2>Example</h2>
 
 		<p>
-			[example:webaudio_sandbox webaudio / sandbox ]</br>
-			[example:webaudio_timing webaudio / timing ]</br>
+			[example:webaudio_sandbox webaudio / sandbox ]<br />
+			[example:webaudio_timing webaudio / timing ]<br />
 			[example:webaudio_visualizer webaudio / visualizer ]
 		</p>
 

+ 2 - 2
docs/api/en/audio/PositionalAudio.html

@@ -22,8 +22,8 @@
 		<h2>Example</h2>
 
 		<p>
-			[example:webaudio_orientation webaudio / orientation ]</br>
-			[example:webaudio_sandbox webaudio / sandbox ]</br>
+			[example:webaudio_orientation webaudio / orientation ]<br />
+			[example:webaudio_sandbox webaudio / sandbox ]<br />
 			[example:webaudio_timing webaudio / timing ]
 		</p>
 

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

@@ -55,6 +55,7 @@
 		THREE.ReinhardToneMapping
 		THREE.Uncharted2ToneMapping
 		THREE.CineonToneMapping
+		THREE.ACESFilmicToneMapping
 		</code>
 		<p>
 		These define the WebGLRenderer's [page:WebGLRenderer.toneMapping toneMapping] property.

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

@@ -46,7 +46,7 @@
 
 		<h3>[property:Material customDistanceMaterial]</h3>
 		<p>
-		Same as customDepthMaterial, but used with [page:PointLight]. Default is *undefined*.
+		Same as [page:.customDepthMaterial customDepthMaterial], but used with [page:PointLight]. Default is *undefined*.
 		</p>
 
 		<h3>[property:Boolean frustumCulled]</h3>
@@ -229,6 +229,8 @@
 		recursive -- if true, descendants of the object are also copied. Default is true.<br /><br />
 
 		Copy the given object into this object.
+
+		Note: event listeners and user-defined callbacks ([page:.onAfterRender] and [page:.onBeforeRender]) are not copied.
 		</p>
 
 		<h3>[method:Object3D getObjectById]( [param:Integer id] )</h3>
@@ -292,7 +294,7 @@
 		Converts the vector from local space to world space.
 		</p>
 
-		<h3>[method:null lookAt]( [param:Vector3 vector] )</br>
+		<h3>[method:null lookAt]( [param:Vector3 vector] )<br />
 		[method:null lookAt]( [param:Float x], [param:Float y], [param:Float z] )</h3>
 		<p>
 		vector - A vector representing a position in world space.<br /><br />

+ 4 - 1
docs/api/en/extras/core/ShapePath.html

@@ -44,6 +44,9 @@
 		The current [page:Path] that is being generated.
 		</p>
 
+		<h3>[property:Color color]</h3>
+		<p>[page:Color] of the shape, by default set to white (0xffffff).</p>
+
 		<h2>Methods</h2>
 
 		<h3>[method:null moveTo]( [param:Float x], [param:Float y] )</h3>
@@ -86,6 +89,6 @@
 
 		<h2>Source</h2>
 
-		[link:https://github.com/mrdoob/three.js/blob/master/src/extras/core/Path.js src/extras/core/Path.js]
+		[link:https://github.com/mrdoob/three.js/blob/master/src/extras/core/ShapePath.js src/extras/core/ShapePath.js]
 	</body>
 </html>

+ 73 - 0
docs/api/en/helpers/PositionalAudioHelper.html

@@ -0,0 +1,73 @@
+<!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 helper displays the directional cone of a [page:PositionalAudio].</p>
+
+		<h2>Example</h2>
+
+		<div>[example:webaudio_orientation webaudio / orientation ]</div>
+
+		<h2>Code Example</h2>
+		<code>
+var positionalAudio = new THREE.PositionalAudio( listener );
+positionalAudio.setDirectionalCone( 180, 230, 0.1 );
+
+var helper = new PositionalAudioHelper( positionalAudio );
+positionalAudio.add( helper );
+		</code>
+
+
+		<h2>Constructor</h2>
+
+		<h3>[name]( [param:PositionalAudio audio], [param:Number range] )</h3>
+		<p>
+			[page:PositionalAudio audio] -- The [page:PositionalAudio] to be visualized. <br /><br/>
+
+			[page:Number range] -- (optional) The range of the directional cone. <br /><br/>
+
+			[page:Number divisionsInnerAngle] -- (optional) The amount of divisions of the inner part of the directional cone. <br /><br/>
+
+			[page:Number divisionsOuterAngle] -- (optional) The amount of divisions of the outer part of the directional cone. <br /><br/>
+		</p>
+
+
+		<h2>Properties</h2>
+		<p>See the base [page:Object3D] class for common properties.</p>
+
+		<h3>[property:PositionalAudio audio]</h3>
+		<p>[page:PositionalAudio] to be visualized.</p>
+
+		<h3>[property:Number range]</h3>
+		<p>The range of the directional cone.</p>
+
+		<h3>[property:Number divisionsInnerAngle]</h3>
+		<p>The amount of divisions of the inner part of the directional cone.</p>
+
+		<h3>[property:Number divisionsOuterAngle]</h3>
+		<p>The amount of divisions of the outer part of the directional cone.</p>
+
+		<h2>Methods</h2>
+		<p>See the base [page:Object3D] class for common methods.</p>
+
+		<h3>[method:null dispose]()</h3>
+		<p>Disposes of the helper.</p>
+
+		<h3>[method:null update]()</h3>
+		<p>Updates the helper.</p>
+
+		<h2>Source</h2>
+
+		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
+	</body>
+</html>

+ 4 - 5
docs/api/en/loaders/AnimationLoader.html

@@ -65,19 +65,18 @@
 		<p>
 		[page:String url] — the path or URL to the file. This can also be a
 			[link:https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs Data URI].<br />
-		[page:Function onLoad] — Will be called when load completes. The argument will be the loaded [page:Animation animation].<br />
+		[page:Function onLoad] — Will be called when load completes. The argument will be the loaded [page:AnimationClip animation clips].<br />
 		[page:Function onProgress] — Will be called while load progresses. The argument will be the XMLHttpRequest instance, which contains .[page:Integer total] and .[page:Integer loaded] bytes.<br />
 		[page:Function onError] — Will be called if load errors.<br /><br />
 
 		Begin loading from url and pass the loaded animation to onLoad.
 		</p>
 
-		<h3>[method:null parse]( [param:JSON json], [param:Function onLoad] )</h3>
+		<h3>[method:Array parse]( [param:JSON json] )</h3>
 		<p>
-		[page:JSON json] — required<br />
-		[page:Function onLoad] — Will be called when parsing completes. <br /><br />
+		[page:JSON json] — required<br /><br />
 
-		Parse the JSON object and pass the result to onLoad. Individual clips in the object will
+		Parse the JSON object and return an array of animation clips. Individual clips in the object will
 		be parsed with [page:AnimationClip.parse].
 		</p>
 

+ 10 - 0
docs/api/en/loaders/ImageBitmapLoader.html

@@ -16,6 +16,13 @@
 			Unlike [page:FileLoader], [name] does not avoid multiple concurrent requests to the same URL.
 		</p>
 
+		<p>
+			Note that [page:Texture.flipY] and [page:Texture.premultiplyAlpha] with [link:https://developer.mozilla.org/de/docs/Web/API/ImageBitmap ImageBitmap] are ignored.
+			[link:https://developer.mozilla.org/de/docs/Web/API/ImageBitmap ImageBitmap] needs these configuration on bitmap creation
+			unlike regular images need them on uploading to GPU. You need to set the equivalent options via [page:ImageBitmapLoader.setOptions]
+			instead. Refer to [link:https://www.khronos.org/registry/webgl/specs/latest/1.0/#6.10 WebGL specification] for the detail.
+		</p>
+
 		<h2>Example</h2>
 
 		<p>
@@ -26,6 +33,9 @@
 		// instantiate a loader
 		var loader = new THREE.ImageBitmapLoader();
 
+		// set options if needed
+		loader.setOptions( { imageOrientation: 'flipY' } );
+
 		// load a image resource
 		loader.load(
 			// resource URL

+ 1 - 1
docs/api/en/loaders/ImageLoader.html

@@ -12,7 +12,7 @@
 
 		<p class="desc">
 			A loader for loading an [page:Image].
-			This uses the [page:FileLoader] internally for loading files, and is used internally by the
+			This is used internally by the
 			[page:CubeTextureLoader], [page:ObjectLoader] and [page:TextureLoader].
 		</p>
 

+ 24 - 0
docs/api/en/loaders/Loader.html

@@ -62,6 +62,30 @@
 		Creates an array of [page:Material] based on the array of parameters m. The index of the parameters decide the correct index of the materials.
 		</p>
 
+		<h2>Handlers</h2>
+
+		<p>
+		*[name].Handlers* is a special object normally used by other loaders like [page:GLTFLoader] or [page:MTLLoader]. It provides an
+		API that allows the definition of special mappings: What loaders should be used in order to load specific files. A typical use case
+		is to overwrite the default loader for textures.<br /><br />
+
+		Note: It's only possible to use *[name].Handlers* if the respective loader support the usage.
+		</p>
+
+		<h3>[method:null add]( [param:Object regex], [param:Loader loader] )</h3>
+		<p>
+		[page:Object regex] — A regular expression.<br />
+		[page:Loader loader] — The loader.
+		<p>
+		Registers a loader with the given regular expression.
+		</p>
+
+		<h3>[method:null get]( [param:String file] )</h3>
+		<p>
+		[page:String file] — The file path.
+		<p>
+		Can be used to retrieve the registered loader for the given file path.
+		</p>
 
 		<h2>Source</h2>
 

+ 8 - 1
docs/api/en/materials/Material.html

@@ -261,6 +261,13 @@
 		Other options are [page:Materials THREE.VertexColors] and [page:Materials THREE.FaceColors].
 		</p>
 
+		<h3>[property:Boolean vertexTangents]</h3>
+		<p>
+		Defines whether precomputed vertex tangents, which must be provided in a vec4 "tangent" attribute,
+		are used. When disabled, tangents are derived automatically. Using precomputed tangents will give
+		more accurate normal map details in some cases, such as with mirrored UVs. Default is false.
+		</p>
+
 		<h3>[property:Boolean visible]</h3>
 		<p>
 		Defines whether this material is visible. Default is *true*.
@@ -288,7 +295,7 @@
 		These needs to be disposed by [page:Texture Texture].
 		</p>
 
-		<h3>[method:null onBeforeCompile]( [param:Object shader], [param:WebGLRenderer renderer] )</h3>
+		<h3>[method:null onBeforeCompile]( [param:Shader shader], [param:WebGLRenderer renderer] )</h3>
 		<p>
 		An optional callback that is executed immediately before the shader program is compiled.
 		This function is called with the shader source code as a parameter. Useful for the modification of built-in materials.

+ 131 - 0
docs/api/en/materials/MeshDistanceMaterial.html

@@ -0,0 +1,131 @@
+<!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:Material] &rarr;
+
+		<h1>[name]</h1>
+
+		<p class="desc">
+			[name] is internally used for implementing shadow mapping with [page:PointLight]s.<br/><br/>
+
+			Can also be used to customize the shadow casting of an object by assigning an instance of [name] to [page:Object3D.customDistanceMaterial].
+			The following examples demonstrates this approach in order to ensure transparent parts of objects do no cast shadows.
+		</p>
+
+		<h2>Example</h2>
+
+		[example:webgl_shadowmap_pointlight WebGL / shadowmap / pointlight]
+
+		<script>
+
+		// iOS iframe auto-resize workaround
+
+		if ( /(iPad|iPhone|iPod)/g.test( navigator.userAgent ) ) {
+
+			var scene = document.getElementById( 'scene' );
+
+			scene.style.width = getComputedStyle( scene ).width;
+			scene.style.height = getComputedStyle( scene ).height;
+			scene.setAttribute( 'scrolling', 'no' );
+
+		}
+
+		</script>
+
+		<h2>Constructor</h2>
+
+		<h3>[name]( [param:Object parameters] )</h3>
+		<p>
+			[page:Object parameters] - (optional) an object with one or more properties defining the material's appearance.
+			Any property of the material (including any property inherited from [page:Material]) can be passed in here.
+		</p>
+
+		<h2>Properties</h2>
+		<p>See the base [page:Material] class for common properties.</p>
+
+		<h3>[property:Texture alphaMap]</h3>
+		<p>The alpha map is a grayscale texture that controls the opacity across the surface
+			(black: fully transparent; white: fully opaque). Default is null.<br /><br />
+
+			Only the color of the texture is used, ignoring the alpha channel if one exists.
+			For RGB and RGBA textures, the [page:WebGLRenderer WebGL] renderer will use the
+			green channel when sampling this texture due to the extra bit of precision provided
+			for green in DXT-compressed and uncompressed RGB 565 formats. Luminance-only and
+			luminance/alpha textures will also still work as expected.
+		</p>
+
+		<h3>[property:Texture displacementMap]</h3>
+		<p>
+			The displacement map affects the position of the mesh's vertices. Unlike other maps
+			which only affect the light and shade of the material the displaced vertices can cast shadows,
+			block other objects, and otherwise act as real geometry. The displacement texture is
+			an image where the value of each pixel (white being the highest) is mapped against,
+			and repositions, the vertices of the mesh.
+		</p>
+
+		<h3>[property:Float displacementScale]</h3>
+		<p>
+			How much the displacement map affects the mesh (where black is no displacement,
+			and white is maximum displacement). Without a displacement map set, this value is not applied.
+			 Default is 1.
+		</p>
+
+		<h3>[property:Float displacementBias]</h3>
+		<p>
+			The offset of the displacement map's values on the mesh's vertices.
+			Without a displacement map set, this value is not applied. Default is 0.
+		</p>
+
+		<h3>[property:Float farDistance]</h3>
+		<p>
+			The far value of the point light's internal shadow camera.
+		</p>
+
+		<h3>[property:Boolean fog]</h3>
+		<p>Whether the material is affected by fog. Default is *false*.</p>
+
+		<h3>[property:Boolean isMeshDistanceMaterial]</h3>
+		<p>
+			Used to check whether this or derived classes are mesh depth materials. Default is *true*.<br /><br />
+
+			You should not change this, as it used internally for optimisation.
+		</p>
+
+		<h3>[property:Boolean lights]</h3>
+		<p>Whether the material is affected by lights. Default is *false*.</p>
+
+		<h3>[property:Texture map]</h3>
+		<p>The color map. Default is  null.</p>
+
+		<h3>[property:boolean morphTargets]</h3>
+		<p>Define whether the material uses morphTargets. Default is false.</p>
+
+		<h3>[property:Float nearDistance]</h3>
+		<p>
+			The near value of the point light's internal shadow camera.
+		</p>
+
+		<h3>[property:Vector3 referencePosition]</h3>
+		<p>
+			The position of the point light in world space.
+		</p>
+
+		<h3>[property:Boolean skinning]</h3>
+		<p>Define whether the material uses skinning. Default is false.</p>
+
+		<h2>Methods</h2>
+		<p>See the base [page:Material] class for common methods.</p>
+
+
+		<h2>Source</h2>
+
+		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
+	</body>
+</html>

+ 150 - 0
docs/api/en/materials/MeshMatcapMaterial.html

@@ -0,0 +1,150 @@
+<!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:Material] &rarr;
+
+		<h1>[name]</h1>
+
+		<p class="desc">
+			[name] is defined by a MatCap (or Lit Sphere) texture, which encodes the material color and shading.<br/><br/>
+			[name] does not respond to lights since the matcap image file encodes baked lighting.
+			It will cast a shadow onto an object that receives shadows (and shadow clipping works), but it will not self-shadow or receive shadows.
+		</p>
+
+		<iframe id="scene" src="scenes/material-browser.html#MeshMatcapMaterial"></iframe>
+
+		<script>
+
+		// iOS iframe auto-resize workaround
+
+		if ( /(iPad|iPhone|iPod)/g.test( navigator.userAgent ) ) {
+
+			var scene = document.getElementById( 'scene' );
+
+			scene.style.width = getComputedStyle( scene ).width;
+			scene.style.height = getComputedStyle( scene ).height;
+			scene.setAttribute( 'scrolling', 'no' );
+
+		}
+
+		</script>
+
+		<h2>Constructor</h2>
+
+		<h3>[name]( [param:Object parameters] )</h3>
+		<p>
+			[page:Object parameters] - (optional) an object with one or more properties defining the material's appearance.
+			Any property of the material (including any property inherited from [page:Material]) can be passed in here.<br /><br />
+
+			The exception is the property [page:Hexadecimal color], which can be passed in as a hexadecimal
+			string and is *0xffffff* (white) by default. [page:Color.set]( color ) is called internally.
+		</p>
+
+		<h2>Properties</h2>
+		<p>See the base [page:Material] class for common properties.</p>
+
+		<h3>[property:Texture alphaMap]</h3>
+		<p>The alpha map is a grayscale texture that controls the opacity across the surface
+			(black: fully transparent; white: fully opaque). Default is null.<br /><br />
+
+			Only the color of the texture is used, ignoring the alpha channel if one exists.
+			For RGB and RGBA textures, the [page:WebGLRenderer WebGL] renderer will use the
+			green channel when sampling this texture due to the extra bit of precision provided
+			for green in DXT-compressed and uncompressed RGB 565 formats. Luminance-only and
+			luminance/alpha textures will also still work as expected.
+		</p>
+
+		<h3>[property:Texture bumpMap]</h3>
+		<p>
+			The texture to create a bump map. The black and white values map to the perceived depth in relation to the lights.
+			Bump doesn't actually affect the geometry of the object, only the lighting. If a normal map is defined this will
+			be ignored.
+		</p>
+
+		<h3>[property:Float bumpScale]</h3>
+		<p>How much the bump map affects the material. Typical ranges are 0-1. Default is 1.</p>
+
+		<h3>[property:Color color]</h3>
+		<p>[page:Color] of the material, by default set to white (0xffffff).</p>
+
+		<h3>[property:Texture displacementMap]</h3>
+		<p>
+			The displacement map affects the position of the mesh's vertices. Unlike other maps
+			which only affect the light and shade of the material the displaced vertices can cast shadows,
+			block other objects, and otherwise act as real geometry. The displacement texture is
+			an image where the value of each pixel (white being the highest) is mapped against,
+			and repositions, the vertices of the mesh.
+		</p>
+
+		<h3>[property:Float displacementScale]</h3>
+		<p>
+			How much the displacement map affects the mesh (where black is no displacement,
+			and white is maximum displacement). Without a displacement map set, this value is not applied.
+			 Default is 1.
+		</p>
+
+		<h3>[property:Float displacementBias]</h3>
+		<p>
+			The offset of the displacement map's values on the mesh's vertices.
+			Without a displacement map set, this value is not applied. Default is 0.
+		</p>
+
+		<h3>[property:Boolean isMeshMatcapMaterial]</h3>
+		<p>
+			Used to check whether this or derived classes are mesh Matcap materials. Default is *true*.<br /><br />
+
+			You should not change this, as it used internally for optimisation.
+		</p>
+
+		<h3>[property:Texture map]</h3>
+		<p>The color map. Default is null. The texture map color is modulated by the diffuse [page:.color].</p>
+
+		<h3>[property:Texture matcap]</h3>
+		<p>The matcap map. Default is null.</p>
+
+		<h3>[property:boolean morphNormals]</h3>
+		<p>
+			Defines whether the material uses morphNormals. Set as true to pass morphNormal
+			attributes from the [page:Geometry]	to the shader. Default is *false*.
+		</p>
+
+		<h3>[property:Boolean morphTargets]</h3>
+		<p>Define whether the material uses morphTargets. Default is false.</p>
+
+		<h3>[property:Texture normalMap]</h3>
+		<p>
+			The texture to create a normal map. The RGB values affect the surface normal for each pixel fragment and change
+			the way the color is lit. Normal maps do not change the actual shape of the surface, only the lighting.
+		</p>
+
+		<h3>[property:Integer normalMapType]</h3>
+		<p>
+			The type of normal map.<br /><br />
+
+			Options are [page:constant THREE.TangentSpaceNormalMap] (default), and [page:constant THREE.ObjectSpaceNormalMap].
+		</p>
+
+		<h3>[property:Vector2 normalScale]</h3>
+		<p>
+			How much the normal map affects the material. Typical ranges are 0-1.
+			Default is a [page:Vector2] set to (1,1).
+		</p>
+
+		<h3>[property:Boolean skinning]</h3>
+		<p>Define whether the material uses skinning. Default is false.</p>
+
+		<h2>Methods</h2>
+		<p>See the base [page:Material] class for common methods.</p>
+
+		<h2>Source</h2>
+
+		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
+	</body>
+</html>

+ 61 - 1
docs/api/en/materials/MeshNormalMaterial.html

@@ -44,6 +44,38 @@
 		<h2>Properties</h2>
 		<p>See the base [page:Material] class for common properties.</p>
 
+		<h3>[property:Texture bumpMap]</h3>
+		<p>
+			The texture to create a bump map. The black and white values map to the perceived depth in relation to the lights.
+			Bump doesn't actually affect the geometry of the object, only the lighting. If a normal map is defined this will
+			be ignored.
+		</p>
+
+		<h3>[property:Float bumpScale]</h3>
+		<p>How much the bump map affects the material. Typical ranges are 0-1. Default is 1.</p>
+
+		<h3>[property:Texture displacementMap]</h3>
+		<p>
+			The displacement map affects the position of the mesh's vertices. Unlike other maps
+			which only affect the light and shade of the material the displaced vertices can cast shadows,
+			block other objects, and otherwise act as real geometry. The displacement texture is
+			an image where the value of each pixel (white being the highest) is mapped against,
+			and repositions, the vertices of the mesh.
+		</p>
+
+		<h3>[property:Float displacementScale]</h3>
+		<p>
+			How much the displacement map affects the mesh (where black is no displacement,
+			and white is maximum displacement). Without a displacement map set, this value is not applied.
+			 Default is 1.
+		</p>
+
+		<h3>[property:Float displacementBias]</h3>
+		<p>
+			The offset of the displacement map's values on the mesh's vertices.
+			Without a displacement map set, this value is not applied. Default is 0.
+		</p>
+
 		<h3>[property:Boolean fog]</h3>
 		<p>Whether the material is affected by fog. Default is *false*.</p>
 
@@ -57,9 +89,37 @@
 		<h3>[property:Boolean lights]</h3>
 		<p>Whether the material is affected by lights. Default is *false*.</p>
 
-		<h3>[property:boolean morphTargets]</h3>
+		<h3>[property:boolean morphNormals]</h3>
+		<p>
+			Defines whether the material uses morphNormals. Set as true to pass morphNormal
+			attributes from the [page:Geometry]	to the shader. Default is *false*.
+		</p>
+
+		<h3>[property:Boolean morphTargets]</h3>
 		<p>Define whether the material uses morphTargets. Default is false.</p>
 
+		<h3>[property:Texture normalMap]</h3>
+		<p>
+			The texture to create a normal map. The RGB values affect the surface normal for each pixel fragment and change
+			the way the color is lit. Normal maps do not change the actual shape of the surface, only the lighting.
+		</p>
+
+		<h3>[property:Integer normalMapType]</h3>
+		<p>
+			The type of normal map.<br /><br />
+
+			Options are [page:constant THREE.TangentSpaceNormalMap] (default), and [page:constant THREE.ObjectSpaceNormalMap].
+		</p>
+
+		<h3>[property:Vector2 normalScale]</h3>
+		<p>
+			How much the normal map affects the material. Typical ranges are 0-1.
+			Default is a [page:Vector2] set to (1,1).
+		</p>
+
+		<h3>[property:Boolean skinning]</h3>
+		<p>Define whether the material uses skinning. Default is false.</p>
+
 		<h3>[property:boolean wireframe]</h3>
 		<p>
 			Render geometry as wireframe. Default is false (i.e. render as smooth shaded).

+ 1 - 1
docs/api/en/math/Matrix3.html

@@ -55,7 +55,7 @@ m.elements = [ 11, 21, 31,
 
 		<h2>Properties</h2>
 
-		<h3>[property:Float32Array elements]</h3>
+		<h3>[property:Array elements]</h3>
 		<p>
 		A [link:https://en.wikipedia.org/wiki/Row-_and_column-major_order column-major]
 		 list of matrix values.

+ 1 - 1
docs/api/en/math/Matrix4.html

@@ -90,7 +90,7 @@ m.elements = [ 11, 21, 31, 41,
 
 		<h2>Properties</h2>
 
-		<h3>[property:Float32Array elements]</h3>
+		<h3>[property:Array elements]</h3>
 		<p>
 		A [link:https://en.wikipedia.org/wiki/Row-_and_column-major_order#Column-major_order column-major]
 		 list of matrix values.

+ 7 - 0
docs/api/en/math/Quaternion.html

@@ -44,6 +44,13 @@
 
 		<h2>Properties</h2>
 
+		<h3>[property:Boolean isQuaternion]</h3>
+		<p>
+			Used to check whether this or derived classes are Quaternions. Default is *true*.<br /><br />
+
+			You should not change this, as it is used internally for optimisation.
+		</p>
+
 		<h3>[property:Float x]</h3>
 		<p>Changing this property will result in [page:.onChangeCallback onChangeCallback] being called.</p>
 

+ 1 - 1
docs/api/en/objects/Mesh.html

@@ -95,7 +95,7 @@
 		<h3>[method:null raycast]( [param:Raycaster raycaster], [param:Array intersects] )</h3>
 		<p>
 		Get intersections between a casted ray and this mesh.
-		[page:Raycaster.intersectObject] will call this method.
+		[page:Raycaster.intersectObject] will call this method, but the results are not ordered.
 		</p>
 
 		<h3>[method:null updateMorphTargets]()</h3>

+ 0 - 6
docs/api/en/renderers/WebGLRenderTargetCube.html

@@ -50,12 +50,6 @@
 
 		<h2>Properties</h2>
 
-		<h3>[property:integer activeCubeFace]</h3>
-		<p>
-		The activeCubeFace property corresponds to a cube side (PX 0, NX 1, PY 2, NY 3, PZ 4, NZ 5) and is
-		used and set internally by the [page:CubeCamera].
-		</p>
-
 		<h3>See [page:WebGLRenderTarget] for inherited properties</h3>
 
 

+ 65 - 47
docs/api/en/renderers/WebGLRenderer.html

@@ -279,13 +279,6 @@
 
 		<h2>Methods</h2>
 
-		<h3>[method:Integer allocTextureUnit]</h3>
-		<p>
-		Attempt to allocate a texture unit for use by a shader. Will warn if trying to allocate
-		more texture units than the GPU supports. This is mainly used internally.
-		See [page:WebGLRenderer.capabilities capabilities.maxTextures].
-		</p>
-
 		<h3>[method:null clear]( [param:Boolean color], [param:Boolean depth], [param:Boolean stencil] )</h3>
 		<p>
 		Tells the renderer to clear its color, depth or stencil drawing buffer(s).
@@ -346,39 +339,68 @@
 		<p>Returns an object that describes the attributes set on the WebGL context when it was created.</p>
 
 		<h3>[method:RenderTarget getRenderTarget]()</h3>
-		<p>Returns the current RenderTarget, if any.</p>
+		<p>Returns the current [page:RenderTarget RenderTarget] if there are; returns *null* otherwise.</p>
+
+		<h3>[method:Vector4 getCurrentViewport]( [param:Vector4 target] )</h3>
+		<p>
+		[page:Vector4 target] — the result will be copied into this Vector4.<br /><br />
 
-		<h3>[method:RenderTarget getCurrentViewport]()</h3>
-		<p>Returns the current viewport.</p>
+		Returns the current viewport.
+		</p>
 
-		<h3>[method:Object getDrawingBufferSize]()</h3>
-		<p>Returns an object containing the width and height of the renderer's drawing buffer, in pixels.</p>
+		<h3>[method:Vector2 getDrawingBufferSize]( [param:Vector2 target] )</h3>
+		<p>
+		[page:Vector2 target] — the result will be copied into this Vector2.<br /><br />
+
+		Returns the width and height of the renderer's drawing buffer, in pixels.
+		</p>
 
 		<h3>[method:number getPixelRatio]()</h3>
 		<p>Returns current device pixel ratio used.</p>
 
-		<h3>[method:Object getSize]()</h3>
-		<p>Returns an object containing the width and height of the renderer's output canvas, in pixels.</p>
+		<h3>[method:Vector4 getScissor]( [param:Vector4 target] )</h3>
+		<p>
+		[page:Vector4 target] — the result will be copied into this Vector4.<br /><br />
+
+		Returns the scissor region.
+		</p>
+
+		<h3>[method:Boolean getScissorTest]()</h3>
+		<p>Returns *true* if scissor test is enabled; returns *false* otherwise.</p>
+
+		<h3>[method:Vector2 getSize]( [param:Vector2 target] )</h3>
+		<p>
+		[page:Vector2 target] — the result will be copied into this Vector2.<br /><br />
+
+		Returns the width and height of the renderer's output canvas, in pixels.
+		</p>
+
+		<h3>[method:Vector4 getViewport]( [param:Vector4 target] )</h3>
+		<p>
+		[page:Vector4 target] — the result will be copied into this Vector4.<br /><br />
+
+		Returns the viewport.
+		</p>
 
 		<h3>[method:null resetGLState]( )</h3>
 		<p>Reset the GL state to default. Called internally if the WebGL context is lost.</p>
 
-		<h3>[method:null readRenderTargetPixels]( [param:WebGLRenderTarget renderTarget], [param:Float x], [param:Float y], [param:Float width], [param:Float height], buffer )</h3>
-		<p>Reads the pixel data from the renderTarget into the buffer you pass in. This is a wrapper around [link:https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/readPixels WebGLRenderingContext.readPixels]().<br />
-		See the [example:webgl_interactive_cubes_gpu interactive / cubes / gpu] example.
+		<h3>[method:null readRenderTargetPixels]( [param:WebGLRenderTarget renderTarget], [param:Float x], [param:Float y], [param:Float width], [param:Float height], [param:TypedArray buffer] )</h3>
+		<p>buffer - Uint8Array is the only destination type supported in all cases, other types are renderTarget and platform dependent. See [link:https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.12 WebGL spec] for details.</p>
+		<p>Reads the pixel data from the renderTarget into the buffer you pass in. This is a wrapper around [link:https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/readPixels WebGLRenderingContext.readPixels]().</p>
+		<p>See the [example:webgl_interactive_cubes_gpu interactive / cubes / gpu] example.
 		</p>
 
-		<h3>[method:null render]( [param:Scene scene], [param:Camera camera], [param:WebGLRenderTarget renderTarget], [param:Boolean forceClear] )</h3>
+
+		<h3>[method:null render]( [param:Scene scene], [param:Camera camera] )</h3>
 		<p>
 			Render a [page:Scene scene] using a [page:Camera camera].<br />
 
-			The render is done to the [page:WebGLRenderTarget renderTarget] (if specified) or to the canvas as usual.<br />
-
-			If [page:Boolean forceClear] is *true*, the depth, stencil and color buffers will be cleared
-			before rendering even if the renderer's [page:WebGLRenderer.autoClear autoClear] property is false.<br />
+			The render is done to a previously specified [page:WebGLRenderTarget renderTarget] set by calling [page:WebGLRenderer.setRenderTarget .setRenderTarget] or to the canvas as usual.<br />
 
-			Even with forceClear set to true you can prevent certain buffers being cleared by setting
-			either the [page:WebGLRenderer.autoClearColor autoClearColor], [page:WebGLRenderer.autoClearStencil autoClearStencil] or [page:WebGLRenderer.autoClearDepth autoClearDepth] properties to false.
+			By default render buffers are cleared before rendering but you can prevent this by setting the property [page:WebGLRenderer.autoClear autoClear] to false.
+			If you want to prevent only certain buffers being cleared you can set either the [page:WebGLRenderer.autoClearColor autoClearColor], [page:WebGLRenderer.autoClearStencil autoClearStencil] or
+			[page:WebGLRenderer.autoClearDepth autoClearDepth] properties to false. To forcibly clear one ore more buffers call [page:WebGLRenderer.clear .clear].
 		</p>
 
 		<h3>[method:null renderBufferDirect]( [param:Camera camera], [param:Fog fog], [param:Geometry geometry], [param:Material material], [param:Object3D object], [param:Object group] )</h3>
@@ -405,15 +427,23 @@
 		<h3>[method:null setPixelRatio]( [param:number value] )</h3>
 		<p>Sets device pixel ratio. This is usually used for HiDPI device to prevent bluring output canvas.</p>
 
-		<h3>[method:null setRenderTarget]( [param:WebGLRenderTarget renderTarget] )</h3>
+		<h3>[method:null setRenderTarget]( [param:WebGLRenderTarget renderTarget], [param:Integer activeCubeFace], [param:Integer activeMipMapLevel] )</h3>
 		<p>
-		renderTarget -- The [page:WebGLRenderTarget renderTarget] that needs to be activated (optional).<br /><br />
-		This method sets the active rendertarget. If the parameter is omitted the canvas is set as the active rendertarget.
+		renderTarget -- The [page:WebGLRenderTarget renderTarget] that needs to be activated. When *null* is given, the canvas is set as the active render target instead.<br />
+		activeCubeFace -- Specifies the active cube side (PX 0, NX 1, PY 2, NY 3, PZ 4, NZ 5) of [page:WebGLRenderTargetCube] (optional).<br />
+		activeMipMapLevel -- Specifies the active mipmap level (optional).<br /><br />
+		This method sets the active rendertarget.
 		</p>
 
-		<h3>[method:null setScissor]( [param:Integer x], [param:Integer y], [param:Integer width], [param:Integer height] )</h3>
+		<h3>[method:null setScissor]( [param:Integer x], [param:Integer y], [param:Integer width], [param:Integer height] )<br />
+		[method:null setScissor]( [param:Vector4 vector] )</h3>
+
 		<p>
-		Sets the scissor area from (x, y) to (x + width, y + height)
+		The x, y, width, and height parameters of the scissor region.<br />
+		Optionally, a 4-component vector specifying the parameters of the region.<br /><br />
+
+		Sets the scissor region from (x, y) to (x + width, y + height).<br />
+		(x, y) is the lower-left corner of the scissor region.
 		</p>
 
 		<h3>[method:null setScissorTest]( [param:Boolean boolean] )</h3>
@@ -429,29 +459,17 @@
 			Setting [page:Boolean updateStyle] to false prevents any style changes to the output canvas.
 		</p>
 
-		<h3>[method:null setTexture2D]( [param:Texture texture], [param:number slot] )</h3>
-		<p>
-		texture -- The [page:Texture texture] that needs to be set.<br />
-		slot -- The number indicating which slot should be used by the texture.<br /><br />
-
-		This method sets the correct texture to the correct slot for the WebGL shader.
-		The slot number can be found as a value of the uniform of the sampler.<br /><br />
+		<h3>[method:null setViewport]( [param:Integer x], [param:Integer y], [param:Integer width], [param:Integer height] )<br />
+		[method:null setViewport]( [param:Vector4 vector] )</h3>
 
-		Note: This method replaces the older [method:null setTexture] method.
-		</p>
-
-		<h3>[method:null setTextureCube]( [param:CubeTexture cubeTexture], [param:Number slot] )</h3>
 		<p>
-		texture -- The [page:CubeTexture cubeTexture] that needs to be set.<br />
-		slot -- The number indicating which slot should be used by the texture.<br /><br />
+		The x, y, width, and height parameters of the viewport.<br />
+		Optionally, a 4-component vector specifying the parameters of a viewport.<br /><br />
 
-		This method sets the correct texture to the correct slot for the WebGL shader.
-		The slot number can be found as a value of the uniform of the sampler.
+		Sets the viewport to render from (x, y) to (x + width, y + height).<br />
+		(x, y) is the lower-left corner of the region.
 		</p>
 
-		<h3>[method:null setViewport]( [param:Integer x], [param:Integer y], [param:Integer width], [param:Integer height] )</h3>
-		<p>Sets the viewport to render from (x, y) to (x + width, y + height).</p>
-
 		<h2>Source</h2>
 
 		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]

+ 10 - 2
docs/api/en/textures/DataTexture3D.html

@@ -32,10 +32,18 @@
 		<div>[example:webgl2_materials_texture3d WebGL2 / materials / texture3d]</div>
 		<div>[example:webgl2_materials_texture3d_volume WebGL2 / materials / texture3d / volume]</div>
 
-		<h2>Properties</h2>
+    <h2>Properties</h2>
 
 		<p>
-		See the base [page:Texture Texture] class for common properties.
+    See the base [page:Texture Texture] class for common properties.
+    </p>
+
+    <h3>[property:number wrapR]</h3>
+		<p>
+		This defines how the texture is wrapped in the depth direction.<br />
+		The default is [page:Textures THREE.ClampToEdgeWrapping], where the edge is clamped to the outer edge texels.
+		The other two choices are [page:Textures THREE.RepeatWrapping] and [page:Textures THREE.MirroredRepeatWrapping].
+		See the [page:Textures texture constants] page for details.
 		</p>
 
 		<h2>Methods</h2>

+ 15 - 3
docs/api/en/textures/Texture.html

@@ -55,6 +55,13 @@
 		as long as video is playing - the [page:VideoTexture VideoTexture] class handles this automatically.
 		</p>
 
+		<h3>[property:Boolean isTexture]</h3>
+		<p>
+			Used to check whether this or derived classes are Textures. Default is *true*.<br /><br />
+
+			You should not change this, as it is used internally for optimisation.
+		</p>
+
 		<h3>[property:array mipmaps]</h3>
 		<p>
 		Array of user-specified mipmaps (optional).
@@ -180,13 +187,18 @@
 
 		<h3>[property:boolean premultiplyAlpha]</h3>
 		<p>
-		False by default, which is the norm for PNG images. Set to true if the RGB values have
-		been stored premultiplied by alpha.
+		If set to *true*, the alpha channel, if present, is multiplied into the color channels when the texture is uploaded to the GPU. Defaut is *false*.<br /><br />
+
+		Note that this property has no effect for [link:https://developer.mozilla.org/de/docs/Web/API/ImageBitmap ImageBitmap].
+		You need to configure on bitmap creation instead. See [page:ImageBitmapLoader].
 		</p>
 
 		<h3>[property:boolean flipY]</h3>
 		<p>
-		True by default. Flips the image's Y axis to match the WebGL texture coordinate space.
+		If set to *true*, the texture is flipped along the vertical axis when uploaded to the GPU. Default is *true*.<br /><br />
+
+		Note that this property has no effect for [link:https://developer.mozilla.org/de/docs/Web/API/ImageBitmap ImageBitmap].
+		You need to configure on bitmap creation instead. See [page:ImageBitmapLoader].
 		</p>
 
 		<h3>[property:number unpackAlignment]</h3>

+ 1 - 1
docs/api/zh/audio/Audio.html

@@ -22,7 +22,7 @@
 		<h2>例子</h2>
 
 		<p>
-			[example:webaudio_sandbox webaudio / sandbox ]</br>
+			[example:webaudio_sandbox webaudio / sandbox ]<br />
 			[example:webaudio_visualizer webaudio / visualizer ]
 		</p>
 

+ 1 - 1
docs/api/zh/audio/AudioAnalyser.html

@@ -22,7 +22,7 @@
 		<h2>示例</h2>
 
 		<p>
-			[example:webaudio_sandbox webaudio / sandbox ]</br>
+			[example:webaudio_sandbox webaudio / sandbox ]<br />
 			[example:webaudio_visualizer webaudio / visualizer ]
 		</p>
 

+ 4 - 4
docs/api/zh/audio/AudioListener.html

@@ -13,8 +13,8 @@
 		<h1>[name]</h1>
 
 		<p class="desc">
-			[name] 用一个虚拟的[link:https://developer.mozilla.org/de/docs/Web/API/AudioListener listener]表示在场景中所有的位置和非位置相关的音效.</br>
-			一个three.js程序通常创建一个[name]. 它是音频实体构造函数的必须参数,比如 [page:Audio Audio] and [page:PositionalAudio PositionalAudio].</br>
+			[name] 用一个虚拟的[link:https://developer.mozilla.org/de/docs/Web/API/AudioListener listener]表示在场景中所有的位置和非位置相关的音效.<br />
+			一个three.js程序通常创建一个[name]. 它是音频实体构造函数的必须参数,比如 [page:Audio Audio] and [page:PositionalAudio PositionalAudio].<br />
 			大多数情况下, listener对象是camera的子对象. Camera的3D变换表示了listener的3D变换.
 		</p>
 
@@ -22,8 +22,8 @@
 		<h2>示例</h2>
 
 		<p>
-			[example:webaudio_sandbox webaudio / sandbox ]</br>
-			[example:webaudio_timing webaudio / timing ]</br>
+			[example:webaudio_sandbox webaudio / sandbox ]<br />
+			[example:webaudio_timing webaudio / timing ]<br />
 			[example:webaudio_visualizer webaudio / visualizer ]
 		</p>
 

+ 2 - 2
docs/api/zh/audio/PositionalAudio.html

@@ -22,8 +22,8 @@
 		<h2>示例</h2>
 
 		<p>
-			[example:webaudio_orientation webaudio / orientation ]</br>
-			[example:webaudio_sandbox webaudio / sandbox ]</br>
+			[example:webaudio_orientation webaudio / orientation ]<br />
+			[example:webaudio_sandbox webaudio / sandbox ]<br />
 			[example:webaudio_timing webaudio / timing ]
 		</p>
 

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

@@ -44,7 +44,7 @@
 	</p>
 
 	<h3>[property:Material customDistanceMaterial]</h3>
-	<p>与customDepthMaterial相同,但与[page:PointLight]一起使用。默认值为*undefined*。
+	<p>与[page:.customDepthMaterial customDepthMaterial]相同,但与[page:PointLight]一起使用。默认值为*undefined*。
 	</p>
 
 	<h3>[property:Boolean frustumCulled]</h3>
@@ -273,7 +273,7 @@
 		将局部空间向量转换为世界空间向量。
 	</p>
 
-	<h3>[method:null lookAt]( [param:Vector3 vector] )</br>
+	<h3>[method:null lookAt]( [param:Vector3 vector] )<br />
 		[method:null lookAt]( [param:Float x], [param:Float y], [param:Float z] )</h3>
 	<p>
 		vector - 一个表示世界空间中位置的向量。<br /><br />

+ 73 - 0
docs/api/zh/helpers/PositionalAudioHelper.html

@@ -0,0 +1,73 @@
+<!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">这一辅助对象显示[page:PositionalAudio]的方向锥。</p>
+
+		<h2>示例</h2>
+
+		<div>[example:webaudio_orientation webaudio / orientation ]</div>
+
+		<h2>示例代码</h2>
+		<code>
+var positionalAudio = new THREE.PositionalAudio( listener );
+positionalAudio.setDirectionalCone( 180, 230, 0.1 );
+
+var helper = new PositionalAudioHelper( positionalAudio );
+positionalAudio.add( helper );
+		</code>
+
+
+		<h2>构造函数</h2>
+
+		<h3>[name]( [param:PositionalAudio audio], [param:Number range] )</h3>
+		<p>
+			[page:PositionalAudio audio] -- 将会被可视化的[page:PositionalAudio]。<br /><br/>
+
+			[page:Number range] -- (可选)方向锥的范围。<br /><br/>
+
+			[page:Number divisionsInnerAngle] -- (可选)方向锥内侧部分的分段数。<br /><br/>
+
+			[page:Number divisionsOuterAngle] -- (可选)方向锥外侧部分的分段数。<br /><br/>
+		</p>
+
+
+		<h2>属性</h2>
+		<p>请参阅其基类[page:Object3D]来了解共有属性。</p>
+
+		<h3>[property:PositionalAudio audio]</h3>
+		<p>将会被可视化的[page:PositionalAudio]。</p>
+
+		<h3>[property:Number range]</h3>
+		<p>方向锥的范围。</p>
+
+		<h3>[property:Number divisionsInnerAngle]</h3>
+		<p>方向锥内侧部分的分段数。</p>
+
+		<h3>[property:Number divisionsOuterAngle]</h3>
+		<p>方向锥外侧部分的分段数。</p>
+
+		<h2>方法</h2>
+		<p>请参阅其基类[page:Object3D]来了解共有方法。</p>
+
+		<h3>[method:null dispose]()</h3>
+		<p>废置这一辅助对象。</p>
+
+		<h3>[method:null update]()</h3>
+		<p>更新这一辅助对象。</p>
+
+		<h2>源代码</h2>
+
+		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
+	</body>
+</html>

+ 4 - 7
docs/api/zh/loaders/AnimationLoader.html

@@ -65,20 +65,17 @@
 		<p>
 		[page:String url] — 文件的URL或者路径,也可以为
 			[link:https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs Data URI].<br />
-		[page:Function onLoad] — 加载完成时将调用。回调参数为将要加载的[page:Animation animation].<br />
+		[page:Function onLoad] — 加载完成时将调用。回调参数为将要加载的[page:AnimationClip animation clips].<br />
 		[page:Function onProgress] —  将在加载过程中进行调用。参数为XMLHttpRequest实例,实例包含[page:Integer total]和[page:Integer loaded]字节。<br />
 		[page:Function onError] — 在加载错误时被调用。<br /><br />
 
             从URL中进行加载并将动画传递给onLoad。
 		</p>
 
-		<h3>[method:null parse]( [param:JSON json], [param:Function onLoad] )</h3>
+		<h3>[method:Array parse]( [param:JSON json] )</h3>
 		<p>
-		[page:JSON json] — 请求<br />
-		[page:Function onLoad] — 当解析完成时,将被调用 <br /><br />
-
-            解析JSON对象并将结果传递给onLoad。对象中的单个片段将
-            用[page [page:AnimationClip.parse]进行解析。
+		[page:JSON json] — 请求 <br /><br />
+			TODO
 		</p>
 
 		<h2>源</h2>

+ 10 - 0
docs/api/zh/loaders/ImageBitmapLoader.html

@@ -16,6 +16,13 @@
 			不像[page:FileLoader], [name]无需避免对同一的URL进行多次请求。
 		</p>
 
+		<p>
+			Note that [page:Texture.flipY] and [page:Texture.premultiplyAlpha] with [link:https://developer.mozilla.org/de/docs/Web/API/ImageBitmap ImageBitmap] are ignored.
+			[link:https://developer.mozilla.org/de/docs/Web/API/ImageBitmap ImageBitmap] needs these configuration on bitmap creation
+			unlike regular images need them on uploading to GPU. You need to set the equivalent options via [page:ImageBitmapLoader.setOptions]
+			instead. Refer to [link:https://www.khronos.org/registry/webgl/specs/latest/1.0/#6.10 WebGL specification] for the detail.
+		</p>
+
 		<h2>例子</h2>
 
 		<p>
@@ -26,6 +33,9 @@
 		// 初始化一个加载器
 		var loader = new THREE.ImageBitmapLoader();
 
+		// set options if needed
+		loader.setOptions( { imageOrientation: 'flipY' } );
+
 		// 加载一个图片资源
 		loader.load(
 			// 资源的URL

+ 20 - 0
docs/api/zh/loaders/Loader.html

@@ -61,6 +61,26 @@
 		基于参数数组m,来创建 [page:Material] 数组. 参数索引与材质的索引一致。
 		</p>
 
+		<h2>Handlers</h2>
+
+		<p>
+		TODO
+		</p>
+
+		<h3>[method:null add]( [param:Object regex], [param:Loader loader] )</h3>
+		<p>
+		[page:Object regex] — TODO<br />
+		[page:Loader loader] — TODO
+		<p>
+		TODO
+		</p>
+
+		<h3>[method:null get]( [param:String file] )</h3>
+		<p>
+		[page:String file] — TODO
+		<p>
+		TODO
+		</p>
 
 		<h2>Source</h2>
 

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

@@ -217,6 +217,10 @@
     其他选项有[page:Materials THREE.VertexColors] 和 [page:Materials THREE.FaceColors]。
 </p>
 
+<h3>[property:Boolean vertexTangents]</h3>
+<p> TODO.
+</p>
+
 <h3>[property:Boolean visible]</h3>
 <p> 此材质是否可见。默认为*true*。
 </p>
@@ -239,7 +243,7 @@
 <p> 处理材质。材质的纹理不会被处理。需要通过[page:Texture Texture]处理。
 </p>
 
-<h3>[method:null onBeforeCompile]( [param:Object shader], [param:WebGLRenderer renderer] )</h3>
+<h3>[method:null onBeforeCompile]( [param:Shader shader], [param:WebGLRenderer renderer] )</h3>
 <p> 在编译shader程序之前立即执行的可选回调。此函数使用shader源码作为参数。用于修改内置材质。
 </p>
 

+ 112 - 0
docs/api/zh/materials/MeshDistanceMaterial.html

@@ -0,0 +1,112 @@
+<!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:Material] &rarr;
+
+		<h1>[name]</h1>
+
+		<p class="desc">
+			TODO
+		</p>
+
+		<h2>Example</h2>
+
+		[example:webgl_shadowmap_pointlight WebGL / shadowmap / pointlight]
+
+		<script>
+
+		// iOS iframe auto-resize workaround
+
+		if ( /(iPad|iPhone|iPod)/g.test( navigator.userAgent ) ) {
+
+			var scene = document.getElementById( 'scene' );
+
+			scene.style.width = getComputedStyle( scene ).width;
+			scene.style.height = getComputedStyle( scene ).height;
+			scene.setAttribute( 'scrolling', 'no' );
+
+		}
+
+		</script>
+
+		<h2>构造函数(Constructor)</h2>
+
+		<h3>[name]( [param:Object parameters] )</h3>
+		<p>[page:Object parameters] - (可选)用于定义材质外观的对象,具有一个或多个属性。
+			材质的任何属性都可以从此处传入(包括从[page:Material]继承的任何属性)。
+		</p>
+
+		<h2>属性(Properties)</h2>
+		<p>常用属性请参见基类[page:Material]。</p>
+
+		<h3>[property:Texture alphaMap]</h3>
+		<p>alpha贴图是一种灰度纹理,用于控制整个表面的不透明度(黑色:完全透明;白色:完全不透明)。默认值为null。<br /><br />
+			仅使用纹理的颜色,忽略alpha通道(如果存在)。对于RGB和RGBA纹理,[page:WebGLRenderer WebGL]渲染器在采样此纹理时将使用绿色通道,
+			因为在DXT压缩和未压缩RGB 565格式中为绿色提供了额外的精度。Luminance-only以及luminance/alpha纹理也仍然有效。
+		</p>
+
+		<h3>[property:Texture displacementMap]</h3>
+		<p> 位移贴图会影响网格顶点的位置,与仅影响材质的光照和阴影的其他贴图不同,移位的顶点可以投射阴影,阻挡其他对象,以及充当真实的几何体。
+			位移纹理是指:网格的所有顶点被映射为图像中每个像素的值(白色是最高的),并且被重定位。
+		</p>
+
+		<h3>[property:Float displacementScale]</h3>
+		<p>位移贴图对网格的影响程度(黑色是无位移,白色是最大位移)。如果没有设置位移贴图,则不会应用此值。默认值为1。
+		</p>
+
+		<h3>[property:Float displacementBias]</h3>
+		<p> 位移贴图在网格顶点上的偏移量。如果没有设置位移贴图,则不会应用此值。默认值为0。
+		</p>
+
+		<h3>[property:Float farDistance]</h3>
+		<p>
+			TODO
+		</p>
+
+		<h3>[property:Boolean fog]</h3>
+		<p> 材质是否受雾影响。默认值为*false*。</p>
+
+		<h3>[property:Boolean isMeshDistanceMaterial]</h3>
+		<p> 用于检查此类或派生类是否为深度网格材质。默认值为 *true*。<br /><br />
+
+			因为其通常用在内部优化,所以不应该更改该属性值。
+		</p>
+
+		<h3>[property:Boolean lights]</h3>
+		<p>材质是否受到光照的影响。默认值为 *false*。</p>
+
+		<h3>[property:Texture map]</h3>
+		<p>颜色贴图。默认为null。</p>
+
+		<h3>[property:boolean morphTargets]</h3>
+		<p>材质是否使用morphTargets。默认值为false。</p>
+
+		<h3>[property:Float nearDistance]</h3>
+		<p>
+			TODO
+		</p>
+
+		<h3>[property:Vector3 referencePosition]</h3>
+		<p>
+			TODO
+		</p>
+
+		<h3>[property:Boolean skinning]</h3>
+		<p>材质是否使用蒙皮。默认值为false。</p>
+
+		<h2>方法(Methods)</h2>
+		<p>常用方法请参见基类[page:Material]。</p>
+
+
+		<h2>源码(Source)</h2>
+
+		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
+	</body>
+</html>

+ 120 - 0
docs/api/zh/materials/MeshMatcapMaterial.html

@@ -0,0 +1,120 @@
+<!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:Material] &rarr;
+
+		<h1>[name]</h1>
+
+		<p class="desc">
+			TODO
+		</p>
+
+		<iframe id="scene" src="scenes/material-browser.html#MeshMatcapMaterial"></iframe>
+
+		<script>
+
+		// iOS iframe auto-resize workaround
+
+		if ( /(iPad|iPhone|iPod)/g.test( navigator.userAgent ) ) {
+
+			var scene = document.getElementById( 'scene' );
+
+			scene.style.width = getComputedStyle( scene ).width;
+			scene.style.height = getComputedStyle( scene ).height;
+			scene.setAttribute( 'scrolling', 'no' );
+
+		}
+
+		</script>
+
+		<h2>构造函数(Constructor)</h2>
+
+		<h3>[name]( [param:Object parameters] )</h3>
+		<p>[page:Object parameters] - (可选)用于定义材质外观的对象,具有一个或多个属性。
+			材质的任何属性都可以从此处传入(包括从[page:Material]继承的任何属性)。<br /><br />
+			属性[page:Hexadecimal color]例外,其可以作为十六进制字符串传递,默认情况下为 *0xffffff*(白色),内部调用[page:Color.set](color)。
+		</p>
+
+		<h2>属性(Properties)</h2>
+		<p>常用属性请参见基类[page:Material]。</p>
+
+		<h3>[property:Texture alphaMap]</h3>
+		<p>Talpha贴图是一种灰度纹理,用于控制整个表面的不透明度(黑色:完全透明;白色:完全不透明)。默认值为null。<br /><br />
+			仅使用纹理的颜色,忽略alpha通道(如果存在)。对于RGB和RGBA纹理,[page:WebGLRenderer WebGL]渲染器在采样此纹理时将使用绿色通道,
+			因为在DXT压缩和未压缩RGB 565格式中为绿色提供了额外的精度。Luminance-only以及luminance/alpha纹理也仍然有效。
+		</p>
+
+		<h3>[property:Texture bumpMap]</h3>
+		<p> 用于创建凹凸贴图的纹理。黑色和白色值映射到与光照相关的感知深度。凹凸实际上不会影响对象的几何形状,只影响光照。如果定义了法线贴图,则将忽略该贴图。
+		</p>
+
+		<h3>[property:Float bumpScale]</h3>
+		<p> 凹凸贴图会对材质产生多大影响。典型范围是0-1。默认值为1。</p>
+
+		<h3>[property:Color color]</h3>
+		<p>材质的颜色([page:Color]),默认值为白色 (0xffffff)。</p>
+
+		<h3>[property:Texture displacementMap]</h3>
+		<p> 位移贴图会影响网格顶点的位置,与仅影响材质的光照和阴影的其他贴图不同,移位的顶点可以投射阴影,阻挡其他对象,
+			以及充当真实的几何体。位移纹理是指:网格的所有顶点被映射为图像中每个像素的值(白色是最高的),并且被重定位。
+		</p>
+
+		<h3>[property:Float displacementScale]</h3>
+		<p> 位移贴图对网格的影响程度(黑色是无位移,白色是最大位移)。如果没有设置位移贴图,则不会应用此值。默认值为1。
+		</p>
+
+		<h3>[property:Float displacementBias]</h3>
+		<p>
+			位移贴图在网格顶点上的偏移量。如果没有设置位移贴图,则不会应用此值。默认值为0。
+		</p>
+
+		<h3>[property:Boolean isMeshMatcapMaterial]</h3>
+		<p>TODO<br /><br />
+
+			因为其通常用在内部优化,所以不应该更改该属性值。
+		</p>
+
+		<h3>[property:Texture map]</h3>
+		<p>颜色贴图。默认为null。纹理贴图颜色由漫反射颜色[page:.color]调节。</p>
+
+		<h3>[property:Texture matcap]</h3>
+		<p>TODO</p>
+
+		<h3>[property:boolean morphNormals]</h3>
+		<p> 定义是否使用morphNormals。设置为true可将morphNormal属性从[page:Geometry]传递到shader。默认值为*false*。
+		</p>
+
+		<h3>[property:Boolean morphTargets]</h3>
+		<p>定义材质是否使用morphTargets。默认值为false。</p>
+
+		<h3>[property:Texture normalMap]</h3>
+		<p> 用于创建法线贴图的纹理。RGB值会影响每个像素片段的曲面法线,并更改颜色照亮的方式。法线贴图不会改变曲面的实际形状,只会改变光照。
+		</p>
+
+		<h3>[property:Integer normalMapType]</h3>
+		<p> 法线贴图的类型。<br /><br />
+			选项为[page:constant THREE.TangentSpaceNormalMap](默认)和[page:constant THREE.ObjectSpaceNormalMap]。
+		</p>
+
+		<h3>[property:Vector2 normalScale]</h3>
+		<p> 法线贴图对材质的影响程度。典型范围是0-1。默认值是[page:Vector2]设置为(1,1)。
+		</p>
+
+		<h3>[property:Boolean skinning]</h3>
+		<p>材质是否使用蒙皮。默认值为false。</p>
+
+		<h2>方法(Methods)</h2>
+		<p>常用方法请参见基类[page:Material]。</p>
+
+		<h2>源码(Source)</h2>
+
+		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
+	</body>
+</html>

+ 42 - 1
docs/api/zh/materials/MeshNormalMaterial.html

@@ -42,6 +42,27 @@
 		<h2>属性(Properties)</h2>
 		<p>常用属性请参见基类[page:Material]。</p>
 
+		<h3>[property:Texture bumpMap]</h3>
+		<p> 用于创建凹凸贴图的纹理。黑色和白色值映射到与光照相关的感知深度。凹凸实际上不会影响对象的几何形状,只影响光照。如果定义了法线贴图,则将忽略该贴图。
+		</p>
+
+		<h3>[property:Float bumpScale]</h3>
+		<p> 凹凸贴图会对材质产生多大影响。典型范围是0-1。默认值为1。</p>
+
+		<h3>[property:Texture displacementMap]</h3>
+		<p> 位移贴图会影响网格顶点的位置,与仅影响材质的光照和阴影的其他贴图不同,移位的顶点可以投射阴影,阻挡其他对象,
+			以及充当真实的几何体。位移纹理是指:网格的所有顶点被映射为图像中每个像素的值(白色是最高的),并且被重定位。
+		</p>
+
+		<h3>[property:Float displacementScale]</h3>
+		<p> 位移贴图对网格的影响程度(黑色是无位移,白色是最大位移)。如果没有设置位移贴图,则不会应用此值。默认值为1。
+		</p>
+
+		<h3>[property:Float displacementBias]</h3>
+		<p>
+			位移贴图在网格顶点上的偏移量。如果没有设置位移贴图,则不会应用此值。默认值为0。
+		</p>
+
 		<h3>[property:Boolean fog]</h3>
 		<p>材质是否受雾影响。默认值为*false*。</p>
 
@@ -54,9 +75,29 @@
 		<h3>[property:Boolean lights]</h3>
 		<p>材质是否受到光照的影响。默认值为 *false*。</p>
 
-		<h3>[property:boolean morphTargets]</h3>
+		<h3>[property:boolean morphNormals]</h3>
+		<p> 定义是否使用morphNormals。设置为true可将morphNormal属性从[page:Geometry]传递到shader。默认值为*false*。
+		</p>
+
+		<h3>[property:Boolean morphTargets]</h3>
 		<p>定义材质是否使用morphTargets。默认值为false。</p>
 
+		<h3>[property:Texture normalMap]</h3>
+		<p> 用于创建法线贴图的纹理。RGB值会影响每个像素片段的曲面法线,并更改颜色照亮的方式。法线贴图不会改变曲面的实际形状,只会改变光照。
+		</p>
+
+		<h3>[property:Integer normalMapType]</h3>
+		<p> 法线贴图的类型。<br /><br />
+			选项为[page:constant THREE.TangentSpaceNormalMap](默认)和[page:constant THREE.ObjectSpaceNormalMap]。
+		</p>
+
+		<h3>[property:Vector2 normalScale]</h3>
+		<p> 法线贴图对材质的影响程度。典型范围是0-1。默认值是[page:Vector2]设置为(1,1)。
+		</p>
+
+		<h3>[property:Boolean skinning]</h3>
+		<p>材质是否使用蒙皮。默认值为false。</p>
+
 		<h3>[property:boolean wireframe]</h3>
 		<p>
 			将几何体渲染为线框。默认值为*false*(即渲染为平滑着色)。

+ 3 - 3
docs/api/zh/math/Matrix3.html

@@ -53,7 +53,7 @@ m.elements = [ 11, 21, 31,
 
 		<h2>属性(Properties)</h2>
 
-		<h3>[property:Float32Array elements]</h3>
+		<h3>[property:Array elements]</h3>
 		<p>
 			矩阵列优先[link:https://en.wikipedia.org/wiki/Row-_and_column-major_order column-major]列表。
 		</p>
@@ -61,7 +61,7 @@ m.elements = [ 11, 21, 31,
 		<h3>[property:Boolean isMatrix3]</h3>
 		<p>
 				用于判定此对象或者此类的派生对象是否是三维矩阵。默认值为 *true*。<br /><br />
-			
+
 				不应该改变该值,因为它在内部用于优化。
 		</p>
 
@@ -103,7 +103,7 @@ m.elements = [ 11, 21, 31,
 		<p>
 		[page:Matrix3 m] - 取逆的矩阵。<br />
 		[page:Boolean throwOnDegenerate] - (optional) 如果设置为true,如果矩阵是退化的(如果不可逆的话),则会抛出一个错误。<br /><br />
-		
+
 		使用逆矩阵计算方法[link:https://en.wikipedia.org/wiki/Invertible_matrix#Analytic_solution analytic method],
 		将当前矩阵设置为给定矩阵的逆矩阵[link:https://en.wikipedia.org/wiki/Invertible_matrix inverse],如果[page:Boolean throwOnDegenerate]
 		参数没有设置且给定矩阵不可逆,那么将当前矩阵设置为3X3单位矩阵。

+ 5 - 5
docs/api/zh/math/Matrix4.html

@@ -83,7 +83,7 @@ m.elements = [ 11, 21, 31, 41,
 
 		<h2>属性(Properties)</h2>
 
-		<h3>[property:Float32Array elements]</h3>
+		<h3>[property:Array elements]</h3>
 		<p>
 		矩阵列优先[link:https://en.wikipedia.org/wiki/Row-_and_column-major_order column-major]列表。
 		</p>
@@ -91,7 +91,7 @@ m.elements = [ 11, 21, 31, 41,
 		<h3>[property:Boolean isMatrix4]</h3>
 		<p>
 			用于判定此对象或者此类的派生对象是否是三维矩阵。默认值为 *true*。<br /><br />
-		
+
 			不应该改变该值,因为它在内部用于优化。
 		</p>
 
@@ -168,7 +168,7 @@ zAxis = (c, g, k)
 		<p>
 			[page:Array array] - 用来存储设置元素数据的数组<br />
 			[page:Integer offset] - (可选参数) 数组的偏移量,默认值为 0。<br /><br />
-	
+
 			使用基于列优先格式[link:https://en.wikipedia.org/wiki/Row-_and_column-major_order#Column-major_order column-major]的数组来设置该矩阵。
 			</p>
 
@@ -176,7 +176,7 @@ zAxis = (c, g, k)
 		<p>
 			[page:Matrix3 m] - 取逆的矩阵。<br />
 			[page:Boolean throwOnDegenerate] - (optional) 如果设置为true,如果矩阵是退化的(如果不可逆的话),则会抛出一个错误。<br /><br />
-			
+
 			使用逆矩阵计算方法[link:https://en.wikipedia.org/wiki/Invertible_matrix#Analytic_solution analytic method],
 			将当前矩阵设置为给定矩阵的逆矩阵[link:https://en.wikipedia.org/wiki/Invertible_matrix inverse],如果[page:Boolean throwOnDegenerate]
 			参数没有设置且给定矩阵不可逆,那么将当前矩阵设置为3X3单位矩阵。
@@ -251,7 +251,7 @@ xAxis.z, yAxis.z, zAxis.z, 0,
 		<h3>[method:this makeRotationX]( [param:Float theta] )</h3>
 		<p>
 		[page:Float theta] — Rotation angle in radians.<br /><br />
-		
+
 		把该矩阵设置为绕x轴旋转弧度[page:Float theta] (&theta;)大小的矩阵。
 		结果如下:
 		<code>

+ 8 - 1
docs/api/zh/math/Quaternion.html

@@ -44,6 +44,13 @@
 
 		<h2>Properties</h2>
 
+		<h3>[property:Boolean isQuaternion]</h3>
+		<p>
+			Used to check whether this or derived classes are Quaternions. Default is *true*.<br /><br />
+
+			You should not change this, as it is used internally for optimisation.
+		</p>
+
 		<h3>[property:Float x]</h3>
 		<p>Changing this property will result in [page:.onChangeCallback onChangeCallback] being called.</p>
 
@@ -290,4 +297,4 @@ q.slerp( qb, t )
 
 		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
 	</body>
-</html>
+</html>

+ 1 - 1
docs/api/zh/objects/Mesh.html

@@ -91,7 +91,7 @@
 		<h3>[method:null raycast]( [param:Raycaster raycaster], [param:Array intersects] )</h3>
 		<p>
 			在一条投射出去的[page:Ray](射线)和这个网格之间产生交互。
-			[page:Raycaster.intersectObject]将会调用这个方法
+			[page:Raycaster.intersectObject]将会调用这个方法但是这个结果是未排序的
 		</p>
 
 		<h3>[method:null updateMorphTargets]()</h3>

+ 0 - 5
docs/api/zh/renderers/WebGLRenderTargetCube.html

@@ -47,11 +47,6 @@
 
 		<h2>属性</h2>
 
-		<h3>[property:integer activeCubeFace]</h3>
-		<p>
-		activeCubeFace属性对应立方体的面(PX 0, NX 1, PY 2, NY 3, PZ 4, NZ 5) 并由[page:CubeCamera]内部使用和设置
-		</p>
-
 		<h3>继承属性,请参阅[page:WebGLRenderTarget]</h3>
 
 

+ 6 - 27
docs/api/zh/renderers/WebGLRenderer.html

@@ -254,12 +254,6 @@
 
 		<h2>方法</h2>
 
-		<h3>[method:Integer allocTextureUnit]</h3>
-		<p>
-		尝试分配纹理单元以供着色器使用。如果尝试分配超过GPU支持量的纹理单元,则会报警告。主要供内部使用。
-		请参阅[page:WebGLRenderer.capabilities capabilities.maxTextures]。
-		</p>
-
 		<h3>[method:null clear]( [param:Boolean color], [param:Boolean depth], [param:Boolean stencil] )</h3>
 		<p>
 		告诉渲染器清除颜色、深度或模板缓存.
@@ -348,7 +342,7 @@
 		<p>将GL状态重置为默认值。WebGL环境丢失时会内部调用</p>
 
 		<h3>[method:null readRenderTargetPixels]( [param:WebGLRenderTarget renderTarget], [param:Float x], [param:Float y], [param:Float width], [param:Float height], buffer )</h3>
-		<p>将enderTarget中的像素数据读取到传入的缓冲区中。这是link:https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/readPixels WebGLRenderingContext.readPixels]()的包装器<br />
+		<p>将enderTarget中的像素数据读取到传入的缓冲区中。这是[link:https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/readPixels WebGLRenderingContext.readPixels]()的包装器<br />
 		示例:[example:webgl_interactive_cubes_gpu interactive / cubes / gpu]
 		</p>
 
@@ -376,7 +370,7 @@
 
 		<h3>[method:null setAnimationLoop]( [param:Function callback] )</h3>
 		<p>[page:Function callback] — 每个可用帧都会调用的函数。 如果传入‘null’,所有正在进行的动画都会停止。</p>
-		<p>可用来代替[link:https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame requestAnimationFrame]的内置函数. 对于WebVR想谬,必须使用此功能</p>
+		<p>可用来代替[link:https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame requestAnimationFrame]的内置函数. 对于WebVR项目,必须使用此函数。</p>
 
 		<h3>[method:null setClearAlpha]( [param:Float alpha] )</h3>
 		<p>设置alpha。合法参数是一个*0.0*到 *1.0*之间的浮点数</p>
@@ -387,9 +381,11 @@
 		<h3>[method:null setPixelRatio]( [param:number value] )</h3>
 		<p>设置设备像素比。通常用于避免HiDPI设备上绘图模糊</p>
 
-		<h3>[method:null setRenderTarget]( [param:WebGLRenderTarget renderTarget] )</h3>
+		<h3>[method:null setRenderTarget]( [param:WebGLRenderTarget renderTarget], [param:Integer activeCubeFace], [param:Integer activeMipMapLevel] )</h3>
 		<p>
-		renderTarget -- 需要被激活的[page:WebGLRenderTarget renderTarget](可选).<br /><br />
+		renderTarget -- 需要被激活的[page:WebGLRenderTarget renderTarget](可选).<br />
+		activeCubeFace -- Specifies the active cube side (PX 0, NX 1, PY 2, NY 3, PZ 4, NZ 5) of [page:WebGLRenderTargetCube] (optional).<br />
+		activeMipMapLevel -- Specifies the active mipmap level (optional).<br /><br />
 		该方法设置活跃rendertarget. 参数缺省则将canvas设置成活跃rendertarget
 		</p>
 
@@ -410,23 +406,6 @@
 		将[page:Boolean updateStyle]设置为false以阻止对canvas的样式做任何改变。
 		</p>
 
-		<h3>[method:null setTexture2D]( [param:Texture texture], [param:number slot] )</h3>
-		<p>
-		texture -- 需被设置的[page:Texture texture]<br />
-		slot -- 纹理应该使用的插槽号<br /><br />
-        该方法为WebGL着色器将正确的纹理设置到正确的插槽中。插槽号可作为取样器的全局变量(uniform)<br /><br />
-
-		说明: 该方法取代了旧的[method:null setTexture]方法
-		</p>
-
-		<h3>[method:null setTextureCube]( [param:CubeTexture cubeTexture], [param:Number slot] )</h3>
-		<p>
-		texture -- 需要被设置的[page:CubeTexture cubeTexture]<br />
-		slot -- 纹理应该使用的插槽号<br /><br />
-
-        该方法为WebGL着色器将正确的纹理设置到正确的插槽中。插槽号可作为取样器的全局变量(uniform)
-		</p>
-
 		<h3>[method:null setViewport]( [param:Integer x], [param:Integer y], [param:Integer width], [param:Integer height] )</h3>
 		<p>将视口大小设置为(x, y)到 (x + width, y + height).</p>
 

+ 13 - 1
docs/api/zh/textures/Texture.html

@@ -54,6 +54,14 @@
 		并在视频播放时不断地更新这个纹理贴图。——[page:VideoTexture VideoTexture] 类会对此自动进行处理。
 		</p>
 
+		<h3>[property:Boolean isTexture]</h3>
+		<p>
+			用于测试这个类或者派生类是否为Texture,默认为*true*。<br /><br />
+
+			你不应当对这个属性进行改变,因为它在内部使用,以用于优化。
+		</p>
+
+
 		<h3>[property:array mipmaps]</h3>
 		<p>
 		用户所给定的mipmap数组(可选)。
@@ -180,11 +188,15 @@
 		<p>
 			默认为false,这是PNG图像的规范。
 			如果RGB值已被Alpha预乘,请将其设为true。
+			Note that this property has no effect for [link:https://developer.mozilla.org/de/docs/Web/API/ImageBitmap ImageBitmap].
+			You need to configure on bitmap creation instead. See [page:ImageBitmapLoader].
 		</p>
 
 		<h3>[property:boolean flipY]</h3>
 		<p>
 		默认为true。翻转图像的Y轴以匹配WebGL纹理坐标空间。
+		Note that this property has no effect for [link:https://developer.mozilla.org/de/docs/Web/API/ImageBitmap ImageBitmap].
+		You need to configure on bitmap creation instead. See [page:ImageBitmapLoader].
 		</p>
 
 		<h3>[property:number unpackAlignment]</h3>
@@ -244,7 +256,7 @@
 
 		<h3>[method:null dispose]()</h3>
 		<p>
-			使用“dispose”事件类型调用[page:EventDispatcher EventDispatcher].dispatchEvent。
+			使用“废置”事件类型调用[page:EventDispatcher EventDispatcher].dispatchEvent。
 		</p>
 
 		<h3>[method:Vector2 transformUv]( [param:Vector2 uv] )</h3>

+ 1 - 0
docs/examples/exporters/GLTFExporter.html

@@ -97,6 +97,7 @@
 			<li>animations - Array<[page:AnimationClip AnimationClip]>. List of animations to be included in the export.</li>
 			<li>forceIndices - bool. Generate indices for non-index geometry and export with them. Default is false.</li>
 			<li>forcePowerOfTwoTextures - bool. Export with images resized to POT size. This option works only if embedImages is true. Default is false.</li>
+			<li>includeCustomExtensions - bool. Export custom glTF extensions defined on an object's <em>userData.gltfExtensions</em> property. Default is false.</li>
 		</ul>
 		</p>
 		<p>

+ 145 - 0
docs/examples/loaders/DRACOLoader.html

@@ -0,0 +1,145 @@
+<!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 geometry compressed with the Draco library. <br /><br />
+			[link:https://google.github.io/draco/ Draco] is an open source library for compressing and
+			decompressing 3D meshes and point clouds. Compressed geometry can be significantly smaller,
+			at the cost of additional decoding time on the client device.
+		</p>
+
+		<p>
+			Standalone Draco files have a <em>.drc</em> extension, and contain vertex positions,
+			normals, colors, and other attributes. Draco files <em>do not</em> contain materials,
+			textures, animation, or node hierarchies – to use these features, embed Draco geometry
+			inside of a glTF file. A normal glTF file can be converted to a Draco-compressed glTF file
+			using [link:https://github.com/AnalyticalGraphicsInc/gltf-pipeline glTF-Pipeline]. When
+			using Draco with glTF, an instance of DRACOLoader will be used internally by [page:GLTFLoader].
+		</p>
+
+		<h2>Example</h2>
+
+		<code>
+		// Instantiate a loader
+		var loader = new THREE.DRACOLoader();
+
+		// Specify path to a folder containing WASM/JS decoding libraries.
+		THREE.DRACOLoader.setDecoderPath( '/examples/js/libs/draco' );
+
+		// Optional: Pre-fetch Draco WASM/JS module.
+		THREE.DRACOLoader.getDecoderModule();
+
+		// Load a Draco geometry
+		loader.load(
+			// resource URL
+			'model.drc',
+			// called when the resource is loaded
+			function ( geometry ) {
+
+				var material = new THREE.MeshStandardMaterial( { color: 0x606060 } );
+				var mesh = new THREE.Mesh( geometry, material );
+				scene.add( mesh );
+
+			},
+			// called as loading progresses
+			function ( xhr ) {
+
+				console.log( ( xhr.loaded / xhr.total * 100 ) + '% loaded' );
+
+			},
+			// called when loading has errors
+			function ( error ) {
+
+				console.log( 'An error happened' );
+
+			}
+		);
+		</code>
+
+		[example:webgl_loader_draco]
+
+		<h2>Browser compatibility</h2>
+
+		<p>DRACOLoader relies on ES6 [link:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise Promises],
+		which are not supported in IE11. To use the loader in IE11, you must
+		[link:https://github.com/stefanpenner/es6-promise include a polyfill]
+		providing a Promise replacement. DRACOLoader will automatically use
+		either the JS or the WASM decoding library, based on browser
+		capabilities.</p>
+
+		<br>
+		<hr>
+
+		<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>Static Methods</h2>
+
+		<h3>[method:null setDecoderPath]( [param:String value] )</h3>
+		<p>
+		[page:String value] — Path to folder containing the JS and WASM decoder libraries.
+		</p>
+
+		<h3>[method:null setDecoderConfig]( [param:Object config] )</h3>
+		<p>
+			[page:String config.type] - (Optional) <em>"js"</em> or <em>"wasm"</em>.<br />
+		</p>
+		<p>
+		Provides configuration for the decoder libraries. Configuration cannot be changed
+		after loading the decoders.
+		</p>
+
+		<h3>[method:Promise getDecoderModule]()</h3>
+		<p>
+		Requests the decoder libraries, if not already loaded.
+		</p>
+
+		<h3>[method:null releaseDecoderModule]()</h3>
+		<p>
+		Disposes of the decoder library and deallocates memory. The decoder
+		[link:https://github.com/google/draco/issues/349 cannot be reloaded afterward].
+		</p>
+
+		<h2>Methods</h2>
+
+		<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>.drc</em> file.<br />
+		[page:Function onLoad] — A function to be called after the loading is successfully completed.<br />
+		[page:Function onProgress] — (optional) A function to be called while the loading is in progress. The argument will be the XMLHttpRequest instance, that 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 error as an argument.<br />
+		</p>
+		<p>
+		Begin loading from url and call the <em>onLoad</em> function with the decompressed geometry.
+		</p>
+
+		<h3>[method:DRACOLoader setPath]( [param:String path] )</h3>
+		<p>
+		[page:String path] — Base path.
+		</p>
+		<p>
+		Set the base path for the <em>.drc</em> file.
+		</p>
+
+		<h2>Source</h2>
+
+		[link:https://github.com/mrdoob/three.js/blob/master/examples/js/loaders/DRACOLoader.js examples/js/loaders/DRACOLoader.js]
+	</body>
+</html>

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

@@ -58,6 +58,9 @@
 		// Optional: Provide a DRACOLoader instance to decode compressed mesh data
 		THREE.DRACOLoader.setDecoderPath( '/examples/js/libs/draco' );
 		loader.setDRACOLoader( new THREE.DRACOLoader() );
+			
+		// Optional: Pre-fetch Draco WASM/JS module, to save time while parsing.
+		THREE.DRACOLoader.getDecoderModule();
 
 		// Load a glTF resource
 		loader.load(

+ 1 - 1
docs/examples/loaders/OBJLoader2.html

@@ -52,7 +52,7 @@
 
 		<h2>Methods</h2>
 
-		<h3>[method:Object3D parse]( {[param:arraybuffer content]|[param:String content]] )</h3>
+		<h3>[method:Object3D parse]( [param:arraybuffer content]|[param:String content] )</h3>
 		<p>
 			[[page:arraybuffer content]|[page:String content]] OBJ data as Uint8Array or String
 		</p>

+ 2 - 1
docs/examples/loaders/SVGLoader.html

@@ -26,8 +26,9 @@
 			// resource URL
 			'data/svgSample.svg',
 			// called when the resource is loaded
-			function ( paths ) {
+			function ( data ) {
 
+				var paths = data.paths;
 				var group = new THREE.Group();
 
 				for ( var i = 0; i < paths.length; i ++ ) {

+ 2 - 3
docs/examples/objects/Lensflare.html

@@ -44,13 +44,12 @@ light.add( lensflare );
 		<h2>Constructor</h2>
 
 
-		<h3>LensflareElement( [param:Texture texture], [param:Float size], [param:Float distance], [param:Color color], [param:Materials blending] )</h3>
+		<h3>LensflareElement( [param:Texture texture], [param:Float size], [param:Float distance], [param:Color color] )</h3>
 		<p>
 		[page:Texture texture] - THREE.Texture to use for the flare. <br />
 		[page:Float size] - (optional) size in pixels <br />
 		[page:Float distance] - (optional) (0-1) from light source (0 = at light source) <br />
-		[page:Color color] - (optional) the [page:Color] of the lens flare<br />
-		[page:Materials blending] - (optional) [page:Materials Blending Mode] - Defaults to THREE.NormalBlending
+		[page:Color color] - (optional) the [page:Color] of the lens flare
 		</p>
 
 		<h2>Properties</h2>

+ 60 - 0
docs/examples/utils/SkeletonUtils.html

@@ -0,0 +1,60 @@
+<!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">Utility functions for [page:Skeleton], [page:SkinnedMesh], and [page:Bone] manipulation.</p>
+
+
+		<h2>Methods</h2>
+
+		<h3>[method:Object3D clone]( [param:Object3D object] )</h3>
+		<p>
+			Clones the given object and its descendants, ensuring that any [page:SkinnedMesh] instances
+			are correctly associated with their bones. Bones are also cloned, and must be descendants of
+			the object passed to this method. Other data, like geometries and materials, are reused by
+			reference.
+		</p>
+
+		<h3>[method:Object findBoneTrackData]( [param:String name], [param:Array tracks] )</h3>
+		<p></p>
+
+		<h3>[method:Bone getBoneByName]( [param:String name], [param:Skeleton skeleton] )</h3>
+		<p></p>
+
+		<h3>[method:Array getBones]( [param:Skeleton skeleton] )</h3>
+		<p></p>
+
+		<h3>[method:Array getEqualsBonesNames]( [param:Skeleton skeleton], [param:Skeleton targetSkeleton] )</h3>
+		<p></p>
+
+		<h3>[method:SkeletonHelper getHelperFromSkeleton]( [param:Skeleton skeleton] )</h3>
+		<p></p>
+
+		<h3>[method:Bone getNearestBone]( [param:Bone bone], [param:Array names] )</h3>
+		<p></p>
+
+		<h3>[method:Object getSkeletonOffsets]( [param:SkeletonHelper target], [param:SkeletonHelper source], [param:Object options] )</h3>
+		<p></p>
+
+		<h3>[method:this renameBones]( [param:Skeleton skeleton], [param:Array names] )</h3>
+		<p></p>
+
+		<h3>[method:null retarget]( [param:SkeletonHelper target], [param:SkeletonHelper source], [param:Object options] )</h3>
+		<p></p>
+
+		<h3>[method:AnimationClip retargetClip]( [param:SkeletonHelper target], [param:SkeletonHelper source], [param:AnimationClip clip], [param:Object options] )</h3>
+		<p></p>
+
+		<h2>Source</h2>
+
+		[link:https://github.com/mrdoob/three.js/blob/master/examples/js/utils/SkeletonUtils.js examples/js/utils/SkeletonUtils.js]
+	</body>
+</html>

+ 15 - 0
docs/index.html

@@ -69,6 +69,8 @@
 
 				language = value;
 				createNavigation();
+				updateFilter();
+				autoChangeUrlLanguage( language );
 
 			}
 
@@ -226,6 +228,19 @@
 
 			}
 
+			// Auto change language url. If a reader open a document in English, when he click "zh", the document he read will auto change into Chinese version
+
+			function autoChangeUrlLanguage( language ) {
+
+				var hash = location.hash;
+				if ( hash === '' ) return;
+				var docType = hash.substr( 0, hash.indexOf( '/' ) + 1 );
+				var docLink = hash.substr( hash.indexOf( '/' ) + 1 );
+				docLink = docLink.substr( docLink.indexOf( '/' ) );
+				location.href = docType + language + docLink;
+
+			}
+
 
 			// Filtering
 

+ 13 - 2
docs/list.js

@@ -22,6 +22,7 @@ var list = {
 
 			"Next Steps": {
 				"How to update things": "manual/en/introduction/How-to-update-things",
+				"How to dispose of objects": "manual/en/introduction/How-to-dispose-of-objects",
 				"How to create VR content": "manual/en/introduction/How-to-create-VR-content",
 				"Matrix transformations": "manual/en/introduction/Matrix-transformations",
 				"Animation system": "manual/en/introduction/Animation-system"
@@ -196,6 +197,7 @@ var list = {
 				"FaceNormalsHelper": "api/en/helpers/FaceNormalsHelper",
 				"GridHelper": "api/en/helpers/GridHelper",
 				"PolarGridHelper": "api/en/helpers/PolarGridHelper",
+				"PositionalAudioHelper": "api/en/helpers/PositionalAudioHelper",
 				"HemisphereLightHelper": "api/en/helpers/HemisphereLightHelper",
 				"PlaneHelper": "api/en/helpers/PlaneHelper",
 				"PointLightHelper": "api/en/helpers/PointLightHelper",
@@ -251,7 +253,9 @@ var list = {
 				"Material": "api/en/materials/Material",
 				"MeshBasicMaterial": "api/en/materials/MeshBasicMaterial",
 				"MeshDepthMaterial": "api/en/materials/MeshDepthMaterial",
+				"MeshDistanceMaterial": "api/en/materials/MeshDistanceMaterial",
 				"MeshLambertMaterial": "api/en/materials/MeshLambertMaterial",
+				"MeshMatcapMaterial": "api/en/materials/MeshMatcapMaterial",
 				"MeshNormalMaterial": "api/en/materials/MeshNormalMaterial",
 				"MeshPhongMaterial": "api/en/materials/MeshPhongMaterial",
 				"MeshPhysicalMaterial": "api/en/materials/MeshPhysicalMaterial",
@@ -361,6 +365,7 @@ var list = {
 
 			"Loaders": {
 				"BabylonLoader": "examples/loaders/BabylonLoader",
+				"DRACOLoader": "examples/loaders/DRACOLoader",
 				"GLTFLoader": "examples/loaders/GLTFLoader",
 				"MMDLoader": "examples/loaders/MMDLoader",
 				"MTLLoader": "examples/loaders/MTLLoader",
@@ -380,7 +385,8 @@ var list = {
 
 			"Exporters": {
 				"GLTFExporter": "examples/exporters/GLTFExporter",
-				"PLYExporter": "examples/exporters/PLYExporter"
+				"PLYExporter": "examples/exporters/PLYExporter",
+				"ColladaExporter": "examples/exporters/ColladaExporter"
 			},
 
 			"Plugins": {
@@ -404,7 +410,8 @@ var list = {
 
 			"Utils": {
 				"BufferGeometryUtils": "examples/utils/BufferGeometryUtils",
-				"SceneUtils": "examples/utils/SceneUtils"
+				"SceneUtils": "examples/utils/SceneUtils",
+				"SkeletonUtils": "examples/utils/SkeletonUtils"
 			}
 
 		},
@@ -447,6 +454,7 @@ var list = {
 
 			"进阶": {
 				"如何更新场景": "manual/zh/introduction/How-to-update-things",
+				"如何废置对象": "manual/zh/introduction/How-to-dispose-of-objects",
 				"如何创建VR内容": "manual/zh/introduction/How-to-create-VR-content",
 				"矩阵变换": "manual/zh/introduction/Matrix-transformations",
 				"动画系统": "manual/zh/introduction/Animation-system"
@@ -621,6 +629,7 @@ var list = {
 				"FaceNormalsHelper": "api/zh/helpers/FaceNormalsHelper",
 				"GridHelper": "api/zh/helpers/GridHelper",
 				"PolarGridHelper": "api/zh/helpers/PolarGridHelper",
+				"PositionalAudioHelper": "api/zh/helpers/PositionalAudioHelper",
 				"HemisphereLightHelper": "api/zh/helpers/HemisphereLightHelper",
 				"PlaneHelper": "api/zh/helpers/PlaneHelper",
 				"PointLightHelper": "api/zh/helpers/PointLightHelper",
@@ -676,7 +685,9 @@ var list = {
 				"Material": "api/zh/materials/Material",
 				"MeshBasicMaterial": "api/zh/materials/MeshBasicMaterial",
 				"MeshDepthMaterial": "api/zh/materials/MeshDepthMaterial",
+				"MeshDistanceMaterial": "api/zh/materials/MeshDistanceMaterial",
 				"MeshLambertMaterial": "api/zh/materials/MeshLambertMaterial",
+				"MeshMatcapMaterial": "api/zh/materials/MeshMatcapMaterial",
 				"MeshNormalMaterial": "api/zh/materials/MeshNormalMaterial",
 				"MeshPhongMaterial": "api/zh/materials/MeshPhongMaterial",
 				"MeshPhysicalMaterial": "api/zh/materials/MeshPhysicalMaterial",

+ 133 - 0
docs/manual/en/introduction/How-to-dispose-of-objects.html

@@ -0,0 +1,133 @@
+<!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>
+	<br />
+
+	<p>
+		One important aspect in order to improve performance and avoid memory leaks in your application is the disposal of unused library entities.
+		Whenever you create an instance of a *three.js* type, you allocate a certain amount of memory. However, *three.js* creates for specific objects
+		like geometries or materials WebGL related entities like buffers or shader programs which are necessary for rendering. It's important to
+		highlight that these objects are not released automatically. Instead, the application has to use a special API in order to free such resources.
+		This guide provides a brief overview about how this API is used and what objects are relevant in this context.
+	</p>
+
+	<h2>Geometries</h2>
+
+	<p>
+		A geometry usually represents vertex information defined as a collection of attributes. *three.js* internally creates an object of type [link:https://developer.mozilla.org/en-US/docs/Web/API/WebGLBuffer WebGLBuffer]
+		for each attribute. These entities are only deleted if you call [page:BufferGeometry.dispose](). If a geometry becomes obsolete in your application,
+		execute the method to free all related resources.
+	</p>
+
+	<h2>Materials</h2>
+
+	<p>
+		A material defines how objects are rendered. *three.js* uses the information of a material definition in order to construct a shader program for rendering.
+		Shader programs can only be deleted if the respective material is disposed. For performance reasons, *three.js* tries to reuse existing
+		shader programs if possible. So a shader program is only deleted if all related materials are disposed. You can indicate the disposal of a material by
+		executing [page:Material.dispose]().
+	</p>
+
+	<h2>Textures</h2>
+
+	<p>
+		The disposal of a material has no effect on textures. They are handled separately since a single texture can be used by multiple materials at the same time.
+		Whenever you create an instance of [page:Texture], three.js internally creates an instance of [link:https://developer.mozilla.org/en-US/docs/Web/API/WebGLTexture WebGLTexture].
+		Similar to buffers, this object can only be deleted by calling [page:Texture.dispose]().
+	</p>
+
+	<h2>Render Targets</h2>
+
+	<p>
+		Objects of type [page:WebGLRenderTarget] not only allocate an instance of [link:https://developer.mozilla.org/en-US/docs/Web/API/WebGLTexture WebGLTexture] but also
+		[link:https://developer.mozilla.org/en-US/docs/Web/API/WebGLFramebuffer WebGLFramebuffer]s and [link:https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderbuffer WebGLRenderbuffer]s
+		for realizing custom rendering destinations. These objects are only deallocated by executing [page:WebGLRenderTarget.dispose]().
+	</p>
+
+	<h2>Scenes</h2>
+
+	<p>
+		The renderer maintains for scenes special data structures for sorting and rendering. If for some reasons a scene object becomes obsolete in an application,
+		call [page:Scene.dispose]() in order to free these resources.
+	</p>
+
+	<h2>Miscellaneous</h2>
+
+	<p>
+		There are other classes from the examples directory like controls or post processing passes which provide *dispose()* methods in order to remove internal event listeners
+		or render targets. In general, it's recommended to check the API or documentation of a class and watch for *dispose()*. If present, you should use it when cleaning things up.
+	</p>
+
+	<h2>FAQ</h2>
+
+	<h3>Why can't *three.js* dispose objects automatically?</h3>
+
+	<p>
+		This question was asked many times by the community so it's important to clarify this matter. Fact is that *three.js* does not know the lifetime or scope
+		of user-created entities like geometries or materials. This is the responsibility of the application. For example even if a material is currently not used for rendering,
+		it might base necessary for the next frame. So if the application decides that a certain object can be deleted, it has to	notify the engine via calling the respective
+		*dispose()* method.
+	</p>
+
+	<h3>Does removing a mesh from the scene also dispose its geometry and material?</h3>
+
+	<p>
+		No, you have to explicitly dispose the geometry and material via *dispose()*. Keep in mind that geometries and materials can be shared among 3D objects like meshes.
+	</p>
+
+	<h3>Does *three.js* provide information about the amount of cached objects?</h3>
+
+	<p>
+		Yes. It's possible to evaluate [page:WebGLRenderer.info], a special property of the renderer with a series of statistical information about the graphics board memory
+		and the rendering process. Among other things, it tells you have many textures, geometries and shader programs are internally stored. If you notice performance problems
+		in your application, it's a good idea to debug this property in order to easily identify a memory leak.
+	</p>
+
+	<p>
+		Internal resources for a texture are only allocated if the image has fully loaded. If you dispose a texture before the image was loaded,
+		nothing happens. No resources were allocated so there is also no need for clean up.
+	</p>
+
+	<h3>What happens when you call *dispose()* on a texture but the image is not loaded yet?</h3>
+
+	<p>
+		Internal resources for a texture are only allocated if the image has fully loaded. If you dispose a texture before the image was loaded,
+		nothing happens. No resources were allocated so there is also no need for clean up.
+	</p>
+
+	<h3>What happens when I call *dispose()* and then use the respective object at a later point?</h3>
+
+	<p>
+		The deleted internal resources will be created again by the engine. So no runtime error will occur but you might notice a negative performance impact for the current frame,
+		especially when shader programs have to be compiled.
+	</p>
+
+	<h3>How should I manage *three.js* objects in my app? When do I know how to dispose things?</h3>
+
+	<p>
+		In general, there is no definite recommendation for this. It highly depends on the specific use case when calling *dispose()* is appropriate. It's important to highlight that
+		it's not always necessary to dispose objects all the time. A good example for this is a game which consists of multiple levels. A good place for object disposal is when
+		switching the level. The app could traverse through the old scene and dispose all obsolete materials, geometries and textures. As mentioned in the previous section, it does not
+		produce a runtime error if you dispose an object that is actually still in use. The worst thing that can happen is performance drop for a single frame.
+	</p>
+
+	<h2>Examples that demonstrate the usage of dispose()</h2>
+
+	<p>
+		[example:webgl_test_memory WebGL / test / memory]<br />
+		[example:webgl_test_memory2 WebGL / test / memory2]<br />
+	</p>
+
+</body>
+
+</html>

+ 1 - 0
docs/manual/en/introduction/Loading-3D-models.html

@@ -63,6 +63,7 @@
 		<li><a href="https://www.foundry.com/products/modo" target="_blank" rel="noopener">Modo</a> by Foundry</li>
 		<li><a href="https://www.marmoset.co/toolbag/" target="_blank" rel="noopener">Toolbag</a> by Marmoset</li>
 		<li><a href="https://www.sidefx.com/products/houdini/" target="_blank" rel="noopener">Houdini</a> by SideFX</li>
+		<li><a href="https://labs.maxon.net/?p=3360" target="_blank" rel="noopener">Cinema 4D</a> by MAXON</li>
 		<li>&hellip;and <a href="https://github.com/khronosgroup/gltf#gltf-tools" target="_blank" rel="noopener">many more</a></li>
 	</ul>
 

+ 7 - 7
docs/manual/en/introduction/Matrix-transformations.html

@@ -22,25 +22,25 @@
 				Modify the object's *position*, *quaternion*, and *scale* properties, and let three.js recompute
 				the object's matrix from these properties:
 				<code>
-				object.position.copy(start_position);
-				object.quaternion.copy(quaternion);
+object.position.copy( start_position );
+object.quaternion.copy( quaternion );
 				</code>
 				By default, the *matrixAutoUpdate* property is set true, and the matrix will be automatically recalculated.
 				If the object is static, or you wish to manually control when recalculation occurs, better performance can be obtained by setting the property false:
 				<code>
-				object.matrixAutoUpdate = false;
+object.matrixAutoUpdate = false;
 				</code>
 				And after changing any properties, manually update the matrix:
 				<code>
-				object.updateMatrix();
+object.updateMatrix();
 				</code>
 			</li>
 			<li>
 				Modify the object's matrix directly. The [page:Matrix4] class has various methods for modifying the matrix:
 				<code>
-				object.matrix.setRotationFromQuaternion(quaternion);
-				object.matrix.setPosition(start_position);
-				object.matrixAutoUpdate = false;
+object.matrix.setRotationFromQuaternion( quaternion );
+object.matrix.setPosition( start_position );
+object.matrixAutoUpdate = false;
 				</code>
 				Note that *matrixAutoUpdate* <em>must</em> be set to *false* in this case, and you should make sure <em>not</em> to call *updateMatrix*. Calling *updateMatrix* will clobber the manual changes made to the matrix, recalculating the matrix from *position*, *scale*, and so on.
 			</li>

+ 4 - 0
docs/manual/en/introduction/Useful-links.html

@@ -125,6 +125,10 @@
 		<li>
 			[link:http://idflood.github.io/ThreeNodes.js/ ThreeNodes.js].
 		</li>
+		<li>
+			<a href="https://marketplace.visualstudio.com/items?itemName=bierner.comment-tagged-templates" target="_blank">comment-tagged-templates</a> -
+			VSCode extension syntax highlighting for tagged template strings, like: glsl.js.
+		</li>
 	 </ul>
 
 	<h2>WebGL References</h2>

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

@@ -10,7 +10,7 @@
 	<body>
 		<h1>创建一个场景([name])</h1><br />
 
-		<p>这一部分将对three.js来做一个简要的介绍;我们将开始搭建一个场景,其中包含一个正在旋转的立方体。页面下方有一个已经完成的例子,当你遇到麻烦,或者需要帮助的时候,可以看一看。</p>
+		<p>这一部分将对three.js来做一个简要的介绍;我们将开始搭建一个场景,其中包含一个正在旋转的立方体。页面下方有一个已经完成的例子,当你遇到麻烦,或者需要帮助的时候,可以看一看。</p>
 
 		<h2>开始之前</h2>
 		<p>

+ 125 - 0
docs/manual/zh/introduction/How-to-dispose-of-objects.html

@@ -0,0 +1,125 @@
+<!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>
+	<br />
+
+	<p>
+		为了提高性能,并避免应用程序中的内存泄露,一个重要的方面是废置未使用的类库实体。
+		每当你创建一个*three.js*中的实例时,都会分配一定数量的内存。然而,*three.js*会创建在渲染中所必需的特定对象,
+		例如几何体或材质,以及与WebGL相关的实体,例如buffers或着色器程序。
+		非常值得注意的是,这些对象并不会被自动释放;相反,应用程序必须使用特殊的API来释放这些资源。
+		本指南简要概述了这一API是如何使用的,以及哪些对象是和这一环境相关的。
+	</p>
+
+	<h2>几何体</h2>
+
+	<p>
+		几何体常用来表示定义为属性集合的顶点信息,*three.js*在内部为每一个属性创建一个[link:https://developer.mozilla.org/en-US/docs/Web/API/WebGLBuffer WebGLBuffer]类型的对象。
+		这些实体仅有在调用[page:BufferGeometry.dispose]()的时候才会被删除。
+		如果应用程序中的几何体已废弃,请执行该方法以释放所有相关资源。
+	</p>
+
+	<h2>材质</h2>
+
+	<p>
+		材质定义了物体将如何被渲染。*three.js*使用材质所定义的信息来构造一个着色器程序,以用于渲染。
+		着色器程序只有在相应材质被废置后才能被删除。由于性能的原因,*three.js*尽可能尝试复用已存在的着色器程序。
+		因此,着色器程序只有在所有相关材质被废置后才被删除。
+		你可以通过执行[page:Material.dispose]()方法来废置材质。
+	</p>
+
+	<h2>纹理</h2>
+
+	<p>
+		对材质的废置不会对纹理造成影响。它们是分离的,因此一个纹理可以同时被多个材质所使用。
+		每当你创建一个[page:Texture]实例的时候,three.js在内部会创建一个[link:https://developer.mozilla.org/en-US/docs/Web/API/WebGLTexture WebGLTexture]实例。
+		和buffer相似,该对象只能通过调用[page:Texture.dispose]()来删除。
+	</p>
+
+	<h2>渲染目标</h2>
+
+	<p>
+		[page:WebGLRenderTarget]类型的对象不仅分配了[link:https://developer.mozilla.org/en-US/docs/Web/API/WebGLTexture WebGLTexture]的实例,
+		还分配了[link:https://developer.mozilla.org/en-US/docs/Web/API/WebGLFramebuffer WebGLFramebuffer]和[link:https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderbuffer WebGLRenderbuffer]来实现自定义渲染目标。
+		这些对象仅能通过执行[page:WebGLRenderTarget.dispose]()来解除分配。
+	</p>
+
+	<h2>杂项</h2>
+
+	<p>
+		有一些来自examples目录的类,例如控制器或者后期处理过程,提供了*dispose()*方法以用于移除内部事件监听器或渲染目标。
+		通常来讲,非常建议查阅类的API或者文档,并注意*dispose()*函数。如果该函数存在的话,你应当在清理时使用它。
+	</p>
+
+	<h2>常见问题</h2>
+
+	<h3>为何*three.js*不能够自动废置对象?</h3>
+
+	<p>
+		这一问题在社区中多次被问到,因此澄清这件事情是十分有必要的。事实是,*three.js*并不知道用户所创建的实体(例如几何体或者材质)的生命周期或作用范围,这些是应用程序的责任。
+		比如说,即使一个材质当前没有被用于渲染,但它也可能是下一帧所必需的。
+		因此,如果应用程序决定某个对象可以被删除,则它必须通过调用对应的*dispose()*方法来通知引擎。
+	</p>
+
+	<h3>将一个mesh(网格)从场景中移除,是否也会废置它的geometry(几何体)和material(材质)?</h3>
+
+	<p>
+		并不会,你必须通过*dispose()*来明确地废置geometry(几何体)或material(材质)。
+		请记住,geometry(几何体)或material(材质)可以在3D物体之间(例如mesh(网格))被共享。
+	</p>
+
+	<h3>*three.js*是否会提供被缓存对象数量的相关信息?</h3>
+
+	<p>
+		是的,可以评估[page:WebGLRenderer.info] —— 渲染器中的一个特殊属性,具有一系列关于显存和渲染过程的统计信息。
+		除此之外,它还告诉你有多少纹理、几何体和着色器程序在内部存储。
+		如果你在你的应用程序中注意到了性能问题,一个较好的方法便是调试该属性,以便轻松识别内存泄漏。
+	</p>
+
+	<p>
+		对于纹理的内部资源仅在图像完全被加载后才会分配。如果你在图像被加载之前废置纹理,什么都不会发生。
+		没有资源被分配,因此也没有必要进行清理。
+	</p>
+
+	<h3>当你在纹理还没有被加载时,在纹理上调用*dispose()*,会发生什么?</h3>
+
+	<p>
+		对于纹理的内部资源仅在图像完全被加载后才会分配。如果你在图像被加载之前废置纹理,什么都不会发生。
+		没有资源被分配,因此也没有必要进行清理。
+	</p>
+
+	<h3>当我在调用*dispose()*之后,使用相应的对象会发生什么?</h3>
+
+	<p>
+		被删除掉的内部资源会被引擎重新创建,因此不会有运行时错误发生,但你可能会注意到这会对当前帧的性能有一些影响,特别是当着色器程序被编译的时候。
+	</p>
+
+	<h3>我如何在我的应用程序中管理*three.js*中的对象?我如何知道什么时候该废置事物?</h3>
+
+	<p>
+		一般来说,对此并没有明确的建议。调用*dispose()*什么时候合适,很大程度上取决于具体的用例。
+		必须指出的是,没有必要总是废置对象。一个较好的例子便是一个由多个关卡所组成的游戏。使用到对象废置的地方就是当切换关卡的时候。
+		应用程序可以通过较老的场景,并废置所有过时的材质、几何体和纹理贴图。
+		正如在前面的章节中所提到,如果你废置一个仍然在使用的对象,并不会导致运行时错误。可能发生的最糟糕的事情便是单帧的性能会下降。
+	</p>
+
+	<h2>演示dispose()使用方法的示例</h2>
+
+	<p>
+		[example:webgl_test_memory WebGL / test / memory]<br />
+		[example:webgl_test_memory2 WebGL / test / memory2]<br />
+	</p>
+
+</body>
+
+</html>

+ 7 - 7
docs/manual/zh/introduction/Matrix-transformations.html

@@ -22,25 +22,25 @@
 			<li>
 				修改对象的*position*,*quaternion*和*scale*属性,让three.js重新计算来自这些属性的对象矩阵:
 				<code>
-				object.position.copy(start_position);
-				object.quaternion.copy(quaternion);
+object.position.copy( start_position );
+object.quaternion.copy( quaternion );
 				</code>
 				默认情况下,*matrixAutoUpdate*属性设置为true,并且将自动重新计算矩阵。
 如果对象是静态的,或者您希望在重新计算时手动控制,则可以通过将属性设置为false来获得更好的性能:
 				<code>
-				object.matrixAutoUpdate = false;
+object.matrixAutoUpdate = false;
 				</code>
 				更改任何属性后,手动更新矩阵:
 				<code>
-				object.updateMatrix();
+object.updateMatrix();
 				</code>
 			</li>
 			<li>
 				直接修改对象的矩阵。 [page:Matrix4]类有各种修改矩阵的方法:
 				<code>
-				object.matrix.setRotationFromQuaternion(quaternion);
-				object.matrix.setPosition(start_position);
-				object.matrixAutoUpdate = false;
+object.matrix.setRotationFromQuaternion( quaternion );
+object.matrix.setPosition( start_position );
+object.matrixAutoUpdate = false;
 				</code>
 				请注意,在这种情况下,*matrixAutoUpdate* <em> 必须 </em>设置为*false*,并且您应该确保<em> 不 </em>调用*updateMatrix*。
 				调用*updateMatrix*将破坏对矩阵所做的手动更改,从*position*,*scale*重新计算矩阵,依此类推。

+ 118 - 49
docs/scenes/js/material.js

@@ -87,6 +87,9 @@ function getObjectsKeys( obj ) {
 
 }
 
+var textureLoader = new THREE.TextureLoader();
+var cubeTextureLoader = new THREE.CubeTextureLoader();
+
 var envMaps = ( function () {
 
 	var path = '../../examples/textures/cube/SwedishRoyalCastle/';
@@ -97,10 +100,10 @@ var envMaps = ( function () {
 		path + 'pz' + format, path + 'nz' + format
 	];
 
-	var reflectionCube = new THREE.CubeTextureLoader().load( urls );
+	var reflectionCube = cubeTextureLoader.load( urls );
 	reflectionCube.format = THREE.RGBFormat;
 
-	var refractionCube = new THREE.CubeTextureLoader().load( urls );
+	var refractionCube = cubeTextureLoader.load( urls );
 	refractionCube.mapping = THREE.CubeRefractionMapping;
 	refractionCube.format = THREE.RGBFormat;
 
@@ -112,18 +115,62 @@ var envMaps = ( function () {
 
 } )();
 
-var envMapKeys = getObjectsKeys( envMaps );
+var diffuseMaps = ( function () {
+
+	var bricks = textureLoader.load( '../../examples/textures/brick_diffuse.jpg' );
+	bricks.wrapS = THREE.RepeatWrapping;
+	bricks.wrapT = THREE.RepeatWrapping;
+	bricks.repeat.set( 9, 1 );
+
+	return {
+		none: null,
+		bricks: bricks
+	};
+
+} )();
+
+var roughnessMaps = ( function () {
+
+	var bricks = textureLoader.load( '../../examples/textures/brick_roughness.jpg' );
+	bricks.wrapT = THREE.RepeatWrapping;
+	bricks.wrapS = THREE.RepeatWrapping;
+	bricks.repeat.set( 9, 1 );
+
+	return {
+		none: null,
+		bricks: bricks
+	};
 
-var textureMaps = ( function () {
+} )();
+
+var matcaps = ( function () {
 
 	return {
 		none: null,
-		grass: new THREE.TextureLoader().load( '../../examples/textures/terrain/grasslight-thin.jpg' )
+		porcelainWhite: textureLoader.load( '../../examples/textures/matcaps/matcap-porcelain-white.jpg' )
 	};
 
 } )();
 
-var textureMapKeys = getObjectsKeys( textureMaps );
+var alphaMaps = ( function () {
+
+	var fibers = textureLoader.load( '../../examples/textures/alphaMap.jpg' );
+	fibers.wrapT = THREE.RepeatWrapping;
+	fibers.wrapS = THREE.RepeatWrapping;
+	fibers.repeat.set( 9, 1 );
+
+	return {
+		none: null,
+		fibers: fibers
+	};
+
+} )();
+
+var envMapKeys = getObjectsKeys( envMaps );
+var diffuseMapKeys = getObjectsKeys( diffuseMaps );
+var roughnessMapKeys = getObjectsKeys( roughnessMaps );
+var matcapKeys = getObjectsKeys( matcaps );
+var alphaMapKeys = getObjectsKeys( alphaMaps );
 
 function generateVertexColors( geometry ) {
 
@@ -247,7 +294,7 @@ function guiMaterial( gui, mesh, material, geometry ) {
 	var folder = gui.addFolder( 'THREE.Material' );
 
 	folder.add( material, 'transparent' );
-	folder.add( material, 'opacity', 0, 1 );
+	folder.add( material, 'opacity', 0, 1 ).step( 0.01 );
 	// folder.add( material, 'blending', constants.blendingMode );
 	// folder.add( material, 'blendSrc', constants.destinationFactors );
 	// folder.add( material, 'blendDst', constants.destinationFactors );
@@ -257,7 +304,7 @@ function guiMaterial( gui, mesh, material, geometry ) {
 	// folder.add( material, 'polygonOffset' );
 	// folder.add( material, 'polygonOffsetFactor' );
 	// folder.add( material, 'polygonOffsetUnits' );
-	folder.add( material, 'alphaTest', 0, 1 );
+	folder.add( material, 'alphaTest', 0, 1 ).step( 0.01 ).onChange( needsUpdate( material, geometry ) );
 	folder.add( material, 'visible' );
 	folder.add( material, 'side', constants.side ).onChange( needsUpdate( material, geometry ) );
 
@@ -267,10 +314,9 @@ function guiMeshBasicMaterial( gui, mesh, material, geometry ) {
 
 	var data = {
 		color: material.color.getHex(),
-		envMaps: envMapKeys,
-		map: textureMapKeys,
-		specularMap: textureMapKeys,
-		alphaMap: textureMapKeys
+		envMaps: envMapKeys[ 0 ],
+		map: diffuseMapKeys[ 0 ],
+		alphaMap: alphaMapKeys[ 0 ]
 	};
 
 	var folder = gui.addFolder( 'THREE.MeshBasicMaterial' );
@@ -282,9 +328,8 @@ function guiMeshBasicMaterial( gui, mesh, material, geometry ) {
 	folder.add( material, 'fog' );
 
 	folder.add( data, 'envMaps', envMapKeys ).onChange( updateTexture( material, 'envMap', envMaps ) );
-	folder.add( data, 'map', textureMapKeys ).onChange( updateTexture( material, 'map', textureMaps ) );
-	folder.add( data, 'specularMap', textureMapKeys ).onChange( updateTexture( material, 'specularMap', textureMaps ) );
-	folder.add( data, 'alphaMap', textureMapKeys ).onChange( updateTexture( material, 'alphaMap', textureMaps ) );
+	folder.add( data, 'map', diffuseMapKeys ).onChange( updateTexture( material, 'map', diffuseMaps ) );
+	folder.add( data, 'alphaMap', alphaMapKeys ).onChange( updateTexture( material, 'alphaMap', alphaMaps ) );
 	folder.add( material, 'combine', constants.combine );
 	folder.add( material, 'reflectivity', 0, 1 );
 	folder.add( material, 'refractionRatio', 0, 1 );
@@ -293,11 +338,17 @@ function guiMeshBasicMaterial( gui, mesh, material, geometry ) {
 
 function guiMeshDepthMaterial( gui, mesh, material, geometry ) {
 
+	var data = {
+		alphaMap: alphaMapKeys[ 0 ]
+	};
+
 	var folder = gui.addFolder( 'THREE.MeshDepthMaterial' );
 
 	folder.add( material, 'wireframe' );
 	folder.add( material, 'wireframeLinewidth', 0, 10 );
 
+	folder.add( data, 'alphaMap', alphaMapKeys ).onChange( updateTexture( material, 'alphaMap', alphaMaps ) );
+
 }
 
 function guiMeshNormalMaterial( gui, mesh, material, geometry ) {
@@ -332,10 +383,9 @@ function guiMeshLambertMaterial( gui, mesh, material, geometry ) {
 	var data = {
 		color: material.color.getHex(),
 		emissive: material.emissive.getHex(),
-		envMaps: envMapKeys,
-		map: textureMapKeys,
-		specularMap: textureMapKeys,
-		alphaMap: textureMapKeys
+		envMaps: envMapKeys[ 0 ],
+		map: diffuseMapKeys[ 0 ],
+		alphaMap: alphaMapKeys[ 0 ]
 	};
 
 	var folder = gui.addFolder( 'THREE.MeshLambertMaterial' );
@@ -349,26 +399,39 @@ function guiMeshLambertMaterial( gui, mesh, material, geometry ) {
 	folder.add( material, 'fog' );
 
 	folder.add( data, 'envMaps', envMapKeys ).onChange( updateTexture( material, 'envMap', envMaps ) );
-	folder.add( data, 'map', textureMapKeys ).onChange( updateTexture( material, 'map', textureMaps ) );
-	folder.add( data, 'specularMap', textureMapKeys ).onChange( updateTexture( material, 'specularMap', textureMaps ) );
-	folder.add( data, 'alphaMap', textureMapKeys ).onChange( updateTexture( material, 'alphaMap', textureMaps ) );
+	folder.add( data, 'map', diffuseMapKeys ).onChange( updateTexture( material, 'map', diffuseMaps ) );
+	folder.add( data, 'alphaMap', alphaMapKeys ).onChange( updateTexture( material, 'alphaMap', alphaMaps ) );
 	folder.add( material, 'combine', constants.combine );
 	folder.add( material, 'reflectivity', 0, 1 );
 	folder.add( material, 'refractionRatio', 0, 1 );
 
 }
 
+function guiMeshMatcapMaterial( gui, mesh, material ) {
+
+	var data = {
+		color: material.color.getHex(),
+		matcap: matcapKeys[ 1 ],
+		alphaMap: alphaMapKeys[ 0 ]
+	};
+
+	var folder = gui.addFolder( 'THREE.MeshMatcapMaterial' );
+
+	folder.addColor( data, 'color' ).onChange( handleColorChange( material.color ) );
+	folder.add( data, 'matcap', matcapKeys ).onChange( updateTexture( material, 'matcap', matcaps ) );
+	folder.add( data, 'alphaMap', alphaMapKeys ).onChange( updateTexture( material, 'alphaMap', alphaMaps ) );
+
+}
+
 function guiMeshPhongMaterial( gui, mesh, material, geometry ) {
 
 	var data = {
 		color: material.color.getHex(),
 		emissive: material.emissive.getHex(),
 		specular: material.specular.getHex(),
-		envMaps: envMapKeys,
-		map: textureMapKeys,
-		lightMap: textureMapKeys,
-		specularMap: textureMapKeys,
-		alphaMap: textureMapKeys
+		envMaps: envMapKeys[ 0 ],
+		map: diffuseMapKeys[ 0 ],
+		alphaMap: alphaMapKeys[ 0 ]
 	};
 
 	var folder = gui.addFolder( 'THREE.MeshPhongMaterial' );
@@ -384,10 +447,8 @@ function guiMeshPhongMaterial( gui, mesh, material, geometry ) {
 	folder.add( material, 'vertexColors', constants.colors ).onChange( needsUpdate( material, geometry ) );
 	folder.add( material, 'fog' );
 	folder.add( data, 'envMaps', envMapKeys ).onChange( updateTexture( material, 'envMap', envMaps ) );
-	folder.add( data, 'map', textureMapKeys ).onChange( updateTexture( material, 'map', textureMaps ) );
-	folder.add( data, 'lightMap', textureMapKeys ).onChange( updateTexture( material, 'lightMap', textureMaps ) );
-	folder.add( data, 'specularMap', textureMapKeys ).onChange( updateTexture( material, 'specularMap', textureMaps ) );
-	folder.add( data, 'alphaMap', textureMapKeys ).onChange( updateTexture( material, 'alphaMap', textureMaps ) );
+	folder.add( data, 'map', diffuseMapKeys ).onChange( updateTexture( material, 'map', diffuseMaps ) );
+	folder.add( data, 'alphaMap', alphaMapKeys ).onChange( updateTexture( material, 'alphaMap', alphaMaps ) );
 
 }
 
@@ -396,11 +457,10 @@ function guiMeshStandardMaterial( gui, mesh, material, geometry ) {
 	var data = {
 		color: material.color.getHex(),
 		emissive: material.emissive.getHex(),
-		envMaps: envMapKeys,
-		map: textureMapKeys,
-		lightMap: textureMapKeys,
-		specularMap: textureMapKeys,
-		alphaMap: textureMapKeys
+		envMaps: envMapKeys[ 0 ],
+		map: diffuseMapKeys[ 0 ],
+		roughnessMap: roughnessMapKeys[ 0 ],
+		alphaMap: alphaMapKeys[ 0 ]
 	};
 
 	var folder = gui.addFolder( 'THREE.MeshStandardMaterial' );
@@ -416,11 +476,11 @@ function guiMeshStandardMaterial( gui, mesh, material, geometry ) {
 	folder.add( material, 'vertexColors', constants.colors ).onChange( needsUpdate( material, geometry ) );
 	folder.add( material, 'fog' );
 	folder.add( data, 'envMaps', envMapKeys ).onChange( updateTexture( material, 'envMap', envMaps ) );
-	folder.add( data, 'map', textureMapKeys ).onChange( updateTexture( material, 'map', textureMaps ) );
-	folder.add( data, 'lightMap', textureMapKeys ).onChange( updateTexture( material, 'lightMap', textureMaps ) );
-	folder.add( data, 'alphaMap', textureMapKeys ).onChange( updateTexture( material, 'alphaMap', textureMaps ) );
+	folder.add( data, 'map', diffuseMapKeys ).onChange( updateTexture( material, 'map', diffuseMaps ) );
+	folder.add( data, 'roughnessMap', roughnessMapKeys ).onChange( updateTexture( material, 'roughnessMap', roughnessMaps ) );
+	folder.add( data, 'alphaMap', alphaMapKeys ).onChange( updateTexture( material, 'alphaMap', alphaMaps ) );
 
-	// TODO roughnessMap and metalnessMap
+	// TODO metalnessMap
 
 }
 
@@ -429,11 +489,10 @@ function guiMeshPhysicalMaterial( gui, mesh, material, geometry ) {
 	var data = {
 		color: material.color.getHex(),
 		emissive: material.emissive.getHex(),
-		envMaps: envMapKeys,
-		map: textureMapKeys,
-		lightMap: textureMapKeys,
-		specularMap: textureMapKeys,
-		alphaMap: textureMapKeys
+		envMaps: envMapKeys[ 0 ],
+		map: diffuseMapKeys[ 0 ],
+		roughnessMap: roughnessMapKeys[ 0 ],
+		alphaMap: alphaMapKeys[ 0 ]
 	};
 
 	var folder = gui.addFolder( 'THREE.MeshPhysicalMaterial' );
@@ -452,11 +511,11 @@ function guiMeshPhysicalMaterial( gui, mesh, material, geometry ) {
 	folder.add( material, 'vertexColors', constants.colors ).onChange( needsUpdate( material, geometry ) );
 	folder.add( material, 'fog' );
 	folder.add( data, 'envMaps', envMapKeys ).onChange( updateTexture( material, 'envMap', envMaps ) );
-	folder.add( data, 'map', textureMapKeys ).onChange( updateTexture( material, 'map', textureMaps ) );
-	folder.add( data, 'lightMap', textureMapKeys ).onChange( updateTexture( material, 'lightMap', textureMaps ) );
-	folder.add( data, 'alphaMap', textureMapKeys ).onChange( updateTexture( material, 'alphaMap', textureMaps ) );
+	folder.add( data, 'map', diffuseMapKeys ).onChange( updateTexture( material, 'map', diffuseMaps ) );
+	folder.add( data, 'roughnessMap', roughnessMapKeys ).onChange( updateTexture( material, 'roughnessMap', roughnessMaps ) );
+	folder.add( data, 'alphaMap', alphaMapKeys ).onChange( updateTexture( material, 'alphaMap', alphaMaps ) );
 
-	// TODO roughnessMap and metalnessMap
+	// TODO metalnessMap
 
 }
 
@@ -487,6 +546,16 @@ function chooseFromHash( gui, mesh, geometry ) {
 
 			break;
 
+		case 'MeshMatcapMaterial' :
+
+			material = new THREE.MeshMatcapMaterial( { matcap: matcaps.porcelainWhite } );
+			guiMaterial( gui, mesh, material, geometry );
+			guiMeshMatcapMaterial( gui, mesh, material, geometry );
+
+			return material;
+
+			break;
+
 		case 'MeshPhongMaterial' :
 
 			material = new THREE.MeshPhongMaterial( { color: 0x2194CE } );

+ 48 - 0
editor/css/dark.css

@@ -250,3 +250,51 @@ select {
 	.Outliner .option.active {
 		background-color: rgba(21,60,94,1);
 	}
+
+/* */
+
+@media all and ( max-width: 600px ) {
+
+	#menubar .menu .options {
+		max-height: calc(100% - 372px);
+	}
+
+	#menubar .menu.right {
+		display: none;
+	}
+
+	#viewport {
+		left: 0;
+		right: 0;
+		top: 32px;
+		height: calc(100% - 352px);
+	}
+
+	#script {
+		left: 0;
+		right: 0;
+		top: 32px;
+		height: calc(100% - 352px);
+	}
+
+	#player {
+		left: 0;
+		right: 0;
+		top: 32px;
+		height: calc(100% - 352px);
+	}
+
+	#sidebar {
+		left: 0;
+		width: 100%;
+		top: calc(100% - 320px);
+		bottom: 0;
+	}
+
+	#toolbar {
+		left: calc(50% - 140px);
+		width: 280px;
+		top: 68px;
+	}
+
+}

+ 48 - 0
editor/css/light.css

@@ -243,3 +243,51 @@ select {
 	.Outliner .option.active {
 		background-color: rgba(0,0,0,0.04);
 	}
+
+/* */
+
+@media all and ( max-width: 600px ) {
+
+	#menubar .menu .options {
+		max-height: calc(100% - 372px);
+	}
+
+	#menubar .menu.right {
+		display: none;
+	}
+
+	#viewport {
+		left: 0;
+		right: 0;
+		top: 32px;
+		height: calc(100% - 352px);
+	}
+
+	#script {
+		left: 0;
+		right: 0;
+		top: 32px;
+		height: calc(100% - 352px);
+	}
+
+	#player {
+		left: 0;
+		right: 0;
+		top: 32px;
+		height: calc(100% - 352px);
+	}
+
+	#sidebar {
+		left: 0;
+		width: 100%;
+		top: calc(100% - 320px);
+		bottom: 0;
+	}
+
+	#toolbar {
+		left: calc(50% - 140px);
+		width: 280px;
+		top: 68px;
+	}
+
+}

+ 0 - 2
editor/examples/arkanoid.app.json

@@ -3,8 +3,6 @@
 		"type": "App"
 	},
 	"project": {
-		"gammaInput": true,
-		"gammaOutput": true,
 		"shadows": true,
 		"vr": false
 	},

+ 0 - 2
editor/examples/camera.app.json

@@ -3,8 +3,6 @@
 		"type": "App"
 	},
 	"project": {
-		"gammaInput": true,
-		"gammaOutput": true,
 		"shadows": true,
 		"vr": false
 	},

+ 0 - 2
editor/examples/particles.app.json

@@ -3,8 +3,6 @@
 		"type": "App"
 	},
 	"project": {
-		"gammaInput": true,
-		"gammaOutput": true,
 		"shadows": true,
 		"vr": false
 	},

+ 0 - 2
editor/examples/pong.app.json

@@ -3,8 +3,6 @@
 		"type": "App"
 	},
 	"project": {
-		"gammaInput": true,
-		"gammaOutput": true,
 		"shadows": true,
 		"vr": false
 	},

+ 0 - 2
editor/examples/shaders.app.json

@@ -3,8 +3,6 @@
 		"type": "App"
 	},
 	"project": {
-		"gammaInput": true,
-		"gammaOutput": true,
 		"shadows": true,
 		"vr": false
 	},

BIN
editor/images/icon.png


BIN
editor/images/icon.xcf


+ 25 - 20
editor/index.html

@@ -4,14 +4,12 @@
 		<title>three.js / editor</title>
 		<meta charset="utf-8">
 		<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
-		<!-- Origin Trial Token, feature = WebXR Device API (For Chrome M69+), origin = https://threejs.org, expires = 2019-01-23 -->
-		<meta http-equiv="origin-trial" data-feature="WebXR Device API (For Chrome M69+)" data-expires="2019-01-23" content="ApibcCZfaeEIkwpe6CSIKZXC8ODly5nYX+QlUSgwhUUlMN1/Ko7dr5XUwZDFl9SiEGtOFFe2csLwnNg33ZBh+QMAAABTeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJYUkRldmljZU02OSIsImV4cGlyeSI6MTU0ODIwMTU5OX0=">
-		<!-- Origin Trial Token, feature = WebXR Gamepad Support, origin = https://threejs.org, expires = 2019-01-23 -->
-		<meta http-equiv="origin-trial" data-feature="WebXR Gamepad Support" data-expires="2019-01-23" content="Agt5pp1xG96NMH+7RdcD7jvbkJiJTagqfKtC+28x/TBeQSh4tF7ad7uXL9Clqbts0vivamPTTkRkNdyfJtEezQ4AAABYeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJYUkdhbWVwYWRTdXBwb3J0IiwiZXhwaXJ5IjoxNTQ4MjAxNTk5fQ==">
+		<link rel="apple-touch-icon" href="images/icon.png">
+		<link rel="manifest" href="manifest.json">
 	</head>
 	<body ontouchstart="">
-		<link href="css/main.css" rel="stylesheet" />
-		<link id="theme" href="css/light.css" rel="stylesheet" />
+		<link rel="stylesheet" href="css/main.css">
+		<link rel="stylesheet" id="theme" href="css/light.css">
 
 		<script src="../build/three.js"></script>
 		<script src="../examples/js/libs/system.min.js"></script>
@@ -88,6 +86,9 @@
 		<script src="js/libs/ui.js"></script>
 		<script src="js/libs/ui.three.js"></script>
 
+		<script src="js/libs/html2canvas.js"></script>
+		<script src="js/libs/three.html.js"></script>
+
 		<script src="js/libs/app.js"></script>
 		<script src="js/Player.js"></script>
 		<script src="js/Script.js"></script>
@@ -129,6 +130,7 @@
 		<script src="js/Sidebar.Geometry.SphereGeometry.js"></script>
 		<script src="js/Sidebar.Geometry.TorusGeometry.js"></script>
 		<script src="js/Sidebar.Geometry.TorusKnotGeometry.js"></script>
+		<script src="js/Sidebar.Geometry.TubeGeometry.js"></script>
 		<script src="../examples/js/geometries/TeapotBufferGeometry.js"></script>
 		<script src="js/Sidebar.Geometry.TeapotBufferGeometry.js"></script>
 		<script src="js/Sidebar.Geometry.LatheGeometry.js"></script>
@@ -139,6 +141,7 @@
 		<script src="js/Strings.js"></script>
 		<script src="js/Toolbar.js"></script>
 		<script src="js/Viewport.js"></script>
+		<script src="js/Viewport.Camera.js"></script>
 		<script src="js/Viewport.Info.js"></script>
 
 		<script src="js/Command.js"></script>
@@ -163,9 +166,6 @@
 		<script src="js/commands/SetMaterialMapCommand.js"></script>
 		<script src="js/commands/SetSceneCommand.js"></script>
 
-		<script src="js/libs/html2canvas.js"></script>
-		<script src="js/libs/three.html.js"></script>
-
 		<script>
 
 			window.URL = window.URL || window.webkitURL;
@@ -191,14 +191,11 @@
 			var player = new Player( editor );
 			document.body.appendChild( player.dom );
 
-			var menubar = new Menubar( editor );
-			document.body.appendChild( menubar.dom );
-
 			var sidebar = new Sidebar( editor );
 			document.body.appendChild( sidebar.dom );
 
-			var modal = new UI.Modal();
-			document.body.appendChild( modal.dom );
+			var menubar = new Menubar( editor );
+			document.body.appendChild( menubar.dom );
 
 			//
 
@@ -269,12 +266,6 @@
 				signals.scriptChanged.add( saveState );
 				signals.historyChanged.add( saveState );
 
-				signals.showModal.add( function ( content ) {
-
-					modal.show( content );
-
-				} );
-
 			} );
 
 			//
@@ -330,6 +321,20 @@
 
 			}
 
+			// ServiceWorker
+
+			if ( 'serviceWorker' in navigator ) {
+
+				try {
+
+					navigator.serviceWorker.register( 'sw.js' );
+
+				} catch ( error ) {
+
+				}
+
+			}
+
 			/*
 			window.addEventListener( 'message', function ( event ) {
 

+ 0 - 2
editor/js/Config.js

@@ -17,8 +17,6 @@ var Config = function () {
 
 		'project/renderer': 'WebGLRenderer',
 		'project/renderer/antialias': true,
-		'project/renderer/gammaInput': false,
-		'project/renderer/gammaOutput': false,
 		'project/renderer/shadows': true,
 
 		'project/vr': false,

+ 76 - 15
editor/js/Editor.js

@@ -22,10 +22,6 @@ var Editor = function () {
 		startPlayer: new Signal(),
 		stopPlayer: new Signal(),
 
-		// actions
-
-		showModal: new Signal(),
-
 		// notifications
 
 		editorCleared: new Signal(),
@@ -55,6 +51,9 @@ var Editor = function () {
 		objectChanged: new Signal(),
 		objectRemoved: new Signal(),
 
+		cameraAdded: new Signal(),
+		cameraRemoved: new Signal(),
+
 		helperAdded: new Signal(),
 		helperRemoved: new Signal(),
 
@@ -68,7 +67,9 @@ var Editor = function () {
 
 		showGridChanged: new Signal(),
 		refreshSidebarObject3D: new Signal(),
-		historyChanged: new Signal()
+		historyChanged: new Signal(),
+
+		viewportCameraChanged: new Signal()
 
 	};
 
@@ -93,9 +94,17 @@ var Editor = function () {
 	this.textures = {};
 	this.scripts = {};
 
+	this.animations = {};
+	this.mixer = new THREE.AnimationMixer( this.scene );
+
 	this.selected = null;
 	this.helpers = {};
 
+	this.cameras = {};
+	this.viewportCamera = this.camera;
+
+	this.addCamera( this.camera );
+
 };
 
 Editor.prototype = {
@@ -146,6 +155,7 @@ Editor.prototype = {
 			if ( child.geometry !== undefined ) scope.addGeometry( child.geometry );
 			if ( child.material !== undefined ) scope.addMaterial( child.material );
 
+			scope.addCamera( child );
 			scope.addHelper( child );
 
 		} );
@@ -196,6 +206,7 @@ Editor.prototype = {
 
 		object.traverse( function ( child ) {
 
+			scope.removeCamera( child );
 			scope.removeHelper( child );
 
 		} );
@@ -239,6 +250,42 @@ Editor.prototype = {
 
 	},
 
+	addAnimation: function ( object, animations ) {
+
+		if ( animations.length > 0 ) {
+
+			this.animations[ object.uuid ] = animations;
+
+		}
+
+	},
+
+	//
+
+	addCamera: function ( camera ) {
+
+		if ( camera.isCamera ) {
+
+			this.cameras[ camera.uuid ] = camera;
+
+			this.signals.cameraAdded.dispatch( camera );
+
+		}
+
+	},
+
+	removeCamera: function ( camera ) {
+
+		if ( this.cameras[ camera.uuid ] !== undefined ) {
+
+			delete this.cameras[ camera.uuid ];
+
+			this.signals.cameraRemoved.dispatch( camera );
+
+		}
+
+	},
+
 	//
 
 	addHelper: function () {
@@ -250,29 +297,29 @@ Editor.prototype = {
 
 			var helper;
 
-			if ( object instanceof THREE.Camera ) {
+			if ( object.isCamera ) {
 
 				helper = new THREE.CameraHelper( object, 1 );
 
-			} else if ( object instanceof THREE.PointLight ) {
+			} else if ( object.isPointLight ) {
 
 				helper = new THREE.PointLightHelper( object, 1 );
 
-			} else if ( object instanceof THREE.DirectionalLight ) {
+			} else if ( object.isDirectionalLight ) {
 
 				helper = new THREE.DirectionalLightHelper( object, 1 );
 
-			} else if ( object instanceof THREE.SpotLight ) {
+			} else if ( object.isSpotLight ) {
 
 				helper = new THREE.SpotLightHelper( object, 1 );
 
-			} else if ( object instanceof THREE.HemisphereLight ) {
+			} else if ( object.isHemisphereLight ) {
 
 				helper = new THREE.HemisphereLightHelper( object, 1 );
 
-			} else if ( object instanceof THREE.SkinnedMesh ) {
+			} else if ( object.isSkinnedMesh ) {
 
-				helper = new THREE.SkeletonHelper( object );
+				helper = new THREE.SkeletonHelper( object.skeleton.bones[ 0 ] );
 
 			} else {
 
@@ -370,6 +417,13 @@ Editor.prototype = {
 
 	},
 
+	setViewportCamera: function ( uuid ) {
+
+		this.viewportCamera = this.cameras[ uuid ];
+		this.signals.viewportCameraChanged.dispatch( this.viewportCamera );
+
+	},
+
 	//
 
 	select: function ( object ) {
@@ -428,7 +482,11 @@ Editor.prototype = {
 
 	focus: function ( object ) {
 
-		this.signals.objectFocused.dispatch( object );
+		if ( object !== undefined ) {
+
+			this.signals.objectFocused.dispatch( object );
+
+		}
 
 	},
 
@@ -444,6 +502,8 @@ Editor.prototype = {
 		this.storage.clear();
 
 		this.camera.copy( this.DEFAULT_CAMERA );
+		this.scene.name = "Scene";
+		this.scene.userData = {};
 		this.scene.background.setHex( 0xaaaaaa );
 		this.scene.fog = null;
 
@@ -460,6 +520,9 @@ Editor.prototype = {
 		this.textures = {};
 		this.scripts = {};
 
+		this.animations = {};
+		this.mixer.stopAllAction();
+
 		this.deselect();
 
 		this.signals.editorCleared.dispatch();
@@ -519,8 +582,6 @@ Editor.prototype = {
 
 			metadata: {},
 			project: {
-				gammaInput: this.config.getKey( 'project/renderer/gammaInput' ),
-				gammaOutput: this.config.getKey( 'project/renderer/gammaOutput' ),
 				shadows: this.config.getKey( 'project/renderer/shadows' ),
 				vr: this.config.getKey( 'project/vr' )
 			},

+ 26 - 11
editor/js/Loader.js

@@ -34,7 +34,7 @@ var Loader = function ( editor ) {
 
 			for ( var i = 0; i < files.length; i ++ ) {
 
-				scope.loadFile( files[ i ], manager ) ;
+				scope.loadFile( files[ i ], manager );
 
 			}
 
@@ -150,7 +150,7 @@ var Loader = function ( editor ) {
 					stream.offset = 0;
 
 					var loader = new THREE.CTMLoader();
-					loader.createModel( new CTM.File( stream ), function( geometry ) {
+					loader.createModel( new CTM.File( stream ), function ( geometry ) {
 
 						geometry.sourceType = "ctm";
 						geometry.sourceFile = file.name;
@@ -180,6 +180,7 @@ var Loader = function ( editor ) {
 
 					collada.scene.name = filename;
 
+					editor.addAnimation( collada.scene, collada.animations );
 					editor.execute( new AddObjectCommand( collada.scene ) );
 
 				}, false );
@@ -196,6 +197,7 @@ var Loader = function ( editor ) {
 					var loader = new THREE.FBXLoader( manager );
 					var object = loader.parse( contents );
 
+					editor.addAnimation( object, object.animations );
 					editor.execute( new AddObjectCommand( object ) );
 
 				}, false );
@@ -215,8 +217,11 @@ var Loader = function ( editor ) {
 					loader.setDRACOLoader( new THREE.DRACOLoader() );
 					loader.parse( contents, '', function ( result ) {
 
-						result.scene.name = filename;
-						editor.execute( new AddObjectCommand( result.scene ) );
+						var scene = result.scene;
+						scene.name = filename;
+
+						editor.addAnimation( scene, result.animations );
+						editor.execute( new AddObjectCommand( scene ) );
 
 					} );
 
@@ -245,8 +250,11 @@ var Loader = function ( editor ) {
 
 					loader.parse( contents, '', function ( result ) {
 
-						result.scene.name = filename;
-						editor.execute( new AddObjectCommand( result.scene ) );
+						var scene = result.scene;
+						scene.name = filename;
+
+						editor.addAnimation( scene, result.animations );
+						editor.execute( new AddObjectCommand( scene ) );
 
 					} );
 
@@ -344,6 +352,7 @@ var Loader = function ( editor ) {
 					mesh.mixer = new THREE.AnimationMixer( mesh );
 					mesh.name = filename;
 
+					editor.addAnimation( mesh, geometry.animations );
 					editor.execute( new AddObjectCommand( mesh ) );
 
 				}, false );
@@ -444,13 +453,13 @@ var Loader = function ( editor ) {
 					var contents = event.target.result;
 
 					var loader = new THREE.SVGLoader();
-					var paths = loader.parse( contents );
+					var paths = loader.parse( contents ).paths;
 
 					//
 
 					var group = new THREE.Group();
 					group.scale.multiplyScalar( 0.1 );
-					group.scale.y *= -1;
+					group.scale.y *= - 1;
 
 					for ( var i = 0; i < paths.length; i ++ ) {
 
@@ -587,7 +596,7 @@ var Loader = function ( editor ) {
 
 				var result = loader.parse( data );
 
-				if ( result instanceof THREE.Scene ) {
+				if ( result.isScene ) {
 
 					editor.execute( new SetSceneCommand( result ) );
 
@@ -678,7 +687,10 @@ var Loader = function ( editor ) {
 					var loader = new THREE.GLTFLoader();
 					loader.parse( file.asArrayBuffer(), '', function ( result ) {
 
-						editor.execute( new AddObjectCommand( result.scene ) );
+						var scene = result.scene;
+
+						editor.addAnimation( scene, result.animations );
+						editor.execute( new AddObjectCommand( scene ) );
 
 					} );
 
@@ -689,7 +701,10 @@ var Loader = function ( editor ) {
 					var loader = new THREE.GLTFLoader( manager );
 					loader.parse( file.asText(), '', function ( result ) {
 
-						editor.execute( new AddObjectCommand( result.scene ) );
+						var scene = result.scene;
+
+						editor.addAnimation( scene, result.animations );
+						editor.execute( new AddObjectCommand( scene ) );
 
 					} );
 

+ 42 - 19
editor/js/Menubar.Add.js

@@ -41,7 +41,7 @@ Menubar.Add = function ( editor ) {
 
 	var option = new UI.Row();
 	option.setClass( 'option' );
-	option.setTextContent( strings.getKey( 'menubar/add/plane' )  );
+	option.setTextContent( strings.getKey( 'menubar/add/plane' ) );
 	option.onClick( function () {
 
 		var geometry = new THREE.PlaneBufferGeometry( 1, 1, 1, 1 );
@@ -58,7 +58,7 @@ Menubar.Add = function ( editor ) {
 
 	var option = new UI.Row();
 	option.setClass( 'option' );
-	option.setTextContent( strings.getKey( 'menubar/add/box' )  );
+	option.setTextContent( strings.getKey( 'menubar/add/box' ) );
 	option.onClick( function () {
 
 		var geometry = new THREE.BoxBufferGeometry( 1, 1, 1, 1, 1, 1 );
@@ -90,7 +90,7 @@ Menubar.Add = function ( editor ) {
 
 	var option = new UI.Row();
 	option.setClass( 'option' );
-	option.setTextContent( strings.getKey( 'menubar/add/cylinder' )  );
+	option.setTextContent( strings.getKey( 'menubar/add/cylinder' ) );
 	option.onClick( function () {
 
 		var geometry = new THREE.CylinderBufferGeometry( 1, 1, 1, 8, 1, false, 0, Math.PI * 2 );
@@ -106,7 +106,7 @@ Menubar.Add = function ( editor ) {
 
 	var option = new UI.Row();
 	option.setClass( 'option' );
-	option.setTextContent( strings.getKey( 'menubar/add/sphere' )  );
+	option.setTextContent( strings.getKey( 'menubar/add/sphere' ) );
 	option.onClick( function () {
 
 		var geometry = new THREE.SphereBufferGeometry( 1, 8, 6, 0, Math.PI * 2, 0, Math.PI );
@@ -122,7 +122,7 @@ Menubar.Add = function ( editor ) {
 
 	var option = new UI.Row();
 	option.setClass( 'option' );
-	option.setTextContent( strings.getKey( 'menubar/add/icosahedron' )  );
+	option.setTextContent( strings.getKey( 'menubar/add/icosahedron' ) );
 	option.onClick( function () {
 
 		var geometry = new THREE.IcosahedronBufferGeometry( 1, 0 );
@@ -138,7 +138,7 @@ Menubar.Add = function ( editor ) {
 
 	var option = new UI.Row();
 	option.setClass( 'option' );
-	option.setTextContent( strings.getKey( 'menubar/add/torus' )  );
+	option.setTextContent( strings.getKey( 'menubar/add/torus' ) );
 	option.onClick( function () {
 
 		var geometry = new THREE.TorusBufferGeometry( 1, 0.4, 8, 6, Math.PI * 2 );
@@ -154,7 +154,7 @@ Menubar.Add = function ( editor ) {
 
 	var option = new UI.Row();
 	option.setClass( 'option' );
-	option.setTextContent( strings.getKey( 'menubar/add/torusknot' )  );
+	option.setTextContent( strings.getKey( 'menubar/add/torusknot' ) );
 	option.onClick( function () {
 
 		var geometry = new THREE.TorusKnotBufferGeometry( 1, 0.4, 64, 8, 2, 3 );
@@ -166,6 +166,29 @@ Menubar.Add = function ( editor ) {
 	} );
 	options.add( option );
 
+	// Tube
+
+	var option = new UI.Row();
+	option.setClass( 'option' );
+	option.setTextContent( strings.getKey( 'menubar/add/tube' ) );
+	option.onClick( function () {
+
+		var path = new THREE.CatmullRomCurve3( [
+			new THREE.Vector3( 2, 2, - 2 ),
+			new THREE.Vector3( 2, - 2, - 0.6666666666666667 ),
+			new THREE.Vector3( - 2, - 2, 0.6666666666666667 ),
+			new THREE.Vector3( - 2, 2, 2 )
+		] );
+
+		var geometry = new THREE.TubeBufferGeometry( path, 64, 1, 8, false );
+		var mesh = new THREE.Mesh( geometry, new THREE.MeshStandardMaterial() );
+		mesh.name = 'Tube';
+
+		editor.execute( new AddObjectCommand( mesh ) );
+
+	} );
+	options.add( option );
+
 	/*
 	// Teapot
 
@@ -199,8 +222,8 @@ Menubar.Add = function ( editor ) {
 
 	var option = new UI.Row();
 	option.setClass( 'option' );
-	option.setTextContent( strings.getKey( 'menubar/add/lathe' )  );
-	option.onClick( function() {
+	option.setTextContent( strings.getKey( 'menubar/add/lathe' ) );
+	option.onClick( function () {
 
 		var points = [
 			new THREE.Vector2( 0, 0 ),
@@ -229,7 +252,7 @@ Menubar.Add = function ( editor ) {
 
 	var option = new UI.Row();
 	option.setClass( 'option' );
-	option.setTextContent( strings.getKey( 'menubar/add/sprite' )  );
+	option.setTextContent( strings.getKey( 'menubar/add/sprite' ) );
 	option.onClick( function () {
 
 		var sprite = new THREE.Sprite( new THREE.SpriteMaterial() );
@@ -248,7 +271,7 @@ Menubar.Add = function ( editor ) {
 
 	var option = new UI.Row();
 	option.setClass( 'option' );
-	option.setTextContent( strings.getKey( 'menubar/add/pointlight' )  );
+	option.setTextContent( strings.getKey( 'menubar/add/pointlight' ) );
 	option.onClick( function () {
 
 		var color = 0xffffff;
@@ -267,7 +290,7 @@ Menubar.Add = function ( editor ) {
 
 	var option = new UI.Row();
 	option.setClass( 'option' );
-	option.setTextContent( strings.getKey( 'menubar/add/spotlight' )  );
+	option.setTextContent( strings.getKey( 'menubar/add/spotlight' ) );
 	option.onClick( function () {
 
 		var color = 0xffffff;
@@ -291,7 +314,7 @@ Menubar.Add = function ( editor ) {
 
 	var option = new UI.Row();
 	option.setClass( 'option' );
-	option.setTextContent( strings.getKey( 'menubar/add/directionallight' )  );
+	option.setTextContent( strings.getKey( 'menubar/add/directionallight' ) );
 	option.onClick( function () {
 
 		var color = 0xffffff;
@@ -312,7 +335,7 @@ Menubar.Add = function ( editor ) {
 
 	var option = new UI.Row();
 	option.setClass( 'option' );
-	option.setTextContent( strings.getKey( 'menubar/add/hemispherelight' )  );
+	option.setTextContent( strings.getKey( 'menubar/add/hemispherelight' ) );
 	option.onClick( function () {
 
 		var skyColor = 0x00aaff;
@@ -333,8 +356,8 @@ Menubar.Add = function ( editor ) {
 
 	var option = new UI.Row();
 	option.setClass( 'option' );
-	option.setTextContent( strings.getKey( 'menubar/add/ambientlight' )  );
-	option.onClick( function() {
+	option.setTextContent( strings.getKey( 'menubar/add/ambientlight' ) );
+	option.onClick( function () {
 
 		var color = 0x222222;
 
@@ -354,10 +377,10 @@ Menubar.Add = function ( editor ) {
 
 	var option = new UI.Row();
 	option.setClass( 'option' );
-	option.setTextContent( strings.getKey( 'menubar/add/perspectivecamera' )  );
-	option.onClick( function() {
+	option.setTextContent( strings.getKey( 'menubar/add/perspectivecamera' ) );
+	option.onClick( function () {
 
-		var camera = new THREE.PerspectiveCamera( 50, 1, 1, 10000 );
+		var camera = new THREE.PerspectiveCamera();
 		camera.name = 'PerspectiveCamera';
 
 		editor.execute( new AddObjectCommand( camera ) );

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

@@ -151,7 +151,7 @@ Menubar.Edit = function ( editor ) {
 
 			var material = object.material;
 
-			if ( material instanceof THREE.ShaderMaterial ) {
+			if ( material.isShaderMaterial ) {
 
 				try {
 

+ 65 - 5
editor/js/Sidebar.Animation.js

@@ -5,19 +5,79 @@
 Sidebar.Animation = function ( editor ) {
 
 	var signals = editor.signals;
+	var mixer = editor.mixer;
 
-	var options = {};
-	var possibleAnimations = {};
+	var actions = {};
+
+	signals.objectSelected.add( function ( object ) {
+
+		var animations = editor.animations[ object !== null ? object.uuid : '' ];
+
+		if ( animations !== undefined ) {
+
+			container.setDisplay( '' );
+
+			var options = {};
+			var firstAnimation;
+
+			for ( var animation of animations ) {
+
+				if ( firstAnimation === undefined ) firstAnimation = animation.name;
+
+				actions[ animation.name ] = mixer.clipAction( animation, object );
+				options[ animation.name ] = animation.name;
+
+			}
+
+			animationsSelect.setOptions( options );
+			animationsSelect.setValue( firstAnimation );
+
+		} else {
+
+			container.setDisplay( 'none' );
+
+		}
+
+	} );
+
+	signals.objectRemoved.add( function ( object ) {
+
+		var animations = editor.animations[ object !== null ? object.uuid : '' ];
+
+		if ( animations !== undefined ) {
+
+			mixer.uncacheRoot( object );
+
+		}
+
+	} );
+
+	function playAction() {
+
+		actions[ animationsSelect.getValue() ].play();
+
+	}
+
+	function stopAction() {
+
+		actions[ animationsSelect.getValue() ].stop();
+
+	}
 
 	var container = new UI.Panel();
 	container.setDisplay( 'none' );
 
-	container.add( new UI.Text( 'Animation' ).setTextTransform( 'uppercase' ) );
+	container.add( new UI.Text( 'Animations' ).setTextTransform( 'uppercase' ) );
 	container.add( new UI.Break() );
 	container.add( new UI.Break() );
 
-	var animationsRow = new UI.Row();
-	container.add( animationsRow );
+	var div = new UI.Div();
+	container.add( div );
+
+	var animationsSelect = new UI.Select().setFontSize( '12px' );
+	div.add( animationsSelect );
+	div.add( new UI.Button( 'Play' ).setMarginLeft( '4px' ).onClick( playAction ) );
+	div.add( new UI.Button( 'Stop' ).setMarginLeft( '4px' ).onClick( stopAction ) );
 
 	return container;
 

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

@@ -17,7 +17,7 @@ Sidebar.Geometry.BufferGeometry = function ( editor ) {
 
 		var geometry = object.geometry;
 
-		if ( geometry instanceof THREE.BufferGeometry ) {
+		if ( geometry && geometry.isBufferGeometry ) {
 
 			container.clear();
 			container.setDisplay( 'block' );

+ 1 - 1
editor/js/Sidebar.Geometry.Geometry.js

@@ -39,7 +39,7 @@ Sidebar.Geometry.Geometry = function ( editor ) {
 
 		var geometry = object.geometry;
 
-		if ( geometry instanceof THREE.Geometry ) {
+		if ( geometry && geometry.isGeometry ) {
 
 			container.setDisplay( 'block' );
 

+ 1 - 1
editor/js/Sidebar.Geometry.Modifiers.js

@@ -17,7 +17,7 @@ Sidebar.Geometry.Modifiers = function ( editor, object ) {
 
 		geometry.computeVertexNormals();
 
-		if ( geometry instanceof THREE.BufferGeometry ) {
+		if ( geometry.isBufferGeometry ) {
 
 			geometry.attributes.normal.needsUpdate = true;
 

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

@@ -0,0 +1,185 @@
+/**
+ * @author Temdog007 / http://github.com/Temdog007
+ */
+
+Sidebar.Geometry.TubeGeometry = function ( editor, object ) {
+
+	var strings = editor.strings;
+
+	var signals = editor.signals;
+
+	var container = new UI.Row();
+
+	var geometry = object.geometry;
+	var parameters = geometry.parameters;
+
+	// points
+
+	var lastPointIdx = 0;
+	var pointsUI = [];
+
+	var pointsRow = new UI.Row();
+	pointsRow.add( new UI.Text( strings.getKey( 'sidebar/geometry/tube_geometry/path' ) ).setWidth( '90px' ) );
+
+	var points = new UI.Span().setDisplay( 'inline-block' );
+	pointsRow.add( points );
+
+	var pointsList = new UI.Div();
+	points.add( pointsList );
+
+	var parameterPoints = parameters.path.points;
+	for ( var i = 0; i < parameterPoints.length; i ++ ) {
+
+		var point = parameterPoints[ i ];
+		pointsList.add( createPointRow( point.x, point.y, point.z ) );
+
+	}
+
+	var addPointButton = new UI.Button( '+' ).onClick( function () {
+
+		if ( pointsUI.length === 0 ) {
+
+			pointsList.add( createPointRow( 0, 0, 0 ) );
+
+		} else {
+
+			var point = pointsUI[ pointsUI.length - 1 ];
+
+			pointsList.add( createPointRow( point.x.getValue(), point.y.getValue(), point.z.getValue() ) );
+
+		}
+
+		update();
+
+	} );
+	points.add( addPointButton );
+
+	container.add( pointsRow );
+
+	// radius
+
+	var radiusRow = new UI.Row();
+	var radius = new UI.Number( parameters.radius ).onChange( update );
+
+	radiusRow.add( new UI.Text( strings.getKey( 'sidebar/geometry/tube_geometry/radius' ) ).setWidth( '90px' ) );
+	radiusRow.add( radius );
+
+	container.add( radiusRow );
+
+	// tubularSegments
+
+	var tubularSegmentsRow = new UI.Row();
+	var tubularSegments = new UI.Integer( parameters.tubularSegments ).onChange( update );
+
+	tubularSegmentsRow.add( new UI.Text( strings.getKey( 'sidebar/geometry/tube_geometry/tubularsegments' ) ).setWidth( '90px' ) );
+	tubularSegmentsRow.add( tubularSegments );
+
+	container.add( tubularSegmentsRow );
+
+	// radialSegments
+
+	var radialSegmentsRow = new UI.Row();
+	var radialSegments = new UI.Integer( parameters.radialSegments ).onChange( update );
+
+	radialSegmentsRow.add( new UI.Text( strings.getKey( 'sidebar/geometry/tube_geometry/radialsegments' ) ).setWidth( '90px' ) );
+	radialSegmentsRow.add( radialSegments );
+
+	container.add( radialSegmentsRow );
+
+	// closed
+
+	var closedRow = new UI.Row();
+	var closed = new UI.Checkbox( parameters.closed ).onChange( update );
+
+	closedRow.add( new UI.Text( strings.getKey( 'sidebar/geometry/tube_geometry/closed' ) ).setWidth( '90px' ) );
+	closedRow.add( closed );
+
+	container.add( closedRow );
+
+	// curveType
+
+	var curveTypeRow = new UI.Row();
+	var curveType = new UI.Select().setOptions( { centripetal: 'centripetal', chordal: 'chordal', catmullrom: 'catmullrom' } ).setValue( parameters.path.curveType ).onChange( update );
+
+	curveTypeRow.add( new UI.Text( strings.getKey( 'sidebar/geometry/tube_geometry/curvetype' ) ).setWidth( '90px' ), curveType );
+
+	container.add( curveTypeRow );
+
+	// tension
+
+	var tensionRow = new UI.Row().setDisplay( curveType.getValue() == 'catmullrom' ? '' : 'none' );
+	var tension = new UI.Number( parameters.path.tension ).setStep( 0.01 ).onChange( update );
+
+	tensionRow.add( new UI.Text( strings.getKey( 'sidebar/geometry/tube_geometry/tension' ) ).setWidth( '90px' ), tension );
+
+	container.add( tensionRow );
+
+	//
+
+	function update() {
+
+		var points = [];
+		var count = 0;
+
+		for ( var i = 0; i < pointsUI.length; i ++ ) {
+
+			var pointUI = pointsUI[ i ];
+
+			if ( ! pointUI ) continue;
+
+			points.push( new THREE.Vector3( pointUI.x.getValue(), pointUI.y.getValue(), pointUI.z.getValue() ) );
+			count ++;
+			pointUI.lbl.setValue( count );
+
+		}
+
+		tensionRow.setDisplay( curveType.getValue() == 'catmullrom' ? '' : 'none' );
+
+		editor.execute( new SetGeometryCommand( object, new THREE[ geometry.type ](
+			new THREE.CatmullRomCurve3( points, closed.getValue(), curveType.getValue(), tension.getValue() ),
+			tubularSegments.getValue(),
+			radius.getValue(),
+			radialSegments.getValue(),
+			closed.getValue()
+		) ) );
+
+	}
+
+	function createPointRow( x, y, z ) {
+
+		var pointRow = new UI.Div();
+		var lbl = new UI.Text( lastPointIdx + 1 ).setWidth( '20px' );
+		var txtX = new UI.Number( x ).setWidth( '30px' ).onChange( update );
+		var txtY = new UI.Number( y ).setWidth( '30px' ).onChange( update );
+		var txtZ = new UI.Number( z ).setWidth( '30px' ).onChange( update );
+		var idx = lastPointIdx;
+		var btn = new UI.Button( '-' ).onClick( function () {
+
+			deletePointRow( idx );
+
+		} );
+
+		pointsUI.push( { row: pointRow, lbl: lbl, x: txtX, y: txtY, z: txtZ } );
+		lastPointIdx ++;
+		pointRow.add( lbl, txtX, txtY, txtZ, btn );
+
+		return pointRow;
+
+	}
+
+	function deletePointRow( idx ) {
+
+		if ( ! pointsUI[ idx ] ) return;
+
+		pointsList.remove( pointsUI[ idx ].row );
+		pointsUI[ idx ] = null;
+
+		update();
+
+	}
+
+	return container;
+
+};
+
+Sidebar.Geometry.TubeBufferGeometry = Sidebar.Geometry.TubeGeometry;

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

@@ -55,7 +55,7 @@ Sidebar.Geometry = function ( editor ) {
 
 			case 'Convert':
 
-				if ( geometry instanceof THREE.Geometry ) {
+				if ( geometry && geometry.isGeometry ) {
 
 					editor.execute( new SetGeometryCommand( object, new THREE.BufferGeometry().fromGeometry( geometry ) ) );
 
@@ -179,6 +179,8 @@ Sidebar.Geometry = function ( editor ) {
 
 			}
 
+			if ( geometry.boundingSphere === null ) geometry.computeBoundingSphere();
+
 			geometryBoundingSphere.setValue( Math.floor( geometry.boundingSphere.radius * 1000 ) / 1000 );
 
 		} else {

+ 139 - 6
editor/js/Sidebar.Material.js

@@ -83,10 +83,14 @@ Sidebar.Material = function ( editor ) {
 		'MeshDepthMaterial': 'MeshDepthMaterial',
 		'MeshNormalMaterial': 'MeshNormalMaterial',
 		'MeshLambertMaterial': 'MeshLambertMaterial',
+		'MeshMatcapMaterial': 'MeshMatcapMaterial',
 		'MeshPhongMaterial': 'MeshPhongMaterial',
+		'MeshToonMaterial': 'MeshToonMaterial',
 		'MeshStandardMaterial': 'MeshStandardMaterial',
 		'MeshPhysicalMaterial': 'MeshPhysicalMaterial',
+		'RawShaderMaterial': 'RawShaderMaterial',
 		'ShaderMaterial': 'ShaderMaterial',
+		'ShadowMaterial': 'ShadowMaterial',
 		'SpriteMaterial': 'SpriteMaterial'
 
 	} ).setWidth( '150px' ).setFontSize( '12px' ).onChange( update );
@@ -257,6 +261,20 @@ Sidebar.Material = function ( editor ) {
 
 	container.add( materialVertexColorsRow );
 
+	// depth packing
+
+	var materialDepthPackingRow = new UI.Row();
+	var materialDepthPacking = new UI.Select().setOptions( {
+		[ THREE.BasicDepthPacking ]: 'BasicDepthPacking',
+		[ THREE.RGBADepthPacking ]: 'RGBADepthPacking'
+	} );
+	materialDepthPacking.onChange( update );
+
+	materialDepthPackingRow.add( new UI.Text( strings.getKey( 'sidebar/material/depthPacking' ) ).setWidth( '90px' ) );
+	materialDepthPackingRow.add( materialDepthPacking );
+
+	container.add( materialDepthPackingRow );
+
 	// skinning
 
 	var materialSkinningRow = new UI.Row();
@@ -279,6 +297,18 @@ Sidebar.Material = function ( editor ) {
 
 	container.add( materialMapRow );
 
+	// matcap map
+
+	var materialMatcapMapRow = new UI.Row();
+	var materialMatcapMapEnabled = new UI.Checkbox( false ).onChange( update );
+	var materialMatcapMap = new UI.Texture().onChange( update );
+
+	materialMatcapMapRow.add( new UI.Text( strings.getKey( 'sidebar/material/matcap' ) ).setWidth( '90px' ) );
+	materialMatcapMapRow.add( materialMatcapMapEnabled );
+	materialMatcapMapRow.add( materialMatcapMap );
+
+	container.add( materialMatcapMapRow );
+
 	// alpha map
 
 	var materialAlphaMapRow = new UI.Row();
@@ -419,6 +449,18 @@ Sidebar.Material = function ( editor ) {
 
 	container.add( materialEmissiveMapRow );
 
+	// gradient map
+
+	var materialGradientMapRow = new UI.Row();
+	var materialGradientMapEnabled = new UI.Checkbox( false ).onChange( update );
+	var materialGradientMap = new UI.Texture().onChange( update );
+
+	materialGradientMapRow.add( new UI.Text( strings.getKey( 'sidebar/material/gradientmap' ) ).setWidth( '90px' ) );
+	materialGradientMapRow.add( materialGradientMapEnabled );
+	materialGradientMapRow.add( materialGradientMap );
+
+	container.add( materialGradientMapRow );
+
 	// side
 
 	var materialSideRow = new UI.Row();
@@ -438,7 +480,7 @@ Sidebar.Material = function ( editor ) {
 	// shading
 
 	var materialShadingRow = new UI.Row();
-	var materialShading = new UI.Checkbox(false).setLeft( '100px' ).onChange( update );
+	var materialShading = new UI.Checkbox( false ).setLeft( '100px' ).onChange( update );
 
 	materialShadingRow.add( new UI.Text( strings.getKey( 'sidebar/material/flatshaded' ) ).setWidth( '90px' ) );
 	materialShadingRow.add( materialShading );
@@ -525,9 +567,9 @@ Sidebar.Material = function ( editor ) {
 		var textureWarning = false;
 		var objectHasUvs = false;
 
-		if ( object instanceof THREE.Sprite ) objectHasUvs = true;
-		if ( geometry instanceof THREE.Geometry && geometry.faceVertexUvs[ 0 ].length > 0 ) objectHasUvs = true;
-		if ( geometry instanceof THREE.BufferGeometry && geometry.attributes.uv !== undefined ) objectHasUvs = true;
+		if ( object.isSprite ) objectHasUvs = true;
+		if ( geometry.isGeometry && geometry.faceVertexUvs[ 0 ].length > 0 ) objectHasUvs = true;
+		if ( geometry.isBufferGeometry && geometry.attributes.uv !== undefined ) objectHasUvs = true;
 
 		if ( material ) {
 
@@ -537,10 +579,16 @@ Sidebar.Material = function ( editor ) {
 
 			}
 
-			if ( material instanceof THREE[ materialClass.getValue() ] === false ) {
+			if ( material.type !== materialClass.getValue() ) {
 
 				material = new THREE[ materialClass.getValue() ]();
 
+				if ( material.type == "RawShaderMaterial" ) {
+
+					material.vertexShader = vertexShaderVariables + material.vertexShader;
+
+				}
+
 				editor.execute( new SetMaterialCommand( currentObject, material, currentMaterialSlot ), 'New Material: ' + materialClass.getValue() );
 				// TODO Copy other references in the scene graph
 				// keeping name and UUID then.
@@ -610,6 +658,17 @@ Sidebar.Material = function ( editor ) {
 
 			}
 
+			if ( material.depthPacking !== undefined ) {
+
+				var depthPacking = parseInt( materialDepthPacking.getValue() );
+				if ( material.depthPacking !== depthPacking ) {
+
+					editor.execute( new SetMaterialValueCommand( currentObject, 'depthPacking', depthPacking, currentMaterialSlot ) );
+
+				}
+
+			}
+
 			if ( material.skinning !== undefined && material.skinning !== materialSkinning.getValue() ) {
 
 				editor.execute( new SetMaterialValueCommand( currentObject, 'skinning', materialSkinning.getValue(), currentMaterialSlot ) );
@@ -637,6 +696,27 @@ Sidebar.Material = function ( editor ) {
 
 			}
 
+			if ( material.matcap !== undefined ) {
+
+				var mapEnabled = materialMatcapMapEnabled.getValue() === true;
+
+				if ( objectHasUvs ) {
+
+					var matcap = mapEnabled ? materialMatcapMap.getValue() : null;
+					if ( material.matcap !== matcap ) {
+
+						editor.execute( new SetMaterialMapCommand( currentObject, 'matcap', matcap, currentMaterialSlot ) );
+
+					}
+
+				} else {
+
+					if ( mapEnabled ) textureWarning = true;
+
+				}
+
+			}
+
 			if ( material.alphaMap !== undefined ) {
 
 				var mapEnabled = materialAlphaMapEnabled.getValue() === true;
@@ -891,6 +971,20 @@ Sidebar.Material = function ( editor ) {
 
 			}
 
+			if ( material.gradientMap !== undefined ) {
+
+				var gradientMapEnabled = materialGradientMapEnabled.getValue() === true;
+
+				var gradientMap = gradientMapEnabled ? materialGradientMap.getValue() : null;
+
+				if ( material.gradientMap !== gradientMap ) {
+
+					editor.execute( new SetMaterialMapCommand( currentObject, 'gradientMap', gradientMap, currentMaterialSlot ) );
+
+				}
+
+			}
+
 			if ( material.side !== undefined ) {
 
 				var side = parseInt( materialSide.getValue() );
@@ -945,7 +1039,7 @@ Sidebar.Material = function ( editor ) {
 
 			if ( material.wireframe !== undefined && material.wireframe !== materialWireframe.getValue() ) {
 
-				editor.execute( new SetMaterialValueCommand( currentObject, 'wireframe', materialWireframe.getValue(), currentMaterialSlot) );
+				editor.execute( new SetMaterialValueCommand( currentObject, 'wireframe', materialWireframe.getValue(), currentMaterialSlot ) );
 
 			}
 
@@ -983,8 +1077,10 @@ Sidebar.Material = function ( editor ) {
 			'clearCoatRoughness': materialClearCoatRoughnessRow,
 			'vertexShader': materialProgramRow,
 			'vertexColors': materialVertexColorsRow,
+			'depthPacking': materialDepthPackingRow,
 			'skinning': materialSkinningRow,
 			'map': materialMapRow,
+			'matcap': materialMatcapMapRow,
 			'alphaMap': materialAlphaMapRow,
 			'bumpMap': materialBumpMapRow,
 			'normalMap': materialNormalMapRow,
@@ -996,6 +1092,7 @@ Sidebar.Material = function ( editor ) {
 			'lightMap': materialLightMapRow,
 			'aoMap': materialAOMapRow,
 			'emissiveMap': materialEmissiveMapRow,
+			'gradientMap': materialGradientMapRow,
 			'side': materialSideRow,
 			'flatShading': materialShadingRow,
 			'blending': materialBlendingRow,
@@ -1122,6 +1219,12 @@ Sidebar.Material = function ( editor ) {
 
 		}
 
+		if ( material.depthPacking !== undefined ) {
+
+			materialDepthPacking.setValue( material.depthPacking );
+
+		}
+
 		if ( material.skinning !== undefined ) {
 
 			materialSkinning.setValue( material.skinning );
@@ -1140,6 +1243,18 @@ Sidebar.Material = function ( editor ) {
 
 		}
 
+		if ( material.matcap !== undefined ) {
+
+			materialMatcapMapEnabled.setValue( material.matcap !== null );
+
+			if ( material.matcap !== null || resetTextureSelectors ) {
+
+				materialMatcapMap.setValue( material.matcap );
+
+			}
+
+		}
+
 		if ( material.alphaMap !== undefined ) {
 
 			materialAlphaMapEnabled.setValue( material.alphaMap !== null );
@@ -1240,6 +1355,18 @@ Sidebar.Material = function ( editor ) {
 
 		}
 
+		if ( material.gradientMap !== undefined ) {
+
+			materialGradientMapEnabled.setValue( material.gradientMap !== null );
+
+			if ( material.gradientMap !== null || resetTextureSelectors ) {
+
+				materialGradientMap.setValue( material.gradientMap );
+
+			}
+
+		}
+
 		if ( material.reflectivity !== undefined ) {
 
 			materialReflectivity.setValue( material.reflectivity );
@@ -1377,6 +1504,12 @@ Sidebar.Material = function ( editor ) {
 
 	} );
 
+	var vertexShaderVariables = [
+		'uniform mat4 projectionMatrix;',
+		'uniform mat4 modelViewMatrix;\n',
+		'attribute vec3 position;\n\n',
+	].join( '\n' );
+
 	return container;
 
 };

+ 2 - 2
editor/js/Sidebar.Object.js

@@ -542,8 +542,8 @@ Sidebar.Object = function ( editor ) {
 
 	function updateTransformRows( object ) {
 
-		if ( object instanceof THREE.Light ||
-		   ( object instanceof THREE.Object3D && object.userData.targetInverse ) ) {
+		if ( object.isLight ||
+		   ( object.isObject3D && object.userData.targetInverse ) ) {
 
 			objectRotationRow.setDisplay( 'none' );
 			objectScaleRow.setDisplay( 'none' );

+ 5 - 28
editor/js/Sidebar.Project.js

@@ -119,45 +119,22 @@ Sidebar.Project = function ( editor ) {
 	} );
 	rendererPropertiesRow.add( rendererShadows );
 
-	rendererPropertiesRow.add( new UI.Break() );
-
-	// Renderer / Gamma input
-
-	var rendererGammaInput = new UI.THREE.Boolean( config.getKey( 'project/renderer/gammaInput' ), strings.getKey( 'sidebar/project/gammainput' ) ).onChange( function () {
-
-		config.setKey( 'project/renderer/gammaInput', this.getValue() );
-		updateRenderer();
-
-	} );
-	rendererPropertiesRow.add( rendererGammaInput );
-
-	// Renderer / Gamma output
-
-	var rendererGammaOutput = new UI.THREE.Boolean( config.getKey( 'project/renderer/gammaOutput' ), strings.getKey( 'sidebar/project/gammaoutput' ) ).onChange( function () {
-
-		config.setKey( 'project/renderer/gammaOutput', this.getValue() );
-		updateRenderer();
-
-	} );
-	rendererPropertiesRow.add( rendererGammaOutput );
-
 	container.add( rendererPropertiesRow );
 
 	//
 
 	function updateRenderer() {
 
-		createRenderer( rendererType.getValue(), rendererAntialias.getValue(), rendererShadows.getValue(), rendererGammaInput.getValue(), rendererGammaOutput.getValue() );
+		createRenderer( rendererType.getValue(), rendererAntialias.getValue() );
 
 	}
 
-	function createRenderer( type, antialias, shadows, gammaIn, gammaOut ) {
+	function createRenderer( type, antialias, shadows ) {
 
 		rendererPropertiesRow.setDisplay( type === 'WebGLRenderer' ? '' : 'none' );
 
-		var renderer = new rendererTypes[ type ]( { antialias: antialias} );
-		renderer.gammaInput = gammaIn;
-		renderer.gammaOutput = gammaOut;
+		var renderer = new rendererTypes[ type ]( { antialias: antialias } );
+
 		if ( shadows && renderer.shadowMap ) {
 
 			renderer.shadowMap.enabled = true;
@@ -169,7 +146,7 @@ Sidebar.Project = function ( editor ) {
 
 	}
 
-	createRenderer( config.getKey( 'project/renderer' ), config.getKey( 'project/renderer/antialias' ), config.getKey( 'project/renderer/shadows' ), config.getKey( 'project/renderer/gammaInput' ), config.getKey( 'project/renderer/gammaOutput' ) );
+	createRenderer( config.getKey( 'project/renderer' ), config.getKey( 'project/renderer/antialias' ), config.getKey( 'project/renderer/shadows' ) );
 
 	return container;
 

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

@@ -59,7 +59,7 @@ Sidebar.Scene = function ( editor ) {
 
 		var html = '<span class="type ' + object.type + '"></span> ' + escapeHTML( object.name );
 
-		if ( object instanceof THREE.Mesh ) {
+		if ( object.isMesh ) {
 
 			var geometry = object.geometry;
 			var material = object.material;
@@ -231,13 +231,13 @@ Sidebar.Scene = function ( editor ) {
 
 			fogColor.setHexValue( scene.fog.color.getHex() );
 
-			if ( scene.fog instanceof THREE.Fog ) {
+			if ( scene.fog.isFog ) {
 
 				fogType.setValue( "Fog" );
 				fogNear.setValue( scene.fog.near );
 				fogFar.setValue( scene.fog.far );
 
-			} else if ( scene.fog instanceof THREE.FogExp2 ) {
+			} else if ( scene.fog.isFogExp2 ) {
 
 				fogType.setValue( "FogExp2" );
 				fogDensity.setValue( scene.fog.density );

+ 1 - 1
editor/js/Sidebar.Settings.js

@@ -72,7 +72,7 @@ Sidebar.Settings = function ( editor ) {
 	themeRow.add( new UI.Text( strings.getKey( 'sidebar/settings/theme' ) ).setWidth( '90px' ) );
 	themeRow.add( theme );
 
-	container.add( themeRow );
+	container.add( themeRow );	
 
 	container.add( new Sidebar.Settings.Shortcuts( editor ) );
 	container.add( new Sidebar.Settings.Viewport( editor ) );

+ 14 - 4
editor/js/Strings.js

@@ -41,6 +41,7 @@ var Strings = function ( config ) {
 			'menubar/add/sphere': 'Sphere',
 			'menubar/add/icosahedron': 'Icosahedron',
 			'menubar/add/torus': 'Torus',
+			'menubar/add/tube': 'Tube',
 			'menubar/add/torusknot': 'TorusKnot',
 			'menubar/add/lathe': 'Lathe',
 			'menubar/add/sprite': 'Sprite',
@@ -162,6 +163,15 @@ var Strings = function ( config ) {
 			'sidebar/geometry/torusKnot_geometry/p': 'P',
 			'sidebar/geometry/torusKnot_geometry/q': 'Q',
 
+			'sidebar/geometry/tube_geometry/path': 'Path',
+			'sidebar/geometry/tube_geometry/radius': 'Radius',
+			'sidebar/geometry/tube_geometry/tube': 'Tube',
+			'sidebar/geometry/tube_geometry/tubularsegments': 'Tubular segments',
+			'sidebar/geometry/tube_geometry/radialsegments': 'Radial segments',
+			'sidebar/geometry/tube_geometry/closed': 'Closed',
+			'sidebar/geometry/tube_geometry/curvetype': 'Curve Type',
+			'sidebar/geometry/tube_geometry/tension': 'Tension',
+
 			'sidebar/material/new': 'New',
 			'sidebar/material/copy': 'Copy',
 			'sidebar/material/paste': 'Paste',
@@ -173,6 +183,7 @@ var Strings = function ( config ) {
 			'sidebar/material/vertex': 'Vertex',
 			'sidebar/material/fragment': 'fragment',
 			'sidebar/material/color': 'Color',
+			'sidebar/material/depthPacking': 'Depth Packing',
 			'sidebar/material/roughness': 'Roughness',
 			'sidebar/material/metalness': 'Metalness',
 			'sidebar/material/emissive': 'Emissive',
@@ -185,6 +196,7 @@ var Strings = function ( config ) {
 			'sidebar/material/vertexcolors/face': 'Face',
 			'sidebar/material/vertexcolors/vertex': 'Vertex',
 			'sidebar/material/skinning': 'Skinning',
+			'sidebar/material/matcap': 'Matcap',
 			'sidebar/material/map': 'Map',
 			'sidebar/material/alphamap': 'Alpha Map',
 			'sidebar/material/bumpmap': 'Bump Map',
@@ -197,6 +209,7 @@ var Strings = function ( config ) {
 			'sidebar/material/lightmap': 'Light Map',
 			'sidebar/material/aomap': 'AO Map',
 			'sidebar/material/emissivemap': 'Emissive Map',
+			'sidebar/material/gradientmap': 'Gradient Map',
 			'sidebar/material/side': 'Side',
 			'sidebar/material/side/front': 'Front',
 			'sidebar/material/side/back': 'Back',
@@ -226,8 +239,6 @@ var Strings = function ( config ) {
 			'sidebar/project/renderer': 'Renderer',
 			'sidebar/project/antialias': 'antialias',
 			'sidebar/project/shadows': 'shadows',
-			'sidebar/project/gammainput': 'γ input',
-			'sidebar/project/gammaoutput': 'γ output',
 
 			'sidebar/settings': 'Settings',
 			'sidebar/settings/language': 'Language',
@@ -291,6 +302,7 @@ var Strings = function ( config ) {
 			'menubar/add/icosahedron': '二十面体',
 			'menubar/add/torus': '圆环体',
 			'menubar/add/torusknot': '环面纽结体',
+			'menubar/add/tube': '管',
 			'menubar/add/lathe': '酒杯',
 			'menubar/add/sprite': '精灵',
 			'menubar/add/pointlight': '点光源',
@@ -475,8 +487,6 @@ var Strings = function ( config ) {
 			'sidebar/project/renderer': '渲染器',
 			'sidebar/project/antialias': '抗锯齿',
 			'sidebar/project/shadows': '阴影',
-			'sidebar/project/gammainput': 'γ输入',
-			'sidebar/project/gammaoutput': 'γ输出',
 
 			'sidebar/settings': '设置',
 			'sidebar/settings/language': '语言',

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

@@ -0,0 +1,48 @@
+/**
+ * @author mrdoob / http://mrdoob.com/
+ */
+
+Viewport.Camera = function ( editor ) {
+
+	var signals = editor.signals;
+
+	//
+
+	var cameraSelect = new UI.Select();
+	cameraSelect.setPosition( 'absolute' );
+	cameraSelect.setRight( '10px' );
+	cameraSelect.setTop( '10px' );
+	cameraSelect.onChange( function () {
+
+		editor.setViewportCamera( this.getValue() );
+
+	} );
+
+	signals.cameraAdded.add( update );
+	signals.cameraRemoved.add( update );
+
+	update();
+
+	//
+
+	function update() {
+
+		var options = {};
+
+		var cameras = editor.cameras;
+
+		for ( var key in cameras ) {
+
+			var camera = cameras[ key ];
+			options[ camera.uuid ] = camera.name;
+
+		}
+
+		cameraSelect.setOptions( options );
+		cameraSelect.setValue( editor.viewportCamera.uuid );
+
+	}
+
+	return cameraSelect;
+
+};

+ 3 - 3
editor/js/Viewport.Info.js

@@ -46,16 +46,16 @@ Viewport.Info = function ( editor ) {
 
 				objects ++;
 
-				if ( object instanceof THREE.Mesh ) {
+				if ( object.isMesh ) {
 
 					var geometry = object.geometry;
 
-					if ( geometry instanceof THREE.Geometry ) {
+					if ( geometry.isGeometry ) {
 
 						vertices += geometry.vertices.length;
 						triangles += geometry.faces.length;
 
-					} else if ( geometry instanceof THREE.BufferGeometry ) {
+					} else if ( geometry.isBufferGeometry ) {
 
 						vertices += geometry.attributes.position.count;
 

+ 56 - 12
editor/js/Viewport.js

@@ -10,6 +10,7 @@ var Viewport = function ( editor ) {
 	container.setId( 'viewport' );
 	container.setPosition( 'absolute' );
 
+	container.add( new Viewport.Camera( editor ) );
 	container.add( new Viewport.Info( editor ) );
 
 	//
@@ -198,7 +199,7 @@ var Viewport = function ( editor ) {
 
 	function onMouseDown( event ) {
 
-		event.preventDefault();
+		// event.preventDefault();
 
 		var array = getMousePosition( container.dom, event.clientX, event.clientY );
 		onDownPosition.fromArray( array );
@@ -312,6 +313,7 @@ var Viewport = function ( editor ) {
 
 		renderer.autoClear = false;
 		renderer.autoUpdateScene = false;
+		renderer.gammaOutput = true;
 		renderer.setPixelRatio( window.devicePixelRatio );
 		renderer.setSize( container.dom.offsetWidth, container.dom.offsetHeight );
 
@@ -393,7 +395,7 @@ var Viewport = function ( editor ) {
 
 		}
 
-		if ( object instanceof THREE.PerspectiveCamera ) {
+		if ( object.isPerspectiveCamera ) {
 
 			object.updateProjectionMatrix();
 
@@ -411,6 +413,7 @@ var Viewport = function ( editor ) {
 
 	signals.objectRemoved.add( function ( object ) {
 
+		controls.enabled = true; // see #14180
 		if ( object === transformControls.object ) {
 
 			transformControls.detach();
@@ -477,16 +480,20 @@ var Viewport = function ( editor ) {
 
 		}
 
-		if ( scene.fog instanceof THREE.Fog ) {
+		if ( scene.fog ) {
 
-			scene.fog.color.setHex( fogColor );
-			scene.fog.near = fogNear;
-			scene.fog.far = fogFar;
+			if ( scene.fog.isFog ) {
 
-		} else if ( scene.fog instanceof THREE.FogExp2 ) {
+				scene.fog.color.setHex( fogColor );
+				scene.fog.near = fogNear;
+				scene.fog.far = fogFar;
 
-			scene.fog.color.setHex( fogColor );
-			scene.fog.density = fogDensity;
+			} else if ( scene.fog.isFogExp2 ) {
+
+				scene.fog.color.setHex( fogColor );
+				scene.fog.density = fogDensity;
+
+			}
 
 		}
 
@@ -494,6 +501,17 @@ var Viewport = function ( editor ) {
 
 	} );
 
+	signals.viewportCameraChanged.add( function ( viewportCamera ) {
+
+		camera = viewportCamera;
+
+		camera.aspect = editor.camera.aspect;
+		camera.projectionMatrix.copy( editor.camera.projectionMatrix );
+
+		render();
+
+	} );
+
 	//
 
 	signals.windowResize.add( function () {
@@ -519,18 +537,44 @@ var Viewport = function ( editor ) {
 
 	} );
 
+	// animations
+
+	var prevTime = performance.now();
+
+	function animate( time ) {
+
+		requestAnimationFrame( animate );
+
+		var mixer = editor.mixer;
+
+		if ( mixer.stats.actions.inUse > 0 ) {
+
+			mixer.update( ( time - prevTime ) / 1000 );
+			render();
+
+		}
+
+		prevTime = time;
+
+	}
+
+	requestAnimationFrame( animate );
+
 	//
 
 	function render() {
 
-		sceneHelpers.updateMatrixWorld();
 		scene.updateMatrixWorld();
-
 		renderer.render( scene, camera );
 
 		if ( renderer instanceof THREE.RaytracingRenderer === false ) {
 
-			renderer.render( sceneHelpers, camera );
+			if ( camera === editor.camera ) {
+
+				sceneHelpers.updateMatrixWorld();
+				renderer.render( sceneHelpers, camera );
+
+			}
 
 		}
 

+ 1 - 2
editor/js/libs/app.js

@@ -21,13 +21,12 @@ var APP = {
 		this.load = function ( json ) {
 
 			renderer = new THREE.WebGLRenderer( { antialias: true } );
+			renderer.gammaOutput = true;
 			renderer.setClearColor( 0x000000 );
 			renderer.setPixelRatio( window.devicePixelRatio );
 
 			var project = json.project;
 
-			if ( project.gammaInput ) renderer.gammaInput = true;
-			if ( project.gammaOutput ) renderer.gammaOutput = true;
 			if ( project.shadows ) renderer.shadowMap.enabled = true;
 			if ( project.vr ) renderer.vr.enabled = true;
 

+ 1 - 1
editor/js/libs/codemirror/mode/glsl.js

@@ -205,7 +205,7 @@
     "do for while if else in out inout float int void bool true false " +
     "lowp mediump highp precision invariant discard return mat2 mat3 " +
     "mat4 vec2 vec3 vec4 ivec2 ivec3 ivec4 bvec2 bvec3 bvec4 sampler2D " +
-    "samplerCube struct gl_FragCoord gl_FragColor";
+    "samplerCube struct gl_FragCoord gl_FragColor gl_Position";
   var glslBuiltins = "radians degrees sin cos tan asin acos atan pow " +
     "exp log exp2 log2 sqrt inversesqrt abs sign floor ceil fract mod " +
     "min max clamp mix step smoothstep length distance dot cross " +

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