Browse Source

Merge branch 'dev' into ChainableEffect

Takahiro 8 years ago
parent
commit
6ff95c95fc
100 changed files with 2130 additions and 935 deletions
  1. 3 3
      .github/ISSUE_TEMPLATE.md
  2. 1 1
      README.md
  3. 2 2
      build/three.js
  4. 0 0
      build/three.js.map
  5. 292 289
      build/three.min.js
  6. 2 2
      build/three.modules.js
  7. 0 0
      build/three.modules.js.map
  8. 132 0
      docs/api/animation/AnimationAction.html
  9. 87 0
      docs/api/animation/AnimationClip.html
  10. 102 0
      docs/api/animation/AnimationMixer.html
  11. 37 21
      docs/api/constants/CustomBlendingEquations.html
  12. 31 11
      docs/api/constants/GLState.html
  13. 24 6
      docs/api/constants/ShadowingTypes.html
  14. 2 2
      docs/api/extras/collada-animation/Animation.html
  15. 2 2
      docs/api/extras/collada-animation/AnimationHandler.html
  16. 2 2
      docs/api/extras/collada-animation/KeyFrameAnimation.html
  17. 1 1
      docs/api/geometries/ExtrudeGeometry.html
  18. 71 0
      docs/api/geometries/ShapeBufferGeometry.html
  19. 15 39
      docs/api/geometries/ShapeGeometry.html
  20. 1 1
      docs/api/loaders/Cache.html
  21. 0 0
      docs/api/loaders/FileLoader.html
  22. 98 56
      docs/api/loaders/MTLLoader.html
  23. 10 12
      docs/api/materials/MeshStandardMaterial.html
  24. 2 2
      docs/api/math/Box2.html
  25. 2 2
      docs/api/math/Box3.html
  26. 1 1
      docs/api/math/Line3.html
  27. 70 0
      docs/api/math/Spherical.html
  28. 5 0
      docs/api/math/Vector3.html
  29. 5 5
      docs/api/renderers/WebGLRenderer.html
  30. 14 6
      docs/list.js
  31. 40 9
      docs/scenes/js/geometry.js
  32. 1 1
      editor/index.html
  33. 1 1
      editor/js/Menubar.Examples.js
  34. 1 1
      editor/js/Menubar.File.js
  35. 1 1
      editor/js/libs/app/index.html
  36. 7 7
      editor/js/libs/tern-threejs/threejs.js
  37. 3 0
      examples/files.js
  38. 11 3
      examples/js/animation/CCDIKSolver.js
  39. 237 25
      examples/js/animation/MMDPhysics.js
  40. 81 20
      examples/js/effects/OutlineEffect.js
  41. 20 23
      examples/js/effects/VREffect.js
  42. 1 1
      examples/js/loaders/3MFLoader.js
  43. 1 1
      examples/js/loaders/AMFLoader.js
  44. 1 1
      examples/js/loaders/AWDLoader.js
  45. 1 1
      examples/js/loaders/AssimpJSONLoader.js
  46. 1 1
      examples/js/loaders/BVHLoader.js
  47. 1 1
      examples/js/loaders/BabylonLoader.js
  48. 2 2
      examples/js/loaders/BinaryLoader.js
  49. 1 1
      examples/js/loaders/ColladaLoader2.js
  50. 2 2
      examples/js/loaders/FBXLoader.js
  51. 3 3
      examples/js/loaders/GLTFLoader.js
  52. 1 1
      examples/js/loaders/HDRCubeTextureLoader.js
  53. 1 1
      examples/js/loaders/KMZLoader.js
  54. 1 1
      examples/js/loaders/MD2Loader.js
  55. 193 132
      examples/js/loaders/MMDLoader.js
  56. 1 1
      examples/js/loaders/MTLLoader.js
  57. 1 1
      examples/js/loaders/NRRDLoader.js
  58. 1 1
      examples/js/loaders/OBJLoader.js
  59. 1 1
      examples/js/loaders/PCDLoader.js
  60. 1 1
      examples/js/loaders/PDBLoader.js
  61. 1 1
      examples/js/loaders/PLYLoader.js
  62. 1 1
      examples/js/loaders/PlayCanvasLoader.js
  63. 1 1
      examples/js/loaders/STLLoader.js
  64. 1 1
      examples/js/loaders/SVGLoader.js
  65. 1 1
      examples/js/loaders/TGALoader.js
  66. 1 1
      examples/js/loaders/TTFLoader.js
  67. 1 1
      examples/js/loaders/UTF8Loader.js
  68. 1 1
      examples/js/loaders/VRMLLoader.js
  69. 1 1
      examples/js/loaders/VTKLoader.js
  70. 1 1
      examples/js/loaders/deprecated/SceneLoader.js
  71. 210 0
      examples/webgl2_sandbox.html
  72. 6 3
      examples/webgl_geometry_shapes.html
  73. 7 4
      examples/webgl_loader_mmd.html
  74. 2 2
      examples/webgl_loader_mmd_audio.html
  75. 1 1
      examples/webgl_loader_msgpack.html
  76. 12 5
      examples/webgl_materials_blending_custom.html
  77. 24 29
      examples/webgl_materials_normalmap.html
  78. 1 1
      examples/webgl_morphtargets_human.html
  79. 2 5
      package.json
  80. 2 1
      rollup.config.js
  81. 24 16
      src/Three.Legacy.js
  82. 2 1
      src/Three.js
  83. 1 1
      src/constants.js
  84. 1 1
      src/geometries/DodecahedronGeometry.js
  85. 1 0
      src/geometries/Geometries.js
  86. 1 1
      src/geometries/IcosahedronGeometry.js
  87. 1 1
      src/geometries/OctahedronGeometry.js
  88. 142 0
      src/geometries/ShapeBufferGeometry.js
  89. 15 116
      src/geometries/ShapeGeometry.js
  90. 1 1
      src/geometries/TetrahedronGeometry.js
  91. 1 1
      src/geometries/TubeBufferGeometry.js
  92. 2 2
      src/loaders/AnimationLoader.js
  93. 2 2
      src/loaders/AudioLoader.js
  94. 2 2
      src/loaders/BinaryTextureLoader.js
  95. 2 2
      src/loaders/BufferGeometryLoader.js
  96. 2 2
      src/loaders/CompressedTextureLoader.js
  97. 15 8
      src/loaders/FileLoader.js
  98. 2 2
      src/loaders/FontLoader.js
  99. 2 2
      src/loaders/ImageLoader.js
  100. 2 2
      src/loaders/JSONLoader.js

+ 3 - 3
.github/ISSUE_TEMPLATE.md

@@ -1,12 +1,12 @@
-##### Description of the problem 
+(*** This section is for bug reports and feature requests only. This is NOT a help site. Do not ask help questions here. If you need help, please use stackoverflow. ***)
 
-(This is NOT a help site. Please read the guidelines above before posting.)
+##### Description of the problem 
 
 
 ##### Three.js version
 
 - [ ] Dev
-- [ ] r81
+- [ ] r82
 - [ ] ...
 
 ##### Browser

+ 1 - 1
README.md

@@ -11,7 +11,7 @@ The aim of the project is to create an easy to use, lightweight, 3D library. The
 ### Usage ###
 
 Download the [minified library](http://threejs.org/build/three.min.js) and include it in your html.
-Alternatively see [how to build the library yourself](https://github.com/mrdoob/three.js/wiki/build.py,-or-how-to-generate-a-compressed-Three.js-file).
+Alternatively see [how to build the library yourself](https://github.com/mrdoob/three.js/wiki/Build-instructions).
 
 ```html
 <script src="js/three.min.js"></script>

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


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


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


File diff suppressed because it is too large
+ 2 - 2
build/three.modules.js


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


+ 132 - 0
docs/api/animation/AnimationAction.html

@@ -0,0 +1,132 @@
+<!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>
+
+    <div class="desc">
+    An AnimationAction schedules clip playback on specific objects.
+    </div>
+
+
+    <h2>Constructor</h2>
+
+
+    <h3>[name]( [page:AnimationMixer mixer], [page:AnimationClip clip], [page:Object3D localRoot] )</h3>
+
+
+    <h2>Properties</h2>
+
+
+    <h3>[property:Number time]</h3>
+
+    <h3>[property:Number timeScale]</h3>
+
+    <h3>[property:Number weight]</h3>
+
+    <h3>[property:Number loop]</h3>
+
+    <h3>[property:Number repetitions]</h3>
+
+    <h3>[property:Boolean paused]</h3>
+
+    <h3>[property:Boolean enabled]</h3>
+
+    <h3>[property:Boolean clampWhenFinished]</h3>
+
+    <h3>[property:Boolean zeroSlopeAtStart]</h3>
+
+    <h3>[property:Boolean zeroSlopeAtEnd]</h3>
+
+
+    <h2>Methods</h2>
+
+
+    <h3>[method:AnimationAction play]()</h3>
+
+    <h3>[method:AnimationAction stop]()</h3>
+
+    <h3>[method:AnimationAction reset]()</h3>
+
+    <h3>[method:Boolean isRunning]()</h3>
+
+    <h3>[method:Boolean isScheduled]()</h3>
+
+    <h3>[method:AnimationAction startAt]()</h3>
+
+    <h3>[method:AnimationAction setLoop]( [page:Number mode], [page:Number repetitions] )</h3>
+
+    <h3>[method:AnimationAction setEffectiveWeight]( [page:Number weight] )</h3>
+
+    <h3>[method:number getEffectiveWeight]()</h3>
+
+    <h3>[method:AnimationAction fadeIn]( [page:Number duration] )</h3>
+
+    <h3>[method:AnimationAction fadeOut]( [page:Number duration] )</h3>
+
+    <h3>[method:AnimationAction crossFadeFrom]( [page:AnimationAction fadeOutAction], [page:Number duration], [page:Boolean warp] )</h3>
+
+    <h3>[method:AnimationAction crossFadeTo]( [page:AnimationAction fadeInAction], [page:Number duration], [page:Boolean warp] )</h3>
+
+    <h3>[method:AnimationAction stopFading]()</h3>
+
+    <h3>[method:AnimationAction setEffectiveTimeScale]( [page:Number timeScale] )</h3>
+
+    <h3>[method:Number getEffectiveTimeScale]()</h3>
+
+    <h3>[method:AnimationAction setDuration]( [page:Number duration] )</h3>
+
+    <h3>[method:AnimationAction syncWith]( [page:AnimationAction action] )</h3>
+
+    <h3>[method:AnimationAction halt]( [page:Number duration] )</h3>
+
+    <h3>[method:AnimationAction warp]( [page:Number startTimeScale], [page:Number endTimeScale], [page:Number duration] )</h3>
+
+    <h3>[method:AnimationAction stopWarping]()</h3>
+
+    <h3>[method:AnimationMixer getMixer]()</h3>
+
+    <h3>[method:AnimationClip getClip]()</h3>
+
+    <h3>[method:Object3D getRoot]()</h3>
+
+
+    <h2>Static Methods</h2>
+
+
+    <h3>[method:AnimationClip parse]( [page:Object json] )</h3>
+    <div>
+    json -- JSON object
+    </div>
+
+    <h3>[method:Object toJSON]( [page:AnimationClip clip] )</h3>
+    <div>
+    clip -- AnimationClip
+    </div>
+
+    <h3>[method:AnimationClip CreateFromMorphTargetSequence]( [page:String name], [page:Array morphTargetSequence], [page:Number fps], [page:Boolean noLoop] )</h3>
+    <div>
+    name -- Name for the new clip <br />
+    morphTargetSequence -- Array of morph targets <br />
+    fps -- Number of frames per second <br />
+    noLoop -- Whether looping occurs automatically.
+    </div>
+
+    <h3>[method:AnimationClip parseAnimation]( [page:Object animation], [page:Array bones] )</h3>
+    <div>
+    Parses the animation.hierarchy format and returns an AnimationClip.
+    </div>
+
+
+    <h2>Source</h2>
+
+
+    [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
+  </body>
+</html>

+ 87 - 0
docs/api/animation/AnimationClip.html

@@ -0,0 +1,87 @@
+<!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>
+
+    <div class="desc">
+    An AnimationClip is a reusable set of Tracks that represent an animation.
+    </div>
+
+
+    <h2>Constructor</h2>
+
+
+    <h3>[name]( [page:String name], [page:Number duration], tracks )</h3>
+
+
+    <h2>Properties</h2>
+
+
+    <h3>[property:String uuid]</h3>
+
+    <h3>[property:String name]</h3>
+
+    <h3>[property:Number duration]</h3>
+
+    <h3>.tracks</h3>
+
+
+    <h2>Methods</h2>
+
+
+    <h3>[method:null resetDuration]()</h3>
+    <div>
+    Resets duration by scanning all tracks in the clip.
+    </div>
+
+    <h3>[method:AnimationClip trim]()</h3>
+    <div>
+    Trims all tracks to the clip's duration.
+    </div>
+
+    <h3>[method:AnimationClip optimize]()</h3>
+    <div>
+    Optimizes each track.
+    </div>
+
+
+    <h2>Static Methods</h2>
+
+
+    <h3>[method:AnimationClip parse]( [page:Object json] )</h3>
+    <div>
+    json -- JSON object
+    </div>
+
+    <h3>[method:Object toJSON]( [page:AnimationClip clip] )</h3>
+    <div>
+    clip -- AnimationClip
+    </div>
+
+    <h3>[method:AnimationClip CreateFromMorphTargetSequence]( [page:String name], [page:Array morphTargetSequence], [page:Number fps], [page:Boolean noLoop] )</h3>
+    <div>
+    name -- Name for the new clip <br />
+    morphTargetSequence -- Array of morph targets <br />
+    fps -- Number of frames per second <br />
+    noLoop -- Whether looping occurs automatically.
+    </div>
+
+    <h3>[method:AnimationClip parseAnimation]( [page:Object animation], [page:Array bones] )</h3>
+    <div>
+    Parses the animation.hierarchy format and returns an AnimationClip.
+    </div>
+
+
+    <h2>Source</h2>
+
+
+    [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
+  </body>
+</html>

+ 102 - 0
docs/api/animation/AnimationMixer.html

@@ -0,0 +1,102 @@
+<!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>
+
+    <div class="desc">
+    The AnimationMixer is a player for AnimationClip objects.
+    </div>
+
+
+    <h2>Constructor</h2>
+
+
+    <h3>[name]( [page:Object3D root] )</h3>
+
+
+    <h2>Properties</h2>
+
+
+    <h3>[property:Number time]</h3>
+
+    <h3>[property:Number timeScale]</h3>
+
+
+    <h2>Methods</h2>
+
+
+    <h3>[method:AnimationAction clipAction]([page:AnimationClip clip], [page:Object3D optionalRoot])</h3>
+    <div>
+    clip -- AnimationClip <br />
+    optionalRoot -- Object3D
+    </div>
+    <div>
+    Return an action for a clip, optionally using a custom root target object.
+    </div>
+
+    <h3>[method:AnimationAction existingAction]([page:AnimationClip clip], [page:Object3D optionalRoot])</h3>
+    <div>
+    clip -- AnimationClip <br />
+    optionalRoot -- Object3D
+    </div>
+    <div>
+    Return an existing action.
+    </div>
+
+    <h3>[method:AnimationMixer stopAllAction]()</h3>
+    <div>
+    Deactivates all scheduled actions.
+    </div>
+
+    <h3>[method:AnimationMixer update]([page:Number deltaTimeMS]) </h3>
+    <div>
+    deltaTimeMS -- Time elapsed since last update in milliseconds.
+    </div>
+    <div>
+    Updates the animation with deltaTimeMS.
+    </div>
+
+    <h3>[method:Object3D getRoot]()</h3>
+    <div>
+    Return this mixer's root target object.
+    </div>
+
+    <h3>[method:null uncacheClip]([page:AnimationClip clip])</h3>
+    <div>
+    clip -- AnimationClip
+    </div>
+    <div>
+    Free all resources for a clip.
+    </div>
+
+    <h3>[method:null uncacheRoot]([page:Object3D root]) </h3>
+    <div>
+    root -- Object3D
+    </div>
+    <div>
+    Free all resources for a root target object.
+    </div>
+
+    <h3>[method:null uncacheAction]([page:AnimationClip clip], [page:Object3D optionalRoot])</h3>
+    <div>
+    clip -- AnimationClip <br />
+    optionalRoot -- Object3D
+    </div>
+    <div>
+    Free all resources for an action.
+    </div>
+
+
+    <h2>Source</h2>
+
+
+    [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
+  </body>
+</html>

+ 37 - 21
docs/api/constants/CustomBlendingEquations.html

@@ -10,32 +10,48 @@
 	<body>
 		<h1>Custom Blending Equation Constants</h1>
 
-		<h2>Equations</h2>
-		<div>
-		THREE.AddEquation<br />
-		THREE.SubtractEquation<br />
-		THREE.ReverseSubtractEquation<br />
-		THREE.MinEquation<br />
+
+		<h2>Example</h2>
+		<div>[example:webgl_materials_blending_custom materials / blending / custom ]</div>
+
+		<h2>Usage</h2>
+		These work with all material types. First set the material's blending mode to THREE.CustomBlending, then set the desired Blending Equation, Source Factor and Destination Factor.
+
+		<code>
+		var material = new THREE.MeshBasicMaterial( {color: 0x00ff00} );
+		material.blending = THREE.CustomBlending;
+		material.blendEquation = THREE.AddEquation; //default
+		material.blendSrc = THREE.SrcAlphaFactor; //default
+		material.blendDst = THREE.OneMinusDstAlphaFactor; //default
+		</code>
+
+		<h2>Blending Equations</h2>
+		<code>
+		THREE.AddEquation
+		THREE.SubtractEquation
+		THREE.ReverseSubtractEquation
+		THREE.MinEquation
 		THREE.MaxEquation
-		</div>
+		</code>
 
-		<h2>Destination Factors</h2>
-		<div>
-		THREE.ZeroFactor<br />
-		THREE.OneFactor<br />
-		THREE.SrcColorFactor<br />
-		THREE.OneMinusSrcColorFactor<br />
-		THREE.SrcAlphaFactor<br />
-		THREE.OneMinusSrcAlphaFactor<br />
-		THREE.DstAlphaFactor<br />
+		<h2>Source Factors</h2>
+		<code>
+		THREE.ZeroFactor
+		THREE.OneFactor
+		THREE.SrcColorFactor
+		THREE.OneMinusSrcColorFactor
+		THREE.SrcAlphaFactor
+		THREE.OneMinusSrcAlphaFactor
+		THREE.DstAlphaFactor
 		THREE.OneMinusDstAlphaFactor
-		</div>
+		THREE.DstColorFactor
+		THREE.OneMinusDstColorFactor
+		THREE.SrcAlphaSaturateFactor
+		</code>
 
-		<h2>Source Factors</h2>
+		<h2>Destination Factors</h2>
 		<div>
-		THREE.DstColorFactor<br />
-		THREE.OneMinusDstColorFactor<br />
-		THREE.SrcAlphaSaturateFactor
+			All of the Source Factors are valid as Destination Factors, except for <code>THREE.SrcAlphaSaturateFactor</code>
 		</div>
 
 		<h2>Source</h2>

+ 31 - 11
docs/api/constants/GLState.html

@@ -9,21 +9,41 @@
 	</head>
 	<body>
 		<h1>GL State Constants</h1>
+		These are used by the WebGLRenderer to set gl.cullFace and gl.frontFace states in the GPU.
 
-		<h2>Cull Face</h2>
-		<div>
-		THREE.CullFaceNone<br />
-		THREE.CullFaceBack<br />
-		THREE.CullFaceFront<br />
+		<h2>Cull Face Modes</h2>
+		<code>
+		THREE.CullFaceNone
+		</code>
+		<p>Disable face culling.</p>
+		<code>
+		THREE.CullFaceBack
+		</code>
+		<p>Cull back faces (default).</p>
+		<code>
+		THREE.CullFaceFront
+		</code>
+		<p>Cull front faces.</p>
+		<code>
 		THREE.CullFaceFrontBack
-		</div>
+		</code>
+		<p>Cull both front and back faces.</p>
 
 		<h2>Front Face Direction</h2>
-		<div>
-		THREE.FrontFaceDirectionCW<br />
-		THREE.FrontFaceDirectionCCW<br />
-		</div>
-	
+		Set the winding order for polygons to either clockwise or counter-clockwise (default).
+		<code>
+		THREE.FrontFaceDirectionCW
+		THREE.FrontFaceDirectionCCW
+		</code>
+
+		<h2>Usage</h2>
+
+		<code>
+		var renderer = new THREE.WebGLRenderer();
+
+		renderer.setFaceCulling ( THREE.CullFaceBack, THREE.FrontFaceDirectionCCW );  //defaults
+		</code>
+
 		<h2>Source</h2>
 
 		[link:https://github.com/mrdoob/three.js/blob/master/src/constants.js src/constants.js]

+ 24 - 6
docs/api/constants/ShadowingTypes.html

@@ -9,14 +9,32 @@
 	</head>
 	<body>
 		<h1>Shadowing Type Constants</h1>
+		<p>These define the shadow map types used by the WebGLRenderer.</p>
 
-		<h2>Shadow Map</h2>
-		<div>
-		THREE.BasicShadowMap<br />
-		THREE.PCFShadowMap<br />
+		<h2>Shadow Map Types</h2>
+		<code>
+		THREE.BasicShadowMap
+		</code>
+		<p>Unfiltered shadow maps - fastest, but lowest quality.</p>
+		<code>
+		THREE.PCFShadowMap
+		</code>
+		<p>Shadow maps filtered using the Percentage-Closer Filtering (PCF) algorithm (default).</p>
+		<code>
 		THREE.PCFSoftShadowMap
-		</div>
-	
+		</code>
+		<p>Shadow maps filtered using the Percentage-Closer Soft Shadows (PCSS) algorithm.</p>
+
+		<h2>Usage</h2>
+		<code>
+		var renderer = new THREE.WebGLRenderer();
+		renderer.shadowMap.enabled = true;
+		renderer.shadowMap.type = THREE.PCFShadowMap; //default
+		</code>
+
+		Note that this just enables shadows in the renderer and sets the shadow map type. <br />
+		To actually cast shadows you will have to set up shadows for the any light you want to cast shadows, and for meshes you want to cast / receive shadows. <br />
+
 		<h2>Source</h2>
 
 		[link:https://github.com/mrdoob/three.js/blob/master/src/constants.js src/constants.js]

+ 2 - 2
docs/api/extras/animation/Animation.html → docs/api/extras/collada-animation/Animation.html

@@ -1,7 +1,7 @@
 <!DOCTYPE html>
 <html lang="en">
 	<head>
-		<meta charset="utf-8" />
+		<meta charset="utf-8" />
 		<base href="../../../" />
 		<script src="list.js"></script>
 		<script src="page.js"></script>
@@ -123,6 +123,6 @@
 
 		<h2>Source</h2>
 
-		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
+		[link:https://github.com/mrdoob/three.js/blob/master/examples/js/loaders/collada/[name].js examples/js/loaders/collada/[name].js]
 	</body>
 </html>

+ 2 - 2
docs/api/extras/animation/AnimationHandler.html → docs/api/extras/collada-animation/AnimationHandler.html

@@ -1,7 +1,7 @@
 <!DOCTYPE html>
 <html lang="en">
 	<head>
-		<meta charset="utf-8" />
+		<meta charset="utf-8" />
 		<base href="../../../" />
 		<script src="list.js"></script>
 		<script src="page.js"></script>
@@ -97,6 +97,6 @@
 
 		<h2>Source</h2>
 
-		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
+		[link:https://github.com/mrdoob/three.js/blob/master/examples/js/loaders/collada/[name].js examples/js/loaders/collada/[name].js]
 	</body>
 </html>

+ 2 - 2
docs/api/extras/animation/KeyFrameAnimation.html → docs/api/extras/collada-animation/KeyFrameAnimation.html

@@ -1,7 +1,7 @@
 <!DOCTYPE html>
 <html lang="en">
 	<head>
-		<meta charset="utf-8" />
+		<meta charset="utf-8" />
 		<base href="../../../" />
 		<script src="list.js"></script>
 		<script src="page.js"></script>
@@ -111,6 +111,6 @@
 		Used internally to traverse the animation
 		</div>
 
-		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
+		[link:https://github.com/mrdoob/three.js/blob/master/examples/js/loaders/collada/[name].js examples/js/loaders/collada/[name].js]
 	</body>
 </html>

+ 1 - 1
docs/api/geometries/ExtrudeGeometry.html

@@ -54,7 +54,7 @@
 			bevelSegments: 1
 		};
 
-		var geometry = new THREE.ExtrudeGeometry( shape, data );
+		var geometry = new THREE.ExtrudeGeometry( shape, extrudeSettings );
 		var material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
 		var mesh = new THREE.Mesh( geometry, material ) ;
 		scene.add( mesh );

+ 71 - 0
docs/api/geometries/ShapeBufferGeometry.html

@@ -0,0 +1,71 @@
+<!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:BufferGeometry] &rarr;
+
+		<h1>[name]</h1>
+
+		<div class="desc">Creates an one-sided polygonal geometry from one or more path shapes.</div>
+
+		<iframe id="scene" src="scenes/geometry-browser.html#ShapeBufferGeometry"></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>Example</h2>
+
+
+		<code>
+		var x = 0, y = 0;
+
+		var heartShape = new THREE.Shape();
+
+		heartShape.moveTo( x + 5, y + 5 );
+		heartShape.bezierCurveTo( x + 5, y + 5, x + 4, y, x, y );
+		heartShape.bezierCurveTo( x - 6, y, x - 6, y + 7,x - 6, y + 7 );
+		heartShape.bezierCurveTo( x - 6, y + 11, x - 3, y + 15.4, x + 5, y + 19 );
+		heartShape.bezierCurveTo( x + 12, y + 15.4, x + 16, y + 11, x + 16, y + 7 );
+		heartShape.bezierCurveTo( x + 16, y + 7, x + 16, y, x + 10, y );
+		heartShape.bezierCurveTo( x + 7, y, x + 5, y + 5, x + 5, y + 5 );
+
+		var geometry = new THREE.ShapeBufferGeometry( heartShape );
+		var material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
+		var mesh = new THREE.Mesh( geometry, material ) ;
+		scene.add( mesh );
+		</code>
+
+		<h2>Constructor</h2>
+
+
+		<h3>[name]([page:Array shapes], [page:Integer curveSegments])</h3>
+		<div>
+		shapes — [page:Array] of shapes or a single [page:Shape shape].<br />
+		curveSegments - [page:Integer] - Number of segments per shape. Default is 12.
+		</div>
+
+		<h2>Source</h2>
+
+		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
+	</body>
+</html>

+ 15 - 39
docs/api/geometries/ShapeGeometry.html

@@ -12,7 +12,7 @@
 
 		<h1>[name]</h1>
 
-		<div class="desc">Creates a one-sided polygonal geometry from one or more path shapes. Similar to [page:ExtrudeGeometry].</div>
+		<div class="desc">Creates an one-sided polygonal geometry from one or more path shapes.</div>
 
 		<iframe id="scene" src="scenes/geometry-browser.html#ShapeGeometry"></iframe>
 
@@ -37,16 +37,19 @@
 
 
 		<code>
-		var length = 16, width = 12;
+		var x = 0, y = 0;
 
-		var shape = new THREE.Shape();
-		shape.moveTo( 0,0 );
-		shape.lineTo( 0, width );
-		shape.lineTo( length, width );
-		shape.lineTo( length, 0 );
-		shape.lineTo( 0, 0 );
+		var heartShape = new THREE.Shape();
 
-		var geometry = new THREE.ShapeGeometry( shape );
+		heartShape.moveTo( x + 5, y + 5 );
+		heartShape.bezierCurveTo( x + 5, y + 5, x + 4, y, x, y );
+		heartShape.bezierCurveTo( x - 6, y, x - 6, y + 7,x - 6, y + 7 );
+		heartShape.bezierCurveTo( x - 6, y + 11, x - 3, y + 15.4, x + 5, y + 19 );
+		heartShape.bezierCurveTo( x + 12, y + 15.4, x + 16, y + 11, x + 16, y + 7 );
+		heartShape.bezierCurveTo( x + 16, y + 7, x + 16, y, x + 10, y );
+		heartShape.bezierCurveTo( x + 7, y, x + 5, y + 5, x + 5, y + 5 );
+
+		var geometry = new THREE.ShapeGeometry( heartShape );
 		var material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
 		var mesh = new THREE.Mesh( geometry, material ) ;
 		scene.add( mesh );
@@ -55,39 +58,12 @@
 		<h2>Constructor</h2>
 
 
-		<h3>[name]([page:Array shapes], [page:Object options])</h3>
-		<div>
-		shapes — [page:Array] of shapes, or a single [page:Shape shape] <br />
-		options — Optional options [page:Object object]
-		<ul>
-		<li>curveSegments - [page:Integer] - Not used at the moment - defaults to 12</li>
-		<li>material - [page:Integer] - index of the material in a material list</li>
-		<li>UVGenerator - A UV generator, defaults to [page:ExtrudeGeometry]'s WorldUVGenerator</li>
-		</ul>
-		</div>
-
-
-		<h2>Methods</h2>
-
-
-
-		<h3>.addShapeList([page:Array shapes], [page:Object options]) [page:this]</h3>
-		<div>
-		shapes — [page:Array] of [page:Shape shapes] <br />
-		options — See options in constructor
-		</div>
+		<h3>[name]([page:Array shapes], [page:Integer curveSegments])</h3>
 		<div>
-		Adds a list of shapes to the geometry.
+		shapes — [page:Array] of shapes or a single [page:Shape shape].<br />
+		curveSegments - [page:Integer] - Number of segments per shape. Default is 12.
 		</div>
 
-		<h3>[method:null addShape]([page:Shape shape], [page:Object options])</h3>
-		<div>
-		shape — [page:Shape] <br />
-		options — See options in constructor
-		</div>
-		<div>
-		Adds a single shape to the geometry
-		</div>
 
 		<h2>Source</h2>
 

+ 1 - 1
docs/api/loaders/Cache.html

@@ -10,7 +10,7 @@
 	<body>
 		<h1>[name]</h1>
 
-		<div class="desc">A simple caching classe, used internaly by [page:XHRLoader].</div>
+		<div class="desc">A simple caching classe, used internaly by [page:FileLoader].</div>
 
 
 		<h2>Constructor</h2>

+ 0 - 0
docs/api/loaders/XHRLoader.html → docs/api/loaders/FileLoader.html


+ 98 - 56
docs/api/loaders/MTLLoader.html

@@ -1,57 +1,99 @@
-<!DOCTYPE html>
-<html lang="en">
-	<head>
+<!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>
-
-		<div class="desc">A loader for loading an <em>.mtl</em> resource, used internaly by [page:OBJMTLLoader] and [page:UTF8Loader].</div>
-
-
-		<h2>Constructor</h2>
-
-		<h3>[name]( [page:String baseUrl], [page:Object options], [page:String crossOrigin] )</h3>
-		<div>
-		[page:String baseUrl] — The base url from which to find subsequent resources.<br />
-		[page:Object options] — Options passed to the created material (side, wrap, normalizeRGB, ignoreZeroRGBs).<br />
-		[page:String crossOrigin] — The crossOrigin string to implement CORS for loading the url from a different domain that allows CORS.<br />
-		</div>
-		<div>
-		Creates a new [name].
-		</div>
-
-		<h2>Properties</h2>
-
-
-		<h2>Methods</h2>
-
-		<h3>[method:null load]( [page:String url], [page:Function onLoad], [page:Function onProgress], [page:Function onError] )</h3>
-		<div>
-		[page:String url] — required<br />
-		[page:Function onLoad] — Will be called when load completes. The argument will be the loaded [page:MTLLoaderMaterialCreator MTLLoader.MaterialCreator] instance.<br />
-		[page:Function onProgress] — Will be called while load progresses. The argument will be the XmlHttpRequest instance, that contain .[page:Integer total] and .[page:Integer loaded] bytes.<br />
-		[page:Function onError] — Will be called when load errors.<br />
-		</div>
-		<div>
-		Begin loading from url and return the loaded material.
-		</div>
-
-		<h3>[method:MTLLoaderMaterialCreator parse]( [page:String text] )</h3>
-		<div>
-		[page:String text] — The textual <em>mtl</em> structure to parse.
-		</div>
-		<div>
-		Parse a <em>mtl</em> text structure and return a [page:MTLLoaderMaterialCreator] instance.<br />
-		</div>
-
-		<h2>Source</h2>
-
-		[link:https://github.com/mrdoob/three.js/blob/master/examples/js/loaders/[name].js examples/js/loaders/[name].js]
-	</body>
-</html>
+		<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>
+
+		<div class="desc">A loader for loading an <em>.mtl</em> resource, used internaly by [page:OBJMTLLoader] and [page:UTF8Loader].</div>
+
+		<h2>Constructor</h2>
+
+		<h3>[name]( [page:LoadingManager loadingManager] )</h3>
+		<div>
+			[page:LoadingManager loadingManager] — LoadingManager to use. Defaults to [page:DefaultLoadingManager DefaultLoadingManager]<br />
+		</div>
+		<div>
+			Creates a new [name].
+		</div>
+
+		<!-- <h2>Properties</h2> -->
+
+
+		<h2>Methods</h2>
+
+
+		<h3>[method:null load]( [page:String url], [page:Function onLoad], [page:Function onProgress], [page:Function onError] )</h3>
+		<div>
+			[page:String url] — required<br />
+			[page:Function onLoad] — Will be called when load completes. The argument will be the loaded [page:MTLLoaderMaterialCreator MTLLoader.MaterialCreator] instance.<br />
+			[page:Function onProgress] — Will be called while load progresses. The argument will be the XmlHttpRequest instance, that contain .[page:Integer total] and .[page:Integer loaded] bytes.<br />
+			[page:Function onError] — Will be called when load errors.<br />
+		</div>
+		<div>
+			Begin loading from url and return the loaded material.
+		</div>
+
+
+		<h3>[method:null setPath]( [page:String path] )</h3>
+		<div>
+			[page:String path] — required<br />
+		</div>
+		<div>
+			 Set base path for resolving references. If set this path will be prepended to each loaded and found reference.
+		</div>
+
+
+		<h3>[method:null setTexturePath]( [page:String path] )</h3>
+		<div>
+			[page:String path] — required<br />
+		</div>
+		<div>
+			Set base path for resolving texture references. If set this path will be prepended found texture reference. If not set and setPath is, it will be used as texture base path.
+		</div>
+
+
+		<h3>[method:null setCrossOrigin]( [page:boolean useCrossOrigin] )</h3>
+		<div>
+			[page:boolean useCrossOrigin] — required<br />
+		</div>
+		<div>
+			Set to true if you need to load textures from a different origin.
+		</div>
+	
+
+		<h3>[method:null setMaterialOptions]( [page:Object options] )</h3>
+		<div>
+			[page:Object options] — required
+			<ul>
+				<li>side: Which side to apply the material. THREE.FrontSide (default), THREE.BackSide, THREE.DoubleSide</li>
+				<li>wrap: What type of wrapping to apply for textures. THREE.RepeatWrapping (default), THREE.ClampToEdgeWrapping, THREE.MirroredRepeatWrapping</li>
+				<li>normalizeRGB: RGBs need to be normalized to 0-1 from 0-255. Default: false, assumed to be already normalized</li>
+				<li>ignoreZeroRGBs: Ignore values of RGBs (Ka,Kd,Ks) that are all 0's. Default: false</li>
+			</ul>
+		</div>
+		<div>
+			Set of options on how to construct the materials
+		</div>
+	
+
+		<h3>[method:MTLLoaderMaterialCreator parse]( [page:String text] )</h3>
+		<div>
+			[page:String text] — The textual <em>mtl</em> structure to parse.
+		</div>
+		<div>
+			Parse a <em>mtl</em> text structure and return a [page:MTLLoaderMaterialCreator] instance.<br />
+		</div>
+		
+
+		<h2>Source</h2>
+
+		[link:https://github.com/mrdoob/three.js/blob/master/examples/js/loaders/[name].js examples/js/loaders/[name].js]
+	</body>
+</html>

+ 10 - 12
docs/api/materials/MeshStandardMaterial.html

@@ -12,7 +12,7 @@
 
 		<h1>[name]</h1>
 
-		<div class="desc">TODO</div>
+		<div class="desc">A standard physically-based material</div>
 
 		<iframe id="scene" src="scenes/material-browser.html#MeshStandardMaterial"></iframe>
 
@@ -91,28 +91,28 @@
 
 		<h3>[property:Float roughness]</h3>
 		<div>
-		TODO.<br />
+		How rough the material appears. 0.0 means a smooth mirror reflection, 1.0 means fully diffuse.<br />
 		</div>
 
 		<h3>[property:Float metalness]</h3>
 		<div>
-		TODO<br />
+		How much the material is like a metal. Non-metallic materials such as wood or stone use 0.0, metallic use 1.0, nothing in between. A value between 0.0 and 1.0 could be used for a rusty metal look.<br />
 		</div>
 
 		<h3>[property:Texture map]</h3>
 		<div>Set color texture map. Default is null. The texture map color is modulated by the diffuse color.</div>
 
 		<h3>[property:Texture lightMap]</h3>
-		<div>Set light map. Default is null. The lightMap requires a second set of UVs.</div>
+		<div>Set light map, a texture that contains pre-baked diffuse lighting added to the surface. Default is null. The lightMap requires a second set of UVs.</div>
 
 		<h3>[property:Float lightMapIntensity]</h3>
-		<div>TODO</div>
+		<div>A scale factor for the light map's effect, higher being brighter.</div>
 
 		<h3>[property:Texture aoMap]</h3>
-		<div>Set ambient occlusion map. Default is null. The aoMap requires a second set of UVs.</div>
+		<div>Set ambient occlusion map, a texture that contains pre-baked darkening due to crevices on the surface. Default is null. The aoMap requires a second set of UVs.</div>
 
 		<h3>[property:Float aoMapIntensity]</h3>
-		<div>TODO</div>
+		<div>A scale factor for the ambient occlusion map's effect, higher being darker and more pronounced.</div>
 
 		<h3>[property:Color emissive]</h3>
 		<div>
@@ -165,13 +165,11 @@
 		</div>
 
 		<h3>[property:Texture roughnessMap]</h3>
-		<div>
-			TODO.
+		<div>The red channel of this texture is used to alter the roughness of the material.
 		</div>
 
 		<h3>[property:Texture metalnessMap]</h3>
-		<div>
-			TODO.
+		<div>The red channel of this texture is used to alter the metalness of the material.
 		</div>
 
 		<h3>[property:Texture alphaMap]</h3>
@@ -182,7 +180,7 @@
 		<div>Set env map. Default is null.</div>
 
 		<h3>[property:Float envMapIntensity]</h3>
-		<div>TODO</div>
+		<div>Scales the effect of the environment map by multiplying its color.</div>
 
 		<h3>[property:Float refractionRatio]</h3>
 		<div>The index of refraction for an environment map using [page:Textures THREE.CubeRefractionMapping]. Default is *0.98*.</div>

+ 2 - 2
docs/api/math/Box2.html

@@ -86,7 +86,7 @@
 		Sets the upper and lower bounds of this box to include all of the points in *points*.
 		</div>
 
-		<h3>[method:Vector2 size]( [page:Vector2 optionalTarget] ) [page:Box2 this]</h3>
+		<h3>[method:Vector2 getSize]( [page:Vector2 optionalTarget] ) [page:Box2 this]</h3>
 		<div>
 		optionalTarget -- If specified, the result will be copied here.
 		</div>
@@ -194,7 +194,7 @@
 		Makes this box empty.
 		</div>
 
-		<h3>[method:Vector2 center]( [page:Vector2 optionalTarget] ) [page:Box2 this]</h3>
+		<h3>[method:Vector2 getCenter]( [page:Vector2 optionalTarget] ) [page:Box2 this]</h3>
 		<div>
 		optionalTarget -- If specified, the result will be copied here.
 		</div>

+ 2 - 2
docs/api/math/Box3.html

@@ -112,7 +112,7 @@
 
 
 
-		<h3>[method:Vector3 size]( [page:Vector3 optionalTarget] ) [page:Box3 this]</h3>
+		<h3>[method:Vector3 getSize]( [page:Vector3 optionalTarget] ) [page:Box3 this]</h3>
 		<div>
 		optionalTarget -- If specified, the result will be copied here.
 		</div>
@@ -237,7 +237,7 @@
 		Makes this box empty.
 		</div>
 
-		<h3>[method:Vector3 center]( [page:Vector3 optionalTarget] ) [page:Box3 this]</h3>
+		<h3>[method:Vector3 getCenter]( [page:Vector3 optionalTarget] ) [page:Box3 this]</h3>
 		<div>
 		optionalTarget -- If specified, the result will be copied here.
 		</div>

+ 1 - 1
docs/api/math/Line3.html

@@ -95,7 +95,7 @@
 		Return a vector at a certain position along the line. When t = 0, it returns the start vector, and when t=1 it returns the end vector.
 		</div>
 
-		<h3>[method:Vector3 center]( [page:Vector3 optionalTarget] )</h3>
+		<h3>[method:Vector3 getCenter]( [page:Vector3 optionalTarget] )</h3>
 		<div>
 		optionalTarget -- [page:Vector3] Optional target to set the result.
 		</div>

+ 70 - 0
docs/api/math/Spherical.html

@@ -0,0 +1,70 @@
+<!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>
+
+		<div class="desc">A point's spherical coordinates.</div>
+
+
+		<h2>Constructor</h2>
+
+
+		<h3>[name]( [page:Float radius], [page:Float phi], [page:Float theta] )</h3>
+		<div>
+		radius -- [page:Float] the radius<br />
+		phi -- [page:Float] polar angle from the y (up) axis<br />
+		theta -- [page:Float] equator angle around the y (up) axis
+		</div>
+		<div>
+		The poles (phi) are at the positive and negative y axis. The equator (theta) starts at positive z.
+		</div>
+
+
+		<h2>Properties</h2>
+
+		<h3>[property:Float radius]</h3>
+
+		<h3>[property:Float phi]</h3>
+
+		<h3>[property:Float theta]</h3>
+
+
+		<h2>Methods</h2>
+
+		<h3>[method:Spherical set]( [page:Float radius], [page:Float phi], [page:Float theta] ) [page:Spherical this]</h3>
+		<div>
+		Sets values of this spherical's component coordinates.
+		</div>
+
+		<h3>[method:Spherical copy]( [page:Spherical s] ) [page:Spherical this]</h3>
+		<div>
+		Copies value of *s* to this spherical.
+		</div>
+
+		<h3>[method:Spherical clone]() [page:Spherical this]</h3>
+		<div>
+		Clones this spherical.
+		</div>
+
+		<h3>[method:Spherical makeSafe]() [page:Spherical this]</h3>
+		<div>
+		Restricts the polar angle phi to be between 0.000001 and pi - 0.000001.
+		</div>
+
+		<h3>[method:Spherical setFromVector3]( [page:Vector3 v] ) [page:Spherical this]</h3>
+		<div>
+		Sets this object from the vector *v*.
+		</div>
+
+		<h2>Source</h2>
+
+		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
+	</body>
+</html>

+ 5 - 0
docs/api/math/Vector3.html

@@ -197,6 +197,11 @@
 		Sets this vector extracting scale from matrix transform.
 		</div>
 
+		<h3>[method:Vector3 setFromSpherical]( [page:Spherical s] ) [page:Vector3 this]</h3>
+		<div>
+		Sets this vector from the spherical coordinates *s*.
+		</div>
+
 		<h3>[method:Vector3 clamp]( [page:Vector3 min], [page:Vector3 max] ) [page:Vector3 this]</h3>
 		<div>
 		min -- [page:Vector3] <br />

+ 5 - 5
docs/api/renderers/WebGLRenderer.html

@@ -103,7 +103,7 @@
 		<h3>[property:Integer shadowMap.type]</h3>
 
 		<div>Defines shadow map type (unfiltered, percentage close filtering, percentage close filtering with bilinear filtering in shader)</div>
-		<div>Options are THREE.BasicShadowMap, THREE.PCFShadowMap, THREE.PCFSoftShadowMap. Default is THREE.PCFShadowMap.</div>
+		<div>Options are THREE.BasicShadowMap, THREE.PCFShadowMap (default), THREE.PCFSoftShadowMap. See [page:ShadowingTypes ShadowingTypes constants] for details.</div>
 
 		<h3>[property:Boolean shadowMap.renderReverseSided]</h3>
 
@@ -240,11 +240,11 @@
 
 		<h3>[method:null setFaceCulling]( cullFace, frontFace )</h3>
 		<div>
-		[page:String cullFace] —- "back", "front", "front_and_back", or false.<br />
-		[page:String frontFace] —- "ccw" or "cw<br />
+		See [page:GLState GLState constants] for all possible values for [page:String cullFace] and [page:String frontFace].<br />
+		Used for setting the gl.frontFace and gl.cullFace states in the GPU, thus enabling/disabling face culling when rendering.<br />
+		If cullFace is set to THREE.[page:String CullFaceNone], culling will be disabled.<br />
 		</div>
-		<div>Used for setting the gl frontFace, cullFace states in the GPU, thus enabling/disabling face culling when rendering.</div>
-		<div>If cullFace is false, culling will be disabled.</div>
+
 
 
 		<h3>[method:null setTexture]( [page:Texture texture], [page:number slot] )</h3>

+ 14 - 6
docs/list.js

@@ -63,6 +63,7 @@ var list = {
 			[ "PolyhedronGeometry", "api/geometries/PolyhedronGeometry" ],
 			[ "RingBufferGeometry", "api/geometries/RingBufferGeometry" ],
 			[ "RingGeometry", "api/geometries/RingGeometry" ],
+			[ "ShapeBufferGeometry", "api/geometries/ShapeBufferGeometry" ],
 			[ "ShapeGeometry", "api/geometries/ShapeGeometry" ],
 			[ "SphereBufferGeometry", "api/geometries/SphereBufferGeometry" ],
 			[ "SphereGeometry", "api/geometries/SphereGeometry" ],
@@ -96,6 +97,7 @@ var list = {
 			[ "BufferGeometryLoader", "api/loaders/BufferGeometryLoader" ],
 			[ "Cache", "api/loaders/Cache" ],
 			[ "ColladaLoader", "api/loaders/ColladaLoader" ],
+			[ "FileLoader", "api/loaders/FileLoader" ],
 			[ "GLTFLoader", "api/loaders/GLTFLoader" ],
 			[ "ImageLoader", "api/loaders/ImageLoader" ],
 			[ "JSONLoader", "api/loaders/JSONLoader" ],
@@ -108,8 +110,7 @@ var list = {
 			[ "PDBLoader", "api/loaders/PDBLoader" ],
 			[ "SVGLoader", "api/loaders/SVGLoader" ],
 			[ "TextureLoader", "api/loaders/TextureLoader" ],
-			[ "TGALoader", "api/loaders/TGALoader" ],
-			[ "XHRLoader", "api/loaders/XHRLoader" ]
+			[ "TGALoader", "api/loaders/TGALoader" ]
 		],
 
 		"Materials": [
@@ -143,6 +144,7 @@ var list = {
 			[ "Quaternion", "api/math/Quaternion" ],
 			[ "Ray", "api/math/Ray" ],
 			[ "Sphere", "api/math/Sphere" ],
+			[ "Spherical", "api/math/Spherical" ],
 			[ "Spline", "api/math/Spline" ],
 			[ "Triangle", "api/math/Triangle" ],
 			[ "Vector2", "api/math/Vector2" ],
@@ -201,14 +203,20 @@ var list = {
 			[ "Texture", "api/textures/Texture" ]
 		],
 
+		"Animation": [
+			[ "AnimationAction", "api/animation/AnimationAction" ],
+			[ "AnimationClip", "api/animation/AnimationClip" ],
+			[ "AnimationMixer", "api/animation/AnimationMixer" ]
+		],
+
 		"Extras": [
 			[ "SceneUtils", "api/extras/SceneUtils" ]
 		],
 
-		"Extras / Animation": [
-			[ "Animation", "api/extras/animation/Animation" ],
-			[ "AnimationHandler", "api/extras/animation/AnimationHandler" ],
-			[ "KeyFrameAnimation", "api/extras/animation/KeyFrameAnimation" ]
+		"Extras / Collada Animation": [
+			[ "Animation", "api/extras/collada-animation/Animation" ],
+			[ "AnimationHandler", "api/extras/collada-animation/AnimationHandler" ],
+			[ "KeyFrameAnimation", "api/extras/collada-animation/KeyFrameAnimation" ]
 		],
 
 		"Extras / Core": [

+ 40 - 9
docs/scenes/js/geometry.js

@@ -111,6 +111,20 @@ var CustomSinCurve = THREE.Curve.create(
 
 );
 
+// heart shape
+
+var x = 0, y = 0;
+
+var heartShape = new THREE.Shape();
+
+heartShape.moveTo( x + 5, y + 5 );
+heartShape.bezierCurveTo( x + 5, y + 5, x + 4, y, x, y );
+heartShape.bezierCurveTo( x - 6, y, x - 6, y + 7,x - 6, y + 7 );
+heartShape.bezierCurveTo( x - 6, y + 11, x - 3, y + 15.4, x + 5, y + 19 );
+heartShape.bezierCurveTo( x + 12, y + 15.4, x + 16, y + 11, x + 16, y + 7 );
+heartShape.bezierCurveTo( x + 16, y + 7, x + 16, y, x + 10, y );
+heartShape.bezierCurveTo( x + 7, y, x + 5, y + 5, x + 5, y + 5 );
+
 var guis = {
 
 	BoxBufferGeometry : function( mesh ) {
@@ -1206,24 +1220,41 @@ var guis = {
 
 	ShapeGeometry: function( mesh ) {
 
-		var length = 16, width = 12;
-
-		var shape = new THREE.Shape();
-		shape.moveTo( 0,0 );
-		shape.lineTo( 0, width );
-		shape.lineTo( length, width );
-		shape.lineTo( length, 0 );
-		shape.lineTo( 0, 0 );
+		var data = {
+			segments : 12
+		};
 
 		function generateGeometry() {
 
 			updateGroupGeometry( mesh,
-				new THREE.ShapeGeometry( shape )
+				new THREE.ShapeGeometry( heartShape, data.segments )
 			);
 
 		}
 
 		var folder = gui.addFolder( 'THREE.ShapeGeometry' );
+		folder.add( data, 'segments', 1, 100 ).step( 1 ).onChange( generateGeometry );
+
+		generateGeometry();
+
+	},
+
+	ShapeBufferGeometry: function( mesh ) {
+
+		var data = {
+			segments : 12
+		};
+
+		function generateGeometry() {
+
+			updateGroupGeometry( mesh,
+				new THREE.ShapeBufferGeometry( heartShape, data.segments )
+			);
+
+		}
+
+		var folder = gui.addFolder( 'THREE.ShapeBufferGeometry' );
+		folder.add( data, 'segments', 1, 100 ).step( 1 ).onChange( generateGeometry );
 
 		generateGeometry();
 

+ 1 - 1
editor/index.html

@@ -365,7 +365,7 @@
 
 				if ( confirm( 'Any unsaved data will be lost. Are you sure?' ) ) {
 
-					var loader = new THREE.XHRLoader();
+					var loader = new THREE.FileLoader();
 					loader.crossOrigin = '';
 					loader.load( file, function ( text ) {
 

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

@@ -25,7 +25,7 @@ Menubar.Examples = function ( editor ) {
 		{ title: 'Pong', file: 'pong.app.json' }
 	];
 
-	var loader = new THREE.XHRLoader();
+	var loader = new THREE.FileLoader();
 
 	for ( var i = 0; i < items.length; i ++ ) {
 

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

@@ -233,7 +233,7 @@ Menubar.File = function ( editor ) {
 
 		} );
 
-		var loader = new THREE.XHRLoader( manager );
+		var loader = new THREE.FileLoader( manager );
 		loader.load( 'js/libs/app/index.html', function ( content ) {
 
 			var includes = [];

+ 1 - 1
editor/js/libs/app/index.html

@@ -33,7 +33,7 @@
 		<!-- includes -->
 		<script>
 
-			var loader = new THREE.XHRLoader();
+			var loader = new THREE.FileLoader();
 			loader.load( 'app.json', function ( text ) {
 
 				var json = JSON.parse( text );

+ 7 - 7
editor/js/libs/tern-threejs/threejs.js

@@ -970,7 +970,7 @@
       "!doc": "A class containing useful utility functions for scene manipulation."
     },
     "Animation": {
-      "!url": "http://threejs.org/docs/#Reference/extras/animation/Animation",
+      "!url": "http://threejs.org/docs/#Reference/extras/collada-animation/Animation",
       "prototype": {
         "root": {
           "!type": "Object3d",
@@ -1037,7 +1037,7 @@
       "!type": "fn(root: Object3d, name: string)"
     },
     "AnimationHandler": {
-      "!url": "http://threejs.org/docs/#Reference/extras/animation/AnimationHandler",
+      "!url": "http://threejs.org/docs/#Reference/extras/collada-animation/AnimationHandler",
       "prototype": {
         "CATMULLROM": {
           "!type": "number",
@@ -1080,7 +1080,7 @@
       "!type": "fn()"
     },
     "AnimationMorphTarget": {
-      "!url": "http://threejs.org/docs/#Reference/extras/animation/AnimationMorphTarget",
+      "!url": "http://threejs.org/docs/#Reference/extras/collada-animation/AnimationMorphTarget",
       "prototype": {
         "root": {
           "!type": "todo",
@@ -1139,7 +1139,7 @@
       "!type": "fn(root: todo, data: todo)"
     },
     "KeyFrameAnimation": {
-      "!url": "http://threejs.org/docs/#Reference/extras/animation/KeyFrameAnimation",
+      "!url": "http://threejs.org/docs/#Reference/extras/collada-animation/KeyFrameAnimation",
       "prototype": {
         "root": {
           "!type": "todo",
@@ -2207,7 +2207,7 @@
           "!doc": "Remove all values from the cache."
         }
       },
-      "!doc": "A simple caching classe, used internaly by [page:XHRLoader].",
+      "!doc": "A simple caching classe, used internaly by [page:FileLoader].",
       "!type": "fn()"
     },
     "ColladaLoader": {
@@ -2513,8 +2513,8 @@
       "!doc": "Class for loading a [page:Texture texture].",
       "!type": "fn(manager: +THREE.LoadingManager)"
     },
-    "XHRLoader": {
-      "!url": "http://threejs.org/docs/#Reference/loaders/XHRLoader",
+    "FileLoader": {
+      "!url": "http://threejs.org/docs/#Reference/loaders/FileLoader",
       "prototype": {
         "cache": {
           "!type": "+THREE.Cache",

+ 3 - 0
examples/files.js

@@ -262,6 +262,9 @@ var files = {
 	"webgl deferred": [
 		"webgldeferred_animation"
 	],
+	"webgl2": [
+		"webgl2_sandbox"
+	],
 	"webvr": [
 		"webvr_cubes",
 		"webvr_panorama",

+ 11 - 3
examples/js/animation/CCDIKSolver.js

@@ -8,6 +8,7 @@
  *
  * ik parameter example
  *
+ * // target, effector, index in links are bone index in skeleton.
  * ik = {
  *	target: 1,
  *	effector: 2,
@@ -71,9 +72,6 @@ THREE.CCDIKSolver.prototype = {
 
 					var angle = targetVec.dot( effectorVec );
 
-					// TODO: continue (or break) the loop for the performance
-					//       if no longer needs to rotate (angle > 1.0-1e-5 ?)
-
 					if ( angle > 1.0 ) {
 
 						angle = 1.0;
@@ -86,6 +84,14 @@ THREE.CCDIKSolver.prototype = {
 
 					angle = math.acos( angle );
 
+					// skip if changing angle is too small to prevent vibration of bone
+					// Refer to http://www20.atpages.jp/katwat/three.js_r58/examples/mytest37/mmd.three.js
+					if ( angle < 1e-5 ) {
+
+						continue;
+
+					}
+
 					if ( ik.minAngle !== undefined && angle < ik.minAngle ) {
 
 						angle = ik.minAngle;
@@ -129,6 +135,8 @@ THREE.CCDIKSolver.prototype = {
 
 			}
 
+			this.mesh.updateMatrixWorld( true );
+
 		}
 
 	}

+ 237 - 25
examples/js/animation/MMDPhysics.js

@@ -4,37 +4,36 @@
  * Dependencies
  *  - Ammo.js https://github.com/kripken/ammo.js
  *
- *
  * MMD specific Physics class.
  *
  * See THREE.MMDLoader for the passed parameter list of RigidBody/Constraint.
  *
+ * Requirement:
+ *  - don't change object's scale from (1,1,1) after setting physics to object
  *
  * TODO
+ *  - optimize for the performance
  *  - use Physijs http://chandlerprall.github.io/Physijs/
  *    and improve the performance by making use of Web worker.
  *  - if possible, make this class being non-MMD specific.
+ *  - object scale change support
  */
 
 THREE.MMDPhysics = function ( mesh, params ) {
 
+	if ( params === undefined ) params = {};
+
 	this.mesh = mesh;
-	this.helper = new THREE.MMDPhysics.PhysicsHelper();
+	this.helper = new THREE.MMDPhysics.ResourceHelper();
 
-	/*
-	 * Note: Default 1 / 65 unit step is a workaround that
-	 *       some bones go wrong at near 60fps if it's 1 / 60.
-	 *       Be careful that small unitStep could cause heavy
-	 *       physics calculation.
-	 */
-	this.unitStep = ( params && params.unitStep ) ? params.unitStep : 1 / 65;
-	this.maxStepNum = ( params && params.maxStepNum ) ? params.maxStepNum : 3;
+	this.unitStep = ( params.unitStep !== undefined ) ? params.unitStep : 1 / 60;
+	this.maxStepNum = ( params.maxStepNum !== undefined ) ? params.maxStepNum : 3;
 
 	this.world = null;
 	this.bodies = [];
 	this.constraints = [];
 
-	this.init();
+	this.init( mesh );
 
 };
 
@@ -42,11 +41,42 @@ THREE.MMDPhysics.prototype = {
 
 	constructor: THREE.MMDPhysics,
 
-	init: function () {
+	init: function ( mesh ) {
+
+		var parent = mesh.parent;
+
+		if ( parent !== null ) {
+
+			parent.remove( mesh );
+
+		}
+
+		var currentPosition = mesh.position.clone();
+		var currentRotation = mesh.rotation.clone();
+		var currentScale = mesh.scale.clone();
+
+		mesh.position.set( 0, 0, 0 );
+		mesh.rotation.set( 0, 0, 0 );
+		mesh.scale.set( 1, 1, 1 );
+
+		mesh.updateMatrixWorld( true );
 
 		this.initWorld();
 		this.initRigidBodies();
 		this.initConstraints();
+
+		if ( parent !== null ) {
+
+			parent.add( mesh );
+
+		}
+
+		mesh.position.copy( currentPosition );
+		mesh.rotation.copy( currentRotation );
+		mesh.scale.copy( currentScale );
+
+		mesh.updateMatrixWorld( true );
+
 		this.reset();
 
 	},
@@ -58,7 +88,7 @@ THREE.MMDPhysics.prototype = {
 		var cache = new Ammo.btDbvtBroadphase();
 		var solver = new Ammo.btSequentialImpulseConstraintSolver();
 		var world = new Ammo.btDiscreteDynamicsWorld( dispatcher, cache, solver, config );
-		world.setGravity( new Ammo.btVector3( 0, -10 * 10, 0 ) );
+		world.setGravity( new Ammo.btVector3( 0, -9.8 * 10, 0 ) );
 		this.world = world;
 
 	},
@@ -99,6 +129,13 @@ THREE.MMDPhysics.prototype = {
 		var stepTime = delta;
 		var maxStepNum = ( ( delta / unitStep ) | 0 ) + 1;
 
+		if ( stepTime < unitStep ) {
+
+			stepTime = unitStep;
+			maxStepNum = 1;
+
+		}
+
 		if ( maxStepNum > this.maxStepNum ) {
 
 			maxStepNum = this.maxStepNum;
@@ -145,7 +182,7 @@ THREE.MMDPhysics.prototype = {
 
 		for ( var i = 0; i < cycles; i++ ) {
 
-			this.update( 1 );
+			this.update( 1 / 60 );
 
 		}
 
@@ -162,12 +199,13 @@ THREE.MMDPhysics.prototype = {
  *
  * 2. provide simple Ammo object operations.
  */
-THREE.MMDPhysics.PhysicsHelper = function () {
+THREE.MMDPhysics.ResourceHelper = function () {
 
 	// for Three.js
 	this.threeVector3s = [];
 	this.threeMatrix4s = [];
 	this.threeQuaternions = [];
+	this.threeEulers = [];
 
 	// for Ammo.js
 	this.transforms = [];
@@ -176,7 +214,7 @@ THREE.MMDPhysics.PhysicsHelper = function () {
 
 };
 
-THREE.MMDPhysics.PhysicsHelper.prototype = {
+THREE.MMDPhysics.ResourceHelper.prototype = {
 
 	allocThreeVector3: function () {
 
@@ -214,6 +252,18 @@ THREE.MMDPhysics.PhysicsHelper.prototype = {
 
 	},
 
+	allocThreeEuler: function () {
+
+		return ( this.threeEulers.length > 0 ) ? this.threeEulers.pop() : new THREE.Euler();
+
+	},
+
+	freeThreeEuler: function ( e ) {
+
+		this.threeEulers.push( e );
+
+	},
+
 	allocTransform: function () {
 
 		return ( this.transforms.length > 0 ) ? this.transforms.pop() : new Ammo.btTransform();
@@ -314,7 +364,13 @@ THREE.MMDPhysics.PhysicsHelper.prototype = {
 
 	setBasisFromArray3: function ( t, a ) {
 
-		t.getBasis().setEulerZYX( a[ 0 ], a[ 1 ], a[ 2 ] );
+		var thQ = this.allocThreeQuaternion();
+		var thE = this.allocThreeEuler();
+		thE.set( a[ 0 ], a[ 1 ], a[ 2 ] );
+		this.setBasisFromArray4( t, thQ.setFromEuler( thE ).toArray() );
+
+		this.freeThreeEuler( thE );
+		this.freeThreeQuaternion( thQ );
 
 	},
 
@@ -598,7 +654,7 @@ THREE.MMDPhysics.RigidBody.prototype = {
 
 	init: function () {
 
-		function generateShape ( p ) {
+		function generateShape( p ) {
 
 			switch( p.shapeType ) {
 
@@ -648,13 +704,19 @@ THREE.MMDPhysics.RigidBody.prototype = {
 
 		var info = new Ammo.btRigidBodyConstructionInfo( weight, state, shape, localInertia );
 		info.set_m_friction( params.friction );
-		info.set_m_restitution( params.restriction );
+		info.set_m_restitution( params.restitution );
 
 		var body = new Ammo.btRigidBody( info );
 
 		if ( params.type === 0 ) {
 
 			body.setCollisionFlags( body.getCollisionFlags() | 2 );
+
+			/*
+			 * It'd be better to comment out this line though in general I should call this method
+			 * because I'm not sure why but physics will be more like MMD's
+			 * if I comment out.
+			 */
 			body.setActivationState( 4 );
 
 		}
@@ -695,12 +757,6 @@ THREE.MMDPhysics.RigidBody.prototype = {
 
 		}
 
-		if ( this.params.type === 2 ) {
-
-			this.setPositionFromBone();
-
-		}
-
 	},
 
 	updateBone: function () {
@@ -721,6 +777,12 @@ THREE.MMDPhysics.RigidBody.prototype = {
 
 		this.bone.updateMatrixWorld( true );
 
+		if ( this.params.type === 2 ) {
+
+			this.setPositionFromBone();
+
+		}
+
 	},
 
 	getBoneTransform: function () {
@@ -932,6 +994,23 @@ THREE.MMDPhysics.Constraint.prototype = {
 
 		}
 
+		/*
+		 * Currently(10/31/2016) official ammo.js doesn't support
+		 * btGeneric6DofSpringConstraint.setParam method.
+		 * You need custom ammo.js (add the method into idl) if you wanna use.
+		 * By setting this parameter, physics will be more like MMD's
+		 */
+		if ( constraint.setParam !== undefined ) {
+
+			for ( var i = 0; i < 6; i ++ ) {
+
+				// this parameter is from http://www20.atpages.jp/katwat/three.js_r58/examples/mytest37/mmd.three.js
+				constraint.setParam( 2, 0.475, i );
+
+			}
+
+		}
+
 		this.world.addConstraint( constraint, true );
 		this.constraint = constraint;
 
@@ -950,3 +1029,136 @@ THREE.MMDPhysics.Constraint.prototype = {
 	}
 
 };
+
+
+/*
+ * This helper displays rigid bodies of mesh for debug.
+ * It should be under Scene because it just sets world position/roration to meshes
+ * for simplicity.
+ */
+THREE.MMDPhysicsHelper = function ( mesh ) {
+
+	if ( mesh.physics === undefined || mesh.geometry.rigidBodies === undefined ) {
+
+		throw 'THREE.MMDPhysicsHelper requires physics in mesh and rigidBodies in mesh.geometry.';
+
+	}
+
+	THREE.Object3D.call( this );
+
+	this.mesh = mesh;
+
+	this._init();
+
+};
+
+THREE.MMDPhysicsHelper.prototype = Object.create( THREE.Object3D.prototype );
+THREE.MMDPhysicsHelper.prototype.constructor = THREE.MMDPhysicsHelper;
+
+THREE.MMDPhysicsHelper.prototype._init = function () {
+
+	function createGeometry( param ) {
+
+		switch ( param.shapeType ) {
+
+			case 0:
+				return new THREE.SphereBufferGeometry( param.width, 16, 8 );
+
+			case 1:
+				return new THREE.BoxBufferGeometry( param.width * 2, param.height * 2, param.depth * 2, 8, 8, 8);
+
+			case 2:
+				return new createCapsuleGeometry( param.width, param.height, 16, 8 );
+
+			default:
+				return null;
+
+		}
+
+	}
+
+	// copy from http://www20.atpages.jp/katwat/three.js_r58/examples/mytest37/mytest37.js?ver=20160815
+	function createCapsuleGeometry( radius, cylinderHeight, segmentsRadius, segmentsHeight ) {
+
+		var geometry = new THREE.CylinderBufferGeometry( radius, radius, cylinderHeight, segmentsRadius, segmentsHeight, true );
+		var upperSphere = new THREE.Mesh( new THREE.SphereBufferGeometry( radius, segmentsRadius, segmentsHeight, 0, Math.PI * 2, 0, Math.PI / 2 ) );
+		var lowerSphere = new THREE.Mesh( new THREE.SphereBufferGeometry( radius, segmentsRadius, segmentsHeight, 0, Math.PI * 2, Math.PI / 2, Math.PI / 2 ) );
+
+		upperSphere.position.set( 0, cylinderHeight / 2, 0 );
+		lowerSphere.position.set( 0, -cylinderHeight / 2, 0 );
+
+		upperSphere.updateMatrix();
+		lowerSphere.updateMatrix();
+
+		geometry.merge( upperSphere.geometry, upperSphere.matrix );
+		geometry.merge( lowerSphere.geometry, lowerSphere.matrix );
+
+		return geometry;
+
+	}
+
+
+	function createMaterial( param ) {
+
+		var color;
+
+		switch ( param.type ) {
+
+			case 0:
+				color = 0xff8888;
+				break;
+
+			case 1:
+				color = 0x88ff88;
+				break;
+
+			case 2:
+				color = 0x8888ff;
+				break;
+
+			default:
+				color = 0x000000;
+				break;
+
+		}
+
+		return new THREE.MeshBasicMaterial( {
+			color: new THREE.Color( color ),
+			wireframe: true,
+			depthTest: false,
+			depthWrite: false,
+			opacity: 0.25,
+			transparent: true
+		} );
+
+	}
+
+	for ( var i = 0, il = this.mesh.geometry.rigidBodies.length; i < il; i ++ ) {
+
+		var param = this.mesh.geometry.rigidBodies[ i ];
+
+		var mesh = new THREE.Mesh( createGeometry( param ), createMaterial( param ) );
+		this.add( mesh );
+
+	}
+
+};
+
+THREE.MMDPhysicsHelper.prototype.update = function () {
+
+	for ( var i = 0, il = this.mesh.geometry.rigidBodies.length; i < il; i ++ ) {
+
+		var body = this.mesh.physics.bodies[ i ].body;
+		var mesh = this.children[ i ];
+
+		var tr = body.getCenterOfMassTransform();
+
+		var o = tr.getOrigin();
+		var r = tr.getRotation();
+
+		mesh.position.set( o.x(), o.y(), o.z() );
+		mesh.quaternion.set( r.x(), r.y(), r.z(), r.w() );
+
+	}
+
+};

+ 81 - 20
examples/js/effects/OutlineEffect.js

@@ -10,15 +10,17 @@
  * new THREE.OutlineEffect( renderer, {
  * 	defaultThickNess: 0.01,
  * 	defaultColor: new THREE.Color( 0x888888 ),
- * 	defaultAlpha: 0.8
+ * 	defaultAlpha: 0.8,
+ * 	defaultKeepAlive: true // keeps outline material in cache even if material is removed from scene
  * } );
  *
  * // How to set outline parameters for each material
  * material.outlineParameters = {
- * 	thickNess: 0.01,
- * 	color: new THREE.Color( 0x888888 ),
- * 	alpha: 0.8,
- * 	visible: true
+ * 	thickNess: 0.01,                     // this paremeter won't work for MultiMaterial
+ * 	color: new THREE.Color( 0x888888 ),  // this paremeter won't work for MultiMaterial
+ * 	alpha: 0.8,                          // this paremeter won't work for MultiMaterial
+ * 	visible: true,
+ * 	keepAlive: true  // this paremeter won't work for Material in materials of MultiMaterial
  * };
  *
  * TODO
@@ -37,6 +39,12 @@ THREE.OutlineEffect = function ( renderer, parameters ) {
 	var defaultThickness = parameters.defaultThickness !== undefined ? parameters.defaultThickness : 0.003;
 	var defaultColor = parameters.defaultColor !== undefined ? parameters.defaultColor : new THREE.Color( 0x000000 );
 	var defaultAlpha = parameters.defaultAlpha !== undefined ? parameters.defaultAlpha : 1.0;
+	var defaultKeepAlive = parameters.defaultKeepAlive !== undefined ? parameters.defaultKeepAlive : false;
+
+	var cache = {};
+	var removeThresholdCount = 60;
+
+	//this.cache = cache;  // for debug
 
 	var invisibleMaterial = new THREE.ShaderMaterial( { visible: false } );
 
@@ -113,7 +121,7 @@ THREE.OutlineEffect = function ( renderer, parameters ) {
 
 	].join( "\n" );
 
-	function createMaterial ( originalMaterial ) {
+	function createMaterial( originalMaterial ) {
 
 		var shaderID = shaderIDs[ originalMaterial.type ];
 		var originalUniforms, originalVertexShader;
@@ -168,7 +176,7 @@ THREE.OutlineEffect = function ( renderer, parameters ) {
 
 	}
 
-	function createMultiMaterial ( originalMaterial ) {
+	function createMultiMaterial( originalMaterial ) {
 
 		var materials = [];
 
@@ -182,33 +190,44 @@ THREE.OutlineEffect = function ( renderer, parameters ) {
 
 	}
 
-	function setOutlineMaterial ( object ) {
+	function setOutlineMaterial( object ) {
 
 		if ( object.material === undefined ) return;
 
-		object.userData.originalMaterial = object.material;
+		var data = cache[ object.material.uuid ];
+
+		if ( data === undefined ) {
 
-		if ( object.userData.outlineMaterial === undefined ) {
+			data = {
+				material: object.material.type === 'MultiMaterial' ? createMultiMaterial( object.material ) : createMaterial( object.material ),
+				used: true,
+				keepAlive: defaultKeepAlive,
+				count: 0
+			};
 
-			object.userData.outlineMaterial = object.material.type === 'MultiMaterial' ? createMultiMaterial( object.material ) : createMaterial( object.material );
+			cache[ object.material.uuid ] = data;
 
 		}
 
-		if ( object.userData.outlineMaterial.type === 'MultiMaterial' ) {
+		var outlineMaterial = data.material;
+		data.used = true;
 
-			updateOutlineMultiMaterial( object.userData.outlineMaterial, object.userData.originalMaterial );
+		if ( outlineMaterial.type === 'MultiMaterial' ) {
+
+			updateOutlineMultiMaterial( outlineMaterial, object.material );
 
 		} else {
 
-			updateOutlineMaterial( object.userData.outlineMaterial, object.userData.originalMaterial );
+			updateOutlineMaterial( outlineMaterial, object.material );
 
 		}
 
-		object.material = object.userData.outlineMaterial;
+		object.userData.originalMaterial = object.material;
+		object.material = outlineMaterial;
 
 	}
 
-	function updateOutlineMaterial ( material, originalMaterial ) {
+	function updateOutlineMaterial( material, originalMaterial ) {
 
 		if ( material === invisibleMaterial ) return;
 
@@ -227,14 +246,16 @@ THREE.OutlineEffect = function ( renderer, parameters ) {
 			if ( outlineParameters.color !== undefined ) material.uniforms.outlineColor.value.copy( outlineParameters.color );
 			if ( outlineParameters.alpha !== undefined ) material.uniforms.outlineAlpha.value = outlineParameters.alpha;
 			if ( outlineParameters.visible !== undefined ) material.visible = outlineParameters.visible;
+			// cache[ originalMaterial.uuid ] is undefined if originalMaterial is in materials of MultiMaterial
+			if ( outlineParameters.keepAlive !== undefined && cache[ originalMaterial.uuid ] !== undefined ) cache[ originalMaterial.uuid ].keepAlive = outlineParameters.keepAlive;
 
 		}
 
-		if ( material.uniforms.outlineAlpha.value < 1.0 ) material.transparent = true;
+		material.transparent = ( material.uniforms.outlineAlpha.value < 1.0 ) ? true : false;
 
 	}
 
-	function updateOutlineMultiMaterial ( material, originalMaterial ) {
+	function updateOutlineMultiMaterial( material, originalMaterial ) {
 
 		var outlineParameters = originalMaterial.outlineParameters;
 
@@ -243,6 +264,7 @@ THREE.OutlineEffect = function ( renderer, parameters ) {
 		if ( outlineParameters !== undefined ) {
 
 			if ( outlineParameters.visible !== undefined ) material.visible = outlineParameters.visible;
+			if ( outlineParameters.keepAlive !== undefined ) cache[ originalMaterial.uuid ].keepAlive = outlineParameters.keepAlive;
 
 		}
 
@@ -254,9 +276,43 @@ THREE.OutlineEffect = function ( renderer, parameters ) {
 
 	}
 
-	function restoreOriginalMaterial ( object ) {
+	function restoreOriginalMaterial( object ) {
+
+		if ( object.userData.originalMaterial !== undefined ) {
+
+			object.material = object.userData.originalMaterial;
+			object.userData.originalMaterial = undefined;
+
+		}
+
+	}
+
+	function removeUnusedOutlineMaterialFromCache() {
 
-		if ( object.userData.originalMaterial !== undefined ) object.material = object.userData.originalMaterial;
+		var keys = Object.keys( cache );
+
+		for ( var i = 0, il = keys.length; i < il; i ++ ) {
+
+			var key = keys[ i ];
+
+			if ( cache[ key ].used === false ) {
+
+				cache[ key ].count++;
+
+				if ( cache[ key ].keepAlive === false && cache[ key ].count > removeThresholdCount ) {
+
+					delete cache[ key ];
+
+				}
+
+			} else {
+
+				cache[ key ].used = false;
+				cache[ key ].count = 0;
+
+			}
+
+		}
 
 	}
 
@@ -277,9 +333,11 @@ THREE.OutlineEffect = function ( renderer, parameters ) {
 
 		// 2. render outline
 		var currentSceneAutoUpdate = scene.autoUpdate;
+		var currentSceneBackground = scene.background;
 		var currentShadowMapEnabled = renderer.shadowMap.enabled;
 
 		scene.autoUpdate = false;
+		scene.background = null;
 		renderer.autoClear = false;
 		renderer.shadowMap.enabled = false;
 
@@ -289,7 +347,10 @@ THREE.OutlineEffect = function ( renderer, parameters ) {
 
 		scene.traverse( restoreOriginalMaterial );
 
+		removeUnusedOutlineMaterialFromCache();
+
 		scene.autoUpdate = currentSceneAutoUpdate;
+		scene.background = currentSceneBackground;
 		renderer.autoClear = currentAutoClear;
 		renderer.shadowMap.enabled = currentShadowMapEnabled;
 

+ 20 - 23
examples/js/effects/VREffect.js

@@ -9,7 +9,7 @@
  *
  */
 
-THREE.VREffect = function ( renderer, onError ) {
+THREE.VREffect = function( renderer, onError ) {
 
 	var vrDisplay, vrDisplays;
 	var eyeTranslationL = new THREE.Vector3();
@@ -20,7 +20,7 @@ THREE.VREffect = function ( renderer, onError ) {
 
 	if ( 'VRFrameData' in window ) {
 
-		frameData = new VRFrameData();
+		frameData = new window.VRFrameData();
 
 	}
 
@@ -42,7 +42,7 @@ THREE.VREffect = function ( renderer, onError ) {
 
 	if ( navigator.getVRDisplays ) {
 
-		navigator.getVRDisplays().then( gotVRDisplays ).catch ( function () {
+		navigator.getVRDisplays().then( gotVRDisplays ).catch( function() {
 
 			console.warn( 'THREE.VREffect: Unable to get VR Displays' );
 
@@ -61,26 +61,26 @@ THREE.VREffect = function ( renderer, onError ) {
 	var rendererUpdateStyle = false;
 	var rendererPixelRatio = renderer.getPixelRatio();
 
-	this.getVRDisplay = function () {
+	this.getVRDisplay = function() {
 
 		return vrDisplay;
 
 	};
 
-	this.setVRDisplay = function ( value ) {
+	this.setVRDisplay = function( value ) {
 
 		vrDisplay = value;
 
 	};
 
-	this.getVRDisplays = function () {
+	this.getVRDisplays = function() {
 
 		console.warn( 'THREE.VREffect: getVRDisplays() is being deprecated.' );
 		return vrDisplays;
 
 	};
 
-	this.setSize = function ( width, height, updateStyle ) {
+	this.setSize = function( width, height, updateStyle ) {
 
 		rendererSize = { width: width, height: height };
 		rendererUpdateStyle = updateStyle;
@@ -100,12 +100,9 @@ THREE.VREffect = function ( renderer, onError ) {
 
 	};
 
-	// fullscreen
+	// VR presentation
 
 	var canvas = renderer.domElement;
-	var requestFullscreen;
-	var exitFullscreen;
-	var fullscreenElement;
 	var defaultLeftBounds = [ 0.0, 0.0, 0.5, 1.0 ];
 	var defaultRightBounds = [ 0.5, 0.0, 0.5, 1.0 ];
 
@@ -120,7 +117,7 @@ THREE.VREffect = function ( renderer, onError ) {
 			var eyeWidth = eyeParamsL.renderWidth;
 			var eyeHeight = eyeParamsL.renderHeight;
 
-			if ( !wasPresenting ) {
+			if ( ! wasPresenting ) {
 
 				rendererPixelRatio = renderer.getPixelRatio();
 				rendererSize = renderer.getSize();
@@ -141,9 +138,9 @@ THREE.VREffect = function ( renderer, onError ) {
 
 	window.addEventListener( 'vrdisplaypresentchange', onVRDisplayPresentChange, false );
 
-	this.setFullScreen = function ( boolean ) {
+	this.setFullScreen = function( boolean ) {
 
-		return new Promise( function ( resolve, reject ) {
+		return new Promise( function( resolve, reject ) {
 
 			if ( vrDisplay === undefined ) {
 
@@ -173,19 +170,19 @@ THREE.VREffect = function ( renderer, onError ) {
 
 	};
 
-	this.requestPresent = function () {
+	this.requestPresent = function() {
 
 		return this.setFullScreen( true );
 
 	};
 
-	this.exitPresent = function () {
+	this.exitPresent = function() {
 
 		return this.setFullScreen( false );
 
 	};
 
-	this.requestAnimationFrame = function ( f ) {
+	this.requestAnimationFrame = function( f ) {
 
 		if ( vrDisplay !== undefined ) {
 
@@ -199,7 +196,7 @@ THREE.VREffect = function ( renderer, onError ) {
 
 	};
 
-	this.cancelAnimationFrame = function ( h ) {
+	this.cancelAnimationFrame = function( h ) {
 
 		if ( vrDisplay !== undefined ) {
 
@@ -213,7 +210,7 @@ THREE.VREffect = function ( renderer, onError ) {
 
 	};
 
-	this.submitFrame = function () {
+	this.submitFrame = function() {
 
 		if ( vrDisplay !== undefined && scope.isPresenting ) {
 
@@ -233,7 +230,7 @@ THREE.VREffect = function ( renderer, onError ) {
 	var cameraR = new THREE.PerspectiveCamera();
 	cameraR.layers.enable( 2 );
 
-	this.render = function ( scene, camera, renderTarget, forceClear ) {
+	this.render = function( scene, camera, renderTarget, forceClear ) {
 
 		if ( vrDisplay && scope.isPresenting ) {
 
@@ -284,13 +281,13 @@ THREE.VREffect = function ( renderer, onError ) {
 				x: Math.round( size.width * leftBounds[ 0 ] ),
 				y: Math.round( size.height * leftBounds[ 1 ] ),
 				width: Math.round( size.width * leftBounds[ 2 ] ),
-				height: Math.round(size.height * leftBounds[ 3 ] )
+				height: Math.round( size.height * leftBounds[ 3 ] )
 			};
 			renderRectR = {
 				x: Math.round( size.width * rightBounds[ 0 ] ),
 				y: Math.round( size.height * rightBounds[ 1 ] ),
 				width: Math.round( size.width * rightBounds[ 2 ] ),
-				height: Math.round(size.height * rightBounds[ 3 ] )
+				height: Math.round( size.height * rightBounds[ 3 ] )
 			};
 
 			if ( renderTarget ) {
@@ -397,7 +394,7 @@ THREE.VREffect = function ( renderer, onError ) {
 
 	};
 
-	this.dispose = function () {
+	this.dispose = function() {
 
 		window.removeEventListener( 'vrdisplaypresentchange', onVRDisplayPresentChange, false );
 

+ 1 - 1
examples/js/loaders/3MFLoader.js

@@ -12,7 +12,7 @@ THREE.ThreeMFLoader.prototype = {
 	load: function ( url, onLoad, onProgress, onError ) {
 
 		var scope = this;
-		var loader = new THREE.XHRLoader( scope.manager );
+		var loader = new THREE.FileLoader( scope.manager );
 		loader.setResponseType( 'arraybuffer' );
 		loader.load( url, function( text ) {
 

+ 1 - 1
examples/js/loaders/AMFLoader.js

@@ -33,7 +33,7 @@ THREE.AMFLoader.prototype = {
 
 		var scope = this;
 
-		var loader = new THREE.XHRLoader( scope.manager );
+		var loader = new THREE.FileLoader( scope.manager );
 		loader.setResponseType( 'arraybuffer' );
 		loader.load( url, function( text ) {
 

+ 1 - 1
examples/js/loaders/AWDLoader.js

@@ -109,7 +109,7 @@
 			this._url = url;
 			this._baseDir = url.substr( 0, url.lastIndexOf( '/' ) + 1 );
 
-			var loader = new THREE.XHRLoader( this.manager );
+			var loader = new THREE.FileLoader( this.manager );
 			loader.setResponseType( 'arraybuffer' );
 			loader.load( url, function ( text ) {
 

+ 1 - 1
examples/js/loaders/AssimpJSONLoader.js

@@ -27,7 +27,7 @@ THREE.AssimpJSONLoader.prototype = {
 
 		this.texturePath = this.texturePath && ( typeof this.texturePath === "string" ) ? this.texturePath : this.extractUrlBase( url );
 
-		var loader = new THREE.XHRLoader( this.manager );
+		var loader = new THREE.FileLoader( this.manager );
 		loader.load( url, function ( text ) {
 
 			var json = JSON.parse( text ), scene, metadata;

+ 1 - 1
examples/js/loaders/BVHLoader.js

@@ -24,7 +24,7 @@ THREE.BVHLoader.prototype = {
 
 		var scope = this;
 
-		var loader = new THREE.XHRLoader( scope.manager );
+		var loader = new THREE.FileLoader( scope.manager );
 		loader.setResponseType( 'arraybuffer' );
 		loader.load( url, function( buffer ) {
 

+ 1 - 1
examples/js/loaders/BabylonLoader.js

@@ -16,7 +16,7 @@ THREE.BabylonLoader.prototype = {
 
 		var scope = this;
 
-		var loader = new THREE.XHRLoader( scope.manager );
+		var loader = new THREE.FileLoader( scope.manager );
 		loader.load( url, function ( text ) {
 
 			onLoad( scope.parse( JSON.parse( text ) ) );

+ 2 - 2
examples/js/loaders/BinaryLoader.js

@@ -37,14 +37,14 @@ THREE.BinaryLoader.prototype = {
 
 		var scope = this;
 
-		var jsonloader = new THREE.XHRLoader( this.manager );
+		var jsonloader = new THREE.FileLoader( this.manager );
 		jsonloader.load( url, function ( data ) {
 
 			var json = JSON.parse( data );
 
 			var bufferUrl = binaryPath + json.buffers;
 
-			var bufferLoader = new THREE.XHRLoader( scope.manager );
+			var bufferLoader = new THREE.FileLoader( scope.manager );
 			bufferLoader.setResponseType( 'arraybuffer' );
 			bufferLoader.load( bufferUrl, function ( bufData ) {
 

+ 1 - 1
examples/js/loaders/ColladaLoader2.js

@@ -24,7 +24,7 @@ THREE.ColladaLoader.prototype = {
 
 		var scope = this;
 
-		var loader = new THREE.XHRLoader( scope.manager );
+		var loader = new THREE.FileLoader( scope.manager );
 		loader.load( url, function ( text ) {
 
 			onLoad( scope.parse( text, getBaseUrl( url ) ) );

+ 2 - 2
examples/js/loaders/FBXLoader.js

@@ -33,7 +33,7 @@
 
 		var scope = this;
 
-		var loader = new THREE.XHRLoader( scope.manager );
+		var loader = new THREE.FileLoader( scope.manager );
 		// loader.setCrossOrigin( this.crossOrigin );
 		loader.load( url, function ( text ) {
 
@@ -528,7 +528,7 @@
 
 	THREE.FBXLoader.prototype.loadFile = function ( url, onLoad, onProgress, onError, responseType ) {
 
-		var loader = new THREE.XHRLoader( this.manager );
+		var loader = new THREE.FileLoader( this.manager );
 
 		loader.setResponseType( responseType );
 

+ 3 - 3
examples/js/loaders/GLTFLoader.js

@@ -24,7 +24,7 @@ THREE.GLTFLoader.prototype = {
 
 		var path = this.path && ( typeof this.path === "string" ) ? this.path : THREE.Loader.prototype.extractUrlBase( url );
 
-		var loader = new THREE.XHRLoader( scope.manager );
+		var loader = new THREE.FileLoader( scope.manager );
 		loader.load( url, function( text ) {
 
 			scope.parse( JSON.parse( text ), onLoad, path );
@@ -822,7 +822,7 @@ GLTFParser.prototype.loadShaders = function() {
 
 		return new Promise( function( resolve ) {
 
-			var loader = new THREE.XHRLoader();
+			var loader = new THREE.FileLoader();
 			loader.responseType = 'text';
 			loader.load( resolveURL( shader.uri, this.options.path ), function( shaderText ) {
 
@@ -844,7 +844,7 @@ GLTFParser.prototype.loadBuffers = function() {
 
 			return new Promise( function( resolve ) {
 
-				var loader = new THREE.XHRLoader();
+				var loader = new THREE.FileLoader();
 				loader.responseType = 'arraybuffer';
 				loader.load( resolveURL( buffer.uri, this.options.path ), function( buffer ) {
 

+ 1 - 1
examples/js/loaders/HDRCubeTextureLoader.js

@@ -27,7 +27,7 @@ THREE.HDRCubeTextureLoader.prototype.load = function(type, urls, onLoad, onProgr
   var loaded = 0;
 
   function loadHDRData(i, onLoad, onProgress, onError) {
-    var loader = new THREE.XHRLoader( this.manager );
+    var loader = new THREE.FileLoader( this.manager );
     loader.setResponseType( 'arraybuffer' );
 
     loader.load( urls[i], function ( buffer ) {

+ 1 - 1
examples/js/loaders/KMZLoader.js

@@ -16,7 +16,7 @@ THREE.KMZLoader.prototype = {
 
 		var scope = this;
 
-		var loader = new THREE.XHRLoader( scope.manager );
+		var loader = new THREE.FileLoader( scope.manager );
 		loader.setResponseType( 'arraybuffer' );
 		loader.load( url, function ( text ) {
 

+ 1 - 1
examples/js/loaders/MD2Loader.js

@@ -16,7 +16,7 @@ THREE.MD2Loader.prototype = {
 
 		var scope = this;
 
-		var loader = new THREE.XHRLoader( scope.manager );
+		var loader = new THREE.FileLoader( scope.manager );
 		loader.setResponseType( 'arraybuffer' );
 		loader.load( url, function ( buffer ) {
 

+ 193 - 132
examples/js/loaders/MMDLoader.js

@@ -308,9 +308,11 @@ THREE.MMDLoader.prototype.extractExtension = function ( url ) {
 
 };
 
-THREE.MMDLoader.prototype.loadFile = function ( url, onLoad, onProgress, onError, responseType ) {
+THREE.MMDLoader.prototype.loadFile = function ( url, onLoad, onProgress, onError, responseType, mimeType ) {
 
-	var loader = new THREE.XHRLoader( this.manager );
+	var loader = new THREE.FileLoader( this.manager );
+
+	if ( mimeType !== undefined ) loader.setMimeType( mimeType );
 
 	loader.setResponseType( responseType );
 
@@ -338,15 +340,7 @@ THREE.MMDLoader.prototype.loadFileAsText = function ( url, onLoad, onProgress, o
 
 THREE.MMDLoader.prototype.loadFileAsShiftJISText = function ( url, onLoad, onProgress, onError ) {
 
-	var request = this.loadFile( url, onLoad, onProgress, onError, 'text' );
-
-	/*
-	 * TODO: some browsers seem not support overrideMimeType
-	 *       so some workarounds for them may be necessary.
-	 * Note: to set property of request after calling request.send(null)
-	 *       (it's called in THREE.XHRLoader.load()) could be a bad manner.
-	 */
-	request.overrideMimeType( 'text/plain; charset=shift_jis' );
+	var request = this.loadFile( url, onLoad, onProgress, onError, 'text', 'text/plain; charset=shift_jis' );
 
 };
 
@@ -786,7 +780,7 @@ THREE.MMDLoader.prototype.parsePmd = function ( buffer ) {
 			p.weight = dv.getFloat32();
 			p.positionDamping = dv.getFloat32();
 			p.rotationDamping = dv.getFloat32();
-			p.restriction = dv.getFloat32();
+			p.restitution = dv.getFloat32();
 			p.friction = dv.getFloat32();
 			p.type = dv.getUint8();
 			return p;
@@ -1231,6 +1225,22 @@ THREE.MMDLoader.prototype.parsePmx = function ( buffer ) {
 					m.uv = dv.getFloat32Array( 4 );
 					p.elements.push( m );
 
+				} else if ( p.type === 4 ) {  // additional uv1
+
+					// TODO: implement
+
+				} else if ( p.type === 5 ) {  // additional uv2
+
+					// TODO: implement
+
+				} else if ( p.type === 6 ) {  // additional uv3
+
+					// TODO: implement
+
+				} else if ( p.type === 7 ) {  // additional uv4
+
+					// TODO: implement
+
 				} else if ( p.type === 8 ) {  // material morph
 
 					var m = {};
@@ -1324,7 +1334,7 @@ THREE.MMDLoader.prototype.parsePmx = function ( buffer ) {
 			p.weight = dv.getFloat32();
 			p.positionDamping = dv.getFloat32();
 			p.rotationDamping = dv.getFloat32();
-			p.restriction = dv.getFloat32();
+			p.restitution = dv.getFloat32();
 			p.friction = dv.getFloat32();
 			p.type = dv.getUint8();
 			return p;
@@ -1681,41 +1691,54 @@ THREE.MMDLoader.prototype.parseVpd = function ( text ) {
 THREE.MMDLoader.prototype.createMesh = function ( model, texturePath, onProgress, onError ) {
 
 	var scope = this;
-	var geometry = new THREE.Geometry();
-        var material = new THREE.MultiMaterial();
+	var geometry = new THREE.BufferGeometry();
+	var material = new THREE.MultiMaterial();
 	var helper = new THREE.MMDLoader.DataCreationHelper();
 
+	var buffer = {};
+
+	buffer.vertices = [];
+	buffer.uvs = [];
+	buffer.normals = [];
+	buffer.skinIndices = [];
+	buffer.skinWeights = [];
+	buffer.indices = [];
+
 	var initVartices = function () {
 
 		for ( var i = 0; i < model.metadata.vertexCount; i++ ) {
 
 			var v = model.vertices[ i ];
 
-			geometry.vertices.push(
-				new THREE.Vector3(
-					v.position[ 0 ],
-					v.position[ 1 ],
-					v.position[ 2 ]
-				)
-			);
+			for ( var j = 0, jl = v.position.length; j < jl; j ++ ) {
 
-			geometry.skinIndices.push(
-				new THREE.Vector4(
-					v.skinIndices.length >= 1 ? v.skinIndices[ 0 ] : 0.0,
-					v.skinIndices.length >= 2 ? v.skinIndices[ 1 ] : 0.0,
-					v.skinIndices.length >= 3 ? v.skinIndices[ 2 ] : 0.0,
-					v.skinIndices.length >= 4 ? v.skinIndices[ 3 ] : 0.0
-				)
-			);
+				buffer.vertices.push( v.position[ j ] );
 
-			geometry.skinWeights.push(
-				new THREE.Vector4(
-					v.skinWeights.length >= 1 ? v.skinWeights[ 0 ] : 0.0,
-					v.skinWeights.length >= 2 ? v.skinWeights[ 1 ] : 0.0,
-					v.skinWeights.length >= 3 ? v.skinWeights[ 2 ] : 0.0,
-					v.skinWeights.length >= 4 ? v.skinWeights[ 3 ] : 0.0
-				)
-			);
+			}
+
+			for ( var j = 0, jl = v.normal.length; j < jl; j ++ ) {
+
+				buffer.normals.push( v.normal[ j ] );
+
+			}
+
+			for ( var j = 0, jl = v.uv.length; j < jl; j ++ ) {
+
+				buffer.uvs.push( v.uv[ j ] );
+
+			}
+
+			for ( var j = 0; j < 4; j ++ ) {
+
+				buffer.skinIndices.push( v.skinIndices.length - 1 >= j ? v.skinIndices[ j ] : 0.0 );
+
+			}
+
+			for ( var j = 0; j < 4; j ++ ) {
+
+				buffer.skinWeights.push( v.skinWeights.length - 1 >= j ? v.skinWeights[ j ] : 0.0 );
+
+			}
 
 		}
 
@@ -1725,22 +1748,11 @@ THREE.MMDLoader.prototype.createMesh = function ( model, texturePath, onProgress
 
 		for ( var i = 0; i < model.metadata.faceCount; i++ ) {
 
-			geometry.faces.push(
-				new THREE.Face3(
-					model.faces[ i ].indices[ 0 ],
-					model.faces[ i ].indices[ 1 ],
-					model.faces[ i ].indices[ 2 ]
-				)
-			);
+			var f = model.faces[ i ];
 
-			for ( var j = 0; j < 3; j++ ) {
+			for ( var j = 0, jl = f.indices.length; j < jl; j ++ ) {
 
-				geometry.faces[ i ].vertexNormals[ j ] =
-					new THREE.Vector3(
-						model.vertices[ model.faces[ i ].indices[ j ] ].normal[ 0 ],
-						model.vertices[ model.faces[ i ].indices[ j ] ].normal[ 1 ],
-						model.vertices[ model.faces[ i ].indices[ j ] ].normal[ 2 ]
-					);
+				buffer.indices.push( f.indices[ j ] );
 
 			}
 
@@ -1905,15 +1917,15 @@ THREE.MMDLoader.prototype.createMesh = function ( model, texturePath, onProgress
 
 	var initMorphs = function () {
 
-		function updateVertex ( params, index, v, ratio ) {
+		function updateVertex( attribute, index, v, ratio ) {
 
-			params.vertices[ index ].x += v.position[ 0 ] * ratio;
-			params.vertices[ index ].y += v.position[ 1 ] * ratio;
-			params.vertices[ index ].z += v.position[ 2 ] * ratio;
+			attribute.array[ index * 3 + 0 ] += v.position[ 0 ] * ratio;
+			attribute.array[ index * 3 + 1 ] += v.position[ 1 ] * ratio;
+			attribute.array[ index * 3 + 2 ] += v.position[ 2 ] * ratio;
 
 		};
 
-		function updateVertices ( params, m, ratio ) {
+		function updateVertices( attribute, m, ratio ) {
 
 			for ( var i = 0; i < m.elementCount; i++ ) {
 
@@ -1931,26 +1943,25 @@ THREE.MMDLoader.prototype.createMesh = function ( model, texturePath, onProgress
 
 				}
 
-				updateVertex( params, index, v, ratio );
+				updateVertex( attribute, index, v, ratio );
 
 			}
 
 		};
 
+		var morphTargets = [];
+		var attributes = [];
+
 		for ( var i = 0; i < model.metadata.morphCount; i++ ) {
 
 			var m = model.morphs[ i ];
-			var params = {};
+			var params = { name: m.name };
 
-			params.name = m.name;
-			params.vertices = [];
+			var attribute = new THREE.Float32Attribute( model.metadata.vertexCount * 3, 3 );
 
-			for ( var j = 0; j < model.metadata.vertexCount; j++ ) {
+			for ( var j = 0; j < model.metadata.vertexCount * 3; j++ ) {
 
-				params.vertices[ j ] = new THREE.Vector3( 0, 0, 0 );
-				params.vertices[ j ].x = geometry.vertices[ j ].x;
-				params.vertices[ j ].y = geometry.vertices[ j ].y;
-				params.vertices[ j ].z = geometry.vertices[ j ].z;
+				attribute.array[ j ] = buffer.vertices[ j ];
 
 			}
 
@@ -1958,13 +1969,13 @@ THREE.MMDLoader.prototype.createMesh = function ( model, texturePath, onProgress
 
 				if ( i !== 0 ) {
 
-					updateVertices( params, m, 1.0 );
+					updateVertices( attribute, m, 1.0 );
 
 				}
 
 			} else {
 
-				if ( m.type === 0 ) {
+				if ( m.type === 0 ) {    // group
 
 					for ( var j = 0; j < m.elementCount; j++ ) {
 
@@ -1973,25 +1984,60 @@ THREE.MMDLoader.prototype.createMesh = function ( model, texturePath, onProgress
 
 						if ( m2.type === 1 ) {
 
-							updateVertices( params, m2, ratio );
+							updateVertices( attribute, m2, ratio );
+
+						} else {
+
+							// TODO: implement
 
 						}
 
 					}
 
-				} else if ( m.type === 1 ) {
+				} else if ( m.type === 1 ) {    // vertex
+
+					updateVertices( attribute, m, 1.0 );
+
+				} else if ( m.type === 2 ) {    // bone
+
+					// TODO: implement
+
+				} else if ( m.type === 3 ) {    // uv
+
+					// TODO: implement
+
+				} else if ( m.type === 4 ) {    // additional uv1
+
+					// TODO: implement
+
+				} else if ( m.type === 5 ) {    // additional uv2
+
+					// TODO: implement
+
+				} else if ( m.type === 6 ) {    // additional uv3
 
-					updateVertices( params, m, 1.0 );
+					// TODO: implement
+
+				} else if ( m.type === 7 ) {    // additional uv4
+
+					// TODO: implement
+
+				} else if ( m.type === 8 ) {    // material
+
+					// TODO: implement
 
 				}
 
 			}
 
-			// TODO: skip if this's non-vertex morphing of PMX to reduce CPU/Memory use
-			geometry.morphTargets.push( params );
+			morphTargets.push( params );
+			attributes.push( attribute );
 
 		}
 
+		geometry.morphTargets = morphTargets;
+		geometry.morphAttributes.position = attributes;
+
 	};
 
 	var initMaterials = function () {
@@ -2066,12 +2112,6 @@ THREE.MMDLoader.prototype.createMesh = function ( model, texturePath, onProgress
 
 		};
 
-		for ( var i = 0; i < model.metadata.materialCount; i++ ) {
-
-			geometry.faceVertexUvs.push( [] );
-
-		}
-
 		for ( var i = 0; i < model.metadata.materialCount; i++ ) {
 
 			var m = model.materials[ i ];
@@ -2080,24 +2120,7 @@ THREE.MMDLoader.prototype.createMesh = function ( model, texturePath, onProgress
 			params.faceOffset = offset;
 			params.faceNum = m.faceCount;
 
-			for ( var j = 0; j < m.faceCount; j++ ) {
-
-				geometry.faces[ offset ].materialIndex = i;
-
-				var uvs = [];
-
-				for ( var k = 0; k < 3; k++ ) {
-
-					var v = model.vertices[ model.faces[ offset ].indices[ k ] ];
-					uvs.push( new THREE.Vector2( v.uv[ 0 ], v.uv[ 1 ] ) );
-
-				}
-
-				geometry.faceVertexUvs[ 0 ].push( uvs );
-
-				offset++;
-
-			}
+			offset += m.faceCount;
 
 			params.name = m.name;
 			params.color = color.fromArray( [ m.diffuse[ 0 ], m.diffuse[ 1 ], m.diffuse[ 2 ] ] ).clone();
@@ -2217,15 +2240,14 @@ THREE.MMDLoader.prototype.createMesh = function ( model, texturePath, onProgress
 				fragmentShader: shader.fragmentShader
 			} );
 
-			m.faceOffset = p.faceOffset;
-			m.faceNum = p.faceNum;
+			geometry.addGroup( p.faceOffset * 3, p.faceNum * 3, i );
 
 			if ( p.name !== undefined ) m.name = p.name;
 
 			m.skinning = geometry.bones.length > 0 ? true : false;
 			m.morphTargets = geometry.morphTargets.length > 0 ? true : false;
 			m.lights = true;
-			m.side = p.side;
+			m.side = ( model.metadata.format === 'pmx' && ( p2.flag & 0x1 ) === 1 ) ? THREE.DoubleSide : p.side;
 			m.transparent = p.transparent;
 			m.fog = true;
 
@@ -2237,6 +2259,9 @@ THREE.MMDLoader.prototype.createMesh = function ( model, texturePath, onProgress
 
 			if ( p.map !== undefined ) {
 
+				m.faceOffset = p.faceOffset;
+				m.faceNum = p.faceNum;
+
 				// Check if this part of the texture image the material uses requires transparency
 				function checkTextureTransparency ( m ) {
 
@@ -2256,7 +2281,7 @@ THREE.MMDLoader.prototype.createMesh = function ( model, texturePath, onProgress
 
 						};
 
-						function detectTextureTransparency ( image, uvs ) {
+						function detectTextureTransparency( image, uvs, indices ) {
 
 							var width = image.width;
 							var height = image.height;
@@ -2269,13 +2294,14 @@ THREE.MMDLoader.prototype.createMesh = function ( model, texturePath, onProgress
 
 							}
 
-							for ( var i = 0; i < uvs.length; i++ ) {
+							for ( var i = 0; i < indices.length; i += 3 ) {
 
 								var centerUV = { x: 0.0, y: 0.0 };
 
 								for ( var j = 0; j < 3; j++ ) {
 
-									var uv = uvs[ i ][ j ];
+									var index = indices[ i * 3 + j ];
+									var uv = { x: uvs[ index * 2 + 0 ], y: uvs[ index * 2 + 1 ] };
 
 									if ( getAlphaByUv( image, uv ) < threshold ) {
 
@@ -2291,7 +2317,6 @@ THREE.MMDLoader.prototype.createMesh = function ( model, texturePath, onProgress
 								centerUV.x /= 3;
 								centerUV.y /= 3;
 
-
 								if ( getAlphaByUv( image, centerUV ) < threshold ) {
 
 									return true;
@@ -2338,9 +2363,9 @@ THREE.MMDLoader.prototype.createMesh = function ( model, texturePath, onProgress
 						};
 
 						var imageData = t.image.data !== undefined ? t.image : createImageData( t.image );
-						var uvs = geometry.faceVertexUvs[ 0 ].slice( m.faceOffset, m.faceOffset + m.faceNum );
+						var indices = geometry.index.array.slice( m.faceOffset * 3, m.faceOffset * 3 + m.faceNum * 3 );
 
-						if ( detectTextureTransparency( imageData, uvs ) ) m.transparent = true;
+						if ( detectTextureTransparency( imageData, geometry.attributes.uv.array, indices ) ) m.transparent = true;
 
 						delete m.faceOffset;
 						delete m.faceNum;
@@ -2430,7 +2455,7 @@ THREE.MMDLoader.prototype.createMesh = function ( model, texturePath, onProgress
 					alpha: p2.edgeColor[ 3 ]
 				};
 
-				if ( m.outlineParameters.thickness === 0.0 ) m.outlineParameters.visible = false;
+				if ( ( p2.flag & 0x10 ) === 0 || m.outlineParameters.thickness === 0.0 ) m.outlineParameters.visible = false;
 
 				m.uniforms.celShading.value = 1;
 
@@ -2584,8 +2609,7 @@ THREE.MMDLoader.prototype.createMesh = function ( model, texturePath, onProgress
 			var bodyB = rigidBodies[ p.rigidBodyIndex2 ];
 
 			/*
-			 * Refer http://www20.atpages.jp/katwat/wp/?p=4135
-			 * for what this is for
+			 * Refer to http://www20.atpages.jp/katwat/wp/?p=4135
 			 */
 			if ( bodyA.type !== 0 && bodyB.type === 2 ) {
 
@@ -2607,6 +2631,20 @@ THREE.MMDLoader.prototype.createMesh = function ( model, texturePath, onProgress
 
 	};
 
+	var initGeometry = function () {
+
+		geometry.setIndex( ( buffer.indices.length > 65535 ? THREE.Uint32Attribute : THREE.Uint16Attribute )( buffer.indices, 1 ) );
+		geometry.addAttribute( 'position', THREE.Float32Attribute( buffer.vertices, 3 ) );
+		geometry.addAttribute( 'normal', THREE.Float32Attribute( buffer.normals, 3 ) );
+		geometry.addAttribute( 'uv', THREE.Float32Attribute( buffer.uvs, 2 ) );
+		geometry.addAttribute( 'skinIndex', THREE.Float32Attribute( buffer.skinIndices, 4 ) );
+		geometry.addAttribute( 'skinWeight', THREE.Float32Attribute( buffer.skinWeights, 4 ) );
+
+		geometry.computeBoundingSphere();
+		geometry.mmdFormat = model.metadata.format;
+
+	};
+
 	this.leftToRightModel( model );
 
 	initVartices();
@@ -2617,12 +2655,7 @@ THREE.MMDLoader.prototype.createMesh = function ( model, texturePath, onProgress
 	initMorphs();
 	initMaterials();
 	initPhysics();
-
-	geometry.computeFaceNormals();
-	geometry.verticesNeedUpdate = true;
-	geometry.normalsNeedUpdate = true;
-	geometry.uvsNeedUpdate = true;
-	geometry.mmdFormat = model.metadata.format;
+	initGeometry();
 
 	var mesh = new THREE.SkinnedMesh( geometry, material );
 
@@ -2809,21 +2842,14 @@ THREE.MMDLoader.prototype.leftToRightModel = function ( model ) {
 
 		var m = model.morphs[ i ];
 
-		if ( model.metadata.format === 'pmx' ) {
-
-			if ( m.type === 1 ) {
+		if ( model.metadata.format === 'pmx' && m.type !== 1 ) {
 
-				m = m.elements;
-
-			} else {
-
-				continue;
-
-			}
+			// TODO: implement
+			continue;
 
 		}
 
-		for ( var j = 0; j < m.elementCount; j++ ) {
+		for ( var j = 0; j < m.elements.length; j++ ) {
 
 			helper.leftToRightVector3( m.elements[ j ].position );
 
@@ -3807,10 +3833,12 @@ THREE.MMDHelper.prototype = {
 
 		}
 
-		mesh.mixer = null;
-		mesh.ikSolver = null;
-		mesh.grantSolver = null;
-		mesh.physics = null;
+		if ( mesh.mixer === undefined ) mesh.mixer = null;
+		if ( mesh.ikSolver === undefined ) mesh.ikSolver = null;
+		if ( mesh.grantSolver === undefined ) mesh.grantSolver = null;
+		if ( mesh.physics === undefined ) mesh.physics = null;
+		if ( mesh.looped === undefined ) mesh.looped = false;
+
 		this.meshes.push( mesh );
 
 		// workaround until I make IK and Physics Animation plugin
@@ -3843,8 +3871,22 @@ THREE.MMDHelper.prototype = {
 
 	setPhysics: function ( mesh, params ) {
 
-		mesh.physics = new THREE.MMDPhysics( mesh, params );
-		mesh.physics.warmup( 10 );
+		if ( params === undefined ) params = {};
+
+		var warmup = params.warmup !== undefined ? params.warmup : 60;
+
+		var physics = new THREE.MMDPhysics( mesh, params );
+
+		if ( mesh.mixer !== null && mesh.mixer !== undefined && this.doAnimation === true && params.preventAnimationWarmup !== false ) {
+
+			this.animateOneMesh( 0, mesh );
+			physics.reset();
+
+		}
+
+		physics.warmup( warmup );
+
+		mesh.physics = physics;
 
 	},
 
@@ -3864,6 +3906,17 @@ THREE.MMDHelper.prototype = {
 
 			mesh.mixer = new THREE.AnimationMixer( mesh );
 
+			// TODO: find a workaround not to access (seems like) private properties
+			//       the name of them begins with "_".
+			mesh.mixer.addEventListener( 'loop', function ( e ) {
+
+				if ( e.action._clip.tracks[ 0 ].name.indexOf( '.bones' ) !== 0 ) return;
+
+				var mesh = e.target._root;
+				mesh.looped = true;
+
+			} );
+
 			var foundAnimation = false;
 			var foundMorphAnimation = false;
 
@@ -4082,6 +4135,14 @@ THREE.MMDHelper.prototype = {
 
 		}
 
+		if ( mesh.looped === true ) {
+
+			if ( physics !== null ) physics.reset();
+
+			mesh.looped = false;
+
+		}
+
 		if ( physics !== null && this.doPhysics === true ) {
 
 			physics.update( delta );

+ 1 - 1
examples/js/loaders/MTLLoader.js

@@ -29,7 +29,7 @@ Object.assign( THREE.MTLLoader.prototype, THREE.EventDispatcher.prototype, {
 
 		var scope = this;
 
-		var loader = new THREE.XHRLoader( this.manager );
+		var loader = new THREE.FileLoader( this.manager );
 		loader.setPath( this.path );
 		loader.load( url, function ( text ) {
 

+ 1 - 1
examples/js/loaders/NRRDLoader.js

@@ -11,7 +11,7 @@ Object.assign( THREE.NRRDLoader.prototype, THREE.EventDispatcher.prototype, {
 
 		var scope = this;
 
-		var loader = new THREE.XHRLoader( scope.manager );
+		var loader = new THREE.FileLoader( scope.manager );
 		loader.setResponseType( 'arraybuffer' );
 		loader.load( url, function( data ) {
 

+ 1 - 1
examples/js/loaders/OBJLoader.js

@@ -43,7 +43,7 @@ THREE.OBJLoader.prototype = {
 
 		var scope = this;
 
-		var loader = new THREE.XHRLoader( scope.manager );
+		var loader = new THREE.FileLoader( scope.manager );
 		loader.setPath( this.path );
 		loader.load( url, function ( text ) {
 

+ 1 - 1
examples/js/loaders/PCDLoader.js

@@ -21,7 +21,7 @@ Object.assign( THREE.PCDLoader.prototype, THREE.EventDispatcher.prototype, {
 
 		var scope = this;
 
-		var loader = new THREE.XHRLoader( scope.manager );
+		var loader = new THREE.FileLoader( scope.manager );
 		loader.setResponseType( 'arraybuffer' );
 		loader.load( url, function( data ) {
 

+ 1 - 1
examples/js/loaders/PDBLoader.js

@@ -16,7 +16,7 @@ THREE.PDBLoader.prototype = {
 
 		var scope = this;
 
-		var loader = new THREE.XHRLoader( scope.manager );
+		var loader = new THREE.FileLoader( scope.manager );
 		loader.load( url, function ( text ) {
 
 			var json = scope.parsePDB( text );

+ 1 - 1
examples/js/loaders/PLYLoader.js

@@ -43,7 +43,7 @@ THREE.PLYLoader.prototype = {
 
 		var scope = this;
 
-		var loader = new THREE.XHRLoader( this.manager );
+		var loader = new THREE.FileLoader( this.manager );
 		loader.setResponseType( 'arraybuffer' );
 		loader.load( url, function ( text ) {
 

+ 1 - 1
examples/js/loaders/PlayCanvasLoader.js

@@ -16,7 +16,7 @@ THREE.PlayCanvasLoader.prototype = {
 
 		var scope = this;
 
-		var loader = new THREE.XHRLoader( scope.manager );
+		var loader = new THREE.FileLoader( scope.manager );
 		loader.load( url, function ( text ) {
 
 			onLoad( scope.parse( JSON.parse( text ) ) );

+ 1 - 1
examples/js/loaders/STLLoader.js

@@ -41,7 +41,7 @@ THREE.STLLoader.prototype = {
 
 		var scope = this;
 
-		var loader = new THREE.XHRLoader( scope.manager );
+		var loader = new THREE.FileLoader( scope.manager );
 		loader.setResponseType( 'arraybuffer' );
 		loader.load( url, function ( text ) {
 

+ 1 - 1
examples/js/loaders/SVGLoader.js

@@ -19,7 +19,7 @@ THREE.SVGLoader.prototype = {
 
 		var parser = new DOMParser();
 
-		var loader = new THREE.XHRLoader( scope.manager );
+		var loader = new THREE.FileLoader( scope.manager );
 		loader.load( url, function ( svgString ) {
 
 			var doc = parser.parseFromString( svgString, 'image/svg+xml' );  // application/xml

+ 1 - 1
examples/js/loaders/TGALoader.js

@@ -16,7 +16,7 @@ THREE.TGALoader.prototype.load = function ( url, onLoad, onProgress, onError ) {
 
 	var texture = new THREE.Texture();
 
-	var loader = new THREE.XHRLoader( this.manager );
+	var loader = new THREE.FileLoader( this.manager );
 	loader.setResponseType( 'arraybuffer' );
 
 	loader.load( url, function ( buffer ) {

+ 1 - 1
examples/js/loaders/TTFLoader.js

@@ -19,7 +19,7 @@ THREE.TTFLoader.prototype.load = function ( url, onLoad, onProgress, onError ) {
 
 	var scope = this;
 
-	var loader = new THREE.XHRLoader( this.manager );
+	var loader = new THREE.FileLoader( this.manager );
 	loader.setResponseType( 'arraybuffer' );
 	loader.load( url, function ( buffer ) {
 

+ 1 - 1
examples/js/loaders/UTF8Loader.js

@@ -727,7 +727,7 @@ THREE.UTF8Loader.prototype.downloadModelJson = function ( jsonUrl, callback, opt
 
 function getHttpRequest( url, onload, opt_onprogress ) {
 
-	var req = new THREE.XHRLoader();
+	var req = new THREE.FileLoader();
 	req.load( url, onload, opt_onprogress );
 
 }

+ 1 - 1
examples/js/loaders/VRMLLoader.js

@@ -30,7 +30,7 @@ THREE.VRMLLoader.prototype = {
 
 		var scope = this;
 
-		var loader = new THREE.XHRLoader( this.manager );
+		var loader = new THREE.FileLoader( this.manager );
 		loader.load( url, function ( text ) {
 
 			onLoad( scope.parse( text ) );

+ 1 - 1
examples/js/loaders/VTKLoader.js

@@ -15,7 +15,7 @@ Object.assign( THREE.VTKLoader.prototype, THREE.EventDispatcher.prototype, {
 
 		var scope = this;
 
-		var loader = new THREE.XHRLoader( scope.manager );
+		var loader = new THREE.FileLoader( scope.manager );
 		loader.setResponseType( 'arraybuffer' );
 		loader.load( url, function( text ) {
 

+ 1 - 1
examples/js/loaders/deprecated/SceneLoader.js

@@ -28,7 +28,7 @@ THREE.SceneLoader.prototype = {
 
 		var scope = this;
 
-		var loader = new THREE.XHRLoader( scope.manager );
+		var loader = new THREE.FileLoader( scope.manager );
 		loader.load( url, function ( text ) {
 
 			scope.parse( JSON.parse( text ), onLoad, url );

+ 210 - 0
examples/webgl2_sandbox.html

@@ -0,0 +1,210 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<title>three.js - webgl2 sandbox</title>
+		<meta charset="utf-8">
+		<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
+		<style>
+			body {
+				background:#000;
+				padding:0;
+				margin:0;
+				font-weight: bold;
+				overflow:hidden;
+			}
+
+			#info {
+				position: absolute;
+				top: 0px; width: 100%;
+				color: #ffffff;
+				padding: 5px;
+				font-family:Monospace;
+				font-size:13px;
+				text-align:center;
+				z-index:1000;
+			}
+
+			a {
+				color: #ffffff;
+			}
+
+		</style>
+	</head>
+
+	<body>
+		<div id="info"><a href="http://threejs.org" target="_blank">three.js</a> - webgl2 sandbox.</div>
+
+		<script src="../build/three.js"></script>
+
+		<script src="js/libs/stats.min.js"></script>
+
+		<script>
+
+			var statsEnabled = true;
+
+			var container, stats;
+
+			var camera, scene, renderer;
+
+			var mesh, zmesh, lightMesh, geometry;
+
+			var mouseX = 0, mouseY = 0;
+
+			var windowHalfX = window.innerWidth / 2;
+			var windowHalfY = window.innerHeight / 2;
+
+			init();
+			animate();
+
+			function init() {
+
+				container = document.createElement( 'div' );
+				document.body.appendChild( container );
+
+				camera = new THREE.PerspectiveCamera( 60, window.innerWidth / window.innerHeight, 1, 20000 );
+				camera.position.z = 3200;
+
+				scene = new THREE.Scene();
+				scene.background = new THREE.Color( 0, 0, 0.5 );
+				scene.fog = new THREE.Fog( 0x000000, 1, 20000 );
+
+				var light = new THREE.PointLight( 0xffffff );
+				scene.add( light );
+
+				var texture1 = new THREE.CanvasTexture( generateTexture( 0, 0.5, 1 ), THREE.UVMapping );
+
+				var materials = [
+
+					new THREE.MeshNormalMaterial(),
+					new THREE.MeshDepthMaterial(),
+					new THREE.MeshBasicMaterial( { color: 0x0066ff, blending: THREE.AdditiveBlending, transparent: true, depthWrite: false } ),
+					new THREE.MeshBasicMaterial( { color: 0xffaa00, wireframe: true } ),
+					new THREE.MeshBasicMaterial( { map: texture1, fog: false } ),
+					new THREE.MeshLambertMaterial( { color: 0xdddddd } ),
+					new THREE.MeshPhongMaterial( { color: 0xdddddd, specular: 0x009900, shininess: 30, shading: THREE.FlatShading } ),
+					new THREE.MeshPhongMaterial( { color: 0xdddddd, specular: 0x009900, shininess: 30, shading: THREE.SmoothShading } )
+
+				];
+
+				var geometry = new THREE.SphereGeometry( 50, 32, 16 );
+
+				for ( var i = 0; i < 5000; i ++ ) {
+
+					// random order
+					//var index = Math.floor( Math.random() * materials.length );
+
+					// sort by material / geometry
+					var index = Math.floor( ( i / 5000 ) * materials.length );
+
+					var material = materials[ index ];
+
+					var mesh = new THREE.Mesh( geometry, material );
+
+					mesh.position.x = Math.random() * 10000 - 5000;
+					mesh.position.y = Math.random() * 10000 - 5000;
+					mesh.position.z = Math.random() * 10000 - 5000;
+
+					//mesh.rotation.x = Math.random() * 360 * ( Math.PI / 180 );
+					mesh.rotation.y = Math.random() * 2 * Math.PI;
+
+					mesh.scale.x = mesh.scale.y = mesh.scale.z = Math.random() * 4 + 1;
+
+					scene.add( mesh );
+
+				}
+
+				renderer = new THREE.WebGL2Renderer();
+				renderer.setPixelRatio( window.devicePixelRatio );
+				renderer.setSize( window.innerWidth, window.innerHeight );
+				container.appendChild( renderer.domElement );
+
+				if ( statsEnabled ) {
+
+					stats = new Stats();
+					container.appendChild( stats.dom );
+
+				}
+
+				document.addEventListener( 'mousemove', onDocumentMouseMove, false );
+
+				//
+
+				window.addEventListener( 'resize', onWindowResize, false );
+
+			}
+
+			function onWindowResize() {
+
+				windowHalfX = window.innerWidth / 2;
+				windowHalfY = window.innerHeight / 2;
+
+				camera.aspect = window.innerWidth / window.innerHeight;
+				camera.updateProjectionMatrix();
+
+				renderer.setSize( window.innerWidth, window.innerHeight );
+
+			}
+
+			function generateTexture( r, g, b ) {
+
+				var canvas = document.createElement( 'canvas' );
+				canvas.width = 256;
+				canvas.height = 256;
+
+				var context = canvas.getContext( '2d' );
+				var image = context.getImageData( 0, 0, 256, 256 );
+
+				var x = 0, y = 0, p;
+
+				for ( var i = 0, j = 0, l = image.data.length; i < l; i += 4, j ++ ) {
+
+					x = j % 256;
+					y = x == 0 ? y + 1 : y;
+					p = Math.floor( x ^ y );
+
+					image.data[ i ] = ~~ p * r;
+					image.data[ i + 1 ] = ~~ p * g;
+					image.data[ i + 2 ] = ~~ p * b;
+					image.data[ i + 3 ] = 255;
+
+				}
+
+				context.putImageData( image, 0, 0 );
+
+				return canvas;
+
+			}
+
+			function onDocumentMouseMove(event) {
+
+				mouseX = ( event.clientX - windowHalfX ) * 10;
+				mouseY = ( event.clientY - windowHalfY ) * 10;
+
+			}
+
+			//
+
+			function animate() {
+
+				requestAnimationFrame( animate );
+
+				render();
+				if ( statsEnabled ) stats.update();
+
+			}
+
+			function render() {
+
+				camera.position.x += ( mouseX - camera.position.x ) * .05;
+				camera.position.y += ( - mouseY - camera.position.y ) * .05;
+
+				camera.lookAt( scene.position );
+
+				renderer.render( scene, camera );
+
+			}
+
+		</script>
+
+	</body>
+</html>

+ 6 - 3
examples/webgl_geometry_shapes.html

@@ -66,15 +66,18 @@
 
 				var loader = new THREE.TextureLoader();
 				var texture = loader.load( "textures/UV_Grid_Sm.jpg" );
+
+				// it's necessary to apply these settings in order to correctly display the texture on a shape geometry
+
 				texture.wrapS = texture.wrapT = THREE.RepeatWrapping;
 				texture.repeat.set( 0.008, 0.008 );
 
 				function addShape( shape, extrudeSettings, color, x, y, z, rx, ry, rz, s ) {
 
 					// flat shape with texture
-					// note: default UVs generated by ShapeGemoetry are simply the x- and y-coordinates of the vertices
+					// note: default UVs generated by ShapeBufferGemoetry are simply the x- and y-coordinates of the vertices
 
-					var geometry = new THREE.ShapeGeometry( shape );
+					var geometry = new THREE.ShapeBufferGeometry( shape );
 
 					var mesh = new THREE.Mesh( geometry, new THREE.MeshPhongMaterial( { side: THREE.DoubleSide, map: texture } ) );
 					mesh.position.set( x, y, z - 175 );
@@ -84,7 +87,7 @@
 
 					// flat shape
 
-					var geometry = new THREE.ShapeGeometry( shape );
+					var geometry = new THREE.ShapeBufferGeometry( shape );
 
 					var mesh = new THREE.Mesh( geometry, new THREE.MeshPhongMaterial( { color: color, side: THREE.DoubleSide } ) );
 					mesh.position.set( x, y, z - 125 );

+ 7 - 4
examples/webgl_loader_mmd.html

@@ -52,8 +52,8 @@
 
 			var container, stats;
 
-			var mesh, camera, scene, renderer, effect;
-			var helper;
+			var mesh, camera, scene, renderer;
+			var helper, physicsHelper;
 
 			var mouseX = 0, mouseY = 0;
 
@@ -123,14 +123,16 @@
 					helper.setAnimation( mesh );
 
 					/*
-					 * Note: You must set Physics
-					 *       before you add mesh to scene or any other 3D object.
+					 * Note: You're recommended to call helper.setPhysics()
+					 *       after calling helper.setAnimation().
 					 * Note: Physics calculation is pretty heavy.
 					 *       It may not be acceptable for most mobile devices yet.
 			 		 */
 					if ( ! isMobileDevice() ) {
 
 						helper.setPhysics( mesh );
+						physicsHelper = new THREE.MMDPhysicsHelper( mesh );
+						scene.add( physicsHelper );
 
 					}
 
@@ -184,6 +186,7 @@
 				camera.lookAt( scene.position );
 
 				helper.animate( clock.getDelta() );
+				if ( physicsHelper !== undefined ) physicsHelper.update();
 				effect.render( scene, camera );
 
 			}

+ 2 - 2
examples/webgl_loader_mmd_audio.html

@@ -130,8 +130,8 @@
 					helper.setAnimation( mesh );
 
 					/*
-					 * Note: You must set Physics
-					 *       before you add mesh to scene or any other 3D object.
+					 * Note: You're recommended to call helper.setPhysics()
+					 *       after calling helper.setAnimation().
 					 * Note: Physics calculation is pretty heavy.
 					 *       It may not be acceptable for most mobile devices yet.
 			 		 */

+ 1 - 1
examples/webgl_loader_msgpack.html

@@ -96,7 +96,7 @@ https://github.com/creationix/msgpack-js-browser
 
 			function loadMSGPack() {
 
-				var loader = new THREE.XHRLoader();
+				var loader = new THREE.FileLoader();
 				loader.setResponseType( 'arraybuffer' );
 				loader.load( 'scenes/robo_pigeon.pack', function ( data ) {
 

+ 12 - 5
examples/webgl_materials_blending_custom.html

@@ -27,10 +27,12 @@
 
 			#btn_sub { background: transparent }
 			#btn_rsub { background: transparent }
+			#btn_min { background: transparent }
+			#btn_max { background: transparent }
 
 			#btn_pre { background: transparent }
 
-			#btn_rsub, #btn_nopre { margin-bottom: 2em }
+			#btn_max, #btn_nopre { margin-bottom: 2em }
 		</style>
 	</head>
 	<body>
@@ -62,6 +64,8 @@
 			<div class="lbl btn" id="btn_add">Add</div>
 			<div class="lbl btn" id="btn_sub">Subtract</div>
 			<div class="lbl btn" id="btn_rsub">ReverseSubtract</div>
+			<div class="lbl btn" id="btn_min">Min</div>
+			<div class="lbl btn" id="btn_max">Max</div>
 
 			Premultiply alpha<br/><br/>
 			<div class="lbl btn" id="btn_pre">On</div>
@@ -97,7 +101,7 @@
 
 				// CAMERA
 
-				camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 1, 1000 );
+				camera = new THREE.PerspectiveCamera( 80, window.innerWidth / window.innerHeight, 1, 1000 );
 				camera.position.z = 700;
 
 				// SCENE
@@ -204,9 +208,8 @@
 				}
 
 				// FOREGROUND OBJECTS
-
-				var src = [ "ZeroFactor", "OneFactor", "SrcAlphaFactor", "OneMinusSrcAlphaFactor", "DstAlphaFactor", "OneMinusDstAlphaFactor", "DstColorFactor", "OneMinusDstColorFactor", "SrcAlphaSaturateFactor" ];
-				var dst = [ "ZeroFactor", "OneFactor", "SrcColorFactor", "OneMinusSrcColorFactor", "SrcAlphaFactor", "OneMinusSrcAlphaFactor", "DstAlphaFactor", "OneMinusDstAlphaFactor" ];
+				var src = [ "ZeroFactor", "OneFactor", "SrcColorFactor", "OneMinusSrcColorFactor", "SrcAlphaFactor", "OneMinusSrcAlphaFactor", "DstAlphaFactor", "OneMinusDstAlphaFactor", "DstColorFactor", "OneMinusDstColorFactor", "SrcAlphaSaturateFactor" ];
+				var dst = [ "ZeroFactor", "OneFactor", "SrcColorFactor", "OneMinusSrcColorFactor", "SrcAlphaFactor", "OneMinusSrcAlphaFactor", "DstAlphaFactor", "OneMinusDstAlphaFactor", "DstColorFactor", "OneMinusDstColorFactor" ];
 
 				var geo1 = new THREE.PlaneBufferGeometry( 100, 100 );
 				var geo2 = new THREE.PlaneBufferGeometry( 100, 25 );
@@ -311,6 +314,8 @@
 				addEqHandler( "btn_add", THREE.AddEquation );
 				addEqHandler( "btn_sub", THREE.SubtractEquation );
 				addEqHandler( "btn_rsub", THREE.ReverseSubtractEquation );
+				addEqHandler( "btn_min", THREE.MinEquation );
+				addEqHandler( "btn_max", THREE.MaxEquation );
 
 				addPreHandler( "btn_pre", mapsPre );
 				addPreHandler( "btn_nopre", mapsNoPre );
@@ -352,6 +357,8 @@
 					document.getElementById( "btn_add" ).style.backgroundColor = "transparent";
 					document.getElementById( "btn_sub" ).style.backgroundColor = "transparent";
 					document.getElementById( "btn_rsub" ).style.backgroundColor = "transparent";
+					document.getElementById( "btn_min" ).style.backgroundColor = "transparent";
+					document.getElementById( "btn_max" ).style.backgroundColor = "transparent";
 
 					el.style.backgroundColor = "darkorange";
 

+ 24 - 29
examples/webgl_materials_normalmap.html

@@ -67,25 +67,24 @@
 		<script src="js/postprocessing/ShaderPass.js"></script>
 		<script src="js/postprocessing/MaskPass.js"></script>
 
-
 		<script>
 
 			if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
 
-			var statsEnabled = true;
-
 			var container, stats, loader;
 
 			var camera, scene, renderer;
 
-			var mesh, zmesh, lightMesh, geometry;
-			var mesh1;
+			var mesh;
 
 			var directionalLight, pointLight, ambientLight;
 
 			var mouseX = 0;
 			var mouseY = 0;
 
+			var targetX = 0;
+			var targetY = 0;
+
 			var windowHalfX = window.innerWidth / 2;
 			var windowHalfY = window.innerHeight / 2;
 
@@ -146,12 +145,9 @@
 
 				//
 
-				if ( statsEnabled ) {
+				stats = new Stats();
+				container.appendChild( stats.dom );
 
-					stats = new Stats();
-					container.appendChild( stats.dom );
-
-				}
 
 				// COMPOSER
 
@@ -165,22 +161,21 @@
 
 				var canvas = renderer.context.canvas;
 
-				effectFXAA.uniforms[ 'resolution' ].value.set( 1 / canvas.width, 1 / canvas.height );
+				effectFXAA.uniforms[ 'resolution' ].value.set( 1 / window.innerWidth, 1 / window.innerHeight );
 
 				effectBleach.uniforms[ 'opacity' ].value = 0.4;
 
 				effectColor.uniforms[ 'powRGB' ].value.set( 1.4, 1.45, 1.45 );
 				effectColor.uniforms[ 'mulRGB' ].value.set( 1.1, 1.1, 1.1 );
 
-				effectFXAA.renderToScreen = true;
+				effectColor.renderToScreen = true;
 
 				composer = new THREE.EffectComposer( renderer );
 
 				composer.addPass( renderModel );
-
+				composer.addPass( effectFXAA );
 				composer.addPass( effectBleach );
 				composer.addPass( effectColor );
-				composer.addPass( effectFXAA );
 
 				// EVENTS
 
@@ -191,12 +186,12 @@
 
 			function createScene( geometry, scale, material ) {
 
-				mesh1 = new THREE.Mesh( geometry, material );
+				mesh = new THREE.Mesh( geometry, material );
 
-				mesh1.position.y = - 50;
-				mesh1.scale.x = mesh1.scale.y = mesh1.scale.z = scale;
+				mesh.position.y = - 50;
+				mesh.scale.x = mesh.scale.y = mesh.scale.z = scale;
 
-				scene.add( mesh1 );
+				scene.add( mesh );
 
 			}
 
@@ -207,12 +202,11 @@
 				SCREEN_WIDTH = window.innerWidth;
 				SCREEN_HEIGHT = window.innerHeight;
 
-				renderer.setSize( SCREEN_WIDTH, SCREEN_HEIGHT );
-
 				camera.aspect = SCREEN_WIDTH / SCREEN_HEIGHT;
 				camera.updateProjectionMatrix();
 
-				composer.reset();
+				renderer.setSize( SCREEN_WIDTH, SCREEN_HEIGHT );
+				composer.setSize( SCREEN_WIDTH, SCREEN_HEIGHT );
 
 				effectFXAA.uniforms[ 'resolution' ].value.set( 1 / SCREEN_WIDTH, 1 / SCREEN_HEIGHT );
 
@@ -220,8 +214,8 @@
 
 			function onDocumentMouseMove(event) {
 
-				mouseX = ( event.clientX - windowHalfX ) * 10;
-				mouseY = ( event.clientY - windowHalfY ) * 10;
+				mouseX = ( event.clientX - windowHalfX );
+				mouseY = ( event.clientY - windowHalfY );
 
 			}
 
@@ -232,22 +226,23 @@
 				requestAnimationFrame( animate );
 
 				render();
-				if ( statsEnabled ) stats.update();
+
+				stats.update();
 
 			}
 
 			function render() {
 
-				var ry = mouseX * 0.0003, rx = mouseY * 0.0003;
+				targetX = mouseX * .001;
+				targetY = mouseY * .001;
 
-				if( mesh1 ) {
+				if ( mesh ) {
 
-					mesh1.rotation.y = ry;
-					mesh1.rotation.x = rx;
+					mesh.rotation.y += 0.05 * ( targetX - mesh.rotation.y );
+					mesh.rotation.x += 0.05 * ( targetY - mesh.rotation.x );
 
 				}
 
-				//renderer.render( scene, camera );
 				composer.render();
 
 			}

+ 1 - 1
examples/webgl_morphtargets_human.html

@@ -118,7 +118,7 @@
 
 				};
 
-				var loader = new THREE.XHRLoader();
+				var loader = new THREE.FileLoader();
 				loader.load( 'models/skinned/UCS_config.json', function ( text ) {
 
 					var config = JSON.parse( text );

+ 2 - 5
package.json

@@ -1,8 +1,9 @@
 {
   "name": "three",
-  "version": "0.81.2",
+  "version": "0.82.0",
   "description": "JavaScript 3D library",
   "main": "build/three.js",
+  "repository": "mrdoob/three.js",
   "jsnext:main": "build/three.modules.js",
   "files": [
     "package.json",
@@ -28,10 +29,6 @@
     "dev": "rollup -c -w",
     "test": "echo \"Error: no test specified\" && exit 1"
   },
-  "repository": {
-    "type": "git",
-    "url": "https://github.com/mrdoob/three.js"
-  },
   "keywords": [
     "three",
     "three.js",

+ 2 - 1
rollup.config.js

@@ -42,5 +42,6 @@ export default {
 			dest: 'build/three.modules.js'
 		}
 	],
-	outro: outro
+	outro: outro,
+	sourceMap: true
 };

+ 24 - 16
src/Three.Legacy.js

@@ -18,6 +18,7 @@ import { ExtrudeGeometry } from './geometries/ExtrudeGeometry.js';
 import { ShapeGeometry } from './geometries/ShapeGeometry.js';
 import { WireframeGeometry } from './geometries/WireframeGeometry.js';
 import { Light } from './lights/Light.js';
+import { FileLoader } from './loaders/FileLoader.js';
 import { AudioLoader } from './loaders/AudioLoader.js';
 import { CubeTextureLoader } from './loaders/CubeTextureLoader.js';
 import { TextureLoader } from './loaders/TextureLoader.js';
@@ -105,6 +106,13 @@ export function WireframeHelper( object, hex ) {
 
 //
 
+export function XHRLoader( manager ) {
+	console.warn( 'THREE.XHRLoader has been renamed to THREE.FileLoader.' );
+	return new FileLoader( manager );
+}
+
+//
+
 Object.assign( Box2.prototype, {
 	center: function ( optionalTarget ) {
 		console.warn( 'THREE.Box2: .center() has been renamed to .getCenter().' );
@@ -462,6 +470,22 @@ Object.defineProperties( BufferGeometry.prototype, {
 
 //
 
+Object.defineProperties( Uniform.prototype, {
+	dynamic: {
+		set: function ( value ) {
+			console.warn( 'THREE.Uniform: .dynamic has been removed. Use object.onBeforeRender() instead.' );
+		}
+	},
+	onUpdate: {
+		value: function () {
+			console.warn( 'THREE.Uniform: .onUpdate() has been removed. Use object.onBeforeRender() instead.' );
+			return this;
+		}
+	}
+} );
+
+//
+
 Object.defineProperties( Material.prototype, {
 	wrapAround: {
 		get: function () {
@@ -525,22 +549,6 @@ EventDispatcher.prototype = Object.assign( Object.create( {
 
 //
 
-Object.defineProperties( Uniform.prototype, {
-	dynamic: {
-		set: function ( value ) {
-			console.warn( 'THREE.Uniform: .dynamic has been removed. Use object.onBeforeRender() instead.' );
-		}
-	},
-	onUpdate: {
-		value: function () {
-			console.warn( 'THREE.Uniform: .onUpdate() has been removed. Use object.onBeforeRender() instead.' );
-			return this;
-		}
-	}
-} );
-
-//
-
 Object.assign( WebGLRenderer.prototype, {
 	supportsFloatTextures: function () {
 		console.warn( 'THREE.WebGLRenderer: .supportsFloatTextures() is now .extensions.get( \'OES_texture_float\' ).' );

+ 2 - 1
src/Three.js

@@ -3,6 +3,7 @@ import './polyfills.js';
 export { WebGLRenderTargetCube } from './renderers/WebGLRenderTargetCube.js';
 export { WebGLRenderTarget } from './renderers/WebGLRenderTarget.js';
 export { WebGLRenderer } from './renderers/WebGLRenderer.js';
+export { WebGL2Renderer } from './renderers/WebGL2Renderer.js';
 export { ShaderLib } from './renderers/shaders/ShaderLib.js';
 export { UniformsLib } from './renderers/shaders/UniformsLib.js';
 export { UniformsUtils } from './renderers/shaders/UniformsUtils.js';
@@ -42,7 +43,7 @@ export { DefaultLoadingManager, LoadingManager } from './loaders/LoadingManager.
 export { JSONLoader } from './loaders/JSONLoader.js';
 export { ImageLoader } from './loaders/ImageLoader.js';
 export { FontLoader } from './loaders/FontLoader.js';
-export { XHRLoader } from './loaders/XHRLoader.js';
+export { FileLoader } from './loaders/FileLoader.js';
 export { Loader } from './loaders/Loader.js';
 export { Cache } from './loaders/Cache.js';
 export { AudioLoader } from './loaders/AudioLoader.js';

+ 1 - 1
src/constants.js

@@ -1,4 +1,4 @@
-export var REVISION = '82dev';
+export var REVISION = '83dev';
 export var MOUSE = { LEFT: 0, MIDDLE: 1, RIGHT: 2 };
 export var CullFaceNone = 0;
 export var CullFaceBack = 1;

+ 1 - 1
src/geometries/DodecahedronGeometry.js

@@ -16,7 +16,7 @@ function DodecahedronGeometry( radius, detail ) {
 		detail: detail
 	};
 
-	this.fromBufferGeometry( new THREE.DodecahedronBufferGeometry( radius, detail ) );
+	this.fromBufferGeometry( new DodecahedronBufferGeometry( radius, detail ) );
 	this.mergeVertices();
 
 }

+ 1 - 0
src/geometries/Geometries.js

@@ -27,6 +27,7 @@ export { PlaneGeometry } from './PlaneGeometry.js';
 export { LatheGeometry } from './LatheGeometry.js';
 export { LatheBufferGeometry } from './LatheBufferGeometry.js';
 export { ShapeGeometry } from './ShapeGeometry.js';
+export { ShapeBufferGeometry } from './ShapeBufferGeometry.js';
 export { ExtrudeGeometry } from './ExtrudeGeometry.js';
 export { EdgesGeometry } from './EdgesGeometry.js';
 export { ConeGeometry } from './ConeGeometry.js';

+ 1 - 1
src/geometries/IcosahedronGeometry.js

@@ -16,7 +16,7 @@ function IcosahedronGeometry( radius, detail ) {
 		detail: detail
 	};
 
-	this.fromBufferGeometry( new THREE.IcosahedronBufferGeometry( radius, detail ) );
+	this.fromBufferGeometry( new IcosahedronBufferGeometry( radius, detail ) );
 	this.mergeVertices();
 
 }

+ 1 - 1
src/geometries/OctahedronGeometry.js

@@ -16,7 +16,7 @@ function OctahedronGeometry( radius, detail ) {
 		detail: detail
 	};
 
-	this.fromBufferGeometry( new THREE.OctahedronBufferGeometry( radius, detail ) );
+	this.fromBufferGeometry( new OctahedronBufferGeometry( radius, detail ) );
 	this.mergeVertices();
 
 }

+ 142 - 0
src/geometries/ShapeBufferGeometry.js

@@ -0,0 +1,142 @@
+import { BufferGeometry } from '../core/BufferGeometry';
+import { Float32Attribute, Uint16Attribute, Uint32Attribute } from '../core/BufferAttribute';
+import { ShapeUtils } from '../extras/ShapeUtils';
+
+/**
+ * @author Mugen87 / https://github.com/Mugen87
+ *
+ * Creates a one-sided polygonal geometry from one or more shapes.
+ *
+ **/
+
+function ShapeBufferGeometry( shapes, curveSegments ) {
+
+	BufferGeometry.call( this );
+
+	this.type = 'ShapeBufferGeometry';
+
+	this.parameters = {
+		shapes: shapes,
+		curveSegments: curveSegments
+	};
+
+	curveSegments = curveSegments || 12;
+
+	var vertices = [];
+	var normals = [];
+	var uvs = [];
+	var indices = [];
+
+	var groupStart = 0;
+	var groupCount = 0;
+
+	// allow single and array values for "shapes" parameter
+
+	if ( Array.isArray( shapes ) === false ) {
+
+		addShape( shapes );
+
+	} else {
+
+		for ( var i = 0; i < shapes.length; i++ ) {
+
+			addShape( shapes[ i ] );
+
+			this.addGroup( groupStart, groupCount, i ); // enables MultiMaterial support
+
+			groupStart += groupCount;
+			groupCount = 0;
+
+		}
+
+	}
+
+	// build geometry
+
+	this.setIndex( ( indices.length > 65535 ? Uint32Attribute : Uint16Attribute )( indices, 1 ) );
+	this.addAttribute( 'position', Float32Attribute( vertices, 3 ) );
+	this.addAttribute( 'normal', Float32Attribute( normals, 3 ) );
+	this.addAttribute( 'uv', Float32Attribute( uvs, 2 ) );
+
+
+	// helper functions
+
+	function addShape( shape ) {
+
+		var i, l, shapeHole;
+
+		var indexOffset = vertices.length / 3;
+		var points = shape.extractPoints( curveSegments );
+
+		var shapeVertices = points.shape;
+		var shapeHoles = points.holes;
+
+		// check direction of vertices
+
+		if ( ShapeUtils.isClockWise( shapeVertices ) === false ) {
+
+			shapeVertices = shapeVertices.reverse();
+
+			// also check if holes are in the opposite direction
+
+			for ( i = 0, l = shapeHoles.length; i < l; i ++ ) {
+
+				shapeHole = shapeHoles[ i ];
+
+				if ( ShapeUtils.isClockWise( shapeHole ) === true ) {
+
+					shapeHoles[ i ] = shapeHole.reverse();
+
+				}
+
+			}
+
+		}
+
+		var faces = ShapeUtils.triangulateShape( shapeVertices, shapeHoles );
+
+		// join vertices of inner and outer paths to a single array
+
+		for ( i = 0, l = shapeHoles.length; i < l; i ++ ) {
+
+			shapeHole = shapeHoles[ i ];
+			shapeVertices = shapeVertices.concat( shapeHole );
+
+		}
+
+		// vertices, normals, uvs
+
+		for ( i = 0, l = shapeVertices.length; i < l; i ++ ) {
+
+			var vertex = shapeVertices[ i ];
+
+			vertices.push( vertex.x, vertex.y, 0 );
+			normals.push( 0, 0, 1 );
+			uvs.push( vertex.x, vertex.y ); // world uvs
+
+		}
+
+		// incides
+
+		for ( i = 0, l = faces.length; i < l; i ++ ) {
+
+			var face = faces[ i ];
+
+			var a = face[ 0 ] + indexOffset;
+			var b = face[ 1 ] + indexOffset;
+			var c = face[ 2 ] + indexOffset;
+
+			indices.push( a, b, c );
+			groupCount += 3;
+
+		}
+
+	}
+
+}
+
+ShapeBufferGeometry.prototype = Object.create( BufferGeometry.prototype );
+ShapeBufferGeometry.prototype.constructor = ShapeBufferGeometry;
+
+
+export { ShapeBufferGeometry };

+ 15 - 116
src/geometries/ShapeGeometry.js

@@ -1,140 +1,39 @@
 import { Geometry } from '../core/Geometry';
-import { Face3 } from '../core/Face3';
-import { Vector3 } from '../math/Vector3';
-import { ShapeUtils } from '../extras/ShapeUtils';
-import { ExtrudeGeometry } from './ExtrudeGeometry';
+import { ShapeBufferGeometry } from './ShapeBufferGeometry';
 
 /**
  * @author jonobr1 / http://jonobr1.com
  *
- * Creates a one-sided polygonal geometry from a path shape. Similar to
- * ExtrudeGeometry.
+ * Creates a one-sided polygonal geometry from a path shape.
  *
- * parameters = {
- *
- *	curveSegments: <int>, // number of points on the curves. NOT USED AT THE MOMENT.
- *
- *	material: <int> // material index for front and back faces
- *	uvGenerator: <Object> // object that provides UV generator functions
- *
- * }
  **/
 
-function ShapeGeometry( shapes, options ) {
+function ShapeGeometry( shapes, curveSegments ) {
 
 	Geometry.call( this );
 
 	this.type = 'ShapeGeometry';
 
-	if ( Array.isArray( shapes ) === false ) shapes = [ shapes ];
-
-	this.addShapeList( shapes, options );
-
-	this.computeFaceNormals();
-
-}
-
-ShapeGeometry.prototype = Object.create( Geometry.prototype );
-ShapeGeometry.prototype.constructor = ShapeGeometry;
-
-/**
- * Add an array of shapes to THREE.ShapeGeometry.
- */
-ShapeGeometry.prototype.addShapeList = function ( shapes, options ) {
-
-	for ( var i = 0, l = shapes.length; i < l; i ++ ) {
-
-		this.addShape( shapes[ i ], options );
-
-	}
-
-	return this;
-
-};
-
-/**
- * Adds a shape to THREE.ShapeGeometry, based on THREE.ExtrudeGeometry.
- */
-ShapeGeometry.prototype.addShape = function ( shape, options ) {
-
-	if ( options === undefined ) options = {};
-	var curveSegments = options.curveSegments !== undefined ? options.curveSegments : 12;
-
-	var material = options.material;
-	var uvgen = options.UVGenerator === undefined ? ExtrudeGeometry.WorldUVGenerator : options.UVGenerator;
-
-	//
-
-	var i, l, hole;
-
-	var shapesOffset = this.vertices.length;
-	var shapePoints = shape.extractPoints( curveSegments );
-
-	var vertices = shapePoints.shape;
-	var holes = shapePoints.holes;
-
-	var reverse = ! ShapeUtils.isClockWise( vertices );
+	if ( typeof curveSegments === 'object' ) {
 
-	if ( reverse ) {
+		console.warn( 'THREE.ShapeGeometry: Options parameter has been removed.' );
 
-		vertices = vertices.reverse();
-
-		// Maybe we should also check if holes are in the opposite direction, just to be safe...
-
-		for ( i = 0, l = holes.length; i < l; i ++ ) {
-
-			hole = holes[ i ];
-
-			if ( ShapeUtils.isClockWise( hole ) ) {
-
-				holes[ i ] = hole.reverse();
-
-			}
-
-		}
-
-		reverse = false;
-
-	}
-
-	var faces = ShapeUtils.triangulateShape( vertices, holes );
-
-	// Vertices
-
-	for ( i = 0, l = holes.length; i < l; i ++ ) {
-
-		hole = holes[ i ];
-		vertices = vertices.concat( hole );
+		curveSegments = curveSegments.curveSegments;
 
 	}
 
-	//
+	this.parameters = {
+		shapes: shapes,
+		curveSegments: curveSegments
+	};
 
-	var vert, vlen = vertices.length;
-	var face, flen = faces.length;
+	this.fromBufferGeometry( new ShapeBufferGeometry( shapes, curveSegments ) );
+	this.mergeVertices();
 
-	for ( i = 0; i < vlen; i ++ ) {
-
-		vert = vertices[ i ];
-
-		this.vertices.push( new Vector3( vert.x, vert.y, 0 ) );
-
-	}
-
-	for ( i = 0; i < flen; i ++ ) {
-
-		face = faces[ i ];
-
-		var a = face[ 0 ] + shapesOffset;
-		var b = face[ 1 ] + shapesOffset;
-		var c = face[ 2 ] + shapesOffset;
-
-		this.faces.push( new Face3( a, b, c, null, null, material ) );
-		this.faceVertexUvs[ 0 ].push( uvgen.generateTopUV( this, a, b, c ) );
-
-	}
+}
 
-};
+ShapeGeometry.prototype = Object.create( Geometry.prototype );
+ShapeGeometry.prototype.constructor = ShapeGeometry;
 
 
 export { ShapeGeometry };

+ 1 - 1
src/geometries/TetrahedronGeometry.js

@@ -16,7 +16,7 @@ function TetrahedronGeometry( radius, detail ) {
 		detail: detail
 	};
 
-	this.fromBufferGeometry( new THREE.TetrahedronBufferGeometry( radius, detail ) );
+	this.fromBufferGeometry( new TetrahedronBufferGeometry( radius, detail ) );
 	this.mergeVertices();
 
 }

+ 1 - 1
src/geometries/TubeBufferGeometry.js

@@ -27,7 +27,7 @@ function TubeBufferGeometry( path, tubularSegments, radius, radialSegments, clos
 	tubularSegments = tubularSegments || 64;
 	radius = radius || 1;
 	radialSegments = radialSegments || 8;
-	closed = closed || false;
+	closed = closed || false;
 
 	var frames = path.computeFrenetFrames( tubularSegments, closed );
 

+ 2 - 2
src/loaders/AnimationLoader.js

@@ -1,5 +1,5 @@
 import { AnimationClip } from '../animation/AnimationClip';
-import { XHRLoader } from './XHRLoader';
+import { FileLoader } from './FileLoader';
 import { DefaultLoadingManager } from './LoadingManager';
 
 /**
@@ -18,7 +18,7 @@ Object.assign( AnimationLoader.prototype, {
 
 		var scope = this;
 
-		var loader = new XHRLoader( scope.manager );
+		var loader = new FileLoader( scope.manager );
 		loader.load( url, function ( text ) {
 
 			onLoad( scope.parse( JSON.parse( text ) ) );

+ 2 - 2
src/loaders/AudioLoader.js

@@ -1,5 +1,5 @@
 import { getAudioContext } from '../audio/AudioContext';
-import { XHRLoader } from './XHRLoader';
+import { FileLoader } from './FileLoader';
 import { DefaultLoadingManager } from './LoadingManager';
 
 /**
@@ -16,7 +16,7 @@ Object.assign( AudioLoader.prototype, {
 
 	load: function ( url, onLoad, onProgress, onError ) {
 
-		var loader = new XHRLoader( this.manager );
+		var loader = new FileLoader( this.manager );
 		loader.setResponseType( 'arraybuffer' );
 		loader.load( url, function ( buffer ) {
 

+ 2 - 2
src/loaders/BinaryTextureLoader.js

@@ -1,5 +1,5 @@
 import { LinearFilter, LinearMipMapLinearFilter, ClampToEdgeWrapping } from '../constants';
-import { XHRLoader } from './XHRLoader';
+import { FileLoader } from './FileLoader';
 import { DataTexture } from '../textures/DataTexture';
 import { DefaultLoadingManager } from './LoadingManager';
 
@@ -27,7 +27,7 @@ Object.assign( BinaryTextureLoader.prototype, {
 
 		var texture = new DataTexture();
 
-		var loader = new XHRLoader( this.manager );
+		var loader = new FileLoader( this.manager );
 		loader.setResponseType( 'arraybuffer' );
 
 		loader.load( url, function ( buffer ) {

+ 2 - 2
src/loaders/BufferGeometryLoader.js

@@ -2,7 +2,7 @@ import { Sphere } from '../math/Sphere';
 import { Vector3 } from '../math/Vector3';
 import { BufferAttribute } from '../core/BufferAttribute';
 import { BufferGeometry } from '../core/BufferGeometry';
-import { XHRLoader } from './XHRLoader';
+import { FileLoader } from './FileLoader';
 import { DefaultLoadingManager } from './LoadingManager';
 
 /**
@@ -21,7 +21,7 @@ Object.assign( BufferGeometryLoader.prototype, {
 
 		var scope = this;
 
-		var loader = new XHRLoader( scope.manager );
+		var loader = new FileLoader( scope.manager );
 		loader.load( url, function ( text ) {
 
 			onLoad( scope.parse( JSON.parse( text ) ) );

+ 2 - 2
src/loaders/CompressedTextureLoader.js

@@ -1,5 +1,5 @@
 import { LinearFilter } from '../constants';
-import { XHRLoader } from './XHRLoader';
+import { FileLoader } from './FileLoader';
 import { CompressedTexture } from '../textures/CompressedTexture';
 import { DefaultLoadingManager } from './LoadingManager';
 
@@ -29,7 +29,7 @@ Object.assign( CompressedTextureLoader.prototype, {
 		var texture = new CompressedTexture();
 		texture.image = images;
 
-		var loader = new XHRLoader( this.manager );
+		var loader = new FileLoader( this.manager );
 		loader.setPath( this.path );
 		loader.setResponseType( 'arraybuffer' );
 

+ 15 - 8
src/loaders/XHRLoader.js → src/loaders/FileLoader.js

@@ -1,17 +1,17 @@
-import { Cache } from './Cache';
-import { DefaultLoadingManager } from './LoadingManager';
-
 /**
  * @author mrdoob / http://mrdoob.com/
  */
 
-function XHRLoader( manager ) {
+import { Cache } from './Cache';
+import { DefaultLoadingManager } from './LoadingManager';
+
+function FileLoader( manager ) {
 
 	this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;
 
 }
 
-Object.assign( XHRLoader.prototype, {
+Object.assign( FileLoader.prototype, {
 
 	load: function ( url, onLoad, onProgress, onError ) {
 
@@ -147,7 +147,7 @@ Object.assign( XHRLoader.prototype, {
 					// Some browsers return HTTP Status 0 when using non-http protocol
 					// e.g. 'file://' or 'data://'. Handle as success.
 
-					console.warn( 'THREE.XHRLoader: HTTP Status 0 received.' );
+					console.warn( 'THREE.FileLoader: HTTP Status 0 received.' );
 
 					if ( onLoad ) onLoad( response );
 
@@ -184,7 +184,7 @@ Object.assign( XHRLoader.prototype, {
 			if ( this.responseType !== undefined ) request.responseType = this.responseType;
 			if ( this.withCredentials !== undefined ) request.withCredentials = this.withCredentials;
 
-			if ( request.overrideMimeType ) request.overrideMimeType( 'text/plain' );
+			if ( request.overrideMimeType ) request.overrideMimeType( this.mimeType !== undefined ? this.mimeType : 'text/plain' );
 
 			request.send( null );
 
@@ -215,9 +215,16 @@ Object.assign( XHRLoader.prototype, {
 		this.withCredentials = value;
 		return this;
 
+	},
+
+	setMimeType: function ( value ) {
+
+		this.mimeType = value;
+		return this;
+
 	}
 
 } );
 
 
-export { XHRLoader };
+export { FileLoader };

+ 2 - 2
src/loaders/FontLoader.js

@@ -1,5 +1,5 @@
 import { Font } from '../extras/core/Font';
-import { XHRLoader } from './XHRLoader';
+import { FileLoader } from './FileLoader';
 import { DefaultLoadingManager } from './LoadingManager';
 
 /**
@@ -18,7 +18,7 @@ Object.assign( FontLoader.prototype, {
 
 		var scope = this;
 
-		var loader = new XHRLoader( this.manager );
+		var loader = new FileLoader( this.manager );
 		loader.load( url, function ( text ) {
 
 			var json;

+ 2 - 2
src/loaders/ImageLoader.js

@@ -1,4 +1,4 @@
-import { XHRLoader } from './XHRLoader';
+import { FileLoader } from './FileLoader';
 import { DefaultLoadingManager } from './LoadingManager';
 
 /**
@@ -37,7 +37,7 @@ Object.assign( ImageLoader.prototype, {
 
 		} else {
 
-			var loader = new XHRLoader();
+			var loader = new FileLoader();
 			loader.setPath( this.path );
 			loader.setResponseType( 'blob' );
 			loader.setWithCredentials( this.withCredentials );

+ 2 - 2
src/loaders/JSONLoader.js

@@ -6,7 +6,7 @@ import { Color } from '../math/Color';
 import { Vector2 } from '../math/Vector2';
 import { Face3 } from '../core/Face3';
 import { Geometry } from '../core/Geometry';
-import { XHRLoader } from './XHRLoader';
+import { FileLoader } from './FileLoader';
 import { DefaultLoadingManager } from './LoadingManager';
 
 /**
@@ -37,7 +37,7 @@ Object.assign( JSONLoader.prototype, {
 
 		var texturePath = this.texturePath && ( typeof this.texturePath === "string" ) ? this.texturePath : Loader.prototype.extractUrlBase( url );
 
-		var loader = new XHRLoader( this.manager );
+		var loader = new FileLoader( this.manager );
 		loader.setWithCredentials( this.withCredentials );
 		loader.load( url, function ( text ) {
 

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