Browse Source

Merge branch 'dev' of https://github.com/mrdoob/three.js into dev

OpenShift guest 12 years ago
parent
commit
e0d92373aa
100 changed files with 3028 additions and 2347 deletions
  1. 21 17
      CONTRIBUTING.md
  2. 1 1
      README.md
  3. 585 206
      build/three.js
  4. 307 302
      build/three.min.js
  5. 0 0
      docs/api/core/BufferGeometry.html
  6. 0 77
      docs/api/core/Ray.html
  7. 0 0
      docs/api/core/Raycaster.html
  8. 0 66
      docs/api/core/Rectangle.html
  9. 0 54
      docs/api/core/UV.html
  10. 42 0
      docs/api/extras/FontUtils.html
  11. 0 15
      docs/api/extras/core/Curve.rst
  12. 0 14
      docs/api/extras/core/CurvePath.rst
  13. 0 14
      docs/api/extras/core/Path.rst
  14. 0 14
      docs/api/extras/core/Shape.rst
  15. 0 14
      docs/api/extras/core/TextPath.rst
  16. 37 0
      docs/api/extras/geometries/AsteriskGeometry.html
  17. 37 0
      docs/api/extras/geometries/CircleGeometry.html
  18. 37 0
      docs/api/extras/geometries/ConvexGeometry.html
  19. 37 0
      docs/api/extras/geometries/ParametricGeometry.html
  20. 37 0
      docs/api/extras/geometries/ShapeGeometry.html
  21. 37 0
      docs/api/extras/geometries/TubeGeometry.html
  22. 0 0
      docs/api/extras/helpers/ArrowHelper.html
  23. 0 0
      docs/api/extras/helpers/DirectionalLightHelper.html
  24. 3 3
      docs/api/extras/helpers/HemisphereLightHelper.html
  25. 3 3
      docs/api/extras/helpers/PointLightHelper.html
  26. 3 3
      docs/api/extras/helpers/SpotLightHelper.html
  27. 0 45
      docs/api/extras/modifiers/SubdivisionModifier.html
  28. 37 0
      docs/api/extras/objects/ImmediateRenderObject.html
  29. 37 0
      docs/api/extras/objects/MorphBlendMesh.html
  30. 0 0
      docs/api/extras/renderers/plugins/DepthPassPlugin.html
  31. 1 3
      docs/api/lights/AmbientLight.html
  32. 37 0
      docs/api/lights/AreaLight.html
  33. 37 0
      docs/api/lights/HemisphereLight.html
  34. 39 0
      docs/api/materials/LineDashedMaterial.html
  35. 39 0
      docs/api/materials/SpriteMaterial.html
  36. 37 0
      docs/api/math/Box2.html
  37. 37 0
      docs/api/math/Box3.html
  38. 0 0
      docs/api/math/Color.html
  39. 1 1
      docs/api/math/Frustum.html
  40. 0 0
      docs/api/math/Math.html
  41. 0 0
      docs/api/math/Matrix3.html
  42. 0 0
      docs/api/math/Matrix4.html
  43. 37 0
      docs/api/math/Plane.html
  44. 0 0
      docs/api/math/Quaternion.html
  45. 37 0
      docs/api/math/Ray.html
  46. 37 0
      docs/api/math/Sphere.html
  47. 0 0
      docs/api/math/Spline.html
  48. 37 0
      docs/api/math/Triangle.html
  49. 1 1
      docs/api/math/Vector2.html
  50. 0 0
      docs/api/math/Vector3.html
  51. 0 0
      docs/api/math/Vector4.html
  52. 39 0
      docs/api/textures/CompressedTexture.html
  53. 45 31
      docs/list.js
  54. 2 0
      editor/index.html
  55. 14 0
      editor/js/ui/Menubar.Add.js
  56. 8 0
      editor/js/ui/Menubar.Edit.js
  57. 5 3
      editor/js/ui/Sidebar.Geometry.js
  58. 7 6
      editor/js/ui/Sidebar.Material.js
  59. 8 0
      editor/js/ui/Viewport.js
  60. 8 3
      examples/canvas_interactive_voxelpainter.html
  61. 1 3
      examples/canvas_materials.html
  62. 4 4
      examples/js/controls/TrackballControls.js
  63. 6 4
      examples/js/loaders/ColladaLoader.js
  64. 0 83
      examples/js/renderers/DOMRenderer.js
  65. 8 11
      examples/js/renderers/SVGRenderer.js
  66. 219 173
      examples/js/renderers/SoftwareRenderer.js
  67. 0 409
      examples/js/renderers/SoftwareRenderer2.js
  68. 0 427
      examples/js/renderers/SoftwareRenderer3.js
  69. 6 4
      examples/js/renderers/WebGLDeferredRenderer.js
  70. 3 3
      examples/misc_controls_pointerlock.html
  71. 1 3
      examples/misc_software.html
  72. 4 9
      examples/misc_ubiquity_test.html
  73. 411 0
      examples/webgl_geometry_normals.html
  74. 2 1
      examples/webgl_interactive_voxelpainter.html
  75. 3 2
      examples/webgl_lights_deferred_arealights.html
  76. 1 1
      src/Three.js
  77. 79 22
      src/core/Geometry.js
  78. 2 2
      src/core/Object3D.js
  79. 64 39
      src/core/Projector.js
  80. 0 4
      src/core/Raycaster.js
  81. 22 7
      src/extras/GeometryUtils.js
  82. 1 1
      src/extras/geometries/LatheGeometry.js
  83. 2 2
      src/extras/geometries/TubeGeometry.js
  84. 1 1
      src/extras/renderers/plugins/DepthPassPlugin.js
  85. 13 9
      src/extras/renderers/plugins/LensFlarePlugin.js
  86. 2 2
      src/extras/renderers/plugins/ShadowMapPlugin.js
  87. 9 5
      src/extras/renderers/plugins/SpritePlugin.js
  88. 7 5
      src/extras/shaders/ShaderFlares.js
  89. 0 2
      src/extras/shaders/ShaderSprite.js
  90. 0 15
      src/materials/ParticleDOMMaterial.js
  91. 10 9
      src/math/Box3.js
  92. 114 37
      src/math/Frustum.js
  93. 109 26
      src/math/Matrix3.js
  94. 70 73
      src/math/Matrix4.js
  95. 48 7
      src/math/Plane.js
  96. 0 24
      src/math/Quaternion.js
  97. 3 3
      src/math/Ray.js
  98. 10 2
      src/math/Sphere.js
  99. 1 0
      src/math/Triangle.js
  100. 18 17
      src/math/Vector2.js

+ 21 - 17
CONTRIBUTING.md

@@ -1,23 +1,27 @@
 # The issues section is for bug reports and feature requests only. If you need help, please use [stackoverflow](http://stackoverflow.com/questions/tagged/three.js).
 # The issues section is for bug reports and feature requests only. If you need help, please use [stackoverflow](http://stackoverflow.com/questions/tagged/three.js).
 
 
-## How to report a bug?
 
 
-* Tell us the revision number of three.js you use.
-* Try checking your application with the latest `dev` branch version of three.js (often problems are already fixed there). See [migration guide](https://github.com/mrdoob/three.js/wiki/Migration).
-* Tell us where did you observe the problem: your browser version, your operating system, your graphics card (for example Chrome 23.0.1271.95, Windows 7, Nvidia Quadro 2000M)
-* If you can, try to check your problem on multiple browsers / multiple computers (if you are on Windows, especially helpful is to [compare ANGLE and OpenGL renderers](https://github.com/mrdoob/three.js/wiki/How-to-use-OpenGL-or-ANGLE-rendering-on-Windows))
-* Describe the problem in details (what you get instead of what's expected). Saying "it doesn't work" doesn't help much.
-* Create a small testcase (big chance is when you do this, you'll find the answer yourself).
-* If small testcase is not possible, at least include a link to online live version of your application.
-* If your problem creates some visual glitch it helps to include a screenshot (highlight problematic area if problem is subtle).
-* What did you try already?
-* Search issue tracker for similar issues. Somebody else may have already filled an issue about your problem (in that case make a comment there instead of creating new issue). Or there may be other issues that seem similar, it helps if you can cross-reference them (mentioned in text hashed issue number like this `#1234`).
+Before reporting a bug
+---
+1. Search issue tracker for similar issues.
+2. Try the latest dev branch version of three.js.
+3. Refer to the [Migration Guide](https://github.com/mrdoob/three.js/wiki/Migration) when upgrading to the dev version.
 
 
-## How to contribute to three.js?
 
 
-* Make sure you have a GitHub account.
-* Fork the repository on GitHub.
-* Check [contribution guidelines](https://github.com/mrdoob/three.js/wiki/How-to-contribute-to-three.js).
-* Make changes to your clone of the repository.
-* Submit a pull request.
+How to report a bug
+---
+1. Specify the revision number of the three.js library where the bug occurred.
+2. Specify your browser version, operating system, and graphics card. (for example, Chrome 23.0.1271.95, Windows 7, Nvidia Quadro 2000M)
+3. Describe the problem in detail. Explain what happened, and what you expected would happen.
+4. Provide a small test-case (http://jsfiddle.net). If a test-case is not possible, provide a link to a live version of your application.
+5. If helpful, include a screenshot. Annotate the screenshot for clarity.
+
+
+How to contribute to three.js
+---
+1. Make sure you have a GitHub account.
+2. Fork the repository on GitHub.
+3. Check the [Contribution Guidelines](https://github.com/mrdoob/three.js/wiki/How-to-contribute-to-three.js).
+4. Make changes to your clone of the repository.
+5. Submit a pull request.
 
 

+ 1 - 1
README.md

@@ -3,7 +3,7 @@ three.js
 
 
 #### JavaScript 3D library ####
 #### JavaScript 3D library ####
 
 
-The aim of the project is to create a lightweight 3D library with a very low level of complexity — in other words, for dummies. The library provides <canvas>, <svg> and WebGL renderers.
+The aim of the project is to create a lightweight 3D library with a very low level of complexity — in other words, for dummies. The library provides <canvas>, <svg>, CSS3D and WebGL renderers.
 
 
 [Examples](http://mrdoob.github.com/three.js/) — [Documentation](http://mrdoob.github.com/three.js/docs/) — [Migrating](https://github.com/mrdoob/three.js/wiki/Migration) — [Help](http://stackoverflow.com/questions/tagged/three.js)
 [Examples](http://mrdoob.github.com/three.js/) — [Documentation](http://mrdoob.github.com/three.js/docs/) — [Migrating](https://github.com/mrdoob/three.js/wiki/Migration) — [Help](http://stackoverflow.com/questions/tagged/three.js)
 
 

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


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


+ 0 - 0
docs/api/renderers/DOMRenderer.html → docs/api/core/BufferGeometry.html


+ 0 - 77
docs/api/core/Ray.html

@@ -1,77 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-	<head>
-		<meta charset="utf-8">
-		<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">Representation of a ray in space.</div>
-		<div class="desc">Pretty useful for detecting collisions between objects in a scene.</div>
-
-
-		<h2>Constructor</h2>
-
-		<h3>[name]( [page:Vector3 origin], [page:Vector3 direction], [page:Number near], [page:Number far])</h3>
-
-
-		<h2>Properties</h2>
-
-		<h3>.[page:Vector3 origin]</h3>
-		
-		<div>
-		Where does the ray start. Default is *0, 0, 0*.
-		</div>
-
-		<h3>.[page:Vector3 direction]</h3>
-		<div>
-		A vector pointing in the direction the ray goes. Default is *0, 0, 0*.
-		</div>
-		
-		<h3>.[page:Number near]</h3>
-		<div>
-		Defines the closest distance that will be checked for intersections, starting from origin. Default is *0*.
-		</div>
-		
-		<h3>.[page:Number far]</h3>
-		<div>
-		Defines the furthest distance that will be checked for intersections, starting from origin. Default is *Infinity*.
-		</div>
-		
-		<div>Hence, intersections will only be checked in the range *(near, far)*.</div>
-
-
-		<h2>Methods</h2>
-
-		<h3>.setPrecision( [page:Float value] )</h3>
-		
-		<div>Defines the maximum precision used when determining intersections. This is specially important when checking collisions between almost parallel objects, and can make the difference between reporting a collision or not.</div>
-		<div>Default is *0.0001*</div>
-
-		<h3>.intersectObject( [page:Object3D object] ) [page:Object]</h3>
-		
-		<div>Determines whether the ray intersects *object*. The result is an array containing tuples of the form</div>
-<code>
-{
-	distance: // distance between the origin and the intersected object,
-	point: // exact point where the intersection occurs,
-	face: // exact face that the ray intersected,
-	object: // the intersected object
-}
-</code>
-
-		<div>Note that even if we're checking only an object against a ray, the ray can intersect the object in more than one point. Hence, the return value is an array and not a single tuple.</div>
-
-		<h3>.intersectObjects( [page:Array objects] ) [page:Array]</h3>
-		
-		<div>Goes through the *objects* array, and determine whether they ray intersects them. The result is an array that contains similar tuples to the ones returned by intersectObject</div>
-
-The entries in the returned array are sorted by ascending distance (i.e. closest objects first).
-		<h2>Source</h2>
-
-		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
-	</body>
-</html>

+ 0 - 0
docs/api/renderers/SVGRenderer.html → docs/api/core/Raycaster.html


+ 0 - 66
docs/api/core/Rectangle.html

@@ -1,66 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-	<head>
-		<meta charset="utf-8">
-		<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">
-			Mainly used internaly by [page:CanvasRenderer] for 2D clipping.
-		</div>
-
-
-		<h2>Constructor</h2>
-
-		<h3>[name]()</h3>
-
-
-		<h2>Methods</h2>
-
-		<h3>.getX() [page:Float]</h3>
-
-		<h3>.getY() [page:Float]</h3>
-
-		<h3>.getWidth() [page:Float]</h3>
-
-		<h3>.getHeight() [page:Float]</h3>
-
-		<h3>.getLeft() [page:Float]</h3>
-
-		<h3>.getTop() [page:Float]</h3>
-
-		<h3>.getRight() [page:Float]</h3>
-
-		<h3>.getBottom() [page:Float]</h3>
-
-		<h3>.set( [page:Float left], [page:Float top], [page:Float right], [page:Float bottom] )</h3>
-
-		<h3>.addPoint( [page:Float x], [page:Float y] )</h3>
-
-		<h3>.add3Points( [page:Float x1], [page:Float y1], [page:Float x2], [page:Float y2], [page:Float x3], [page:Float y3] )</h3>
-
-		<h3>.addRectangle( [page:Rectangle r] )</h3>
-
-		<h3>.inflate( [page:Float v] )</h3>
-
-		<h3>.minSelf( [page:Rectangle r] )</h3>
-
-		<h3>.intersects( [page:Rectangle r] ) [page:Boolean]</h3>
-		<div>
-		Adapted from [link:http://gamemath.com/2011/09/detecting-whether-two-boxes-overlap/].
-		</div>
-
-		<h3>.empty()</h3>
-
-		<h3>.isEmpty() [page:Boolean]</h3>
-
-
-		<h2>Source</h2>
-
-		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
-	</body>
-</html>

+ 0 - 54
docs/api/core/UV.html

@@ -1,54 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-	<head>
-		<meta charset="utf-8">
-		<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 texture coordinate.</div>
-
-		<h2>Example</h2>
-
-		<code>var uv = new THREE.UV( 0, 1 );</code>
-
-
-		<h2>Constructor</h2>
-
-		<h3>[name]( [page:Float u], [page:Float v] )</h3>
-		<div>
-		u — Horizontal coordinate.<br />
-		v — Vertical coordinate.<br />
-		</div>
-
-
-		<h2>Properties</h2>
-
-		<h3>.[page:Float u]</h3>
-		<div>
-		Horizontal coordinate.<br />
-		</div>
-
-		<h3>.[page:Float v]</h3>
-		<div>
-		Vertical coordinate.<br />
-		</div>
-
-
-		<h2>Methods</h2>
-
-		<h3>.set( [page:Float u], [page:Float v] )</h3>
-
-		<h3>.copy( [page:UV uv] )</h3>
-
-		<h3>.clone() [page:UV]</h3>
-
-
-		<h2>Source</h2>
-
-		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
-	</body>
-</html>

+ 42 - 0
docs/api/extras/FontUtils.html

@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<meta charset="utf-8">
+		<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">This is a utility class to handle values in <a href="https://en.wikipedia.org/wiki/RGB_color_model">RGB</a> and <a href="https://en.wikipedia.org/wiki/HSL_and_HSV">HSV</a> color spaces.</div>
+
+
+		<h2>Methods</h2>
+
+		<h3>.adjustHSV( [page:Color color], [page:Number h], [page:Number s], [page:Number v] )</h3>
+		
+		<div class="desc">Taking a color as input, converts it to HSV, and applies the h, s, v parameters in place, i.e. no new color is returned but the original object is modified.</div>
+		
+		<div>
+		[page:Color color] — source color to be adjusted<br />
+		[page:Number h] — hue change amount<br />
+		[page:Number s] — saturation change amount<br />
+		[page:Number v] — value change amount
+		</div>
+		
+		<h3>.rgbToHsv( [page:Color color], [page:Object hsv] )</h3>
+		
+		<div class="desc">Converts an RGB color into an HSV triplet and returns the converted color.</div>
+		
+		<div>
+		[page:Color color] — source color to be converted<br />
+		[page:Object hsv] — object in which the return value will be stored, if not null
+		</div>
+
+
+		<h2>Source</h2>
+
+		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
+	</body>
+</html>

+ 0 - 15
docs/api/extras/core/Curve.rst

@@ -1,15 +0,0 @@
-Curve - Extensible curve object
---------------------------------------
-
-.. rubric:: Constructor
-
-.. class:: Curve()
-
-    Extensible curve object
-
-.. rubric:: Attributes
-
-.. rubric:: Method
-
-.. rubric:: Example(s)
-    

+ 0 - 14
docs/api/extras/core/CurvePath.rst

@@ -1,14 +0,0 @@
-CurvePath - Path with connected curves
--------------------------------------------
-
-.. rubric:: Constructor
-
-.. class:: CurvePath()
-
-    A Path made with connected set of curves
-    
-.. rubric:: Attributes
-
-.. rubric:: Method
-
-.. rubric:: Example(s)

+ 0 - 14
docs/api/extras/core/Path.rst

@@ -1,14 +0,0 @@
-Path - A CurvePath with a Drawing API
--------------------------------------------
-
-.. rubric:: Constructor
-
-.. class:: Path()
-
-    A CurvePath with convenience Drawing methods 
-    
-.. rubric:: Attributes
-
-.. rubric:: Method
-
-.. rubric:: Example(s)

+ 0 - 14
docs/api/extras/core/Shape.rst

@@ -1,14 +0,0 @@
-Shape - A closed 2d path with holes
-----------------------------------------
-
-.. rubric:: Constructor
-
-.. class:: Shape()
-
-    A closed 2d Path with holes
-    
-.. rubric:: Attributes
-
-.. rubric:: Method
-
-.. rubric:: Example(s)

+ 0 - 14
docs/api/extras/core/TextPath.rst

@@ -1,14 +0,0 @@
-TextPath - Class for turning Text to Shapes
-----------------------------------------------
-
-.. rubric:: Constructor
-
-.. class:: TextPath()
-
-    Class for turning Text to Shapes
-    
-.. rubric:: Attributes
-
-.. rubric:: Method
-
-.. rubric:: Example(s)

+ 37 - 0
docs/api/extras/geometries/AsteriskGeometry.html

@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<meta charset="utf-8">
+		<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">todo</div>
+
+
+		<h2>Constructor</h2>
+
+		<h3>[name]( radius, detail )</h3>
+
+
+		<h2>Properties</h2>
+
+		<h3>.[page:Vector3 todo]</h3>
+
+
+		<h2>Methods</h2>
+
+		<h3>.todo( [page:Vector3 todo] )</h3>
+		<div>
+		todo — todo<br />
+		</div>
+
+
+		<h2>Source</h2>
+
+		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
+	</body>
+</html>

+ 37 - 0
docs/api/extras/geometries/CircleGeometry.html

@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<meta charset="utf-8">
+		<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">todo</div>
+
+
+		<h2>Constructor</h2>
+
+		<h3>[name]( radius, detail )</h3>
+
+
+		<h2>Properties</h2>
+
+		<h3>.[page:Vector3 todo]</h3>
+
+
+		<h2>Methods</h2>
+
+		<h3>.todo( [page:Vector3 todo] )</h3>
+		<div>
+		todo — todo<br />
+		</div>
+
+
+		<h2>Source</h2>
+
+		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
+	</body>
+</html>

+ 37 - 0
docs/api/extras/geometries/ConvexGeometry.html

@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<meta charset="utf-8">
+		<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">todo</div>
+
+
+		<h2>Constructor</h2>
+
+		<h3>[name]( radius, detail )</h3>
+
+
+		<h2>Properties</h2>
+
+		<h3>.[page:Vector3 todo]</h3>
+
+
+		<h2>Methods</h2>
+
+		<h3>.todo( [page:Vector3 todo] )</h3>
+		<div>
+		todo — todo<br />
+		</div>
+
+
+		<h2>Source</h2>
+
+		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
+	</body>
+</html>

+ 37 - 0
docs/api/extras/geometries/ParametricGeometry.html

@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<meta charset="utf-8">
+		<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">todo</div>
+
+
+		<h2>Constructor</h2>
+
+		<h3>[name]( radius, detail )</h3>
+
+
+		<h2>Properties</h2>
+
+		<h3>.[page:Vector3 todo]</h3>
+
+
+		<h2>Methods</h2>
+
+		<h3>.todo( [page:Vector3 todo] )</h3>
+		<div>
+		todo — todo<br />
+		</div>
+
+
+		<h2>Source</h2>
+
+		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
+	</body>
+</html>

+ 37 - 0
docs/api/extras/geometries/ShapeGeometry.html

@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<meta charset="utf-8">
+		<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">todo</div>
+
+
+		<h2>Constructor</h2>
+
+		<h3>[name]( radius, detail )</h3>
+
+
+		<h2>Properties</h2>
+
+		<h3>.[page:Vector3 todo]</h3>
+
+
+		<h2>Methods</h2>
+
+		<h3>.todo( [page:Vector3 todo] )</h3>
+		<div>
+		todo — todo<br />
+		</div>
+
+
+		<h2>Source</h2>
+
+		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
+	</body>
+</html>

+ 37 - 0
docs/api/extras/geometries/TubeGeometry.html

@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<meta charset="utf-8">
+		<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">todo</div>
+
+
+		<h2>Constructor</h2>
+
+		<h3>[name]( radius, detail )</h3>
+
+
+		<h2>Properties</h2>
+
+		<h3>.[page:Vector3 todo]</h3>
+
+
+		<h2>Methods</h2>
+
+		<h3>.todo( [page:Vector3 todo] )</h3>
+		<div>
+		todo — todo<br />
+		</div>
+
+
+		<h2>Source</h2>
+
+		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
+	</body>
+</html>

+ 0 - 0
docs/api/extras/core/BufferGeometry.html → docs/api/extras/helpers/ArrowHelper.html


+ 0 - 0
docs/api/extras/core/TextPath.html → docs/api/extras/helpers/DirectionalLightHelper.html


+ 3 - 3
docs/api/extras/renderers/effects/CrosseyedEffect.html → docs/api/extras/helpers/HemisphereLightHelper.html

@@ -2,9 +2,9 @@
 <html lang="en">
 <html lang="en">
 	<head>
 	<head>
 		<meta charset="utf-8">
 		<meta charset="utf-8">
-		<script src="../../../../list.js"></script>
-		<script src="../../../../page.js"></script>
-		<link type="text/css" rel="stylesheet" href="../../../../page.css" />
+		<script src="../../../list.js"></script>
+		<script src="../../../page.js"></script>
+		<link type="text/css" rel="stylesheet" href="../../../page.css" />
 	</head>
 	</head>
 	<body>
 	<body>
 		<h1>[name]</h1>
 		<h1>[name]</h1>

+ 3 - 3
docs/api/extras/renderers/effects/StereoEffect.html → docs/api/extras/helpers/PointLightHelper.html

@@ -2,9 +2,9 @@
 <html lang="en">
 <html lang="en">
 	<head>
 	<head>
 		<meta charset="utf-8">
 		<meta charset="utf-8">
-		<script src="../../../../list.js"></script>
-		<script src="../../../../page.js"></script>
-		<link type="text/css" rel="stylesheet" href="../../../../page.css" />
+		<script src="../../../list.js"></script>
+		<script src="../../../page.js"></script>
+		<link type="text/css" rel="stylesheet" href="../../../page.css" />
 	</head>
 	</head>
 	<body>
 	<body>
 		<h1>[name]</h1>
 		<h1>[name]</h1>

+ 3 - 3
docs/api/extras/renderers/effects/ParallaxBarrierEffect.html → docs/api/extras/helpers/SpotLightHelper.html

@@ -2,9 +2,9 @@
 <html lang="en">
 <html lang="en">
 	<head>
 	<head>
 		<meta charset="utf-8">
 		<meta charset="utf-8">
-		<script src="../../../../list.js"></script>
-		<script src="../../../../page.js"></script>
-		<link type="text/css" rel="stylesheet" href="../../../../page.css" />
+		<script src="../../../list.js"></script>
+		<script src="../../../page.js"></script>
+		<link type="text/css" rel="stylesheet" href="../../../page.css" />
 	</head>
 	</head>
 	<body>
 	<body>
 		<h1>[name]</h1>
 		<h1>[name]</h1>

+ 0 - 45
docs/api/extras/modifiers/SubdivisionModifier.html

@@ -1,45 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-	<head>
-		<meta charset="utf-8">
-		<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">Applies Catmull-Clark Subdivision Surfaces for creating smooth geometry meshes</div>
-
-
-		<h2>Constructor</h2>
-
-		<h3>[name]( subdivisions )</h3>
-
-
-		<h2>Properties</h2>
-
-		<h3>.subdivisions</h3>
-		<div>Number of time subdivision will be applied</div>
-
-		<h3>.useOldVertexColors</h3>
-
-		<h3>.supportUVs</h3>
-
-		<h3>.debug</h3>
-
-		<h2>Methods</h2>
-
-		<h3>.modify ( geometry )</h3>
-		<div>Modifies the geometry by running subdivision surfaces. This calls .smooth() internally</div>
-
-		<h3>.smooth ( oldGeometry )</h3>
-		<div>Performs an iteration of Catmull-Clark Subdivision</div>
-
-
-
-		<h2>Source</h2>
-
-		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
-	</body>
-</html>

+ 37 - 0
docs/api/extras/objects/ImmediateRenderObject.html

@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<meta charset="utf-8">
+		<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">todo</div>
+
+
+		<h2>Constructor</h2>
+
+		<h3>[name]( texture, size, distance, blending, color )</h3>
+
+
+		<h2>Properties</h2>
+
+		<h3>.[page:Vector3 todo]</h3>
+
+
+		<h2>Methods</h2>
+
+		<h3>.todo( [page:Vector3 todo] )</h3>
+		<div>
+		todo — todo<br />
+		</div>
+
+
+		<h2>Source</h2>
+
+		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
+	</body>
+</html>

+ 37 - 0
docs/api/extras/objects/MorphBlendMesh.html

@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<meta charset="utf-8">
+		<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">todo</div>
+
+
+		<h2>Constructor</h2>
+
+		<h3>[name]( texture, size, distance, blending, color )</h3>
+
+
+		<h2>Properties</h2>
+
+		<h3>.[page:Vector3 todo]</h3>
+
+
+		<h2>Methods</h2>
+
+		<h3>.todo( [page:Vector3 todo] )</h3>
+		<div>
+		todo — todo<br />
+		</div>
+
+
+		<h2>Source</h2>
+
+		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
+	</body>
+</html>

+ 0 - 0
docs/api/extras/renderers/effects/AnaglyphEffect.html → docs/api/extras/renderers/plugins/DepthPassPlugin.html


+ 1 - 3
docs/api/lights/AmbientLight.html

@@ -18,11 +18,9 @@
 
 
 		<h2>Example</h2>
 		<h2>Example</h2>
 
 
-<code>var light = new THREE.AmbientLight( 0xff0000 );
+<code>var light = new THREE.AmbientLight( 0x404040 ); // soft white light
 scene.add( light );</code>
 scene.add( light );</code>
 
 
-		will light objects with red.
-
 		<h2>Constructor</h2>
 		<h2>Constructor</h2>
 
 
 		<h3>[name]( [page:Float hex] )</h3>
 		<h3>[name]( [page:Float hex] )</h3>

+ 37 - 0
docs/api/lights/AreaLight.html

@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<meta charset="utf-8">
+		<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">todo</div>
+
+
+		<h2>Constructor</h2>
+
+		<h3>[name]()</h3>
+
+
+		<h2>Properties</h2>
+
+		<h3>.[page:Vector3 todo]</h3>
+
+
+		<h2>Methods</h2>
+
+		<h3>.todo( [page:Vector3 todo] )</h3>
+		<div>
+		todo — todo<br />
+		</div>
+
+
+		<h2>Source</h2>
+
+		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
+	</body>
+</html>

+ 37 - 0
docs/api/lights/HemisphereLight.html

@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<meta charset="utf-8">
+		<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">todo</div>
+
+
+		<h2>Constructor</h2>
+
+		<h3>[name]()</h3>
+
+
+		<h2>Properties</h2>
+
+		<h3>.[page:Vector3 todo]</h3>
+
+
+		<h2>Methods</h2>
+
+		<h3>.todo( [page:Vector3 todo] )</h3>
+		<div>
+		todo — todo<br />
+		</div>
+
+
+		<h2>Source</h2>
+
+		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
+	</body>
+</html>

+ 39 - 0
docs/api/materials/LineDashedMaterial.html

@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<meta charset="utf-8">
+		<script src="../../list.js"></script>
+		<script src="../../page.js"></script>
+		<link type="text/css" rel="stylesheet" href="../../page.css" />
+	</head>
+	<body>
+		[page:Material] &rarr;
+
+		<h1>[name]</h1>
+
+		<div class="desc">todo</div>
+
+
+		<h2>Constructor</h2>
+
+		<h3>[name]()</h3>
+
+
+		<h2>Properties</h2>
+
+		<h3>.[page:Vector3 todo]</h3>
+
+
+		<h2>Methods</h2>
+
+		<h3>.todo( [page:Vector3 todo] )</h3>
+		<div>
+		todo — todo<br />
+		</div>
+
+
+		<h2>Source</h2>
+
+		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
+	</body>
+</html>

+ 39 - 0
docs/api/materials/SpriteMaterial.html

@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<meta charset="utf-8">
+		<script src="../../list.js"></script>
+		<script src="../../page.js"></script>
+		<link type="text/css" rel="stylesheet" href="../../page.css" />
+	</head>
+	<body>
+		[page:Material] &rarr;
+
+		<h1>[name]</h1>
+
+		<div class="desc">todo</div>
+
+
+		<h2>Constructor</h2>
+
+		<h3>[name]()</h3>
+
+
+		<h2>Properties</h2>
+
+		<h3>.[page:Vector3 todo]</h3>
+
+
+		<h2>Methods</h2>
+
+		<h3>.todo( [page:Vector3 todo] )</h3>
+		<div>
+		todo — todo<br />
+		</div>
+
+
+		<h2>Source</h2>
+
+		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
+	</body>
+</html>

+ 37 - 0
docs/api/math/Box2.html

@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<meta charset="utf-8">
+		<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">todo</div>
+
+
+		<h2>Constructor</h2>
+
+		<h3>[name]()</h3>
+
+
+		<h2>Properties</h2>
+
+		<h3>.[page:Vector3 todo]</h3>
+
+
+		<h2>Methods</h2>
+
+		<h3>.todo( [page:Vector3 todo] )</h3>
+		<div>
+		todo — todo<br />
+		</div>
+
+
+		<h2>Source</h2>
+
+		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
+	</body>
+</html>

+ 37 - 0
docs/api/math/Box3.html

@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<meta charset="utf-8">
+		<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">todo</div>
+
+
+		<h2>Constructor</h2>
+
+		<h3>[name]()</h3>
+
+
+		<h2>Properties</h2>
+
+		<h3>.[page:Vector3 todo]</h3>
+
+
+		<h2>Methods</h2>
+
+		<h3>.todo( [page:Vector3 todo] )</h3>
+		<div>
+		todo — todo<br />
+		</div>
+
+
+		<h2>Source</h2>
+
+		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
+	</body>
+</html>

+ 0 - 0
docs/api/core/Color.html → docs/api/math/Color.html


+ 1 - 1
docs/api/core/Frustum.html → docs/api/math/Frustum.html

@@ -29,7 +29,7 @@
 
 
 		<h3>.setFromMatrix( [page:Matrix4 matrix] )</h3>
 		<h3>.setFromMatrix( [page:Matrix4 matrix] )</h3>
 
 
-		<h3>.contains( [page:Object3D object] ) [page:Boolean]</h3>
+		<h3>.intersectsObject( [page:Object3D object] ) [page:Boolean]</h3>
 		<div>
 		<div>
 		Checks whether the object is inside the Frustum.
 		Checks whether the object is inside the Frustum.
 		</div>
 		</div>

+ 0 - 0
docs/api/core/Math.html → docs/api/math/Math.html


+ 0 - 0
docs/api/core/Matrix3.html → docs/api/math/Matrix3.html


+ 0 - 0
docs/api/core/Matrix4.html → docs/api/math/Matrix4.html


+ 37 - 0
docs/api/math/Plane.html

@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<meta charset="utf-8">
+		<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">todo</div>
+
+
+		<h2>Constructor</h2>
+
+		<h3>[name]()</h3>
+
+
+		<h2>Properties</h2>
+
+		<h3>.[page:Vector3 todo]</h3>
+
+
+		<h2>Methods</h2>
+
+		<h3>.todo( [page:Vector3 todo] )</h3>
+		<div>
+		todo — todo<br />
+		</div>
+
+
+		<h2>Source</h2>
+
+		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
+	</body>
+</html>

+ 0 - 0
docs/api/core/Quaternion.html → docs/api/math/Quaternion.html


+ 37 - 0
docs/api/math/Ray.html

@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<meta charset="utf-8">
+		<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">todo</div>
+
+
+		<h2>Constructor</h2>
+
+		<h3>[name]()</h3>
+
+
+		<h2>Properties</h2>
+
+		<h3>.[page:Vector3 todo]</h3>
+
+
+		<h2>Methods</h2>
+
+		<h3>.todo( [page:Vector3 todo] )</h3>
+		<div>
+		todo — todo<br />
+		</div>
+
+
+		<h2>Source</h2>
+
+		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
+	</body>
+</html>

+ 37 - 0
docs/api/math/Sphere.html

@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<meta charset="utf-8">
+		<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">todo</div>
+
+
+		<h2>Constructor</h2>
+
+		<h3>[name]()</h3>
+
+
+		<h2>Properties</h2>
+
+		<h3>.[page:Vector3 todo]</h3>
+
+
+		<h2>Methods</h2>
+
+		<h3>.todo( [page:Vector3 todo] )</h3>
+		<div>
+		todo — todo<br />
+		</div>
+
+
+		<h2>Source</h2>
+
+		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
+	</body>
+</html>

+ 0 - 0
docs/api/core/Spline.html → docs/api/math/Spline.html


+ 37 - 0
docs/api/math/Triangle.html

@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<meta charset="utf-8">
+		<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">todo</div>
+
+
+		<h2>Constructor</h2>
+
+		<h3>[name]()</h3>
+
+
+		<h2>Properties</h2>
+
+		<h3>.[page:Vector3 todo]</h3>
+
+
+		<h2>Methods</h2>
+
+		<h3>.todo( [page:Vector3 todo] )</h3>
+		<div>
+		todo — todo<br />
+		</div>
+
+
+		<h2>Source</h2>
+
+		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
+	</body>
+</html>

+ 1 - 1
docs/api/core/Vector2.html → docs/api/math/Vector2.html

@@ -9,7 +9,7 @@
 	<body>
 	<body>
 		<h1>[name]</h1>
 		<h1>[name]</h1>
 
 
-		<div class="desc">2D Vector.</div>
+		<div class="desc">2D vector.</div>
 
 
 		<h2>Example</h2>
 		<h2>Example</h2>
 
 

+ 0 - 0
docs/api/core/Vector3.html → docs/api/math/Vector3.html


+ 0 - 0
docs/api/core/Vector4.html → docs/api/math/Vector4.html


+ 39 - 0
docs/api/textures/CompressedTexture.html

@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<meta charset="utf-8">
+		<script src="../../list.js"></script>
+		<script src="../../page.js"></script>
+		<link type="text/css" rel="stylesheet" href="../../page.css" />
+	</head>
+	<body>
+		[page:Texture] &rarr;
+
+		<h1>[name]</h1>
+
+		<div class="desc">todo</div>
+
+
+		<h2>Constructor</h2>
+
+		<h3>[name]( mipmaps, width, height, format, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy )</h3>
+
+
+		<h2>Properties</h2>
+
+		<h3>.[page:Vector3 todo]</h3>
+
+
+		<h2>Methods</h2>
+
+		<h3>.todo( [page:Vector3 todo] )</h3>
+		<div>
+		todo — todo<br />
+		</div>
+
+
+		<h2>Source</h2>
+
+		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
+	</body>
+</html>

+ 45 - 31
docs/list.js

@@ -14,32 +14,23 @@ var list = {
 		],
 		],
 
 
 		"Core": [
 		"Core": [
+			[ "BufferGeometry", "api/core/BufferGeometry" ],
 			[ "Clock", "api/core/Clock" ],
 			[ "Clock", "api/core/Clock" ],
-			[ "Color", "api/core/Color" ],
 			[ "EventDispatcher", "api/core/EventDispatcher" ],
 			[ "EventDispatcher", "api/core/EventDispatcher" ],
 			[ "Face3", "api/core/Face3" ],
 			[ "Face3", "api/core/Face3" ],
 			[ "Face4", "api/core/Face4" ],
 			[ "Face4", "api/core/Face4" ],
-			[ "Frustum", "api/core/Frustum" ],
 			[ "Geometry", "api/core/Geometry" ],
 			[ "Geometry", "api/core/Geometry" ],
-			[ "Math", "api/core/Math" ],
-			[ "Matrix3", "api/core/Matrix3" ],
-			[ "Matrix4", "api/core/Matrix4" ],
 			[ "Object3D", "api/core/Object3D" ],
 			[ "Object3D", "api/core/Object3D" ],
 			[ "Projector", "api/core/Projector" ],
 			[ "Projector", "api/core/Projector" ],
-			[ "Quaternion", "api/core/Quaternion" ],
 			[ "Raycaster", "api/core/Raycaster" ],
 			[ "Raycaster", "api/core/Raycaster" ],
-			[ "Rectangle", "api/core/Rectangle" ],
-			[ "Spline", "api/core/Spline" ],
-			[ "UV", "api/core/UV" ],
-			[ "Vector2", "api/core/Vector2" ],
-			[ "Vector3", "api/core/Vector3" ],
-			[ "Vector4", "api/core/Vector4" ]
 		],
 		],
 
 
 		"Lights": [
 		"Lights": [
 			[ "Light", "api/lights/Light" ],
 			[ "Light", "api/lights/Light" ],
 			[ "AmbientLight", "api/lights/AmbientLight" ],
 			[ "AmbientLight", "api/lights/AmbientLight" ],
+			[ "AreaLight", "api/lights/AreaLight" ],
 			[ "DirectionalLight", "api/lights/DirectionalLight" ],
 			[ "DirectionalLight", "api/lights/DirectionalLight" ],
+			[ "HemisphereLight", "api/lights/HemisphereLight" ],
 			[ "PointLight", "api/lights/PointLight" ],
 			[ "PointLight", "api/lights/PointLight" ],
 			[ "SpotLight", "api/lights/SpotLight" ]
 			[ "SpotLight", "api/lights/SpotLight" ]
 		],
 		],
@@ -59,6 +50,7 @@ var list = {
 		"Materials": [
 		"Materials": [
 			[ "Material", "api/materials/Material" ],
 			[ "Material", "api/materials/Material" ],
 			[ "LineBasicMaterial", "api/materials/LineBasicMaterial" ],
 			[ "LineBasicMaterial", "api/materials/LineBasicMaterial" ],
+			[ "LineDashedMaterial", "api/materials/LineDashedMaterial" ],
 			[ "MeshBasicMaterial", "api/materials/MeshBasicMaterial" ],
 			[ "MeshBasicMaterial", "api/materials/MeshBasicMaterial" ],
 			[ "MeshDepthMaterial", "api/materials/MeshDepthMaterial" ],
 			[ "MeshDepthMaterial", "api/materials/MeshDepthMaterial" ],
 			[ "MeshFaceMaterial", "api/materials/MeshFaceMaterial" ],
 			[ "MeshFaceMaterial", "api/materials/MeshFaceMaterial" ],
@@ -68,8 +60,28 @@ var list = {
 			[ "ParticleBasicMaterial", "api/materials/ParticleBasicMaterial" ],
 			[ "ParticleBasicMaterial", "api/materials/ParticleBasicMaterial" ],
 			[ "ParticleCanvasMaterial", "api/materials/ParticleCanvasMaterial" ],
 			[ "ParticleCanvasMaterial", "api/materials/ParticleCanvasMaterial" ],
 			[ "ParticleDOMMaterial", "api/materials/ParticleDOMMaterial" ],
 			[ "ParticleDOMMaterial", "api/materials/ParticleDOMMaterial" ],
-			[ "ShaderMaterial", "api/materials/ShaderMaterial" ]
-
+			[ "ShaderMaterial", "api/materials/ShaderMaterial" ],
+			[ "SpriteMaterial", "api/materials/SpriteMaterial" ]
+
+		],
+
+		"Math": [
+			[ "Box2", "api/math/Box2" ],
+			[ "Box3", "api/math/Box3" ],
+			[ "Color", "api/math/Color" ],
+			[ "Frustum", "api/math/Frustum" ],
+			[ "Math", "api/math/Math" ],
+			[ "Matrix3", "api/math/Matrix3" ],
+			[ "Matrix4", "api/math/Matrix4" ],
+			[ "Plane", "api/math/Plane" ],
+			[ "Quaternion", "api/math/Quaternion" ],
+			[ "Ray", "api/math/Ray" ],
+			[ "Sphere", "api/math/Sphere" ],
+			[ "Spline", "api/math/Spline" ],
+			[ "Triangle", "api/math/Triangle" ],
+			[ "Vector2", "api/math/Vector2" ],
+			[ "Vector3", "api/math/Vector3" ],
+			[ "Vector4", "api/math/Vector4" ]
 		],
 		],
 
 
 		"Objects": [
 		"Objects": [
@@ -88,8 +100,6 @@ var list = {
 
 
 		"Renderers": [
 		"Renderers": [
 			[ "CanvasRenderer", "api/renderers/CanvasRenderer" ],
 			[ "CanvasRenderer", "api/renderers/CanvasRenderer" ],
-			[ "DOMRenderer", "api/renderers/DOMRenderer" ],
-			[ "SVGRenderer", "api/renderers/SVGRenderer" ],
 			[ "WebGLRenderer", "api/renderers/WebGLRenderer" ],
 			[ "WebGLRenderer", "api/renderers/WebGLRenderer" ],
 			[ "WebGLRenderTarget", "api/renderers/WebGLRenderTarget" ],
 			[ "WebGLRenderTarget", "api/renderers/WebGLRenderTarget" ],
 			[ "WebGLRenderTargetCube", "api/renderers/WebGLRenderTargetCube" ],
 			[ "WebGLRenderTargetCube", "api/renderers/WebGLRenderTargetCube" ],
@@ -112,12 +122,14 @@ var list = {
 		],
 		],
 
 
 		"Textures": [
 		"Textures": [
+			[ "CompressedTexture", "api/textures/CompressedTexture" ],
 			[ "DataTexture", "api/textures/DataTexture" ],
 			[ "DataTexture", "api/textures/DataTexture" ],
 			[ "Texture", "api/textures/Texture" ]
 			[ "Texture", "api/textures/Texture" ]
 		],
 		],
 
 
 		"Extras": [
 		"Extras": [
 			[ "ColorUtils", "api/extras/ColorUtils" ],
 			[ "ColorUtils", "api/extras/ColorUtils" ],
+			[ "FontUtils", "api/extras/FontUtils" ],
 			[ "GeometryUtils", "api/extras/GeometryUtils" ],
 			[ "GeometryUtils", "api/extras/GeometryUtils" ],
 			[ "ImageUtils", "api/extras/ImageUtils" ],
 			[ "ImageUtils", "api/extras/ImageUtils" ],
 			[ "SceneUtils", "api/extras/SceneUtils" ],
 			[ "SceneUtils", "api/extras/SceneUtils" ],
@@ -137,7 +149,6 @@ var list = {
 		],
 		],
 
 
 		"Extras / Core": [
 		"Extras / Core": [
-			[ "BufferGeometry", "api/extras/core/BufferGeometry" ],
 			[ "Curve", "api/extras/core/Curve" ],
 			[ "Curve", "api/extras/core/Curve" ],
 			[ "CurvePath", "api/extras/core/CurvePath" ],
 			[ "CurvePath", "api/extras/core/CurvePath" ],
 			[ "Gyroscope", "api/extras/core/Gyroscope" ],
 			[ "Gyroscope", "api/extras/core/Gyroscope" ],
@@ -146,42 +157,45 @@ var list = {
 		],
 		],
 
 
 		"Extras / Geometries": [
 		"Extras / Geometries": [
+			[ "AsteriskGeometry", "api/extras/geometries/AsteriskGeometry" ],
+			[ "CircleGeometry", "api/extras/geometries/CircleGeometry" ],
+			[ "ConvexGeometry", "api/extras/geometries/ConvexGeometry" ],
 			[ "CubeGeometry", "api/extras/geometries/CubeGeometry" ],
 			[ "CubeGeometry", "api/extras/geometries/CubeGeometry" ],
 			[ "CylinderGeometry", "api/extras/geometries/CylinderGeometry" ],
 			[ "CylinderGeometry", "api/extras/geometries/CylinderGeometry" ],
 			[ "ExtrudeGeometry", "api/extras/geometries/ExtrudeGeometry" ],
 			[ "ExtrudeGeometry", "api/extras/geometries/ExtrudeGeometry" ],
 			[ "IcosahedronGeometry", "api/extras/geometries/IcosahedronGeometry" ],
 			[ "IcosahedronGeometry", "api/extras/geometries/IcosahedronGeometry" ],
 			[ "LatheGeometry", "api/extras/geometries/LatheGeometry" ],
 			[ "LatheGeometry", "api/extras/geometries/LatheGeometry" ],
 			[ "OctahedronGeometry", "api/extras/geometries/OctahedronGeometry" ],
 			[ "OctahedronGeometry", "api/extras/geometries/OctahedronGeometry" ],
+			[ "ParametricGeometry", "api/extras/geometries/ParametricGeometry" ],
 			[ "PlaneGeometry", "api/extras/geometries/PlaneGeometry" ],
 			[ "PlaneGeometry", "api/extras/geometries/PlaneGeometry" ],
 			[ "PolyhedronGeometry", "api/extras/geometries/PolyhedronGeometry" ],
 			[ "PolyhedronGeometry", "api/extras/geometries/PolyhedronGeometry" ],
+			[ "ShapeGeometry", "api/extras/geometries/ShapeGeometry" ],
 			[ "SphereGeometry", "api/extras/geometries/SphereGeometry" ],
 			[ "SphereGeometry", "api/extras/geometries/SphereGeometry" ],
 			[ "TetrahedronGeometry", "api/extras/geometries/TetrahedronGeometry" ],
 			[ "TetrahedronGeometry", "api/extras/geometries/TetrahedronGeometry" ],
 			[ "TextGeometry", "api/extras/geometries/TextGeometry" ],
 			[ "TextGeometry", "api/extras/geometries/TextGeometry" ],
 			[ "TorusGeometry", "api/extras/geometries/TorusGeometry" ],
 			[ "TorusGeometry", "api/extras/geometries/TorusGeometry" ],
-			[ "TorusKnotGeometry", "api/extras/geometries/TorusKnotGeometry" ]
+			[ "TorusKnotGeometry", "api/extras/geometries/TorusKnotGeometry" ],
+			[ "TubeGeometry", "api/extras/geometries/TubeGeometry" ]
 		],
 		],
 
 
 		"Extras / Helpers": [
 		"Extras / Helpers": [
+			[ "ArrowHelper", "api/extras/helpers/ArrowHelper" ],
 			[ "AxisHelper", "api/extras/helpers/AxisHelper" ],
 			[ "AxisHelper", "api/extras/helpers/AxisHelper" ],
-			[ "CameraHelper", "api/extras/helpers/CameraHelper" ]
-		],
-
-		"Extras / Modifiers": [
-			[ "SubdivisionModifier", "api/extras/modifiers/SubdivisionModifier" ]
+			[ "CameraHelper", "api/extras/helpers/CameraHelper" ],
+			[ "DirectionalLightHelper", "api/extras/helpers/DirectionalLightHelper" ],
+			[ "HemisphereLightHelper", "api/extras/helpers/HemisphereLightHelper" ],
+			[ "PointLightHelper", "api/extras/helpers/PointLightHelper" ],
+			[ "SpotLightHelper", "api/extras/helpers/SpotLightHelper" ]
 		],
 		],
 
 
 		"Extras / Objects": [
 		"Extras / Objects": [
-			[ "LensFlare", "api/extras/objects/LensFlare" ]
-		],
-
-		"Extras / Renderers / Effects": [
-			[ "AnaglyphEffect", "api/extras/renderers/effects/AnaglyphEffect" ],
-			[ "CrosseyedEffect", "api/extras/renderers/effects/CrosseyedEffect" ],
-			[ "ParallaxBarrierEffect", "api/extras/renderers/effects/ParallaxBarrierEffect" ],
-			[ "StereoEffect", "api/extras/renderers/effects/StereoEffect" ]
+			[ "ImmediateRenderObject", "api/extras/objects/ImmediateRenderObject" ],
+			[ "LensFlare", "api/extras/objects/LensFlare" ],
+			[ "MorphBlendMesh", "api/extras/objects/MorphBlendMesh" ]
 		],
 		],
 
 
 		"Extras / Renderers / Plugins": [
 		"Extras / Renderers / Plugins": [
+			[ "DepthPassPlugin", "api/extras/renderers/plugins/DepthPassPlugin" ],
 			[ "LensFlarePlugin", "api/extras/renderers/plugins/LensFlarePlugin" ],
 			[ "LensFlarePlugin", "api/extras/renderers/plugins/LensFlarePlugin" ],
 			[ "ShadowMapPlugin", "api/extras/renderers/plugins/ShadowMapPlugin" ],
 			[ "ShadowMapPlugin", "api/extras/renderers/plugins/ShadowMapPlugin" ],
 			[ "SpritePlugin", "api/extras/renderers/plugins/SpritePlugin" ]
 			[ "SpritePlugin", "api/extras/renderers/plugins/SpritePlugin" ]

+ 2 - 0
editor/index.html

@@ -108,6 +108,7 @@
 
 
 				// actions
 				// actions
 
 
+				cloneSelectedObject: new SIGNALS.Signal(),
 				removeSelectedObject: new SIGNALS.Signal(),
 				removeSelectedObject: new SIGNALS.Signal(),
 				exportGeometry: new SIGNALS.Signal(),
 				exportGeometry: new SIGNALS.Signal(),
 				exportScene: new SIGNALS.Signal(),
 				exportScene: new SIGNALS.Signal(),
@@ -224,6 +225,7 @@
 						break;
 						break;
 
 
 					case 'js':
 					case 'js':
+					case 'json':
 
 
 						var reader = new FileReader();
 						var reader = new FileReader();
 						reader.addEventListener( 'load', function ( event ) {
 						reader.addEventListener( 'load', function ( event ) {

+ 14 - 0
editor/js/ui/Menubar.Add.js

@@ -29,6 +29,8 @@ Menubar.Add = function ( signals ) {
 		var heightSegments = 1;
 		var heightSegments = 1;
 
 
 		var geometry = new THREE.PlaneGeometry( width, height, widthSegments, heightSegments );
 		var geometry = new THREE.PlaneGeometry( width, height, widthSegments, heightSegments );
+		geometry.name = 'Plane ' + geometry.id;
+
 		var mesh = new THREE.Mesh( geometry, createDummyMaterial( geometry ) );
 		var mesh = new THREE.Mesh( geometry, createDummyMaterial( geometry ) );
 		mesh.name = 'Plane ' + mesh.id;
 		mesh.name = 'Plane ' + mesh.id;
 
 
@@ -55,6 +57,8 @@ Menubar.Add = function ( signals ) {
 		var depthSegments = 1;
 		var depthSegments = 1;
 
 
 		var geometry = new THREE.CubeGeometry( width, height, depth, widthSegments, heightSegments, depthSegments );
 		var geometry = new THREE.CubeGeometry( width, height, depth, widthSegments, heightSegments, depthSegments );
+		geometry.name = 'Cube ' + geometry.id;
+
 		var mesh = new THREE.Mesh( geometry, createDummyMaterial( geometry ) );
 		var mesh = new THREE.Mesh( geometry, createDummyMaterial( geometry ) );
 		mesh.name = 'Cube ' + mesh.id;
 		mesh.name = 'Cube ' + mesh.id;
 
 
@@ -79,6 +83,8 @@ Menubar.Add = function ( signals ) {
 		var openEnded = false;
 		var openEnded = false;
 
 
 		var geometry = new THREE.CylinderGeometry( radiusTop, radiusBottom, height, radiusSegments, heightSegments, openEnded );
 		var geometry = new THREE.CylinderGeometry( radiusTop, radiusBottom, height, radiusSegments, heightSegments, openEnded );
+		geometry.name = 'Cylinder ' + geometry.id;
+
 		var mesh = new THREE.Mesh( geometry, createDummyMaterial( geometry ) );
 		var mesh = new THREE.Mesh( geometry, createDummyMaterial( geometry ) );
 		mesh.name = 'Cylinder ' + mesh.id;
 		mesh.name = 'Cylinder ' + mesh.id;
 
 
@@ -99,6 +105,8 @@ Menubar.Add = function ( signals ) {
 		var heightSegments = 16;
 		var heightSegments = 16;
 
 
 		var geometry = new THREE.SphereGeometry( radius, widthSegments, heightSegments );
 		var geometry = new THREE.SphereGeometry( radius, widthSegments, heightSegments );
+		geometry.name = 'Sphere ' + geometry.id;
+
 		var mesh = new THREE.Mesh( geometry, createDummyMaterial( geometry ) );
 		var mesh = new THREE.Mesh( geometry, createDummyMaterial( geometry ) );
 		mesh.name = 'Sphere ' + mesh.id;
 		mesh.name = 'Sphere ' + mesh.id;
 
 
@@ -118,6 +126,8 @@ Menubar.Add = function ( signals ) {
 		var detail = 2;
 		var detail = 2;
 
 
 		var geometry = new THREE.IcosahedronGeometry ( radius, detail );
 		var geometry = new THREE.IcosahedronGeometry ( radius, detail );
+		geometry.name = 'Icosahedron ' + geometry.id;
+
 		var mesh = new THREE.Mesh( geometry, createDummyMaterial( geometry ) );
 		var mesh = new THREE.Mesh( geometry, createDummyMaterial( geometry ) );
 		mesh.name = 'Icosahedron ' + mesh.id;
 		mesh.name = 'Icosahedron ' + mesh.id;
 
 
@@ -140,6 +150,8 @@ Menubar.Add = function ( signals ) {
 		var arc = Math.PI * 2;
 		var arc = Math.PI * 2;
 
 
 		var geometry = new THREE.TorusGeometry( radius, tube, radialSegments, tubularSegments, arc );
 		var geometry = new THREE.TorusGeometry( radius, tube, radialSegments, tubularSegments, arc );
+		geometry.name = 'Torus ' + geometry.id;
+
 		var mesh = new THREE.Mesh( geometry, createDummyMaterial( geometry ) );
 		var mesh = new THREE.Mesh( geometry, createDummyMaterial( geometry ) );
 		mesh.name = 'Torus ' + mesh.id;
 		mesh.name = 'Torus ' + mesh.id;
 
 
@@ -164,6 +176,8 @@ Menubar.Add = function ( signals ) {
 		var heightScale = 1;
 		var heightScale = 1;
 
 
 		var geometry = new THREE.TorusKnotGeometry( radius, tube, radialSegments, tubularSegments, p, q, heightScale );
 		var geometry = new THREE.TorusKnotGeometry( radius, tube, radialSegments, tubularSegments, p, q, heightScale );
+		geometry.name = 'TorusKnot ' + geometry.id;
+
 		var mesh = new THREE.Mesh( geometry, createDummyMaterial( geometry ) );
 		var mesh = new THREE.Mesh( geometry, createDummyMaterial( geometry ) );
 		mesh.name = 'TorusKnot ' + mesh.id;
 		mesh.name = 'TorusKnot ' + mesh.id;
 
 

+ 8 - 0
editor/js/ui/Menubar.Edit.js

@@ -15,6 +15,14 @@ Menubar.Edit = function ( signals ) {
 	options.setClass( 'options' );
 	options.setClass( 'options' );
 	container.add( options );
 	container.add( options );
 
 
+	// clone
+
+	var option = new UI.Panel();
+	option.setClass( 'option' );
+	option.setTextContent( 'Clone' );
+	option.onClick( function () { signals.cloneSelectedObject.dispatch(); } );
+	options.add( option );
+
 	// delete
 	// delete
 
 
 	var option = new UI.Panel();
 	var option = new UI.Panel();

+ 5 - 3
editor/js/ui/Sidebar.Geometry.js

@@ -1,7 +1,8 @@
 Sidebar.Geometry = function ( signals ) {
 Sidebar.Geometry = function ( signals ) {
 
 
-	var geometries = {
+	var geometryClasses = {
 
 
+		"CircleGeometry": THREE.CircleGeometry,
 		"ConvexGeometry": THREE.ConvexGeometry,
 		"ConvexGeometry": THREE.ConvexGeometry,
 		"CubeGeometry": THREE.CubeGeometry,
 		"CubeGeometry": THREE.CubeGeometry,
 		"CylinderGeometry": THREE.CylinderGeometry,
 		"CylinderGeometry": THREE.CylinderGeometry,
@@ -12,6 +13,7 @@ Sidebar.Geometry = function ( signals ) {
 		"ParametricGeometry": THREE.ParametricGeometry,
 		"ParametricGeometry": THREE.ParametricGeometry,
 		"PlaneGeometry": THREE.PlaneGeometry,
 		"PlaneGeometry": THREE.PlaneGeometry,
 		"PolyhedronGeometry": THREE.PolyhedronGeometry,
 		"PolyhedronGeometry": THREE.PolyhedronGeometry,
+		"ShapeGeometry": THREE.ShapeGeometry,
 		"SphereGeometry": THREE.SphereGeometry,
 		"SphereGeometry": THREE.SphereGeometry,
 		"TetrahedronGeometry": THREE.TetrahedronGeometry,
 		"TetrahedronGeometry": THREE.TetrahedronGeometry,
 		"TextGeometry": THREE.TextGeometry,
 		"TextGeometry": THREE.TextGeometry,
@@ -110,9 +112,9 @@ Sidebar.Geometry = function ( signals ) {
 
 
 	function getGeometryInstanceName( geometry ) {
 	function getGeometryInstanceName( geometry ) {
 
 
-		for ( var key in geometries ) {
+		for ( var key in geometryClasses ) {
 
 
-			if ( geometry instanceof geometries[ key ] ) return key;
+			if ( geometry instanceof geometryClasses[ key ] ) return key;
 
 
 		}
 		}
 
 

+ 7 - 6
editor/js/ui/Sidebar.Material.js

@@ -1,8 +1,9 @@
 Sidebar.Material = function ( signals ) {
 Sidebar.Material = function ( signals ) {
 
 
-    var materials = {
+    var materialClasses = {
 
 
 		'LineBasicMaterial': THREE.LineBasicMaterial,
 		'LineBasicMaterial': THREE.LineBasicMaterial,
+		'LineDashedMaterial': THREE.LineDashedMaterial,
 		'MeshBasicMaterial': THREE.MeshBasicMaterial,
 		'MeshBasicMaterial': THREE.MeshBasicMaterial,
 		'MeshDepthMaterial': THREE.MeshDepthMaterial,
 		'MeshDepthMaterial': THREE.MeshDepthMaterial,
 		'MeshFaceMaterial': THREE.MeshFaceMaterial,
 		'MeshFaceMaterial': THREE.MeshFaceMaterial,
@@ -11,7 +12,6 @@ Sidebar.Material = function ( signals ) {
 		'MeshPhongMaterial': THREE.MeshPhongMaterial,
 		'MeshPhongMaterial': THREE.MeshPhongMaterial,
 		'ParticleBasicMaterial': THREE.ParticleBasicMaterial,
 		'ParticleBasicMaterial': THREE.ParticleBasicMaterial,
 		'ParticleCanvasMaterial': THREE.ParticleCanvasMaterial,
 		'ParticleCanvasMaterial': THREE.ParticleCanvasMaterial,
-		'ParticleDOMMaterial': THREE.ParticleDOMMaterial,
 		'ShaderMaterial': THREE.ShaderMaterial,
 		'ShaderMaterial': THREE.ShaderMaterial,
 		'Material': THREE.Material
 		'Material': THREE.Material
 
 
@@ -41,6 +41,7 @@ Sidebar.Material = function ( signals ) {
 	var materialClass = new UI.Select( 'absolute' ).setOptions( {
 	var materialClass = new UI.Select( 'absolute' ).setOptions( {
 
 
 		'LineBasicMaterial': 'LineBasicMaterial',
 		'LineBasicMaterial': 'LineBasicMaterial',
+		'LineDashedMaterial': 'LineDashedMaterial',
 		'MeshBasicMaterial': 'MeshBasicMaterial',
 		'MeshBasicMaterial': 'MeshBasicMaterial',
 		'MeshDepthMaterial': 'MeshDepthMaterial',
 		'MeshDepthMaterial': 'MeshDepthMaterial',
 		'MeshFaceMaterial': 'MeshFaceMaterial',
 		'MeshFaceMaterial': 'MeshFaceMaterial',
@@ -229,9 +230,9 @@ Sidebar.Material = function ( signals ) {
 
 
 			material.name = materialName.getValue();
 			material.name = materialName.getValue();
 
 
-			if ( material instanceof materials[ materialClass.getValue() ] == false ) {
+			if ( material instanceof materialClasses[ materialClass.getValue() ] == false ) {
 
 
-				material = new materials[ materialClass.getValue() ]();
+				material = new materialClasses[ materialClass.getValue() ]();
 				selected.material = material;
 				selected.material = material;
 
 
 			}
 			}
@@ -452,9 +453,9 @@ Sidebar.Material = function ( signals ) {
 
 
 	function getMaterialInstanceName( material ) {
 	function getMaterialInstanceName( material ) {
 
 
-		for ( var key in materials ) {
+		for ( var key in materialClasses ) {
 
 
-			if ( material instanceof materials[ key ] ) return key;
+			if ( material instanceof materialClasses[ key ] ) return key;
 
 
 		}
 		}
 
 

+ 8 - 0
editor/js/ui/Viewport.js

@@ -388,6 +388,14 @@ var Viewport = function ( signals ) {
 
 
 	} );
 	} );
 
 
+	signals.cloneSelectedObject.add( function () {
+
+		if ( selected === camera ) return;
+
+		signals.objectAdded.dispatch( selected.clone() );
+
+	} );
+
 	signals.removeSelectedObject.add( function () {
 	signals.removeSelectedObject.add( function () {
 
 
 		if ( selected === camera ) return;
 		if ( selected === camera ) return;

+ 8 - 3
examples/canvas_interactive_voxelpainter.html

@@ -160,17 +160,22 @@
 
 
 				if ( intersects.length > 0 ) {
 				if ( intersects.length > 0 ) {
 
 
+					var interect = intersects[ 0 ];
+
 					if ( isCtrlDown ) {
 					if ( isCtrlDown ) {
 
 
-						if ( intersects[ 0 ].object != plane ) {
+						if ( interect.object != plane ) {
 
 
-							scene.remove( intersects[ 0 ].object );
+							scene.remove( interect.object );
 
 
 						}
 						}
 
 
 					} else {
 					} else {
 
 
-						var position = new THREE.Vector3().add( intersects[ 0 ].point, intersects[ 0 ].object.matrixRotationWorld.multiplyVector3( intersects[ 0 ].face.normal.clone() ) );
+						var normal = interect.face.normal.clone();
+						normal.applyMatrix4( interect.object.matrixRotationWorld );
+
+						var position = new THREE.Vector3().add( interect.point, normal );
 
 
 						var geometry = new THREE.CubeGeometry( 50, 50, 50 );
 						var geometry = new THREE.CubeGeometry( 50, 50, 50 );
 
 

+ 1 - 3
examples/canvas_materials.html

@@ -63,7 +63,7 @@
 
 
 				// Spheres
 				// Spheres
 
 
-				var geometry = new THREE.SphereGeometry( 100, 14, 7, false );
+				var geometry = new THREE.SphereGeometry( 100, 14, 7 );
 
 
 				var materials = [
 				var materials = [
 
 
@@ -135,9 +135,7 @@
 				scene.add( pointLight );
 				scene.add( pointLight );
 
 
 				renderer = new THREE.CanvasRenderer();
 				renderer = new THREE.CanvasRenderer();
-				// renderer = new THREE.WebGLRenderer();
 				renderer.setSize( window.innerWidth, window.innerHeight );
 				renderer.setSize( window.innerWidth, window.innerHeight );
-
 				container.appendChild( renderer.domElement );
 				container.appendChild( renderer.domElement );
 
 
 				var debugCanvas = document.createElement( 'canvas' );
 				var debugCanvas = document.createElement( 'canvas' );

+ 4 - 4
examples/js/controls/TrackballControls.js

@@ -135,10 +135,10 @@ THREE.TrackballControls = function ( object, domElement ) {
 
 
 			quaternion.setFromAxisAngle( axis, -angle );
 			quaternion.setFromAxisAngle( axis, -angle );
 
 
-			quaternion.multiplyVector3( _eye );
-			quaternion.multiplyVector3( _this.object.up );
+			_eye.applyQuaternion( quaternion );
+			_this.object.up.applyQuaternion( quaternion );
 
 
-			quaternion.multiplyVector3( _rotateEnd );
+			_rotateEnd.applyQuaternion( quaternion );
 
 
 			if ( _this.staticMoving ) {
 			if ( _this.staticMoving ) {
 
 
@@ -147,7 +147,7 @@ THREE.TrackballControls = function ( object, domElement ) {
 			} else {
 			} else {
 
 
 				quaternion.setFromAxisAngle( axis, angle * ( _this.dynamicDampingFactor - 1.0 ) );
 				quaternion.setFromAxisAngle( axis, angle * ( _this.dynamicDampingFactor - 1.0 ) );
-				quaternion.multiplyVector3( _rotateStart );
+				_rotateStart.applyQuaternion( quaternion );
 
 
 			}
 			}
 
 

+ 6 - 4
examples/js/loaders/ColladaLoader.js

@@ -444,7 +444,7 @@ THREE.ColladaLoader = function () {
 
 
 			for ( var i = 0; i < geometry.vertices.length; i ++ ) {
 			for ( var i = 0; i < geometry.vertices.length; i ++ ) {
 
 
-				skin.bindShapeMatrix.multiplyVector3( geometry.vertices[ i ] );
+				geometry.vertices[ i ].applyMatrix4( skin.bindShapeMatrix );
 
 
 			}
 			}
 
 
@@ -575,7 +575,7 @@ THREE.ColladaLoader = function () {
 
 
 		for ( i = 0; i < geometry.vertices.length; i ++ ) {
 		for ( i = 0; i < geometry.vertices.length; i ++ ) {
 
 
-			skinController.skin.bindShapeMatrix.multiplyVector3( geometry.vertices[i] );
+			geometry.vertices[i].applyMatrix4( skinController.skin.bindShapeMatrix );
 
 
 		}
 		}
 
 
@@ -619,7 +619,7 @@ THREE.ColladaLoader = function () {
 					v.y = o.y;
 					v.y = o.y;
 					v.z = o.z;
 					v.z = o.z;
 
 
-					bones[i].skinningMatrix.multiplyVector3(v);
+					v.applyMatrix4( bones[i].skinningMatrix );
 
 
 					s.x += (v.x * weight);
 					s.x += (v.x * weight);
 					s.y += (v.y * weight);
 					s.y += (v.y * weight);
@@ -849,7 +849,9 @@ THREE.ColladaLoader = function () {
 		if ( options.centerGeometry && obj.geometry ) {
 		if ( options.centerGeometry && obj.geometry ) {
 
 
 			var delta = THREE.GeometryUtils.center( obj.geometry );
 			var delta = THREE.GeometryUtils.center( obj.geometry );
-			obj.quaternion.multiplyVector3( delta.multiplySelf( obj.scale ) );
+			delta.multiplySelf( obj.scale );
+			delta.applyQuaternion( obj.quaternion );
+
 			obj.position.subSelf( delta );
 			obj.position.subSelf( delta );
 
 
 		}
 		}

+ 0 - 83
examples/js/renderers/DOMRenderer.js

@@ -1,83 +0,0 @@
-/**
- * @author mrdoob / http://mrdoob.com/
- */
-
-THREE.DOMRenderer = function () {
-
-	console.log( 'THREE.DOMRenderer', THREE.REVISION );
-
-	var _renderData, _elements,
-	_width, _height, _widthHalf, _heightHalf, _transformProp,
-	_projector = new THREE.Projector();
-
-	var getSupportedProp = function ( proparray ) {
-
-		var root = document.documentElement
-
-		for ( var i = 0; i < proparray.length; i ++ ) {
-
-			if ( typeof root.style[ proparray[ i ] ] === "string" ) {
-
-				return proparray[i];
-
-			}
-
-		}
-
-		return null;
-
-	};
-
-	_transformProp = getSupportedProp( [ 'transform', 'MozTransform', 'WebkitTransform', 'msTransform', 'OTransform' ] );
-
-	this.domElement = document.createElement( 'div' );
-
-	this.setSize = function ( width, height ) {
-
-		_width = width;
-		_height = height;
-
-		_widthHalf = _width / 2;
-		_heightHalf = _height / 2;
-
-	};
-
-	this.render = function ( scene, camera ) {
-
-		var e, el, m, ml, element, material, dom, v1x, v1y;
-
-		_renderData = _projector.projectScene( scene, camera );
-		_elements = _renderData.elements;
-
-		for ( e = 0, el = _elements.length; e < el; e ++ ) {
-
-			element = _elements[ e ];
-
-			if ( element instanceof THREE.RenderableParticle && element.material instanceof THREE.ParticleDOMMaterial ) {
-
-				dom = element.material.element;
-
-				v1x = element.x * _widthHalf + _widthHalf - ( dom.offsetWidth >> 1 );
-				v1y = element.y * _heightHalf + _heightHalf - ( dom.offsetHeight >> 1 );
-
-				dom.style.left = v1x + 'px';
-				dom.style.top = v1y + 'px';
-				dom.style.zIndex = Math.abs( Math.floor( ( 1 - element.z ) * camera.far / camera.near ) )
-
-				if ( _transformProp ) {
-
-					var scaleX = element.scale.x * _widthHalf;
-					var scaleY = element.scale.y * _heightHalf;
-					var scaleVal = "scale(" + scaleX + "," + scaleY + ")";
-
-					dom.style[ _transformProp ] = scaleVal;
-
-				}
-
-			}
-
-		}
-
-	};
-
-};

+ 8 - 11
examples/js/renderers/SVGRenderer.js

@@ -364,7 +364,7 @@ THREE.SVGRenderer = function () {
 				_color.g = _ambientLight.g;
 				_color.g = _ambientLight.g;
 				_color.b = _ambientLight.b;
 				_color.b = _ambientLight.b;
 
 
-				calculateLight( _lights, element.centroidWorld, element.normalWorld, _color );
+				calculateLight( _lights, element.centroidModel, element.normalModel, _color );
 
 
 				_color.r = _color.r * _diffuseColor.r + _emissiveColor.r;
 				_color.r = _color.r * _diffuseColor.r + _emissiveColor.r;
 				_color.g = _color.g * _diffuseColor.g + _emissiveColor.g;
 				_color.g = _color.g * _diffuseColor.g + _emissiveColor.g;
@@ -383,7 +383,9 @@ THREE.SVGRenderer = function () {
 
 
 		} else if ( material instanceof THREE.MeshNormalMaterial ) {
 		} else if ( material instanceof THREE.MeshNormalMaterial ) {
 
 
-			_color.setRGB( normalToComponent( element.normalWorld.x ), normalToComponent( element.normalWorld.y ), normalToComponent( element.normalWorld.z ) );
+			_color.r = 0.5 * element.normalModelView.x + 0.5;
+			_color.g = 0.5 * element.normalModelView.y + 0.5;
+			_color.b = 0.5 * element.normalModelView.z + 0.5;
 
 
 		}
 		}
 
 
@@ -440,7 +442,7 @@ THREE.SVGRenderer = function () {
 				_color.g = _ambientLight.g;
 				_color.g = _ambientLight.g;
 				_color.b = _ambientLight.b;
 				_color.b = _ambientLight.b;
 
 
-				calculateLight( _lights, element.centroidWorld, element.normalWorld, _color );
+				calculateLight( _lights, element.centroidModel, element.normalModel, _color );
 
 
 				_color.r = _color.r * _diffuseColor.r + _emissiveColor.r;
 				_color.r = _color.r * _diffuseColor.r + _emissiveColor.r;
 				_color.g = _color.g * _diffuseColor.g + _emissiveColor.g;
 				_color.g = _color.g * _diffuseColor.g + _emissiveColor.g;
@@ -459,7 +461,9 @@ THREE.SVGRenderer = function () {
 
 
 		} else if ( material instanceof THREE.MeshNormalMaterial ) {
 		} else if ( material instanceof THREE.MeshNormalMaterial ) {
 
 
-			_color.setRGB( normalToComponent( element.normalWorld.x ), normalToComponent( element.normalWorld.y ), normalToComponent( element.normalWorld.z ) );
+			_color.r = 0.5 * element.normalModelView.x + 0.5;
+			_color.g = 0.5 * element.normalModelView.y + 0.5;
+			_color.b = 0.5 * element.normalModelView.z + 0.5;
 
 
 		}
 		}
 
 
@@ -537,13 +541,6 @@ THREE.SVGRenderer = function () {
 
 
 	}
 	}
 
 
-	function normalToComponent( normal ) {
-
-		var component = ( normal + 1 ) * 0.5;
-		return component < 0 ? 0 : ( component > 1 ? 1 : component );
-
-	}
-
 	function pad( str ) {
 	function pad( str ) {
 
 
 		while ( str.length < 6 ) str = '0' + str;
 		while ( str.length < 6 ) str = '0' + str;

+ 219 - 173
examples/js/renderers/SoftwareRenderer.js

@@ -1,5 +1,6 @@
 /**
 /**
  * @author mrdoob / http://mrdoob.com/
  * @author mrdoob / http://mrdoob.com/
+ * @author mraleph / http://mrale.ph/
  */
  */
 
 
 THREE.SoftwareRenderer = function () {
 THREE.SoftwareRenderer = function () {
@@ -9,17 +10,27 @@ THREE.SoftwareRenderer = function () {
 	var canvas = document.createElement( 'canvas' );
 	var canvas = document.createElement( 'canvas' );
 	var context = canvas.getContext( '2d' );
 	var context = canvas.getContext( '2d' );
 
 
-	var imagedata = context.getImageData( 0, 0, canvas.width, canvas.height );
-	var data = imagedata.data;
-
 	var canvasWidth = canvas.width;
 	var canvasWidth = canvas.width;
 	var canvasHeight = canvas.height;
 	var canvasHeight = canvas.height;
 
 
 	var canvasWidthHalf = canvasWidth / 2;
 	var canvasWidthHalf = canvasWidth / 2;
 	var canvasHeightHalf = canvasHeight / 2;
 	var canvasHeightHalf = canvasHeight / 2;
 
 
-	var edges = [ new Edge(), new Edge(), new Edge() ];
-	var span = new Span();
+	var imagedata = context.getImageData( 0, 0, canvas.width, canvas.height );
+	var data = imagedata.data;
+
+	var blocksize = 8;
+
+	var canvasWBlocks = Math.floor( ( canvasWidth + blocksize - 1 ) / blocksize );
+	var canvasHBlocks = Math.floor( ( canvasHeight + blocksize - 1 ) / blocksize );
+
+	var block_full = new Uint8Array( canvasWBlocks * canvasHBlocks );
+
+	var rectx1 = Infinity, recty1 = Infinity;
+	var rectx2 = 0, recty2 = 0;
+
+	var prevrectx1 = Infinity, prevrecty1 = Infinity;
+	var prevrectx2 = 0, prevrecty2 = 0;
 
 
 	var projector = new THREE.Projector();
 	var projector = new THREE.Projector();
 
 
@@ -41,13 +52,22 @@ THREE.SoftwareRenderer = function () {
 		imagedata = context.getImageData( 0, 0, width, height );
 		imagedata = context.getImageData( 0, 0, width, height );
 		data = imagedata.data;
 		data = imagedata.data;
 
 
+		canvasWBlocks = Math.floor( ( canvasWidth + blocksize - 1 ) / blocksize );
+		canvasHBlocks = Math.floor( ( canvasHeight + blocksize - 1 ) / blocksize );
+
+		console.log( canvasWBlocks, canvasHBlocks );
+
+		block_full = new Uint8Array( canvasWBlocks * canvasHBlocks )
+
 	};
 	};
 
 
 	this.clear = function () {
 	this.clear = function () {
 
 
-		for ( var i = 3, l = data.length; i < l; i += 4 ) {
+		clearRectangle( prevrectx1, prevrecty1, prevrectx2, prevrecty2 );
+
+		for ( var i = 0, l = block_full.length; i < l; i ++ ) {
 
 
-			data[ i ] = 0;
+			block_full[ i ] = 0;
 
 
 		}
 		}
 
 
@@ -55,14 +75,17 @@ THREE.SoftwareRenderer = function () {
 
 
 	this.render = function ( scene, camera ) {
 	this.render = function ( scene, camera ) {
 
 
-		var m, ml, element, material, dom, v1x, v1y;
+		rectx1 = Infinity;
+		recty1 = Infinity;
+		rectx2 = 0;
+		recty2 = 0;
 
 
 		if ( this.autoClear ) this.clear();
 		if ( this.autoClear ) this.clear();
 
 
 		var renderData = projector.projectScene( scene, camera );
 		var renderData = projector.projectScene( scene, camera );
 		var elements = renderData.elements;
 		var elements = renderData.elements;
 
 
-		elements.sort( function painterSort( a, b ) { return a.z - b.z; } );
+		elements.sort( numericalSort );
 
 
 		for ( var e = 0, el = elements.length; e < el; e ++ ) {
 		for ( var e = 0, el = elements.length; e < el; e ++ ) {
 
 
@@ -77,13 +100,13 @@ THREE.SoftwareRenderer = function () {
 				drawTriangle(
 				drawTriangle(
 					v1.x * canvasWidthHalf + canvasWidthHalf,
 					v1.x * canvasWidthHalf + canvasWidthHalf,
 					- v1.y * canvasHeightHalf + canvasHeightHalf,
 					- v1.y * canvasHeightHalf + canvasHeightHalf,
-					0xff0000,
 					v2.x * canvasWidthHalf + canvasWidthHalf,
 					v2.x * canvasWidthHalf + canvasWidthHalf,
 					- v2.y * canvasHeightHalf + canvasHeightHalf,
 					- v2.y * canvasHeightHalf + canvasHeightHalf,
-					0x00ff00,
 					v3.x * canvasWidthHalf + canvasWidthHalf,
 					v3.x * canvasWidthHalf + canvasWidthHalf,
 					- v3.y * canvasHeightHalf + canvasHeightHalf,
 					- v3.y * canvasHeightHalf + canvasHeightHalf,
-					0x0000ff
+					0.5 * element.normalModelView.x + 0.5,
+					0.5 * element.normalModelView.y + 0.5,
+					0.5 * element.normalModelView.z + 0.5
 				)
 				)
 
 
 			} else if ( element instanceof THREE.RenderableFace4 ) {
 			} else if ( element instanceof THREE.RenderableFace4 ) {
@@ -96,42 +119,53 @@ THREE.SoftwareRenderer = function () {
 				drawTriangle(
 				drawTriangle(
 					v1.x * canvasWidthHalf + canvasWidthHalf,
 					v1.x * canvasWidthHalf + canvasWidthHalf,
 					- v1.y * canvasHeightHalf + canvasHeightHalf,
 					- v1.y * canvasHeightHalf + canvasHeightHalf,
-					0xff0000,
 					v2.x * canvasWidthHalf + canvasWidthHalf,
 					v2.x * canvasWidthHalf + canvasWidthHalf,
 					- v2.y * canvasHeightHalf + canvasHeightHalf,
 					- v2.y * canvasHeightHalf + canvasHeightHalf,
-					0x00ff00,
 					v3.x * canvasWidthHalf + canvasWidthHalf,
 					v3.x * canvasWidthHalf + canvasWidthHalf,
 					- v3.y * canvasHeightHalf + canvasHeightHalf,
 					- v3.y * canvasHeightHalf + canvasHeightHalf,
-					0x0000ff
+					0.5 * element.normalModelView.x + 0.5,
+					0.5 * element.normalModelView.y + 0.5,
+					0.5 * element.normalModelView.z + 0.5
 				);
 				);
 
 
 				drawTriangle(
 				drawTriangle(
 					v3.x * canvasWidthHalf + canvasWidthHalf,
 					v3.x * canvasWidthHalf + canvasWidthHalf,
 					- v3.y * canvasHeightHalf + canvasHeightHalf,
 					- v3.y * canvasHeightHalf + canvasHeightHalf,
-					0x0000ff,
 					v4.x * canvasWidthHalf + canvasWidthHalf,
 					v4.x * canvasWidthHalf + canvasWidthHalf,
 					- v4.y * canvasHeightHalf + canvasHeightHalf,
 					- v4.y * canvasHeightHalf + canvasHeightHalf,
-					0xff00ff,
 					v1.x * canvasWidthHalf + canvasWidthHalf,
 					v1.x * canvasWidthHalf + canvasWidthHalf,
 					- v1.y * canvasHeightHalf + canvasHeightHalf,
 					- v1.y * canvasHeightHalf + canvasHeightHalf,
-					0xff0000
+					0.5 * element.normalModelView.x + 0.5,
+					0.5 * element.normalModelView.y + 0.5,
+					0.5 * element.normalModelView.z + 0.5
 				);
 				);
 
 
 			}
 			}
 
 
 		}
 		}
 
 
-		context.putImageData( imagedata, 0, 0 );
+		var x = Math.min( rectx1, prevrectx1 );
+		var y = Math.min( recty1, prevrecty1 );
+		var width = Math.max( rectx2, prevrectx2 ) - x;
+		var height = Math.max( recty2, prevrecty2 ) - y;
+
+		context.putImageData( imagedata, 0, 0, x, y, width, height );
+
+		prevrectx1 = rectx1; prevrecty1 = recty1;
+		prevrectx2 = rectx2; prevrecty2 = recty2;
 
 
 	};
 	};
 
 
+	function numericalSort( a, b ) {
+
+		return a.z - b.z;
+
+	}
+
 	function drawPixel( x, y, r, g, b ) {
 	function drawPixel( x, y, r, g, b ) {
 
 
 		var offset = ( x + y * canvasWidth ) * 4;
 		var offset = ( x + y * canvasWidth ) * 4;
 
 
-		if ( x < 0 || y < 0 ) return;
-		if ( x > canvasWidth || y > canvasHeight ) return;
-
 		if ( data[ offset + 3 ] ) return;
 		if ( data[ offset + 3 ] ) return;
 
 
 		data[ offset ] = r;
 		data[ offset ] = r;
@@ -141,232 +175,244 @@ THREE.SoftwareRenderer = function () {
 
 
 	}
 	}
 
 
-	/*
-	function drawRectangle( x1, y1, x2, y2, color ) {
+	function clearRectangle( x1, y1, x2, y2 ) {
 
 
-		var r = color >> 16 & 255;
-		var g = color >> 8 & 255;
-		var b = color & 255;
+		var xmin = Math.max( Math.min( x1, x2 ), 0 );
+		var xmax = Math.min( Math.max( x1, x2 ), canvasWidth );
+		var ymin = Math.max( Math.min( y1, y2 ), 0 );
+		var ymax = Math.min( Math.max( y1, y2 ), canvasHeight );
 
 
-		var xmin = Math.min( x1, x2 ) >> 0;
-		var xmax = Math.max( x1, x2 ) >> 0;
-		var ymin = Math.min( y1, y2 ) >> 0;
-		var ymax = Math.max( y1, y2 ) >> 0;
+		var offset = ( xmin + ymin * canvasWidth - 1 ) * 4 + 3;
+		var linestep = ( canvasWidth - ( xmax - xmin ) ) * 4;
 
 
 		for ( var y = ymin; y < ymax; y ++ ) {
 		for ( var y = ymin; y < ymax; y ++ ) {
 
 
 			for ( var x = xmin; x < xmax; x ++ ) {
 			for ( var x = xmin; x < xmax; x ++ ) {
 
 
-				drawPixel( x, y, r, g, b );
+				data[ offset += 4 ] = 0;
 
 
 			}
 			}
 
 
+			offset += linestep;
+
 		}
 		}
 
 
 	}
 	}
-	*/
-
-	function drawTriangle( x1, y1, color1, x2, y2, color2, x3, y3, color3 ) {
-
-		// http://joshbeam.com/articles/triangle_rasterization/
 
 
-		edges[ 0 ].set( x1, y1, color1, x2, y2, color2 );
-		edges[ 1 ].set( x2, y2, color2, x3, y3, color3 );
-		edges[ 2 ].set( x3, y3, color3, x1, y1, color1 );
+	function drawTriangle( x1, y1, x2, y2, x3, y3, r, g, b ) {
 
 
-		var maxLength = 0;
-		var longEdge = 0;
+		// https://gist.github.com/2486101
+		// explanation: ttp://pouet.net/topic.php?which=8760&page=1
 
 
-		// find edge with the greatest length in the y axis
+		// 28.4 fixed-point coordinates
 
 
-		for ( var i = 0; i < 3; i ++ ) {
+		var x1 = (16 * x1) | 0;
+		var x2 = (16 * x2) | 0;
+		var x3 = (16 * x3) | 0;
 
 
-			var length = ( edges[ i ].y2 - edges[ i ].y1 );
+		var y1 = (16 * y1) | 0;
+		var y2 = (16 * y2) | 0;
+		var y3 = (16 * y3) | 0;
 
 
-			if ( length > maxLength ) {
+		// Deltas
 
 
-				maxLength = length;
-				longEdge = i;
+		var dx12 = x1 - x2, dy12 = y2 - y1;
+		var dx23 = x2 - x3, dy23 = y3 - y2;
+		var dx31 = x3 - x1, dy31 = y1 - y3;
 
 
-			}
-		}
+		// Bounding rectangle
 
 
-		var shortEdge1 = ( longEdge + 1 ) % 3;
-		var shortEdge2 = ( longEdge + 2 ) % 3;
+		var minx = Math.max( ( Math.min( x1, x2, x3 ) + 0xf ) >> 4, 0 );
+		var maxx = Math.min( ( Math.max( x1, x2, x3 ) + 0xf ) >> 4, canvasWidth );
+		var miny = Math.max( ( Math.min( y1, y2, y3 ) + 0xf ) >> 4, 0 );
+		var maxy = Math.min( ( Math.max( y1, y2, y3 ) + 0xf ) >> 4, canvasHeight );
 
 
-		drawSpans( edges[ longEdge ], edges[ shortEdge1 ] );
-		drawSpans( edges[ longEdge ], edges[ shortEdge2 ] );
+		rectx1 = Math.min( minx, rectx1 );
+		rectx2 = Math.max( maxx, rectx2 );
+		recty1 = Math.min( miny, recty1 );
+		recty2 = Math.max( maxy, recty2 );
 
 
-	}
+		// Block size, standard 8x8 (must be power of two)
 
 
-	function drawSpans( e1, e2 ) {
+		var q = blocksize;
 
 
-		var e1ydiff = e1.y2 - e1.y1;
-		if ( e1ydiff === 0 ) return;
+		// Start in corner of 8x8 block
 
 
-		var e2ydiff = e2.y2 - e2.y1;
-		if ( e2ydiff === 0 ) return;
+		minx &= ~(q - 1);
+		miny &= ~(q - 1);
 
 
-		var e1xdiff = e1.x2 - e1.x1;
-		var e2xdiff = e2.x2 - e2.x1;
+		// Constant part of half-edge functions
 
 
-		var e1colordiffr = e1.r2 - e1.r1;
-		var e1colordiffg = e1.g2 - e1.g1;
-		var e1colordiffb = e1.b2 - e1.b1;
+		var c1 = dy12 * ((minx << 4) - x1) + dx12 * ((miny << 4) - y1);
+		var c2 = dy23 * ((minx << 4) - x2) + dx23 * ((miny << 4) - y2);
+		var c3 = dy31 * ((minx << 4) - x3) + dx31 * ((miny << 4) - y3);
 
 
-		var e2colordiffr = e2.r2 - e2.r1;
-		var e2colordiffg = e2.g2 - e2.g1;
-		var e2colordiffb = e2.b2 - e2.b1;
+		// Correct for fill convention
 
 
-		var factor1 = ( e2.y1 - e1.y1 ) / e1ydiff;
-		var factorStep1 = 1 / e1ydiff;
-		var factor2 = 0;
-		var factorStep2 = 1 / e2ydiff;
+		if ( dy12 > 0 || ( dy12 == 0 && dx12 > 0 ) ) c1 ++;
+		if ( dy23 > 0 || ( dy23 == 0 && dx23 > 0 ) ) c2 ++;
+		if ( dy31 > 0 || ( dy31 == 0 && dx31 > 0 ) ) c3 ++;
 
 
+		// Note this doesn't kill subpixel precision, but only because we test for >=0 (not >0).
+		// It's a bit subtle. :)
+		c1 = (c1 - 1) >> 4;
+		c2 = (c2 - 1) >> 4;
+		c3 = (c3 - 1) >> 4;
 
 
-		for ( var y = e2.y1; y < e2.y2; y ++ ) {
+		// Set up min/max corners
+		var qm1 = q - 1; // for convenience
+		var nmin1 = 0, nmax1 = 0;
+		var nmin2 = 0, nmax2 = 0;
+		var nmin3 = 0, nmax3 = 0;
+		if (dx12 >= 0) nmax1 -= qm1*dx12; else nmin1 -= qm1*dx12;
+		if (dy12 >= 0) nmax1 -= qm1*dy12; else nmin1 -= qm1*dy12;
+		if (dx23 >= 0) nmax2 -= qm1*dx23; else nmin2 -= qm1*dx23;
+		if (dy23 >= 0) nmax2 -= qm1*dy23; else nmin2 -= qm1*dy23;
+		if (dx31 >= 0) nmax3 -= qm1*dx31; else nmin3 -= qm1*dx31;
+		if (dy31 >= 0) nmax3 -= qm1*dy31; else nmin3 -= qm1*dy31;
 
 
-			span.set(
-				e1.x1 + ( e1xdiff * factor1 ),
-				e1.r1 + e1colordiffr * factor1,
-				e1.g1 + e1colordiffg * factor1,
-				e1.b1 + e1colordiffb * factor1,
+		// Loop through blocks
+		var linestep = (canvasWidth - q) * 4;
+		var scale = 255.0 / (c1 + c2 + c3);
 
 
-				e2.x1 + ( e2xdiff * factor2 ),
-				e2.r1 + e2colordiffr * factor2,
-				e2.g1 + e2colordiffg * factor2,
-				e2.b1 + e2colordiffb * factor2
-			);
+		var cb1 = c1;
+		var cb2 = c2;
+		var cb3 = c3;
+		var qstep = -q;
+		var e1x = qstep * dy12;
+		var e2x = qstep * dy23;
+		var e3x = qstep * dy31;
+		var x0 = minx;
 
 
-			var xdiff = span.x2 - span.x1;
-			if ( xdiff > 0 ) {
+		for (var y0 = miny; y0 < maxy; y0 += q) {
 
 
-				var colordiffr = span.r2 - span.r1;
-				var colordiffg = span.g2 - span.g1;
-				var colordiffb = span.b2 - span.b1;
+			// New block line - keep hunting for tri outer edge in old block line dir
+			while (x0 >= minx && x0 < maxx && cb1 >= nmax1 && cb2 >= nmax2 && cb3 >= nmax3) {
 
 
-				var factor = 0;
-				var factorStep = 1 / xdiff;
-
-				for ( var x = span.x1; x < span.x2; x ++ ) {
-
-					var r = span.r1 + colordiffr * factor;
-					var g = span.g1 + colordiffg * factor;
-					var b = span.b1 + colordiffb * factor;
-
-					drawPixel( x, y, r, g, b );
-					factor += factorStep;
-
-				}
+				x0 += qstep;
+				cb1 += e1x;
+				cb2 += e2x;
+				cb3 += e3x;
 
 
 			}
 			}
 
 
-			factor1 += factorStep1;
-			factor2 += factorStep2;
+			// Okay, we're now in a block we know is outside. Reverse direction and go into main loop.
+			qstep = -qstep;
+			e1x = -e1x;
+			e2x = -e2x;
+			e3x = -e3x;
 
 
-		}
-
-	}
-
-	function Edge() {
-
-		this.x1 = 0;
-		this.y1 = 0;
+			while (1) {
 
 
-		this.x2 = 0;
-		this.y2 = 0;
+				// Step everything
+				x0 += qstep;
+				cb1 += e1x;
+				cb2 += e2x;
+				cb3 += e3x;
 
 
-		this.r1 = 0;
-		this.g1 = 0;
-		this.b1 = 0;
+				// We're done with this block line when at least one edge completely out
+				// If an edge function is too small and decreasing in the current traversal
+				// dir, we're done with this line.
+				if (x0 < minx || x0 >= maxx) break;
+				if (cb1 < nmax1) if (e1x < 0) break; else continue;
+				if (cb2 < nmax2) if (e2x < 0) break; else continue;
+				if (cb3 < nmax3) if (e3x < 0) break; else continue;
 
 
-		this.r2 = 0;
-		this.g2 = 0;
-		this.b2 = 0;
+				// We can skip this block if it's already fully covered
+				var blockX = (x0 / q) | 0;
+				var blockY = (y0 / q) | 0;
+				var blockInd = blockX + blockY * canvasWBlocks;
+				if (block_full[blockInd]) continue;
 
 
-		this.set = function ( x1, y1, color1, x2, y2, color2 ) {
+				// Offset at top-left corner
+				var offset = (x0 + y0 * canvasWidth) * 4;
 
 
-			if ( y1 < y2 ) {
+				// Accept whole block when fully covered
+				if (cb1 >= nmin1 && cb2 >= nmin2 && cb3 >= nmin3) {
 
 
-				this.x1 = x1 >> 0;
-				this.y1 = y1 >> 0;
+					var cy1 = cb1;
+					var cy2 = cb2;
 
 
-				this.x2 = x2 >> 0;
-				this.y2 = y2 >> 0;
+					for ( var iy = 0; iy < q; iy ++ ) {
 
 
-				this.r1 = color1 >> 16 & 255;
-				this.g1 = color1 >> 8 & 255;
-				this.b1 = color1 & 255;
+						var cx1 = cy1;
+						var cx2 = cy2;
 
 
-				this.r2 = color2 >> 16 & 255;
-				this.g2 = color2 >> 8 & 255;
-				this.b2 = color2 & 255;
+						for ( var ix = 0; ix < q; ix ++ ) {
 
 
-			} else {
+							if (!data[offset + 3]) {
 
 
-				this.x1 = x2 >> 0;
-				this.y1 = y2 >> 0;
+								var u = cx1 * scale; // 0-255!
+								var v = cx2 * scale; // 0-255!
+								data[offset] = u;
+								data[offset + 1] = v;
+								data[offset + 2] = 0;
+								data[offset + 3] = 255;
 
 
-				this.x2 = x1 >> 0;
-				this.y2 = y1 >> 0;
+							}
 
 
-				this.r1 = color2 >> 16 & 255;
-				this.g1 = color2 >> 8 & 255;
-				this.b1 = color2 & 255;
+							cx1 += dy12;
+							cx2 += dy23;
+							offset += 4;
 
 
-				this.r2 = color1 >> 16 & 255;
-				this.g2 = color1 >> 8 & 255;
-				this.b2 = color1 & 255;
+						}
 
 
-			}
+						cy1 += dx12;
+						cy2 += dx23;
+						offset += linestep;
 
 
-		}
+					}
 
 
-	}
+					block_full[blockInd] = 1;
 
 
-	function Span() {
+				} else { // Partially covered block
 
 
-		this.x1 = 0;
-		this.x2 = 0;
+					var cy1 = cb1;
+					var cy2 = cb2;
+					var cy3 = cb3;
 
 
-		this.r1 = 0;
-		this.g1 = 0;
-		this.b1 = 0;
+					for ( var iy = 0; iy < q; iy ++ ) {
 
 
-		this.r2 = 0;
-		this.g2 = 0;
-		this.b2 = 0;
+						var cx1 = cy1;
+						var cx2 = cy2;
+						var cx3 = cy3;
 
 
-		this.set = function ( x1, r1, g1, b1, x2, r2, g2, b2 ) {
+						for ( var ix = 0; ix < q; ix ++ ) {
 
 
-			if ( x1 < x2 ) {
+							if ( (cx1 | cx2 | cx3) >= 0 && !data[offset+3]) {
 
 
-				this.x1 = x1 >> 0;
-				this.x2 = x2 >> 0;
+								var u = cx1 * scale; // 0-255!
+								var v = cx2 * scale; // 0-255!
+								data[offset] = u;
+								data[offset + 1] = v;
+								data[offset + 2] = 0;
+								data[offset + 3] = 255;
 
 
-				this.r1 = r1;
-				this.g1 = g1;
-				this.b1 = b1;
+							}
 
 
-				this.r2 = r2;
-				this.g2 = g2;
-				this.b2 = b2;
+							cx1 += dy12;
+							cx2 += dy23;
+							cx3 += dy31;
+							offset += 4;
 
 
-			} else {
+						}
 
 
-				this.x1 = x2 >> 0;
-				this.x2 = x1 >> 0;
+						cy1 += dx12;
+						cy2 += dx23;
+						cy3 += dx31;
+						offset += linestep;
 
 
-				this.r1 = r2;
-				this.g1 = g2;
-				this.b1 = b2;
+					}
 
 
-				this.r2 = r1;
-				this.g2 = g1;
-				this.b2 = b1;
+				}
 
 
 			}
 			}
 
 
+			// Advance to next row of blocks
+			cb1 += q*dx12;
+			cb2 += q*dx23;
+			cb3 += q*dx31;
+
 		}
 		}
 
 
 	}
 	}

+ 0 - 409
examples/js/renderers/SoftwareRenderer2.js

@@ -1,409 +0,0 @@
-/**
- * @author mrdoob / http://mrdoob.com/
- */
-
-THREE.SoftwareRenderer2 = function () {
-
-	console.log( 'THREE.SoftwareRenderer', THREE.REVISION );
-
-	var canvas = document.createElement( 'canvas' );
-	var context = canvas.getContext( '2d' );
-
-	var imagedata = context.getImageData( 0, 0, canvas.width, canvas.height );
-	var data = imagedata.data;
-
-	var canvasWidth = canvas.width;
-	var canvasHeight = canvas.height;
-
-	var canvasWidthHalf = canvasWidth / 2;
-	var canvasHeightHalf = canvasHeight / 2;
-
-	var rectx1 = Infinity, recty1 = Infinity;
-	var rectx2 = 0, recty2 = 0;
-
-	var prevrectx1 = Infinity, prevrecty1 = Infinity;
-	var prevrectx2 = 0, prevrecty2 = 0;
-
-	var projector = new THREE.Projector();
-
-	this.domElement = canvas;
-
-	this.autoClear = true;
-
-	this.setSize = function ( width, height ) {
-
-		canvas.width = width;
-		canvas.height = height;
-
-		canvasWidth = canvas.width;
-		canvasHeight = canvas.height;
-
-		canvasWidthHalf = width / 2;
-		canvasHeightHalf = height / 2;
-
-		imagedata = context.getImageData( 0, 0, width, height );
-		data = imagedata.data;
-
-	};
-
-	this.clear = function () {
-
-		clearRectangle( prevrectx1, prevrecty1, prevrectx2, prevrecty2 );
-
-	};
-
-	this.render = function ( scene, camera ) {
-
-		rectx1 = Infinity;
-		recty1 = Infinity;
-		rectx2 = 0;
-		recty2 = 0;
-
-		if ( this.autoClear ) this.clear();
-
-		var renderData = projector.projectScene( scene, camera );
-		var elements = renderData.elements;
-
-		elements.sort( numericalSort );
-
-		for ( var e = 0, el = elements.length; e < el; e ++ ) {
-
-			var element = elements[ e ];
-
-			if ( element instanceof THREE.RenderableFace3 ) {
-
-				var v1 = element.v1.positionScreen;
-				var v2 = element.v2.positionScreen;
-				var v3 = element.v3.positionScreen;
-
-				drawTriangle(
-					v1.x * canvasWidthHalf + canvasWidthHalf,
-					- v1.y * canvasHeightHalf + canvasHeightHalf,
-					v2.x * canvasWidthHalf + canvasWidthHalf,
-					- v2.y * canvasHeightHalf + canvasHeightHalf,
-					v3.x * canvasWidthHalf + canvasWidthHalf,
-					- v3.y * canvasHeightHalf + canvasHeightHalf,
-					normalToComponent( element.normalWorld.x ),
-					normalToComponent( element.normalWorld.y ),
-					normalToComponent( element.normalWorld.z )
-				)
-
-			} else if ( element instanceof THREE.RenderableFace4 ) {
-
-				var v1 = element.v1.positionScreen;
-				var v2 = element.v2.positionScreen;
-				var v3 = element.v3.positionScreen;
-				var v4 = element.v4.positionScreen;
-
-				drawTriangle(
-					v1.x * canvasWidthHalf + canvasWidthHalf,
-					- v1.y * canvasHeightHalf + canvasHeightHalf,
-					v2.x * canvasWidthHalf + canvasWidthHalf,
-					- v2.y * canvasHeightHalf + canvasHeightHalf,
-					v3.x * canvasWidthHalf + canvasWidthHalf,
-					- v3.y * canvasHeightHalf + canvasHeightHalf,
-					normalToComponent( element.normalWorld.x ),
-					normalToComponent( element.normalWorld.y ),
-					normalToComponent( element.normalWorld.z )
-				);
-
-				drawTriangle(
-					v3.x * canvasWidthHalf + canvasWidthHalf,
-					- v3.y * canvasHeightHalf + canvasHeightHalf,
-					v4.x * canvasWidthHalf + canvasWidthHalf,
-					- v4.y * canvasHeightHalf + canvasHeightHalf,
-					v1.x * canvasWidthHalf + canvasWidthHalf,
-					- v1.y * canvasHeightHalf + canvasHeightHalf,
-					normalToComponent( element.normalWorld.x ),
-					normalToComponent( element.normalWorld.y ),
-					normalToComponent( element.normalWorld.z )
-				);
-
-			}
-
-		}
-
-		var x = Math.min( rectx1, prevrectx1 );
-		var y = Math.min( recty1, prevrecty1 );
-		var width = Math.max( rectx2, prevrectx2 ) - x;
-		var height = Math.max( recty2, prevrecty2 ) - y;
-
-		/*
-		console.log( rectx1, recty1, rectx2, recty2 );
-		console.log( prevrectx1, prevrecty1, prevrectx2, prevrecty2 );
-		console.log( x, y, width, height );
-		console.log( canvasWidth, canvasHeight );
-		*/
-
-		context.putImageData( imagedata, 0, 0, x, y, width, height );
-
-		prevrectx1 = rectx1; prevrecty1 = recty1;
-		prevrectx2 = rectx2; prevrecty2 = recty2;
-
-	};
-
-	function numericalSort( a, b ) {
-
-		return a.z - b.z;
-
-	}
-
-	function drawPixel( x, y, r, g, b ) {
-
-		var offset = ( x + y * canvasWidth ) * 4;
-
-		if ( data[ offset + 3 ] ) return;
-
-		data[ offset ] = r;
-		data[ offset + 1 ] = g;
-		data[ offset + 2 ] = b;
-		data[ offset + 3 ] = 255;
-
-	}
-
-	function clearRectangle( x1, y1, x2, y2 ) {
-
-		var xmin = Math.max( Math.min( x1, x2 ), 0 );
-		var xmax = Math.min( Math.max( x1, x2 ), canvasWidth );
-		var ymin = Math.max( Math.min( y1, y2 ), 0 );
-		var ymax = Math.min( Math.max( y1, y2 ), canvasHeight );
-
-		var offset = ( xmin + ymin * canvasWidth ) * 4 + 3;
-		var linestep = ( canvasWidth - ( xmax - xmin ) ) * 4;
-
-		for ( var y = ymin; y < ymax; y ++ ) {
-
-			for ( var x = xmin; x < xmax; x ++ ) {
-
-				data[ offset ] = 0;
-				offset += 4;
-
-			}
-
-			offset += linestep;
-
-		}
-
-	}
-
-	function drawTriangle( x1, y1, x2, y2, x3, y3, r, g, b ) {
-
-		// http://devmaster.net/forums/topic/1145-advanced-rasterization/
-
-		// 28.4 fixed-point coordinates
-
-		var x1 = Math.round( 16 * x1 );
-		var x2 = Math.round( 16 * x2 );
-		var x3 = Math.round( 16 * x3 );
-
-		var y1 = Math.round( 16 * y1 );
-		var y2 = Math.round( 16 * y2 );
-		var y3 = Math.round( 16 * y3 );
-
-		// Deltas
-
-		var dx12 = x1 - x2;
-		var dx23 = x2 - x3;
-		var dx31 = x3 - x1;
-
-		var dy12 = y1 - y2;
-		var dy23 = y2 - y3;
-		var dy31 = y3 - y1;
-
-		// Fixed-point deltas
-
-		var fdx12 = dx12 << 4;
-		var fdx23 = dx23 << 4;
-		var fdx31 = dx31 << 4;
-
-		var fdy12 = dy12 << 4;
-		var fdy23 = dy23 << 4;
-		var fdy31 = dy31 << 4;
-
-		// Bounding rectangle
-
-		var xmin = Math.max( ( Math.min( x1, x2, x3 ) + 0xf ) >> 4, 0 );
-		var xmax = Math.min( ( Math.max( x1, x2, x3 ) + 0xf ) >> 4, canvasWidth );
-		var ymin = Math.max( ( Math.min( y1, y2, y3 ) + 0xf ) >> 4, 0 );
-		var ymax = Math.min( ( Math.max( y1, y2, y3 ) + 0xf ) >> 4, canvasHeight );
-
-		rectx1 = Math.min( xmin, rectx1 );
-		rectx2 = Math.max( xmax, rectx2 );
-		recty1 = Math.min( ymin, recty1 );
-		recty2 = Math.max( ymax, recty2 );
-
-		// Constant part of half-edge functions
-
-		var c1 = dy12 * x1 - dx12 * y1;
-		var c2 = dy23 * x2 - dx23 * y2;
-		var c3 = dy31 * x3 - dx31 * y3;
-
-		// Correct for fill convention
-
-		if ( dy12 < 0 || ( dy12 == 0 && dx12 > 0 ) ) c1 ++;
-		if ( dy23 < 0 || ( dy23 == 0 && dx23 > 0 ) ) c2 ++;
-		if ( dy31 < 0 || ( dy31 == 0 && dx31 > 0 ) ) c3++;
-
-		var cy1 = c1 + dx12 * ( ymin << 4 ) - dy12 * ( xmin << 4 );
-		var cy2 = c2 + dx23 * ( ymin << 4 ) - dy23 * ( xmin << 4 );
-		var cy3 = c3 + dx31 * ( ymin << 4 ) - dy31 * ( xmin << 4 );
-
-		// Scan through bounding rectangle
-
-		for ( var y = ymin; y < ymax; y ++ ) {
-
-			// Start value for horizontal scan
-
-			var cx1 = cy1;
-			var cx2 = cy2;
-			var cx3 = cy3;
-
-			for ( var x = xmin; x < xmax; x ++ ) {
-
-				if ( cx1 > 0 && cx2 > 0 && cx3 > 0 ) {
-
-					drawPixel( x, y, r, g, b );
-
-				}
-
-				cx1 -= fdy12;
-				cx2 -= fdy23;
-				cx3 -= fdy31;
-
-			}
-
-			cy1 += fdx12;
-			cy2 += fdx23;
-			cy3 += fdx31;
-
-		}
-
-	}
-
-	function drawTriangleColor3( x1, y1, x2, y2, x3, y3, color1, color2, color3 ) {
-
-		// http://devmaster.net/forums/topic/1145-advanced-rasterization/
-
-		var r1 = color1 >> 16 & 255;
-		var r2 = color2 >> 16 & 255;
-		var r3 = color3 >> 16 & 255;
-
-		var g1 = color1 >> 8 & 255;
-		var g2 = color2 >> 8 & 255;
-		var g3 = color3 >> 8 & 255;
-
-		var b1 = color1 & 255;
-		var b2 = color2 & 255;
-		var b3 = color3 & 255;
-
-		var deltasr = computeDelta( x1, y1, r1, x2, y2, r2, x3, y3, r3 );
-		var deltasg = computeDelta( x1, y1, g1, x2, y2, g2, x3, y3, g3 );
-		var deltasb = computeDelta( x1, y1, b1, x2, y2, b2, x3, y3, b3 );
-
-		// 28.4 fixed-point coordinates
-
-		var X1 = Math.round( 16 * x1 );
-		var X2 = Math.round( 16 * x2 );
-		var X3 = Math.round( 16 * x3 );
-
-		var Y1 = Math.round( 16 * y1 );
-		var Y2 = Math.round( 16 * y2 );
-		var Y3 = Math.round( 16 * y3 );
-
-		// Deltas
-
-		var dx12 = X1 - X2;
-		var dx23 = X2 - X3;
-		var dx31 = X3 - X1;
-
-		var dy12 = Y1 - Y2;
-		var dy23 = Y2 - Y3;
-		var dy31 = Y3 - Y1;
-
-		// Fixed-point deltas
-
-		var fdx = [ dx12 << 4, dx23 << 4, dx31 << 4 ];
-		var fdy = [ dy12 << 4, dy23 << 4, dy31 << 4 ];
-
-		// Bounding rectangle
-
-		var minx = Math.max( ( Math.min( X1, X2, X3 ) + 0xf ) >> 4, 0 );
-		var maxx = Math.min( ( Math.max( X1, X2, X3 ) + 0xf ) >> 4, canvasWidth );
-		var miny = Math.max( ( Math.min( Y1, Y2, Y3 ) + 0xf ) >> 4, 0 );
-		var maxy = Math.min( ( Math.max( Y1, Y2, Y3 ) + 0xf ) >> 4, canvasHeight );
-
-		// Constant part of half-edge functions
-
-		var c1 = dy12 * X1 - dx12 * Y1;
-		var c2 = dy23 * X2 - dx23 * Y2;
-		var c3 = dy31 * X3 - dx31 * Y3;
-
-		// Correct for fill convention
-
-		if ( dy12 < 0 || ( dy12 == 0 && dx12 > 0 ) ) c1 ++;
-		if ( dy23 < 0 || ( dy23 == 0 && dx23 > 0 ) ) c2 ++;
-		if ( dy31 < 0 || ( dy31 == 0 && dx31 > 0 ) ) c3 ++;
-
-		var cy1 = c1 + dx12 * ( miny << 4 ) - dy12 * ( minx << 4 );
-		var cy2 = c2 + dx23 * ( miny << 4 ) - dy23 * ( minx << 4 );
-		var cy3 = c3 + dx31 * ( miny << 4 ) - dy31 * ( minx << 4 );
-
-		// Scan through bounding rectangle
-
-		var minyx1 = ( minx - x1 );
-		var minyy1 = ( miny - y1 );
-
-		var ry = deltasr[ 1 ] * minyy1;
-		var gy = deltasg[ 1 ] * minyy1;
-		var by = deltasb[ 1 ] * minyy1;
-
-		for ( var y = miny; y < maxy; y ++ ) {
-
-			// Start value for horizontal scan
-
-			var cx1 = cy1;
-			var cx2 = cy2;
-			var cx3 = cy3;
-
-			var rx = deltasr[ 0 ] * minyx1 + ry;
-			var gx = deltasg[ 0 ] * minyx1 + gy;
-			var bx = deltasb[ 0 ] * minyx1 + by;
-
-			for ( var x = minx; x < maxx; x ++ ) {
-
-				if ( cx1 > 0 && cx2 > 0 && cx3 > 0 ) {
-
-					drawPixel( x, y, r1 + rx, g1 + gx, b1 + bx );
-
-				}
-
-				cx1 -= fdy[ 0 ];
-				cx2 -= fdy[ 1 ];
-				cx3 -= fdy[ 2 ];
-
-				rx += deltasr[ 0 ];
-				gx += deltasg[ 0 ];
-				bx += deltasb[ 0 ];
-
-			}
-
-			cy1 += fdx[ 0 ];
-			cy2 += fdx[ 1 ];
-			cy3 += fdx[ 2 ];
-
-			ry += deltasr[ 1 ];
-			gy += deltasg[ 1 ];
-			by += deltasb[ 1 ];
-
-		}
-
-	}
-
-	function normalToComponent( normal ) {
-
-		var component = ( normal + 1 ) * 127;
-		return component < 0 ? 0 : ( component > 255 ? 255 : component );
-
-	}
-
-};

+ 0 - 427
examples/js/renderers/SoftwareRenderer3.js

@@ -1,427 +0,0 @@
-/**
- * @author mrdoob / http://mrdoob.com/
- * @author mraleph / http://mrale.ph/
- */
-
-THREE.SoftwareRenderer3 = function () {
-
-	console.log( 'THREE.SoftwareRenderer', THREE.REVISION );
-
-	var canvas = document.createElement( 'canvas' );
-	var context = canvas.getContext( '2d' );
-
-	var canvasWidth = canvas.width;
-	var canvasHeight = canvas.height;
-
-	var canvasWidthHalf = canvasWidth / 2;
-	var canvasHeightHalf = canvasHeight / 2;
-
-	var imagedata = context.getImageData( 0, 0, canvas.width, canvas.height );
-	var data = imagedata.data;
-
-	var blocksize = 8;
-
-	var canvasWBlocks = Math.floor( ( canvasWidth + blocksize - 1 ) / blocksize );
-	var canvasHBlocks = Math.floor( ( canvasHeight + blocksize - 1 ) / blocksize );
-
-	var block_full = new Uint8Array( canvasWBlocks * canvasHBlocks );
-
-	var rectx1 = Infinity, recty1 = Infinity;
-	var rectx2 = 0, recty2 = 0;
-
-	var prevrectx1 = Infinity, prevrecty1 = Infinity;
-	var prevrectx2 = 0, prevrecty2 = 0;
-
-	var projector = new THREE.Projector();
-
-	this.domElement = canvas;
-
-	this.autoClear = true;
-
-	this.setSize = function ( width, height ) {
-
-		canvas.width = width;
-		canvas.height = height;
-
-		canvasWidth = canvas.width;
-		canvasHeight = canvas.height;
-
-		canvasWidthHalf = width / 2;
-		canvasHeightHalf = height / 2;
-
-		imagedata = context.getImageData( 0, 0, width, height );
-		data = imagedata.data;
-
-		canvasWBlocks = Math.floor( ( canvasWidth + blocksize - 1 ) / blocksize );
-		canvasHBlocks = Math.floor( ( canvasHeight + blocksize - 1 ) / blocksize );
-
-		console.log( canvasWBlocks, canvasHBlocks );
-
-		block_full = new Uint8Array( canvasWBlocks * canvasHBlocks )
-
-	};
-
-	this.clear = function () {
-
-		clearRectangle( prevrectx1, prevrecty1, prevrectx2, prevrecty2 );
-
-		for ( var i = 0, l = block_full.length; i < l; i ++ ) {
-
-			block_full[ i ] = 0;
-
-		}
-
-	};
-
-	this.render = function ( scene, camera ) {
-
-		rectx1 = Infinity;
-		recty1 = Infinity;
-		rectx2 = 0;
-		recty2 = 0;
-
-		if ( this.autoClear ) this.clear();
-
-		var renderData = projector.projectScene( scene, camera );
-		var elements = renderData.elements;
-
-		elements.sort( numericalSort );
-
-		for ( var e = 0, el = elements.length; e < el; e ++ ) {
-
-			var element = elements[ e ];
-
-			if ( element instanceof THREE.RenderableFace3 ) {
-
-				var v1 = element.v1.positionScreen;
-				var v2 = element.v2.positionScreen;
-				var v3 = element.v3.positionScreen;
-
-				drawTriangle(
-					v1.x * canvasWidthHalf + canvasWidthHalf,
-					- v1.y * canvasHeightHalf + canvasHeightHalf,
-					v2.x * canvasWidthHalf + canvasWidthHalf,
-					- v2.y * canvasHeightHalf + canvasHeightHalf,
-					v3.x * canvasWidthHalf + canvasWidthHalf,
-					- v3.y * canvasHeightHalf + canvasHeightHalf,
-					normalToComponent( element.normalWorld.x ),
-					normalToComponent( element.normalWorld.y ),
-					normalToComponent( element.normalWorld.z )
-				)
-
-			} else if ( element instanceof THREE.RenderableFace4 ) {
-
-				var v1 = element.v1.positionScreen;
-				var v2 = element.v2.positionScreen;
-				var v3 = element.v3.positionScreen;
-				var v4 = element.v4.positionScreen;
-
-				drawTriangle(
-					v1.x * canvasWidthHalf + canvasWidthHalf,
-					- v1.y * canvasHeightHalf + canvasHeightHalf,
-					v2.x * canvasWidthHalf + canvasWidthHalf,
-					- v2.y * canvasHeightHalf + canvasHeightHalf,
-					v3.x * canvasWidthHalf + canvasWidthHalf,
-					- v3.y * canvasHeightHalf + canvasHeightHalf,
-					normalToComponent( element.normalWorld.x ),
-					normalToComponent( element.normalWorld.y ),
-					normalToComponent( element.normalWorld.z )
-				);
-
-				drawTriangle(
-					v3.x * canvasWidthHalf + canvasWidthHalf,
-					- v3.y * canvasHeightHalf + canvasHeightHalf,
-					v4.x * canvasWidthHalf + canvasWidthHalf,
-					- v4.y * canvasHeightHalf + canvasHeightHalf,
-					v1.x * canvasWidthHalf + canvasWidthHalf,
-					- v1.y * canvasHeightHalf + canvasHeightHalf,
-					normalToComponent( element.normalWorld.x ),
-					normalToComponent( element.normalWorld.y ),
-					normalToComponent( element.normalWorld.z )
-				);
-
-			}
-
-		}
-
-		var x = Math.min( rectx1, prevrectx1 );
-		var y = Math.min( recty1, prevrecty1 );
-		var width = Math.max( rectx2, prevrectx2 ) - x;
-		var height = Math.max( recty2, prevrecty2 ) - y;
-
-		context.putImageData( imagedata, 0, 0, x, y, width, height );
-
-		prevrectx1 = rectx1; prevrecty1 = recty1;
-		prevrectx2 = rectx2; prevrecty2 = recty2;
-
-	};
-
-	function numericalSort( a, b ) {
-
-		return a.z - b.z;
-
-	}
-
-	function drawPixel( x, y, r, g, b ) {
-
-		var offset = ( x + y * canvasWidth ) * 4;
-
-		if ( data[ offset + 3 ] ) return;
-
-		data[ offset ] = r;
-		data[ offset + 1 ] = g;
-		data[ offset + 2 ] = b;
-		data[ offset + 3 ] = 255;
-
-	}
-
-	function clearRectangle( x1, y1, x2, y2 ) {
-
-		var xmin = Math.max( Math.min( x1, x2 ), 0 );
-		var xmax = Math.min( Math.max( x1, x2 ), canvasWidth );
-		var ymin = Math.max( Math.min( y1, y2 ), 0 );
-		var ymax = Math.min( Math.max( y1, y2 ), canvasHeight );
-
-		var offset = ( xmin + ymin * canvasWidth - 1 ) * 4 + 3;
-		var linestep = ( canvasWidth - ( xmax - xmin ) ) * 4;
-
-		for ( var y = ymin; y < ymax; y ++ ) {
-
-			for ( var x = xmin; x < xmax; x ++ ) {
-
-				data[ offset += 4 ] = 0;
-
-			}
-
-			offset += linestep;
-
-		}
-
-	}
-
-	function drawTriangle( x1, y1, x2, y2, x3, y3, r, g, b ) {
-
-		// https://gist.github.com/2486101
-		// explanation: ttp://pouet.net/topic.php?which=8760&page=1
-
-		// 28.4 fixed-point coordinates
-
-		var x1 = (16 * x1) | 0;
-		var x2 = (16 * x2) | 0;
-		var x3 = (16 * x3) | 0;
-
-		var y1 = (16 * y1) | 0;
-		var y2 = (16 * y2) | 0;
-		var y3 = (16 * y3) | 0;
-
-		// Deltas
-
-		var dx12 = x1 - x2, dy12 = y2 - y1;
-		var dx23 = x2 - x3, dy23 = y3 - y2;
-		var dx31 = x3 - x1, dy31 = y1 - y3;
-
-		// Bounding rectangle
-
-		var minx = Math.max( ( Math.min( x1, x2, x3 ) + 0xf ) >> 4, 0 );
-		var maxx = Math.min( ( Math.max( x1, x2, x3 ) + 0xf ) >> 4, canvasWidth );
-		var miny = Math.max( ( Math.min( y1, y2, y3 ) + 0xf ) >> 4, 0 );
-		var maxy = Math.min( ( Math.max( y1, y2, y3 ) + 0xf ) >> 4, canvasHeight );
-
-		rectx1 = Math.min( minx, rectx1 );
-		rectx2 = Math.max( maxx, rectx2 );
-		recty1 = Math.min( miny, recty1 );
-		recty2 = Math.max( maxy, recty2 );
-
-		// Block size, standard 8x8 (must be power of two)
-
-		var q = blocksize;
-
-		// Start in corner of 8x8 block
-
-		minx &= ~(q - 1);
-		miny &= ~(q - 1);
-
-		// Constant part of half-edge functions
-
-		var c1 = dy12 * ((minx << 4) - x1) + dx12 * ((miny << 4) - y1);
-		var c2 = dy23 * ((minx << 4) - x2) + dx23 * ((miny << 4) - y2);
-		var c3 = dy31 * ((minx << 4) - x3) + dx31 * ((miny << 4) - y3);
-
-		// Correct for fill convention
-
-		if ( dy12 > 0 || ( dy12 == 0 && dx12 > 0 ) ) c1 ++;
-		if ( dy23 > 0 || ( dy23 == 0 && dx23 > 0 ) ) c2 ++;
-		if ( dy31 > 0 || ( dy31 == 0 && dx31 > 0 ) ) c3 ++;
-
-		// Note this doesn't kill subpixel precision, but only because we test for >=0 (not >0).
-		// It's a bit subtle. :)
-		c1 = (c1 - 1) >> 4;
-		c2 = (c2 - 1) >> 4;
-		c3 = (c3 - 1) >> 4;
-
-		// Set up min/max corners
-		var qm1 = q - 1; // for convenience
-		var nmin1 = 0, nmax1 = 0;
-		var nmin2 = 0, nmax2 = 0;
-		var nmin3 = 0, nmax3 = 0;
-		if (dx12 >= 0) nmax1 -= qm1*dx12; else nmin1 -= qm1*dx12;
-		if (dy12 >= 0) nmax1 -= qm1*dy12; else nmin1 -= qm1*dy12;
-		if (dx23 >= 0) nmax2 -= qm1*dx23; else nmin2 -= qm1*dx23;
-		if (dy23 >= 0) nmax2 -= qm1*dy23; else nmin2 -= qm1*dy23;
-		if (dx31 >= 0) nmax3 -= qm1*dx31; else nmin3 -= qm1*dx31;
-		if (dy31 >= 0) nmax3 -= qm1*dy31; else nmin3 -= qm1*dy31;
-
-		// Loop through blocks
-		var linestep = (canvasWidth - q) * 4;
-		var scale = 255.0 / (c1 + c2 + c3);
-
-		var cb1 = c1;
-		var cb2 = c2;
-		var cb3 = c3;
-		var qstep = -q;
-		var e1x = qstep * dy12;
-		var e2x = qstep * dy23;
-		var e3x = qstep * dy31;
-		var x0 = minx;
-
-		for (var y0 = miny; y0 < maxy; y0 += q) {
-
-			// New block line - keep hunting for tri outer edge in old block line dir
-			while (x0 >= minx && x0 < maxx && cb1 >= nmax1 && cb2 >= nmax2 && cb3 >= nmax3) {
-
-				x0 += qstep;
-				cb1 += e1x;
-				cb2 += e2x;
-				cb3 += e3x;
-
-			}
-
-			// Okay, we're now in a block we know is outside. Reverse direction and go into main loop.
-			qstep = -qstep;
-			e1x = -e1x;
-			e2x = -e2x;
-			e3x = -e3x;
-
-			while (1) {
-
-				// Step everything
-				x0 += qstep;
-				cb1 += e1x;
-				cb2 += e2x;
-				cb3 += e3x;
-
-				// We're done with this block line when at least one edge completely out
-				// If an edge function is too small and decreasing in the current traversal
-				// dir, we're done with this line.
-				if (x0 < minx || x0 >= maxx) break;
-				if (cb1 < nmax1) if (e1x < 0) break; else continue;
-				if (cb2 < nmax2) if (e2x < 0) break; else continue;
-				if (cb3 < nmax3) if (e3x < 0) break; else continue;
-
-				// We can skip this block if it's already fully covered
-				var blockX = (x0 / q) | 0;
-				var blockY = (y0 / q) | 0;
-				var blockInd = blockX + blockY * canvasWBlocks;
-				if (block_full[blockInd]) continue;
-
-				// Offset at top-left corner
-				var offset = (x0 + y0 * canvasWidth) * 4;
-
-				// Accept whole block when fully covered
-				if (cb1 >= nmin1 && cb2 >= nmin2 && cb3 >= nmin3) {
-
-					var cy1 = cb1;
-					var cy2 = cb2;
-
-					for ( var iy = 0; iy < q; iy ++ ) {
-
-						var cx1 = cy1;
-						var cx2 = cy2;
-
-						for ( var ix = 0; ix < q; ix ++ ) {
-
-							if (!data[offset + 3]) {
-
-								var u = cx1 * scale; // 0-255!
-								var v = cx2 * scale; // 0-255!
-								data[offset] = u;
-								data[offset + 1] = v;
-								data[offset + 2] = 0;
-								data[offset + 3] = 255;
-
-							}
-
-							cx1 += dy12;
-							cx2 += dy23;
-							offset += 4;
-
-						}
-
-						cy1 += dx12;
-						cy2 += dx23;
-						offset += linestep;
-
-					}
-
-					block_full[blockInd] = 1;
-
-				} else { // Partially covered block
-
-					var cy1 = cb1;
-					var cy2 = cb2;
-					var cy3 = cb3;
-
-					for ( var iy = 0; iy < q; iy ++ ) {
-
-						var cx1 = cy1;
-						var cx2 = cy2;
-						var cx3 = cy3;
-
-						for ( var ix = 0; ix < q; ix ++ ) {
-
-							if ( (cx1 | cx2 | cx3) >= 0 && !data[offset+3]) {
-
-								var u = cx1 * scale; // 0-255!
-								var v = cx2 * scale; // 0-255!
-								data[offset] = u;
-								data[offset + 1] = v;
-								data[offset + 2] = 0;
-								data[offset + 3] = 255;
-
-							}
-
-							cx1 += dy12;
-							cx2 += dy23;
-							cx3 += dy31;
-							offset += 4;
-
-						}
-
-						cy1 += dx12;
-						cy2 += dx23;
-						cy3 += dx31;
-						offset += linestep;
-
-					}
-
-				}
-
-			}
-
-			// Advance to next row of blocks
-			cb1 += q*dx12;
-			cb2 += q*dx23;
-			cb3 += q*dx31;
-
-		}
-
-	}
-
-	function normalToComponent( normal ) {
-
-		var component = ( normal + 1 ) * 127;
-		return component < 0 ? 0 : ( component > 255 ? 255 : component );
-
-	}
-
-};

+ 6 - 4
examples/js/renderers/WebGLDeferredRenderer.js

@@ -330,7 +330,8 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
 			uniforms[ "lightRadius" ].value = distance;
 			uniforms[ "lightRadius" ].value = distance;
 
 
 			positionVS.copy( light.matrixWorld.getPosition() );
 			positionVS.copy( light.matrixWorld.getPosition() );
-			camera.matrixWorldInverse.multiplyVector3( positionVS );
+			positionVS.applyMatrix4( camera.matrixWorldInverse );
+
 			uniforms[ "lightPositionVS" ].value.copy( positionVS );
 			uniforms[ "lightPositionVS" ].value.copy( positionVS );
 
 
 			lightProxy.position.copy( light.matrixWorld.getPosition() );
 			lightProxy.position.copy( light.matrixWorld.getPosition() );
@@ -421,7 +422,7 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
 		var modelMatrix = light.matrixWorld;
 		var modelMatrix = light.matrixWorld;
 
 
 		positionVS.copy( modelMatrix.getPosition() );
 		positionVS.copy( modelMatrix.getPosition() );
-		viewMatrix.multiplyVector3( positionVS );
+		positionVS.applyMatrix4( viewMatrix );
 
 
 		directionVS.copy( modelMatrix.getPosition() );
 		directionVS.copy( modelMatrix.getPosition() );
 		directionVS.subSelf( light.target.matrixWorld.getPosition() );
 		directionVS.subSelf( light.target.matrixWorld.getPosition() );
@@ -629,7 +630,8 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
 		var viewMatrix = camera.matrixWorldInverse;
 		var viewMatrix = camera.matrixWorldInverse;
 
 
 		positionVS.copy( modelMatrix.getPosition() );
 		positionVS.copy( modelMatrix.getPosition() );
-		viewMatrix.multiplyVector3( positionVS );
+		positionVS.applyMatrix4( viewMatrix );
+
 		uniforms[ "lightPositionVS" ].value.copy( positionVS );
 		uniforms[ "lightPositionVS" ].value.copy( positionVS );
 
 
 		rightVS.copy( light.right );
 		rightVS.copy( light.right );
@@ -1144,4 +1146,4 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
 
 
 	createRenderTargets();
 	createRenderTargets();
 
 
-};
+};

+ 3 - 3
examples/misc_controls_pointerlock.html

@@ -193,7 +193,7 @@
 				scene.add( controls.getObject() );
 				scene.add( controls.getObject() );
 
 
 				ray = new THREE.Raycaster();
 				ray = new THREE.Raycaster();
-				ray.direction.set( 0, -1, 0 );
+				ray.ray.direction.set( 0, -1, 0 );
 
 
 				// floor
 				// floor
 
 
@@ -284,8 +284,8 @@
 
 
 				controls.isOnObject( false );
 				controls.isOnObject( false );
 
 
-				ray.origin.copy( controls.getObject().position );
-				ray.origin.y -= 10;
+				ray.ray.origin.copy( controls.getObject().position );
+				ray.ray.origin.y -= 10;
 
 
 				var intersections = ray.intersectObjects( objects );
 				var intersections = ray.intersectObjects( objects );
 
 

+ 1 - 3
examples/misc_software.html

@@ -20,8 +20,6 @@
 		<script src="js/controls/TrackballControls.js"></script>
 		<script src="js/controls/TrackballControls.js"></script>
 
 
 		<script src="js/renderers/SoftwareRenderer.js"></script>
 		<script src="js/renderers/SoftwareRenderer.js"></script>
-		<script src="js/renderers/SoftwareRenderer2.js"></script>
-		<script src="js/renderers/SoftwareRenderer3.js"></script>
 
 
 		<script src="js/libs/stats.min.js"></script>
 		<script src="js/libs/stats.min.js"></script>
 
 
@@ -70,7 +68,7 @@
 				plane.rotation.x = - Math.PI / 2;
 				plane.rotation.x = - Math.PI / 2;
 				scene.add( plane );
 				scene.add( plane );
 
 
-				renderer = new THREE.SoftwareRenderer3();
+				renderer = new THREE.SoftwareRenderer();
 				renderer.setSize( window.innerWidth || 2, window.innerHeight || 2 );
 				renderer.setSize( window.innerWidth || 2, window.innerHeight || 2 );
 
 
 				container.appendChild( renderer.domElement );
 				container.appendChild( renderer.domElement );

+ 4 - 9
examples/misc_ubiquity_test.html

@@ -17,7 +17,7 @@
 		<script src="../build/three.min.js"></script>
 		<script src="../build/three.min.js"></script>
 
 
 		<script src="js/renderers/SVGRenderer.js"></script>
 		<script src="js/renderers/SVGRenderer.js"></script>
-		<script src="js/renderers/SoftwareRenderer3.js"></script>
+		<script src="js/renderers/SoftwareRenderer.js"></script>
 		<script src="js/libs/stats.min.js"></script>
 		<script src="js/libs/stats.min.js"></script>
 
 
 		<script src="obj/Qrcode.js"></script>
 		<script src="obj/Qrcode.js"></script>
@@ -33,7 +33,7 @@
 			var camera, scene;
 			var camera, scene;
 			var canvasRenderer, svgRenderer, softwareRenderer, webglRenderer;
 			var canvasRenderer, svgRenderer, softwareRenderer, webglRenderer;
 
 
-			var mesh, group, qrcode;
+			var mesh, group;
 
 
 			var mouseX = 0, mouseY = 0;
 			var mouseX = 0, mouseY = 0;
 
 
@@ -55,7 +55,7 @@
 
 
 				// QRCODE
 				// QRCODE
 
 
-				qrcode = mesh = new THREE.Mesh( new Qrcode(), new THREE.MeshLambertMaterial( { /*emissive: 0xff0000,*/ vertexColors: THREE.FaceColors } ) );
+				mesh = new THREE.Mesh( new Qrcode(), new THREE.MeshLambertMaterial( { /*emissive: 0xff0000,*/ vertexColors: THREE.FaceColors } ) );
 				mesh.scale.x = mesh.scale.y = mesh.scale.z = 2;
 				mesh.scale.x = mesh.scale.y = mesh.scale.z = 2;
 				scene.add( mesh );
 				scene.add( mesh );
 
 
@@ -146,7 +146,7 @@
 				svgRenderer.setQuality( 'low' );
 				svgRenderer.setQuality( 'low' );
 				container.appendChild( svgRenderer.domElement );
 				container.appendChild( svgRenderer.domElement );
 
 
-				softwareRenderer = new THREE.SoftwareRenderer3();
+				softwareRenderer = new THREE.SoftwareRenderer();
 				softwareRenderer.setSize( SCREEN_WIDTH, SCREEN_HEIGHT );
 				softwareRenderer.setSize( SCREEN_WIDTH, SCREEN_HEIGHT );
 				container.appendChild( softwareRenderer.domElement );
 				container.appendChild( softwareRenderer.domElement );
 
 
@@ -211,11 +211,6 @@
 
 
 				group.rotation.y += 0.01;
 				group.rotation.y += 0.01;
 
 
-				/*
-				qrcode.rotation.x += 0.01;
-				qrcode.rotation.z += 0.02;
-				*/
-
 				canvasRenderer.render( scene, camera );
 				canvasRenderer.render( scene, camera );
 				svgRenderer.render( scene, camera );
 				svgRenderer.render( scene, camera );
 				softwareRenderer.render( scene, camera );
 				softwareRenderer.render( scene, camera );

+ 411 - 0
examples/webgl_geometry_normals.html

@@ -0,0 +1,411 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<title>three.js webgl - geometry - Subdivisions with Catmull-Clark</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 {
+				font-family: Monospace;
+				background-color: #f0f0f0;
+				margin: 0px;
+				overflow: hidden;
+			}
+		</style>
+	</head>
+	<body>
+
+		<script src="../build/three.js"></script>
+		<script src="js/libs/stats.min.js"></script>
+		<script src="fonts/helvetiker_regular.typeface.js"></script>
+
+		<script>
+
+			var container, stats;
+
+			var camera, scene, renderer;
+
+			var cube, plane;
+
+			var targetYRotation = targetXRotation = 0;
+			var targetYRotationOnMouseDown = targetXRotationOnMouseDown = 0;
+
+			var mouseX = 0, mouseY = 0;
+			var mouseXOnMouseDown = 0;
+
+			var windowHalfX = window.innerWidth / 2;
+			var windowHalfY = window.innerHeight / 2;
+
+
+			// Create new object by parameters
+
+			var createSomething = function( klass, args ) {
+
+				var F = function( klass, args ) {
+
+				    return klass.apply( this, args );
+
+				}
+
+				F.prototype = klass.prototype;
+
+				return new F( klass, args );
+
+			};
+
+
+			// Cube
+
+			var materials = [];
+
+			for ( var i = 0; i < 6; i ++ ) {
+
+				materials.push( [ new THREE.MeshBasicMaterial( { color: Math.random() * 0xffffff, wireframe: false } ) ] );
+
+			}
+
+
+
+			var geometriesParams = [
+
+				{ type: 'CubeGeometry', args: [ 200, 200, 200, 2, 2, 2, materials ] },
+				{ type: 'TorusGeometry', args: [ 100, 60, 12, 12 ] },
+				{ type: 'TorusKnotGeometry', args: [  ] },
+				{ type: 'SphereGeometry', args: [ 100, 12, 12 ] },
+				{ type: 'SphereGeometry', args: [ 100, 5, 5 ] },
+				{ type: 'SphereGeometry', args: [ 100, 13, 13 ] },
+				{ type: 'IcosahedronGeometry', args: [ 100, 1 ] },
+				{ type: 'CylinderGeometry', args: [ 25, 75, 200, 8, 3 ]} ,
+				{ type: 'OctahedronGeometry', args: [200, 0] },
+				{ type: 'LatheGeometry', args: [ [
+					new THREE.Vector3(0,0,-100),
+					new THREE.Vector3(0,50,-50),
+					new THREE.Vector3(0,10,0),
+					new THREE.Vector3(0,50,050),
+					new THREE.Vector3(0,0,100) ] ]},
+				{ type: 'TextGeometry', args: ['&', {
+										size: 200,
+										height: 50,
+										curveSegments: 1,
+										font: "helvetiker"
+
+									}]},
+				{ type: 'PlaneGeometry', args: [ 200, 200, 4, 4 ] }
+
+			];
+
+			var info;
+			var geometryIndex = 0;
+
+			// start scene
+
+			init();
+			animate();
+
+			function nextGeometry() {
+
+				geometryIndex ++;
+
+				if ( geometryIndex > geometriesParams.length - 1 ) {
+
+					geometryIndex = 0;
+
+				}
+
+				addStuff();
+
+			}
+
+			function switchGeometry(i) {
+
+				geometryIndex = i;
+
+				addStuff();
+			}
+
+			function updateInfo() {
+
+				var params = geometriesParams[ geometryIndex ];
+
+				var dropdown = '<select id="dropdown" onchange="switchGeometry(this.value)">';
+
+				for (  i = 0; i < geometriesParams.length; i ++ ) {
+					dropdown += '<option value="' + i + '"';
+
+					dropdown += (geometryIndex == i)  ? ' selected' : '';
+
+					dropdown += '>' + geometriesParams[i].type + '</option>';
+				}
+
+				dropdown += '</select>';
+			
+				var text =
+					'Drag to spin THREE.' + params.type +
+				 	'<br>' +
+					'<br>Geometry: ' + dropdown + ' <a href="#" onclick="nextGeometry();return false;">next</a>';
+
+				text +=
+					'<br><br><font color="3333FF">Blue Arrows: Face Normals</font>' + 
+					'<br><font color="FF3333">Red Arrows: Vertex Normals before Geometry.mergeVertices</font>' + 
+					'<br>Black Arrows: Vertex Normals after Geometry.mergeVertices';
+
+				info.innerHTML = text;
+
+			}
+
+			function addStuff() {
+
+				if ( window.group !== undefined ) {
+
+					scene.remove( group );
+	
+				}
+
+
+
+				var params = geometriesParams[ geometryIndex ];
+
+				geometry = createSomething( THREE[ params.type ], params.args );
+
+				// scale geometry to a uniform size
+				geometry.computeBoundingSphere();
+				
+				var scaleFactor = 160 / geometry.boundingSphere.radius;
+				geometry.applyMatrix( new THREE.Matrix4().makeScale( new THREE.Vector3( scaleFactor, scaleFactor, scaleFactor ) ) );
+
+				var originalGeometry = geometry.clone();
+				originalGeometry.computeFaceNormals();
+				originalGeometry.computeVertexNormals( true );
+			
+				// in case of duplicated vertices
+				geometry.mergeVertices();
+				geometry.computeCentroids();
+				geometry.computeFaceNormals();
+				geometry.computeVertexNormals( true );
+			
+				updateInfo();
+
+				var faceABCD = "abcd";
+				var color, f, p, n, vertexIndex;
+
+				for ( i = 0; i < geometry.faces.length; i ++ ) {
+
+					f  = geometry.faces[ i ];
+
+
+					n = ( f instanceof THREE.Face3 ) ? 3 : 4;
+
+					for( var j = 0; j < n; j++ ) {
+
+						vertexIndex = f[ faceABCD.charAt( j ) ];
+
+						p = geometry.vertices[ vertexIndex ];
+
+						color = new THREE.Color( 0xffffff );
+						color.setHSV( ( p.y ) / 400 + 0.5, 1.0, 1.0 );
+
+						f.vertexColors[ j ] = color;
+
+					}
+
+				}
+
+
+				group = new THREE.Object3D();
+				var mesh = new THREE.Mesh( geometry, new THREE.MeshBasicMaterial( { color: 0xfefefe, wireframe: true, opacity: 0.5 } ) );
+				group.add( mesh );
+				scene.add( group );
+
+				var fvNames = [ 'a', 'b', 'c', 'd' ];
+
+				var normalLength = 15;
+				
+			
+				for( var f = 0, fl = geometry.faces.length; f < fl; f ++ ) {
+					var face = geometry.faces[ f ];
+					var arrow = new THREE.ArrowHelper( 
+							face.normal,
+							face.centroid,
+							normalLength,
+							0x3333FF );
+					mesh.add( arrow );
+				}
+
+				for( var f = 0, fl = originalGeometry.faces.length; f < fl; f ++ ) {
+					var face = originalGeometry.faces[ f ];
+					if( face.vertexNormals === undefined ) {
+						continue;
+					}
+					for( var v = 0, vl = face.vertexNormals.length; v < vl; v ++ ) {
+						var arrow = new THREE.ArrowHelper( 
+								face.vertexNormals[ v ],
+								originalGeometry.vertices[ face[ fvNames[ v ] ] ],
+								normalLength,
+								0xFF3333 );
+						mesh.add( arrow );
+					}
+				}
+
+				for( var f = 0, fl = mesh.geometry.faces.length; f < fl; f ++ ) {
+					var face = mesh.geometry.faces[ f ];
+					if( face.vertexNormals === undefined ) {
+						continue;
+					}
+					for( var v = 0, vl = face.vertexNormals.length; v < vl; v ++ ) {
+						var arrow = new THREE.ArrowHelper( 
+								face.vertexNormals[ v ],
+								mesh.geometry.vertices[ face[ fvNames[ v ] ] ],
+								normalLength,
+								0x000000 );
+						mesh.add( arrow );
+					}
+				}
+
+			}
+
+			function init() {
+
+				container = document.createElement( 'div' );
+				document.body.appendChild( container );
+
+				info = document.createElement( 'div' );
+				info.style.position = 'absolute';
+				info.style.top = '10px';
+				info.style.width = '100%';
+				info.style.textAlign = 'center';
+				info.innerHTML = 'Drag to spin the geometry ';
+				container.appendChild( info );
+
+				camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 1, 1000 );
+				camera.position.z = 500;
+
+				scene = new THREE.Scene();
+
+				var light = new THREE.PointLight( 0xffffff, 1.5 );
+				light.position.set( 1000, 1000, 2000 );
+				scene.add( light );
+
+				addStuff();
+
+				renderer = new THREE.WebGLRenderer( { antialias: true } ); // WebGLRenderer CanvasRenderer
+				renderer.setSize( window.innerWidth, window.innerHeight );
+
+				container.appendChild( renderer.domElement );
+
+				stats = new Stats();
+				stats.domElement.style.position = 'absolute';
+				stats.domElement.style.top = '0px';
+				container.appendChild( stats.domElement );
+
+				document.addEventListener( 'mousedown', onDocumentMouseDown, false );
+				document.addEventListener( 'touchstart', onDocumentTouchStart, false );
+				document.addEventListener( 'touchmove', onDocumentTouchMove, 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 onDocumentMouseDown( event ) {
+
+				//event.preventDefault();
+
+				document.addEventListener( 'mousemove', onDocumentMouseMove, false );
+				document.addEventListener( 'mouseup', onDocumentMouseUp, false );
+				document.addEventListener( 'mouseout', onDocumentMouseOut, false );
+
+				mouseXOnMouseDown = event.clientX - windowHalfX;
+				mouseYOnMouseDown = event.clientY - windowHalfY;
+				targetYRotationOnMouseDown = targetYRotation;
+				targetXRotationOnMouseDown = targetXRotation;
+
+			}
+
+			function onDocumentMouseMove( event ) {
+
+				mouseX = event.clientX - windowHalfX;
+				mouseY = event.clientY - windowHalfY;
+
+				targetYRotation = targetYRotationOnMouseDown + ( mouseX - mouseXOnMouseDown ) * 0.02;
+				targetXRotation = targetXRotationOnMouseDown + ( mouseY - mouseYOnMouseDown ) * 0.02;
+
+			}
+
+			function onDocumentMouseUp( event ) {
+
+				document.removeEventListener( 'mousemove', onDocumentMouseMove, false );
+				document.removeEventListener( 'mouseup', onDocumentMouseUp, false );
+				document.removeEventListener( 'mouseout', onDocumentMouseOut, false );
+			}
+
+			function onDocumentMouseOut( event ) {
+
+				document.removeEventListener( 'mousemove', onDocumentMouseMove, false );
+				document.removeEventListener( 'mouseup', onDocumentMouseUp, false );
+				document.removeEventListener( 'mouseout', onDocumentMouseOut, false );
+			}
+
+			function onDocumentTouchStart( event ) {
+
+				if ( event.touches.length == 1 ) {
+
+					event.preventDefault();
+
+					mouseXOnMouseDown = event.touches[ 0 ].pageX - windowHalfX;
+					targetRotationOnMouseDown = targetRotation;
+
+				}
+			}
+
+			function onDocumentTouchMove( event ) {
+
+				if ( event.touches.length == 1 ) {
+
+					event.preventDefault();
+
+					mouseX = event.touches[ 0 ].pageX - windowHalfX;
+					targetRotation = targetRotationOnMouseDown + ( mouseX - mouseXOnMouseDown ) * 0.05;
+
+				}
+			}
+
+			//
+
+			function animate() {
+
+				requestAnimationFrame( animate );
+
+				render();
+				stats.update();
+
+			}
+
+			function render() {
+
+				group.rotation.x = ( targetXRotation) * 0.15;
+				group.rotation.y =  ( targetYRotation ) * 0.15;
+
+				renderer.render( scene, camera );
+
+			}
+
+		</script>
+
+	</body>
+</html>
+

+ 2 - 1
examples/webgl_interactive_voxelpainter.html

@@ -174,8 +174,9 @@
 			function setVoxelPosition( intersector ) {
 			function setVoxelPosition( intersector ) {
 
 
 				tmpVec.copy( intersector.face.normal );
 				tmpVec.copy( intersector.face.normal );
+				tmpVec.applyMatrix4( intersector.object.matrixRotationWorld );
 
 
-				voxelPosition.add( intersector.point, intersector.object.matrixRotationWorld.multiplyVector3( tmpVec ) );
+				voxelPosition.add( intersector.point, tmpVec );
 
 
 				voxelPosition.x = Math.floor( voxelPosition.x / 50 ) * 50 + 25;
 				voxelPosition.x = Math.floor( voxelPosition.x / 50 ) * 50 + 25;
 				voxelPosition.y = Math.floor( voxelPosition.y / 50 ) * 50 + 25;
 				voxelPosition.y = Math.floor( voxelPosition.y / 50 ) * 50 + 25;

+ 3 - 2
examples/webgl_lights_deferred_arealights.html

@@ -174,8 +174,9 @@
 
 
 				light.right.set( 1, 0, 0 );
 				light.right.set( 1, 0, 0 );
 				light.normal.set( 0, -1, 0 );
 				light.normal.set( 0, -1, 0 );
-				light.right = matrix.multiplyVector3( light.right );
-				light.normal = matrix.multiplyVector3( light.normal );
+
+				light.right.applyMatrix4( matrix );
+				light.normal.applyMatrix4( matrix );
 
 
 			}
 			}
 
 

+ 1 - 1
src/Three.js

@@ -3,7 +3,7 @@
  * @author Larry Battle / http://bateru.com/news
  * @author Larry Battle / http://bateru.com/news
  */
  */
 
 
-var THREE = THREE || { REVISION: '54' };
+var THREE = THREE || { REVISION: '55dev' };
 
 
 self.console = self.console || {
 self.console = self.console || {
 
 

+ 79 - 22
src/core/Geometry.js

@@ -60,31 +60,27 @@ THREE.Geometry.prototype = {
 
 
 	applyMatrix: function ( matrix ) {
 	applyMatrix: function ( matrix ) {
 
 
-		var normalMatrix = new THREE.Matrix3();
-
-		normalMatrix.getInverse( matrix ).transpose();
+		var normalMatrix = new THREE.Matrix3().getInverse( matrix ).transpose();
 
 
 		for ( var i = 0, il = this.vertices.length; i < il; i ++ ) {
 		for ( var i = 0, il = this.vertices.length; i < il; i ++ ) {
 
 
 			var vertex = this.vertices[ i ];
 			var vertex = this.vertices[ i ];
-
-			matrix.multiplyVector3( vertex );
+			vertex.applyMatrix4( matrix );
 
 
 		}
 		}
 
 
 		for ( var i = 0, il = this.faces.length; i < il; i ++ ) {
 		for ( var i = 0, il = this.faces.length; i < il; i ++ ) {
 
 
 			var face = this.faces[ i ];
 			var face = this.faces[ i ];
-
-			normalMatrix.multiplyVector3( face.normal ).normalize();
+			face.normal.applyMatrix3( normalMatrix ).normalize();
 
 
 			for ( var j = 0, jl = face.vertexNormals.length; j < jl; j ++ ) {
 			for ( var j = 0, jl = face.vertexNormals.length; j < jl; j ++ ) {
 
 
-				normalMatrix.multiplyVector3( face.vertexNormals[ j ] ).normalize();
+				face.vertexNormals[ j ].applyMatrix3( normalMatrix ).normalize();
 
 
 			}
 			}
 
 
-			matrix.multiplyVector3( face.centroid );
+			face.centroid.applyMatrix4( matrix );
 
 
 		}
 		}
 
 
@@ -614,7 +610,10 @@ THREE.Geometry.prototype = {
 		var precisionPoints = 4; // number of decimal points, eg. 4 for epsilon of 0.0001
 		var precisionPoints = 4; // number of decimal points, eg. 4 for epsilon of 0.0001
 		var precision = Math.pow( 10, precisionPoints );
 		var precision = Math.pow( 10, precisionPoints );
 		var i,il, face;
 		var i,il, face;
-		var abcd = 'abcd', o, k, j, jl, u;
+		var indices, k, j, jl, u;
+
+		// reset cache of vertices as it now will be changing.
+		this.__tmpVertices = undefined;
 
 
 		for ( i = 0, il = this.vertices.length; i < il; i ++ ) {
 		for ( i = 0, il = this.vertices.length; i < il; i ++ ) {
 
 
@@ -637,7 +636,9 @@ THREE.Geometry.prototype = {
 		};
 		};
 
 
 
 
-		// Start to patch face indices
+		// if faces are completely degenerate after merging vertices, we
+		// have to remove them from the geometry.
+		var faceIndicesToRemove = [];
 
 
 		for( i = 0, il = this.faces.length; i < il; i ++ ) {
 		for( i = 0, il = this.faces.length; i < il; i ++ ) {
 
 
@@ -649,6 +650,22 @@ THREE.Geometry.prototype = {
 				face.b = changes[ face.b ];
 				face.b = changes[ face.b ];
 				face.c = changes[ face.c ];
 				face.c = changes[ face.c ];
 
 
+				indices = [ face.a, face.b, face.c ];
+
+				var dupIndex = -1;
+				
+				// if any duplicate vertices are found in a Face3
+				// we have to remove the face as nothing can be saved
+				for( var n = 0; n < 3; n ++ ) {
+					if( indices[ n ] == indices[ ( n + 1 ) % 3 ] ) {
+
+						dupIndex = n;
+						faceIndicesToRemove.push( i );
+						break;
+
+					}
+				}
+
 			} else if ( face instanceof THREE.Face4 ) {
 			} else if ( face instanceof THREE.Face4 ) {
 
 
 				face.a = changes[ face.a ];
 				face.a = changes[ face.a ];
@@ -658,36 +675,76 @@ THREE.Geometry.prototype = {
 
 
 				// check dups in (a, b, c, d) and convert to -> face3
 				// check dups in (a, b, c, d) and convert to -> face3
 
 
-				o = [ face.a, face.b, face.c, face.d ];
+				indices = [ face.a, face.b, face.c, face.d ];
+
+				var dupIndex = -1;
+
+				for( var n = 0; n < 4; n ++ ) {
+					if( indices[ n ] == indices[ ( n + 1 ) % 4 ] ) {
+
+
+						// if more than one duplicated vertex is found
+						// we can't generate any valid Face3's, thus
+						// we need to remove this face complete.
+						if( dupIndex >= 0 ) {
+
+							faceIndicesToRemove.push( i );
+
+						}
 
 
-				for ( k = 3; k > 0; k -- ) {
+						dupIndex = n;
 
 
-					if ( o.indexOf( face[ abcd[ k ] ] ) !== k ) {
+					}
+				}
 
 
-						// console.log('faces', face.a, face.b, face.c, face.d, 'dup at', k);
+				if( dupIndex >= 0 ) {
 
 
-						o.splice( k, 1 );
+					indices.splice( dupIndex, 1 );
 
 
-						this.faces[ i ] = new THREE.Face3( o[0], o[1], o[2], face.normal, face.color, face.materialIndex );
+					var newFace = new THREE.Face3( indices[0], indices[1], indices[2], face.normal, face.color, face.materialIndex );
 
 
-						for ( j = 0, jl = this.faceVertexUvs.length; j < jl; j ++ ) {
+					for ( j = 0, jl = this.faceVertexUvs.length; j < jl; j ++ ) {
 
 
-							u = this.faceVertexUvs[ j ][ i ];
-							if ( u ) u.splice( k, 1 );
+						u = this.faceVertexUvs[ j ][ i ];
 
 
+						if ( u ) {
+							u.splice( dupIndex, 1 );
 						}
 						}
 
 
-						this.faces[ i ].vertexColors = face.vertexColors;
+					}
+
+					if( face.vertexNormals && face.vertexNormals.length > 0) {
+
+						newFace.vertexNormals = face.vertexNormals;
+						newFace.vertexNormals.splice( dupIndex, 1 );
 
 
-						break;
 					}
 					}
 
 
+					if( face.vertexColors && face.vertexColors.length > 0 ) {
+
+						newFace.vertexColors = face.vertexColors;
+						newFace.vertexColors.splice( dupIndex, 1 );
+					}
+
+					this.faces[ i ] = newFace;
 				}
 				}
 
 
 			}
 			}
 
 
 		}
 		}
 
 
+		for( i = faceIndicesToRemove.length - 1; i >= 0; i -- ) {
+
+			this.faces.splice( i, 1 );
+			
+			for ( j = 0, jl = this.faceVertexUvs.length; j < jl; j ++ ) {
+
+				this.faceVertexUvs[ j ].splice( i, 1 );
+
+			}
+
+		}
+
 		// Use unique set of vertices
 		// Use unique set of vertices
 
 
 		var diff = this.vertices.length - unique.length;
 		var diff = this.vertices.length - unique.length;

+ 2 - 2
src/core/Object3D.js

@@ -91,13 +91,13 @@ THREE.Object3D.prototype = {
 
 
 	localToWorld: function ( vector ) {
 	localToWorld: function ( vector ) {
 
 
-		return this.matrixWorld.multiplyVector3( vector );
+		return vector.applyMatrix4( this.matrixWorld );
 
 
 	},
 	},
 
 
 	worldToLocal: function ( vector ) {
 	worldToLocal: function ( vector ) {
 
 
-		return THREE.Object3D.__m1.getInverse( this.matrixWorld ).multiplyVector3( vector );
+		return vector.applyMatrix4( THREE.Object3D.__m1.getInverse( this.matrixWorld ) );
 
 
 	},
 	},
 
 

+ 64 - 39
src/core/Projector.js

@@ -18,9 +18,16 @@ THREE.Projector = function() {
 	_vector3 = new THREE.Vector3(),
 	_vector3 = new THREE.Vector3(),
 	_vector4 = new THREE.Vector4(),
 	_vector4 = new THREE.Vector4(),
 
 
+	_viewMatrix = new THREE.Matrix4(),
 	_viewProjectionMatrix = new THREE.Matrix4(),
 	_viewProjectionMatrix = new THREE.Matrix4(),
+
+	_modelMatrix,
 	_modelViewProjectionMatrix = new THREE.Matrix4(),
 	_modelViewProjectionMatrix = new THREE.Matrix4(),
+
 	_normalMatrix = new THREE.Matrix3(),
 	_normalMatrix = new THREE.Matrix3(),
+	_normalViewMatrix = new THREE.Matrix3(),
+
+	_centroid = new THREE.Vector3(),
 
 
 	_frustum = new THREE.Frustum(),
 	_frustum = new THREE.Frustum(),
 
 
@@ -34,9 +41,8 @@ THREE.Projector = function() {
 		camera.matrixWorldInverse.getInverse( camera.matrixWorld );
 		camera.matrixWorldInverse.getInverse( camera.matrixWorld );
 
 
 		_viewProjectionMatrix.multiply( camera.projectionMatrix, camera.matrixWorldInverse );
 		_viewProjectionMatrix.multiply( camera.projectionMatrix, camera.matrixWorldInverse );
-		_viewProjectionMatrix.multiplyVector3( vector );
 
 
-		return vector;
+		return vector.applyMatrix4( _viewProjectionMatrix );
 
 
 	};
 	};
 
 
@@ -45,9 +51,8 @@ THREE.Projector = function() {
 		camera.projectionMatrixInverse.getInverse( camera.projectionMatrix );
 		camera.projectionMatrixInverse.getInverse( camera.projectionMatrix );
 
 
 		_viewProjectionMatrix.multiply( camera.matrixWorld, camera.projectionMatrixInverse );
 		_viewProjectionMatrix.multiply( camera.matrixWorld, camera.projectionMatrixInverse );
-		_viewProjectionMatrix.multiplyVector3( vector );
 
 
-		return vector;
+		return vector.applyMatrix4( _viewProjectionMatrix );
 
 
 	};
 	};
 
 
@@ -89,7 +94,7 @@ THREE.Projector = function() {
 
 
 				} else if ( object instanceof THREE.Mesh || object instanceof THREE.Line ) {
 				} else if ( object instanceof THREE.Mesh || object instanceof THREE.Line ) {
 
 
-					if ( object.frustumCulled === false || _frustum.contains( object ) === true ) {
+					if ( object.frustumCulled === false || _frustum.intersectsObject( object ) === true ) {
 
 
 						_object = getNextObjectInPool();
 						_object = getNextObjectInPool();
 						_object.object = object;
 						_object.object = object;
@@ -101,7 +106,7 @@ THREE.Projector = function() {
 						} else {
 						} else {
 
 
 							_vector3.copy( object.matrixWorld.getPosition() );
 							_vector3.copy( object.matrixWorld.getPosition() );
-							_viewProjectionMatrix.multiplyVector3( _vector3 );
+							_vector3.applyMatrix4( _viewProjectionMatrix );
 							_object.z = _vector3.z;
 							_object.z = _vector3.z;
 
 
 						}
 						}
@@ -124,7 +129,7 @@ THREE.Projector = function() {
 					} else {
 					} else {
 
 
 						_vector3.copy( object.matrixWorld.getPosition() );
 						_vector3.copy( object.matrixWorld.getPosition() );
-						_viewProjectionMatrix.multiplyVector3( _vector3 );
+						_vector3.applyMatrix4( _viewProjectionMatrix );
 						_object.z = _vector3.z;
 						_object.z = _vector3.z;
 
 
 					}
 					}
@@ -143,7 +148,7 @@ THREE.Projector = function() {
 					} else {
 					} else {
 
 
 						_vector3.copy( object.matrixWorld.getPosition() );
 						_vector3.copy( object.matrixWorld.getPosition() );
-						_viewProjectionMatrix.multiplyVector3( _vector3 );
+						_vector3.applyMatrix4( _viewProjectionMatrix );
 						_object.z = _vector3.z;
 						_object.z = _vector3.z;
 
 
 					}
 					}
@@ -169,10 +174,10 @@ THREE.Projector = function() {
 	this.projectScene = function ( scene, camera, sortObjects, sortElements ) {
 	this.projectScene = function ( scene, camera, sortObjects, sortElements ) {
 
 
 		var near = camera.near, far = camera.far, visible = false,
 		var near = camera.near, far = camera.far, visible = false,
-		o, ol, v, vl, f, fl, n, nl, c, cl, u, ul, object, modelMatrix,
+		o, ol, v, vl, f, fl, n, nl, c, cl, u, ul, object,
 		geometry, vertices, vertex, vertexPositionScreen,
 		geometry, vertices, vertex, vertexPositionScreen,
-		faces, face, faceVertexNormals, normal, faceVertexUvs, uvs,
-		v1, v2, v3, v4, isFaceMaterial, objectMaterials, material, side;
+		faces, face, faceVertexNormals, faceVertexUvs, uvs,
+		v1, v2, v3, v4, isFaceMaterial, objectMaterials;
 
 
 		_face3Count = 0;
 		_face3Count = 0;
 		_face4Count = 0;
 		_face4Count = 0;
@@ -185,9 +190,11 @@ THREE.Projector = function() {
 
 
 		if ( camera.parent === undefined ) camera.updateMatrixWorld();
 		if ( camera.parent === undefined ) camera.updateMatrixWorld();
 
 
-		camera.matrixWorldInverse.getInverse( camera.matrixWorld );
+		_viewMatrix.copy( camera.matrixWorldInverse.getInverse( camera.matrixWorld ) );
+		_viewProjectionMatrix.multiply( camera.projectionMatrix, _viewMatrix );
 
 
-		_viewProjectionMatrix.multiply( camera.projectionMatrix, camera.matrixWorldInverse );
+		_normalViewMatrix.getInverse( _viewMatrix );
+		_normalViewMatrix.transpose();
 
 
 		_frustum.setFromMatrix( _viewProjectionMatrix );
 		_frustum.setFromMatrix( _viewProjectionMatrix );
 
 
@@ -197,7 +204,7 @@ THREE.Projector = function() {
 
 
 			object = _renderData.objects[ o ].object;
 			object = _renderData.objects[ o ].object;
 
 
-			modelMatrix = object.matrixWorld;
+			_modelMatrix = object.matrixWorld;
 
 
 			_vertexCount = 0;
 			_vertexCount = 0;
 
 
@@ -209,23 +216,21 @@ THREE.Projector = function() {
 				faces = geometry.faces;
 				faces = geometry.faces;
 				faceVertexUvs = geometry.faceVertexUvs;
 				faceVertexUvs = geometry.faceVertexUvs;
 
 
-				_normalMatrix.getInverse( modelMatrix );
+				_normalMatrix.getInverse( _modelMatrix );
 				_normalMatrix.transpose();
 				_normalMatrix.transpose();
 
 
 				isFaceMaterial = object.material instanceof THREE.MeshFaceMaterial;
 				isFaceMaterial = object.material instanceof THREE.MeshFaceMaterial;
 				objectMaterials = isFaceMaterial === true ? object.material : null;
 				objectMaterials = isFaceMaterial === true ? object.material : null;
 
 
-				side = object.material.side;
-
 				for ( v = 0, vl = vertices.length; v < vl; v ++ ) {
 				for ( v = 0, vl = vertices.length; v < vl; v ++ ) {
 
 
 					_vertex = getNextVertexInPool();
 					_vertex = getNextVertexInPool();
 					_vertex.positionWorld.copy( vertices[ v ] );
 					_vertex.positionWorld.copy( vertices[ v ] );
 
 
-					modelMatrix.multiplyVector3( _vertex.positionWorld );
+					_vertex.positionWorld.applyMatrix4( _modelMatrix );
 
 
 					_vertex.positionScreen.copy( _vertex.positionWorld );
 					_vertex.positionScreen.copy( _vertex.positionWorld );
-					_viewProjectionMatrix.multiplyVector4( _vertex.positionScreen );
+					_vertex.positionScreen.applyMatrix4( _viewProjectionMatrix );
 
 
 					_vertex.positionScreen.x /= _vertex.positionScreen.w;
 					_vertex.positionScreen.x /= _vertex.positionScreen.w;
 					_vertex.positionScreen.y /= _vertex.positionScreen.w;
 					_vertex.positionScreen.y /= _vertex.positionScreen.w;
@@ -238,11 +243,13 @@ THREE.Projector = function() {
 
 
 					face = faces[ f ];
 					face = faces[ f ];
 
 
-					material = isFaceMaterial === true ? objectMaterials.materials[ face.materialIndex ] : object.material;
+					var material = isFaceMaterial === true
+						? objectMaterials.materials[ face.materialIndex ]
+						: object.material;
 
 
 					if ( material === undefined ) continue;
 					if ( material === undefined ) continue;
 
 
-					side = material.side;
+					var side = material.side;
 
 
 					if ( face instanceof THREE.Face3 ) {
 					if ( face instanceof THREE.Face3 ) {
 
 
@@ -313,27 +320,42 @@ THREE.Projector = function() {
 
 
 					}
 					}
 
 
-					_face.normalWorld.copy( face.normal );
+					_face.normalModel.copy( face.normal );
 
 
-					if ( visible === false && ( side === THREE.BackSide || side === THREE.DoubleSide ) ) _face.normalWorld.negate();
-					_normalMatrix.multiplyVector3( _face.normalWorld ).normalize();
+					if ( visible === false && ( side === THREE.BackSide || side === THREE.DoubleSide ) ) {
 
 
-					_face.centroidWorld.copy( face.centroid );
-					modelMatrix.multiplyVector3( _face.centroidWorld );
+						_face.normalModel.negate();
+
+					}
 
 
-					_face.centroidScreen.copy( _face.centroidWorld );
-					_viewProjectionMatrix.multiplyVector3( _face.centroidScreen );
+					_face.normalModel.applyMatrix3( _normalMatrix );
+					_face.normalModel.normalize();
+
+					_face.normalModelView.copy( _face.normalModel );
+					_face.normalModelView.applyMatrix3( _normalViewMatrix );
+
+					_face.centroidModel.copy( face.centroid );
+					_face.centroidModel.applyMatrix4( _modelMatrix );
 
 
 					faceVertexNormals = face.vertexNormals;
 					faceVertexNormals = face.vertexNormals;
 
 
 					for ( n = 0, nl = faceVertexNormals.length; n < nl; n ++ ) {
 					for ( n = 0, nl = faceVertexNormals.length; n < nl; n ++ ) {
 
 
-						normal = _face.vertexNormalsWorld[ n ];
-						normal.copy( faceVertexNormals[ n ] );
+						var normalModel = _face.vertexNormalsModel[ n ];
+						normalModel.copy( faceVertexNormals[ n ] );
 
 
-						if ( visible === false && ( side === THREE.BackSide || side === THREE.DoubleSide ) ) normal.negate();
+						if ( visible === false && ( side === THREE.BackSide || side === THREE.DoubleSide ) ) {
 
 
-						_normalMatrix.multiplyVector3( normal ).normalize();
+							normalModel.negate();
+
+						}
+
+						normalModel.applyMatrix3( _normalMatrix );
+						normalModel.normalize();
+
+						var normalModelView = _face.vertexNormalsModelView[ n ];
+						normalModelView.copy( normalModel );
+						normalModelView.applyMatrix3( _normalViewMatrix );
 
 
 					}
 					}
 
 
@@ -356,7 +378,10 @@ THREE.Projector = function() {
 					_face.color = face.color;
 					_face.color = face.color;
 					_face.material = material;
 					_face.material = material;
 
 
-					_face.z = _face.centroidScreen.z;
+					_centroid.copy( _face.centroidModel )
+					_centroid.applyMatrix4( _viewProjectionMatrix );
+
+					_face.z = _centroid.z;
 
 
 					_renderData.elements.push( _face );
 					_renderData.elements.push( _face );
 
 
@@ -364,13 +389,13 @@ THREE.Projector = function() {
 
 
 			} else if ( object instanceof THREE.Line ) {
 			} else if ( object instanceof THREE.Line ) {
 
 
-				_modelViewProjectionMatrix.multiply( _viewProjectionMatrix, modelMatrix );
+				_modelViewProjectionMatrix.multiply( _viewProjectionMatrix, _modelMatrix );
 
 
 				vertices = object.geometry.vertices;
 				vertices = object.geometry.vertices;
 
 
 				v1 = getNextVertexInPool();
 				v1 = getNextVertexInPool();
 				v1.positionScreen.copy( vertices[ 0 ] );
 				v1.positionScreen.copy( vertices[ 0 ] );
-				_modelViewProjectionMatrix.multiplyVector4( v1.positionScreen );
+				v1.positionScreen.applyMatrix4( _modelViewProjectionMatrix );
 
 
 				// Handle LineStrip and LinePieces
 				// Handle LineStrip and LinePieces
 				var step = object.type === THREE.LinePieces ? 2 : 1;
 				var step = object.type === THREE.LinePieces ? 2 : 1;
@@ -379,7 +404,7 @@ THREE.Projector = function() {
 
 
 					v1 = getNextVertexInPool();
 					v1 = getNextVertexInPool();
 					v1.positionScreen.copy( vertices[ v ] );
 					v1.positionScreen.copy( vertices[ v ] );
-					_modelViewProjectionMatrix.multiplyVector4( v1.positionScreen );
+					v1.positionScreen.applyMatrix4( _modelViewProjectionMatrix );
 
 
 					if ( ( v + 1 ) % step > 0 ) continue;
 					if ( ( v + 1 ) % step > 0 ) continue;
 
 
@@ -416,12 +441,12 @@ THREE.Projector = function() {
 
 
 			object = _renderData.sprites[ o ].object;
 			object = _renderData.sprites[ o ].object;
 
 
-			modelMatrix = object.matrixWorld;
+			_modelMatrix = object.matrixWorld;
 
 
 			if ( object instanceof THREE.Particle ) {
 			if ( object instanceof THREE.Particle ) {
 
 
-				_vector4.set( modelMatrix.elements[12], modelMatrix.elements[13], modelMatrix.elements[14], 1 );
-				_viewProjectionMatrix.multiplyVector4( _vector4 );
+				_vector4.set( _modelMatrix.elements[12], _modelMatrix.elements[13], _modelMatrix.elements[14], 1 );
+				_vector4.applyMatrix4( _viewProjectionMatrix );
 
 
 				_vector4.z /= _vector4.w;
 				_vector4.z /= _vector4.w;
 
 

+ 0 - 4
src/core/Raycaster.js

@@ -34,10 +34,6 @@
 
 
 	};
 	};
 
 
-	var v0 = new THREE.Vector3(), v1 = new THREE.Vector3(), v2 = new THREE.Vector3();
-
-	// http://www.blackpawn.com/texts/pointinpoly/default.html
-
 	var intersectObject = function ( object, raycaster, intersects ) {
 	var intersectObject = function ( object, raycaster, intersects ) {
 
 
 		if ( object instanceof THREE.Particle ) {
 		if ( object instanceof THREE.Particle ) {

+ 22 - 7
src/extras/GeometryUtils.js

@@ -9,7 +9,7 @@ THREE.GeometryUtils = {
 
 
 	merge: function ( geometry1, object2 /* mesh | geometry */ ) {
 	merge: function ( geometry1, object2 /* mesh | geometry */ ) {
 
 
-		var matrix, matrixRotation,
+		var matrix, normalMatrix,
 		vertexOffset = geometry1.vertices.length,
 		vertexOffset = geometry1.vertices.length,
 		uvPosition = geometry1.faceVertexUvs[ 0 ].length,
 		uvPosition = geometry1.faceVertexUvs[ 0 ].length,
 		geometry2 = object2 instanceof THREE.Mesh ? object2.geometry : object2,
 		geometry2 = object2 instanceof THREE.Mesh ? object2.geometry : object2,
@@ -25,8 +25,10 @@ THREE.GeometryUtils = {
 			object2.matrixAutoUpdate && object2.updateMatrix();
 			object2.matrixAutoUpdate && object2.updateMatrix();
 
 
 			matrix = object2.matrix;
 			matrix = object2.matrix;
-			matrixRotation = new THREE.Matrix4();
-			matrixRotation.extractRotation( matrix, object2.scale );
+
+			normalMatrix = new THREE.Matrix3();
+			normalMatrix.getInverse( matrix );
+			normalMatrix.transpose();
 
 
 		}
 		}
 
 
@@ -38,7 +40,7 @@ THREE.GeometryUtils = {
 
 
 			var vertexCopy = vertex.clone();
 			var vertexCopy = vertex.clone();
 
 
-			if ( matrix ) matrix.multiplyVector3( vertexCopy );
+			if ( matrix ) vertexCopy.applyMatrix4( matrix );
 
 
 			vertices1.push( vertexCopy );
 			vertices1.push( vertexCopy );
 
 
@@ -64,13 +66,21 @@ THREE.GeometryUtils = {
 
 
 			faceCopy.normal.copy( face.normal );
 			faceCopy.normal.copy( face.normal );
 
 
-			if ( matrixRotation ) matrixRotation.multiplyVector3( faceCopy.normal );
+			if ( normalMatrix ) {
+
+				faceCopy.normal.applyMatrix3( normalMatrix ).normalize();
+
+			}
 
 
 			for ( var j = 0, jl = faceVertexNormals.length; j < jl; j ++ ) {
 			for ( var j = 0, jl = faceVertexNormals.length; j < jl; j ++ ) {
 
 
 				normal = faceVertexNormals[ j ].clone();
 				normal = faceVertexNormals[ j ].clone();
 
 
-				if ( matrixRotation ) matrixRotation.multiplyVector3( normal );
+				if ( normalMatrix ) {
+
+					normal.applyMatrix3( normalMatrix ).normalize();
+
+				}
 
 
 				faceCopy.vertexNormals.push( normal );
 				faceCopy.vertexNormals.push( normal );
 
 
@@ -88,7 +98,12 @@ THREE.GeometryUtils = {
 			faceCopy.materialIndex = face.materialIndex;
 			faceCopy.materialIndex = face.materialIndex;
 
 
 			faceCopy.centroid.copy( face.centroid );
 			faceCopy.centroid.copy( face.centroid );
-			if ( matrix ) matrix.multiplyVector3( faceCopy.centroid );
+
+			if ( matrix ) {
+
+				faceCopy.centroid.applyMatrix4( matrix );
+
+			}
 
 
 			faces1.push( faceCopy );
 			faces1.push( faceCopy );
 
 

+ 1 - 1
src/extras/geometries/LatheGeometry.js

@@ -26,7 +26,7 @@ THREE.LatheGeometry = function ( points, steps, angle ) {
 
 
 		for ( var j = 0; j < _newV.length; j ++ ) {
 		for ( var j = 0; j < _newV.length; j ++ ) {
 
 
-			_newV[ j ] = _matrix.multiplyVector3( _newV[ j ].clone() );
+			_newV[ j ] = _newV[ j ].clone().applyMatrix4( _matrix );
 			this.vertices.push( _newV[ j ] );
 			this.vertices.push( _newV[ j ] );
 
 
 		}
 		}

+ 2 - 2
src/extras/geometries/TubeGeometry.js

@@ -246,7 +246,7 @@ THREE.TubeGeometry.FrenetFrames = function(path, segments, closed) {
 
 
 			theta = Math.acos( tangents[ i-1 ].dot( tangents[ i ] ) );
 			theta = Math.acos( tangents[ i-1 ].dot( tangents[ i ] ) );
 
 
-			mat.makeRotationAxis( vec, theta ).multiplyVector3( normals[ i ] );
+			normals[ i ].applyMatrix4( mat.makeRotationAxis( vec, theta ) );
 
 
 		}
 		}
 
 
@@ -271,7 +271,7 @@ THREE.TubeGeometry.FrenetFrames = function(path, segments, closed) {
 		for ( i = 1; i < numpoints; i++ ) {
 		for ( i = 1; i < numpoints; i++ ) {
 
 
 			// twist a little...
 			// twist a little...
-			mat.makeRotationAxis( tangents[ i ], theta * i ).multiplyVector3( normals[ i ] );
+			normals[ i ].applyMatrix4( mat.makeRotationAxis( tangents[ i ], theta * i ) );
 			binormals[ i ].cross( tangents[ i ], normals[ i ] );
 			binormals[ i ].cross( tangents[ i ], normals[ i ] );
 
 
 		}
 		}

+ 1 - 1
src/extras/renderers/plugins/DepthPassPlugin.js

@@ -88,7 +88,7 @@ THREE.DepthPassPlugin = function ( ) {
 
 
 			if ( object.visible ) {
 			if ( object.visible ) {
 
 
-				if ( ! ( object instanceof THREE.Mesh || object instanceof THREE.ParticleSystem ) || ! ( object.frustumCulled ) || _frustum.contains( object ) ) {
+				if ( ! ( object instanceof THREE.Mesh || object instanceof THREE.ParticleSystem ) || ! ( object.frustumCulled ) || _frustum.intersectsObject( object ) ) {
 
 
 					object._modelViewMatrix.multiply( camera.matrixWorldInverse, object.matrixWorld );
 					object._modelViewMatrix.multiply( camera.matrixWorldInverse, object.matrixWorld );
 
 

+ 13 - 9
src/extras/renderers/plugins/LensFlarePlugin.js

@@ -5,13 +5,15 @@
 
 
 THREE.LensFlarePlugin = function ( ) {
 THREE.LensFlarePlugin = function ( ) {
 
 
-	var _gl, _renderer, _lensFlare = {};
+	var _gl, _renderer, _precision, _lensFlare = {};
 
 
 	this.init = function ( renderer ) {
 	this.init = function ( renderer ) {
 
 
 		_gl = renderer.context;
 		_gl = renderer.context;
 		_renderer = renderer;
 		_renderer = renderer;
 
 
+		_precision = renderer.getPrecision();
+
 		_lensFlare.vertices = new Float32Array( 8 + 8 );
 		_lensFlare.vertices = new Float32Array( 8 + 8 );
 		_lensFlare.faces = new Uint16Array( 6 );
 		_lensFlare.faces = new Uint16Array( 6 );
 
 
@@ -65,12 +67,12 @@ THREE.LensFlarePlugin = function ( ) {
 		if ( _gl.getParameter( _gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS ) <= 0 ) {
 		if ( _gl.getParameter( _gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS ) <= 0 ) {
 
 
 			_lensFlare.hasVertexTexture = false;
 			_lensFlare.hasVertexTexture = false;
-			_lensFlare.program = createProgram( THREE.ShaderFlares[ "lensFlare" ] );
+			_lensFlare.program = createProgram( THREE.ShaderFlares[ "lensFlare" ], _precision );
 
 
 		} else {
 		} else {
 
 
 			_lensFlare.hasVertexTexture = true;
 			_lensFlare.hasVertexTexture = true;
-			_lensFlare.program = createProgram( THREE.ShaderFlares[ "lensFlareVertexTexture" ] );
+			_lensFlare.program = createProgram( THREE.ShaderFlares[ "lensFlareVertexTexture" ], _precision );
 
 
 		}
 		}
 
 
@@ -158,8 +160,8 @@ THREE.LensFlarePlugin = function ( ) {
 
 
 			tempPosition.set( flare.matrixWorld.elements[12], flare.matrixWorld.elements[13], flare.matrixWorld.elements[14] );
 			tempPosition.set( flare.matrixWorld.elements[12], flare.matrixWorld.elements[13], flare.matrixWorld.elements[14] );
 
 
-			camera.matrixWorldInverse.multiplyVector3( tempPosition );
-			camera.projectionMatrix.multiplyVector3( tempPosition );
+			tempPosition.applyMatrix4( camera.matrixWorldInverse );
+			tempPosition.applyMatrix4( camera.projectionMatrix );
 
 
 			// setup arrays for gl programs
 			// setup arrays for gl programs
 
 
@@ -274,15 +276,17 @@ THREE.LensFlarePlugin = function ( ) {
 
 
 	};
 	};
 
 
-	function createProgram ( shader ) {
+	function createProgram ( shader, precision ) {
 
 
 		var program = _gl.createProgram();
 		var program = _gl.createProgram();
 
 
 		var fragmentShader = _gl.createShader( _gl.FRAGMENT_SHADER );
 		var fragmentShader = _gl.createShader( _gl.FRAGMENT_SHADER );
 		var vertexShader = _gl.createShader( _gl.VERTEX_SHADER );
 		var vertexShader = _gl.createShader( _gl.VERTEX_SHADER );
 
 
-		_gl.shaderSource( fragmentShader, shader.fragmentShader );
-		_gl.shaderSource( vertexShader, shader.vertexShader );
+		var prefix = "precision " + precision + " float;\n";
+
+		_gl.shaderSource( fragmentShader, prefix + shader.fragmentShader );
+		_gl.shaderSource( vertexShader, prefix + shader.vertexShader );
 
 
 		_gl.compileShader( fragmentShader );
 		_gl.compileShader( fragmentShader );
 		_gl.compileShader( vertexShader );
 		_gl.compileShader( vertexShader );
@@ -296,4 +300,4 @@ THREE.LensFlarePlugin = function ( ) {
 
 
 	};
 	};
 
 
-};
+};

+ 2 - 2
src/extras/renderers/plugins/ShadowMapPlugin.js

@@ -238,7 +238,7 @@ THREE.ShadowMapPlugin = function ( ) {
 
 
 				if ( object.visible && object.castShadow ) {
 				if ( object.visible && object.castShadow ) {
 
 
-					if ( ! ( object instanceof THREE.Mesh || object instanceof THREE.ParticleSystem ) || ! ( object.frustumCulled ) || _frustum.contains( object ) ) {
+					if ( ! ( object instanceof THREE.Mesh || object instanceof THREE.ParticleSystem ) || ! ( object.frustumCulled ) || _frustum.intersectsObject( object ) ) {
 
 
 						object._modelViewMatrix.multiply( shadowCamera.matrixWorldInverse, object.matrixWorld );
 						object._modelViewMatrix.multiply( shadowCamera.matrixWorldInverse, object.matrixWorld );
 
 
@@ -451,7 +451,7 @@ THREE.ShadowMapPlugin = function ( ) {
 			p.copy( pointsFrustum[ i ] );
 			p.copy( pointsFrustum[ i ] );
 			THREE.ShadowMapPlugin.__projector.unprojectVector( p, camera );
 			THREE.ShadowMapPlugin.__projector.unprojectVector( p, camera );
 
 
-			shadowCamera.matrixWorldInverse.multiplyVector3( p );
+			p.applyMatrix4( shadowCamera.matrixWorldInverse );
 
 
 			if ( p.x < _min.x ) _min.x = p.x;
 			if ( p.x < _min.x ) _min.x = p.x;
 			if ( p.x > _max.x ) _max.x = p.x;
 			if ( p.x > _max.x ) _max.x = p.x;

+ 9 - 5
src/extras/renderers/plugins/SpritePlugin.js

@@ -5,13 +5,15 @@
 
 
 THREE.SpritePlugin = function ( ) {
 THREE.SpritePlugin = function ( ) {
 
 
-	var _gl, _renderer, _sprite = {};
+	var _gl, _renderer, _precision, _sprite = {};
 
 
 	this.init = function ( renderer ) {
 	this.init = function ( renderer ) {
 
 
 		_gl = renderer.context;
 		_gl = renderer.context;
 		_renderer = renderer;
 		_renderer = renderer;
 
 
+		_precision = renderer.getPrecision();
+
 		_sprite.vertices = new Float32Array( 8 + 8 );
 		_sprite.vertices = new Float32Array( 8 + 8 );
 		_sprite.faces    = new Uint16Array( 6 );
 		_sprite.faces    = new Uint16Array( 6 );
 
 
@@ -43,7 +45,7 @@ THREE.SpritePlugin = function ( ) {
 		_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, _sprite.elementBuffer );
 		_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, _sprite.elementBuffer );
 		_gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, _sprite.faces, _gl.STATIC_DRAW );
 		_gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, _sprite.faces, _gl.STATIC_DRAW );
 
 
-		_sprite.program = createProgram( THREE.ShaderSprite[ "sprite" ] );
+		_sprite.program = createProgram( THREE.ShaderSprite[ "sprite" ], _precision );
 
 
 		_sprite.attributes = {};
 		_sprite.attributes = {};
 		_sprite.uniforms = {};
 		_sprite.uniforms = {};
@@ -262,15 +264,17 @@ THREE.SpritePlugin = function ( ) {
 
 
 	};
 	};
 
 
-	function createProgram ( shader ) {
+	function createProgram ( shader, precision ) {
 
 
 		var program = _gl.createProgram();
 		var program = _gl.createProgram();
 
 
 		var fragmentShader = _gl.createShader( _gl.FRAGMENT_SHADER );
 		var fragmentShader = _gl.createShader( _gl.FRAGMENT_SHADER );
 		var vertexShader = _gl.createShader( _gl.VERTEX_SHADER );
 		var vertexShader = _gl.createShader( _gl.VERTEX_SHADER );
 
 
-		_gl.shaderSource( fragmentShader, shader.fragmentShader );
-		_gl.shaderSource( vertexShader, shader.vertexShader );
+		var prefix = "precision " + precision + " float;\n";
+
+		_gl.shaderSource( fragmentShader, prefix + shader.fragmentShader );
+		_gl.shaderSource( vertexShader, prefix + shader.vertexShader );
 
 
 		_gl.compileShader( fragmentShader );
 		_gl.compileShader( fragmentShader );
 		_gl.compileShader( vertexShader );
 		_gl.compileShader( vertexShader );

+ 7 - 5
src/extras/shaders/ShaderFlares.js

@@ -9,10 +9,11 @@ THREE.ShaderFlares = {
 
 
 		vertexShader: [
 		vertexShader: [
 
 
+			"uniform lowp int renderType;",
+
 			"uniform vec3 screenPosition;",
 			"uniform vec3 screenPosition;",
 			"uniform vec2 scale;",
 			"uniform vec2 scale;",
 			"uniform float rotation;",
 			"uniform float rotation;",
-			"uniform int renderType;",
 
 
 			"uniform sampler2D occlusionMap;",
 			"uniform sampler2D occlusionMap;",
 
 
@@ -58,11 +59,10 @@ THREE.ShaderFlares = {
 
 
 		fragmentShader: [
 		fragmentShader: [
 
 
-			"precision mediump float;",
+			"uniform lowp int renderType;",
 
 
 			"uniform sampler2D map;",
 			"uniform sampler2D map;",
 			"uniform float opacity;",
 			"uniform float opacity;",
-			"uniform int renderType;",
 			"uniform vec3 color;",
 			"uniform vec3 color;",
 
 
 			"varying vec2 vUV;",
 			"varying vec2 vUV;",
@@ -103,10 +103,11 @@ THREE.ShaderFlares = {
 
 
 		vertexShader: [
 		vertexShader: [
 
 
+			"uniform lowp int renderType;",
+
 			"uniform vec3 screenPosition;",
 			"uniform vec3 screenPosition;",
 			"uniform vec2 scale;",
 			"uniform vec2 scale;",
 			"uniform float rotation;",
 			"uniform float rotation;",
-			"uniform int renderType;",
 
 
 			"attribute vec2 position;",
 			"attribute vec2 position;",
 			"attribute vec2 uv;",
 			"attribute vec2 uv;",
@@ -136,10 +137,11 @@ THREE.ShaderFlares = {
 
 
 			"precision mediump float;",
 			"precision mediump float;",
 
 
+			"uniform lowp int renderType;",
+
 			"uniform sampler2D map;",
 			"uniform sampler2D map;",
 			"uniform sampler2D occlusionMap;",
 			"uniform sampler2D occlusionMap;",
 			"uniform float opacity;",
 			"uniform float opacity;",
-			"uniform int renderType;",
 			"uniform vec3 color;",
 			"uniform vec3 color;",
 
 
 			"varying vec2 vUV;",
 			"varying vec2 vUV;",

+ 0 - 2
src/extras/shaders/ShaderSprite.js

@@ -57,8 +57,6 @@ THREE.ShaderSprite = {
 
 
 		fragmentShader: [
 		fragmentShader: [
 
 
-			"precision mediump float;",
-
 			"uniform vec3 color;",
 			"uniform vec3 color;",
 			"uniform sampler2D map;",
 			"uniform sampler2D map;",
 			"uniform float opacity;",
 			"uniform float opacity;",

+ 0 - 15
src/materials/ParticleDOMMaterial.js

@@ -1,15 +0,0 @@
-/**
- * @author mrdoob / http://mrdoob.com/
- */
-
-THREE.ParticleDOMMaterial = function ( element ) {
-
-	this.element = element;
-
-};
-
-THREE.ParticleDOMMaterial.prototype.clone = function(){
-
-	return new THREE.ParticleDOMMaterial( this.element );
-
-};

+ 10 - 9
src/math/Box3.js

@@ -256,17 +256,18 @@ THREE.Box3.prototype = {
 	},
 	},
 
 
 	transform: function ( matrix ) {
 	transform: function ( matrix ) {
-		
+
 		// NOTE: I am using a binary pattern to specify all 2^3 combinations below
 		// NOTE: I am using a binary pattern to specify all 2^3 combinations below
 		var newPoints = [
 		var newPoints = [
-			matrix.multiplyVector3( THREE.Box3.__v0.set( this.min.x, this.min.y, this.min.z ) ), // 000
-			matrix.multiplyVector3( THREE.Box3.__v1.set( this.min.x, this.min.y, this.max.z ) ), // 001
-			matrix.multiplyVector3( THREE.Box3.__v2.set( this.min.x, this.max.y, this.min.z ) ), // 010
-			matrix.multiplyVector3( THREE.Box3.__v3.set( this.min.x, this.max.y, this.max.z ) ), // 011
-			matrix.multiplyVector3( THREE.Box3.__v4.set( this.max.x, this.min.y, this.min.z ) ), // 100
-			matrix.multiplyVector3( THREE.Box3.__v5.set( this.max.x, this.min.y, this.max.z ) ), // 101
-			matrix.multiplyVector3( THREE.Box3.__v6.set( this.max.x, this.max.y, this.min.z ) ), // 110
-			matrix.multiplyVector3( THREE.Box3.__v7.set( this.max.x, this.max.y, this.max.z ) )  // 111
+			THREE.Box3.__v0.set( this.min.x, this.min.y, this.min.z ).applyMatrix4( matrix ),
+			THREE.Box3.__v0.set( this.min.x, this.min.y, this.min.z ).applyMatrix4( matrix ), // 000
+			THREE.Box3.__v1.set( this.min.x, this.min.y, this.max.z ).applyMatrix4( matrix ), // 001
+			THREE.Box3.__v2.set( this.min.x, this.max.y, this.min.z ).applyMatrix4( matrix ), // 010
+			THREE.Box3.__v3.set( this.min.x, this.max.y, this.max.z ).applyMatrix4( matrix ), // 011
+			THREE.Box3.__v4.set( this.max.x, this.min.y, this.min.z ).applyMatrix4( matrix ), // 100
+			THREE.Box3.__v5.set( this.max.x, this.min.y, this.max.z ).applyMatrix4( matrix ), // 101
+			THREE.Box3.__v6.set( this.max.x, this.max.y, this.min.z ).applyMatrix4( matrix ), // 110
+			THREE.Box3.__v7.set( this.max.x, this.max.y, this.max.z ).applyMatrix4( matrix )  // 111
 		];
 		];
 
 
 		this.makeEmpty();
 		this.makeEmpty();

+ 114 - 37
src/math/Frustum.js

@@ -4,65 +4,142 @@
  * @author bhouston / http://exocortex.com
  * @author bhouston / http://exocortex.com
  */
  */
 
 
-THREE.Frustum = function ( ) {
+THREE.Frustum = function ( p0, p1, p2, p3, p4, p5 ) {
 
 
 	this.planes = [
 	this.planes = [
 
 
-		new THREE.Plane(),
-		new THREE.Plane(),
-		new THREE.Plane(),
-		new THREE.Plane(),
-		new THREE.Plane(),
-		new THREE.Plane()
+		( p0 !== undefined ) ? p0 : new THREE.Plane(),
+		( p1 !== undefined ) ? p1 : new THREE.Plane(),
+		( p2 !== undefined ) ? p2 : new THREE.Plane(),
+		( p3 !== undefined ) ? p3 : new THREE.Plane(),
+		( p4 !== undefined ) ? p4 : new THREE.Plane(),
+		( p5 !== undefined ) ? p5 : new THREE.Plane()
 
 
 	];
 	];
 
 
 };
 };
 
 
-THREE.Frustum.prototype.setFromMatrix = function ( m ) {
+THREE.Frustum.prototype = {
 
 
-	var planes = this.planes;
+	set: function ( p0, p1, p2, p3, p4, p5 ) {
 
 
-	var me = m.elements;
-	var me0 = me[0], me1 = me[1], me2 = me[2], me3 = me[3];
-	var me4 = me[4], me5 = me[5], me6 = me[6], me7 = me[7];
-	var me8 = me[8], me9 = me[9], me10 = me[10], me11 = me[11];
-	var me12 = me[12], me13 = me[13], me14 = me[14], me15 = me[15];
+		var planes = this.planes;
 
 
-	planes[ 0 ].setComponents( me3 - me0, me7 - me4, me11 - me8, me15 - me12 );
-	planes[ 1 ].setComponents( me3 + me0, me7 + me4, me11 + me8, me15 + me12 );
-	planes[ 2 ].setComponents( me3 + me1, me7 + me5, me11 + me9, me15 + me13 );
-	planes[ 3 ].setComponents( me3 - me1, me7 - me5, me11 - me9, me15 - me13 );
-	planes[ 4 ].setComponents( me3 - me2, me7 - me6, me11 - me10, me15 - me14 );
-	planes[ 5 ].setComponents( me3 + me2, me7 + me6, me11 + me10, me15 + me14 );
+		planes[0].copy( p0 );
+		planes[1].copy( p1 );
+		planes[2].copy( p2 );
+		planes[3].copy( p3 );
+		planes[4].copy( p4 );
+		planes[5].copy( p5 );
 
 
-	for ( var i = 0; i < 6; i ++ ) {
+		return this;
 
 
-		planes[ i ].normalize();
+	},
 
 
-	}
+	copy: function ( frustum ) {
 
 
-};
+		var planes = this.planes;
 
 
-THREE.Frustum.prototype.contains = function ( object ) {
+		for( var i = 0; i < 6; i ++ ) {
 
 
-	var planes = this.planes;
+			planes[i].copy( frustum.planes[i] );
 
 
-	var matrix = object.matrixWorld;
-	var matrixPosition = matrix.getPosition();
-	var radius = - object.geometry.boundingSphere.radius * matrix.getMaxScaleOnAxis();
+		}
 
 
-	var distance = 0.0;
+		return this;
 
 
-	for ( var i = 0; i < 6; i ++ ) {
+	},
 
 
-		distance = planes[ i ].distanceToPoint( matrixPosition );
-		if ( distance <= radius ) return false;
+	setFromMatrix: function ( m ) {
 
 
-	}
+		var planes = this.planes;
+		var me = m.elements;
+		var me0 = me[0], me1 = me[1], me2 = me[2], me3 = me[3];
+		var me4 = me[4], me5 = me[5], me6 = me[6], me7 = me[7];
+		var me8 = me[8], me9 = me[9], me10 = me[10], me11 = me[11];
+		var me12 = me[12], me13 = me[13], me14 = me[14], me15 = me[15];
 
 
-	return true;
+		planes[ 0 ].setComponents( me3 - me0, me7 - me4, me11 - me8, me15 - me12 ).normalize();
+		planes[ 1 ].setComponents( me3 + me0, me7 + me4, me11 + me8, me15 + me12 ).normalize();
+		planes[ 2 ].setComponents( me3 + me1, me7 + me5, me11 + me9, me15 + me13 ).normalize();
+		planes[ 3 ].setComponents( me3 - me1, me7 - me5, me11 - me9, me15 - me13 ).normalize();
+		planes[ 4 ].setComponents( me3 - me2, me7 - me6, me11 - me10, me15 - me14 ).normalize();
+		planes[ 5 ].setComponents( me3 + me2, me7 + me6, me11 + me10, me15 + me14 ).normalize();
 
 
-};
+		return this;
+
+	},
+
+	intersectsObject: function ( object ) {
+
+		// this method is expanded inlined for performance reasons.
+		var matrix = object.matrixWorld;
+		var planes = this.planes;
+		var center = matrix.getPosition();
+		var negRadius = - object.geometry.boundingSphere.radius * matrix.getMaxScaleOnAxis();
+
+		for ( var i = 0; i < 6; i ++ ) {
+
+			var distance = planes[ i ].distanceToPoint( center );
+
+			if( distance < negRadius ) {
+
+				return false;
+
+			}
+
+		}
+
+		return true;
+
+	},
+
+	intersectsSphere: function ( sphere ) {
+
+		var planes = this.planes;
+		var center = sphere.center;
+		var negRadius = -sphere.radius;
+
+		for ( var i = 0; i < 6; i ++ ) {
+
+			var distance = planes[ i ].distanceToPoint( center );
+
+			if( distance < negRadius ) {
 
 
-THREE.Frustum.__v1 = new THREE.Vector3();
+				return false;
+
+			}
+
+		}
+
+		return true;
+
+	},
+
+	containsPoint: function ( point ) {
+
+		var planes = this.planes;
+
+		for ( var i = 0; i < 6; i ++ ) {
+
+			if( planes[ i ].distanceToPoint( point ) < 0 ) {
+
+				return false;
+
+			}
+
+		}
+
+		return true;
+
+	},
+
+	clone: function () {
+
+		var planes = this.planes;
+
+		return new THREE.Frustum( planes[0], planes[1], planes[2], planes[3], planes[4], planes[5] );
+
+	}
+
+};

+ 109 - 26
src/math/Matrix3.js

@@ -1,29 +1,65 @@
 /**
 /**
  * @author alteredq / http://alteredqualia.com/
  * @author alteredq / http://alteredqualia.com/
  * @author WestLangley / http://github.com/WestLangley
  * @author WestLangley / http://github.com/WestLangley
+ * @author bhouston / http://exocortex.com
  */
  */
 
 
-THREE.Matrix3 = function () {
+THREE.Matrix3 = function ( n11, n12, n13, n21, n22, n23, n31, n32, n33 ) {
 
 
 	this.elements = new Float32Array(9);
 	this.elements = new Float32Array(9);
 
 
+	this.set(
+
+		( n11 !== undefined ) ? n11 : 1, n12 || 0, n13 || 0,
+		n21 || 0, ( n22 !== undefined ) ? n22 : 1, n23 || 0,
+		n31 || 0, n32 || 0, ( n33 !== undefined ) ? n33 : 1
+
+	);
 };
 };
 
 
 THREE.Matrix3.prototype = {
 THREE.Matrix3.prototype = {
 
 
 	constructor: THREE.Matrix3,
 	constructor: THREE.Matrix3,
 
 
-	multiplyVector3: function ( v ) {
+	set: function ( n11, n12, n13, n21, n22, n23, n31, n32, n33 ) {
 
 
 		var te = this.elements;
 		var te = this.elements;
 
 
-		var vx = v.x, vy = v.y, vz = v.z;
+		te[0] = n11; te[3] = n12; te[6] = n13;
+		te[1] = n21; te[4] = n22; te[7] = n23;
+		te[2] = n31; te[5] = n32; te[8] = n33;
+
+		return this;
+
+	},
+
+	identity: function () {
+
+		this.set(
+
+			1, 0, 0,
+			0, 1, 0,
+			0, 0, 1
+
+		);
+
+		return this;
+
+	},
+
+	copy: function ( m ) {
+
+		var me = m.elements;
+
+		this.set(
 
 
-		v.x = te[0] * vx + te[3] * vy + te[6] * vz;
-		v.y = te[1] * vx + te[4] * vy + te[7] * vz;
-		v.z = te[2] * vx + te[5] * vy + te[8] * vz;
+			me[0], me[3], me[6],
+			me[1], me[4], me[7],
+			me[2], me[5], me[8]
 
 
-		return v;
+		);
+
+		return this;
 
 
 	},
 	},
 
 
@@ -49,40 +85,73 @@ THREE.Matrix3.prototype = {
 
 
 	},
 	},
 
 
-	getInverse: function ( matrix ) {
+	multiplyScalar: function ( s ) {
+
+		var te = this.elements;
+
+		te[0] *= s; te[3] *= s; te[6] *= s;
+		te[1] *= s; te[4] *= s; te[7] *= s;
+		te[2] *= s; te[5] *= s; te[8] *= s;
+
+		return this;
+
+	},
+
+	determinant: function () {
+
+		var te = this.elements;
+
+		var a = te[0], b = te[1], c = te[2],
+			d = te[3], e = te[4], f = te[5],
+			g = te[6], h = te[7], i = te[8];
+
+		return a*e*i - a*f*h - b*d*i + b*f*g + c*d*h - c*e*g;
+
+	},
+
+	getInverse: function ( matrix, throwOnInvertible ) {
 
 
 		// input: THREE.Matrix4
 		// input: THREE.Matrix4
 		// ( based on http://code.google.com/p/webgl-mjs/ )
 		// ( based on http://code.google.com/p/webgl-mjs/ )
 
 
 		var me = matrix.elements;
 		var me = matrix.elements;
+		var te = this.elements;
 
 
-		var a11 =   me[10] * me[5] - me[6] * me[9];
-		var a21 = - me[10] * me[1] + me[2] * me[9];
-		var a31 =   me[6] * me[1] - me[2] * me[5];
-		var a12 = - me[10] * me[4] + me[6] * me[8];
-		var a22 =   me[10] * me[0] - me[2] * me[8];
-		var a32 = - me[6] * me[0] + me[2] * me[4];
-		var a13 =   me[9] * me[4] - me[5] * me[8];
-		var a23 = - me[9] * me[0] + me[1] * me[8];
-		var a33 =   me[5] * me[0] - me[1] * me[4];
+		te[ 0 ] =   me[10] * me[5] - me[6] * me[9];
+		te[ 1 ] = - me[10] * me[1] + me[2] * me[9];
+		te[ 2 ] =   me[6] * me[1] - me[2] * me[5];
+		te[ 3 ] = - me[10] * me[4] + me[6] * me[8];
+		te[ 4 ] =   me[10] * me[0] - me[2] * me[8];
+		te[ 5 ] = - me[6] * me[0] + me[2] * me[4];
+		te[ 6 ] =   me[9] * me[4] - me[5] * me[8];
+		te[ 7 ] = - me[9] * me[0] + me[1] * me[8];
+		te[ 8 ] =   me[5] * me[0] - me[1] * me[4];
 
 
-		var det = me[0] * a11 + me[1] * a12 + me[2] * a13;
+		var det = me[ 0 ] * te[ 0 ] + me[ 1 ] * te[ 3 ] + me[ 2 ] * te[ 6 ];
 
 
 		// no inverse
 		// no inverse
 
 
 		if ( det === 0 ) {
 		if ( det === 0 ) {
 
 
-			console.warn( "Matrix3.getInverse(): determinant == 0" );
+			var msg = "Matrix3.getInverse(): can't invert matrix, determinant is 0";
 
 
-		}
+			if ( throwOnInvertible || false ) {
 
 
-		var idet = 1.0 / det;
+				throw new Error( msg ); 
 
 
-		var m = this.elements;
+			} else {
+
+				console.warn( msg );
+
+			}
 
 
-		m[ 0 ] = idet * a11; m[ 1 ] = idet * a21; m[ 2 ] = idet * a31;
-		m[ 3 ] = idet * a12; m[ 4 ] = idet * a22; m[ 5 ] = idet * a32;
-		m[ 6 ] = idet * a13; m[ 7 ] = idet * a23; m[ 8 ] = idet * a33;
+			this.identity();
+
+			return this;
+
+		}
+
+		this.multiplyScalar( 1.0 / det );
 
 
 		return this;
 		return this;
 
 
@@ -118,8 +187,22 @@ THREE.Matrix3.prototype = {
 
 
 		return this;
 		return this;
 
 
+	},
+
+	clone: function () {
+
+		var te = this.elements;
+
+		return new THREE.Matrix3(
+
+			te[0], te[3], te[6],
+			te[1], te[4], te[7],
+			te[2], te[5], te[8]
+
+		);
+
 	}
 	}
 
 
 };
 };
 
 
-THREE.Matrix3.__v1 = new THREE.Vector3();
+THREE.Matrix3.__v1 = new THREE.Vector3();

+ 70 - 73
src/math/Matrix4.js

@@ -7,6 +7,7 @@
  * @author alteredq / http://alteredqualia.com/
  * @author alteredq / http://alteredqualia.com/
  * @author mikael emtinger / http://gomo.se/
  * @author mikael emtinger / http://gomo.se/
  * @author timknip / http://www.floorplanner.com/
  * @author timknip / http://www.floorplanner.com/
+ * @author bhouston / http://exocortex.com
  */
  */
 
 
 
 
@@ -321,35 +322,6 @@ THREE.Matrix4.prototype = {
 
 
 	},
 	},
 
 
-	multiplyVector3: function ( v ) {
-
-		var te = this.elements;
-
-		var vx = v.x, vy = v.y, vz = v.z;
-		var d = 1 / ( te[3] * vx + te[7] * vy + te[11] * vz + te[15] );
-
-		v.x = ( te[0] * vx + te[4] * vy + te[8] * vz + te[12] ) * d;
-		v.y = ( te[1] * vx + te[5] * vy + te[9] * vz + te[13] ) * d;
-		v.z = ( te[2] * vx + te[6] * vy + te[10] * vz + te[14] ) * d;
-
-		return v;
-
-	},
-
-	multiplyVector4: function ( v ) {
-
-		var te = this.elements;
-		var vx = v.x, vy = v.y, vz = v.z, vw = v.w;
-
-		v.x = te[0] * vx + te[4] * vy + te[8] * vz + te[12] * vw;
-		v.y = te[1] * vx + te[5] * vy + te[9] * vz + te[13] * vw;
-		v.z = te[2] * vx + te[6] * vy + te[10] * vz + te[14] * vw;
-		v.w = te[3] * vx + te[7] * vy + te[11] * vz + te[15] * vw;
-
-		return v;
-
-	},
-
 	multiplyVector3Array: function ( a ) {
 	multiplyVector3Array: function ( a ) {
 
 
 		var tmp = THREE.Matrix4.__v1;
 		var tmp = THREE.Matrix4.__v1;
@@ -415,35 +387,39 @@ THREE.Matrix4.prototype = {
 		//( based on http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm )
 		//( based on http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm )
 
 
 		return (
 		return (
-			n14 * n23 * n32 * n41-
-			n13 * n24 * n32 * n41-
-			n14 * n22 * n33 * n41+
-			n12 * n24 * n33 * n41+
-
-			n13 * n22 * n34 * n41-
-			n12 * n23 * n34 * n41-
-			n14 * n23 * n31 * n42+
-			n13 * n24 * n31 * n42+
-
-			n14 * n21 * n33 * n42-
-			n11 * n24 * n33 * n42-
-			n13 * n21 * n34 * n42+
-			n11 * n23 * n34 * n42+
-
-			n14 * n22 * n31 * n43-
-			n12 * n24 * n31 * n43-
-			n14 * n21 * n32 * n43+
-			n11 * n24 * n32 * n43+
-
-			n12 * n21 * n34 * n43-
-			n11 * n22 * n34 * n43-
-			n13 * n22 * n31 * n44+
-			n12 * n23 * n31 * n44+
-
-			n13 * n21 * n32 * n44-
-			n11 * n23 * n32 * n44-
-			n12 * n21 * n33 * n44+
-			n11 * n22 * n33 * n44
+			n41 * (
+				+n14 * n23 * n32
+				-n13 * n24 * n32
+				-n14 * n22 * n33
+				+n12 * n24 * n33
+				+n13 * n22 * n34
+				-n12 * n23 * n34
+			) +
+			n42 * (
+				+n11 * n23 * n34
+				-n11 * n24 * n33
+				+n14 * n21 * n33
+				-n13 * n21 * n34
+				+n13 * n24 * n31
+				-n14 * n23 * n31
+			) +
+			n43 * (
+				+n11 * n24 * n32
+				-n11 * n22 * n34
+				-n14 * n21 * n32
+				+n12 * n21 * n34
+				+n14 * n22 * n31
+				-n12 * n24 * n31
+			) +
+			n44 * (
+				-n13 * n22 * n31
+				-n11 * n23 * n32
+				+n11 * n22 * n33
+				+n13 * n21 * n32
+				-n12 * n21 * n33
+				+n12 * n23 * n31
+			)
+
 		);
 		);
 
 
 	},
 	},
@@ -470,7 +446,7 @@ THREE.Matrix4.prototype = {
 		var te = this.elements;
 		var te = this.elements;
 		flat[ 0 ] = te[0]; flat[ 1 ] = te[1]; flat[ 2 ] = te[2]; flat[ 3 ] = te[3];
 		flat[ 0 ] = te[0]; flat[ 1 ] = te[1]; flat[ 2 ] = te[2]; flat[ 3 ] = te[3];
 		flat[ 4 ] = te[4]; flat[ 5 ] = te[5]; flat[ 6 ] = te[6]; flat[ 7 ] = te[7];
 		flat[ 4 ] = te[4]; flat[ 5 ] = te[5]; flat[ 6 ] = te[6]; flat[ 7 ] = te[7];
-		flat[ 8 ]  = te[8]; flat[ 9 ]  = te[9]; flat[ 10 ] = te[10]; flat[ 11 ] = te[11];
+		flat[ 8 ] = te[8]; flat[ 9 ] = te[9]; flat[ 10 ] = te[10]; flat[ 11 ] = te[11];
 		flat[ 12 ] = te[12]; flat[ 13 ] = te[13]; flat[ 14 ] = te[14]; flat[ 15 ] = te[15];
 		flat[ 12 ] = te[12]; flat[ 13 ] = te[13]; flat[ 14 ] = te[14]; flat[ 15 ] = te[15];
 
 
 		return flat;
 		return flat;
@@ -544,7 +520,7 @@ THREE.Matrix4.prototype = {
 
 
 	},
 	},
 
 
-	getInverse: function ( m ) {
+	getInverse: function ( m, throwOnInvertible ) {
 
 
 		// based on http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm
 		// based on http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm
 		var te = this.elements;
 		var te = this.elements;
@@ -571,7 +547,29 @@ THREE.Matrix4.prototype = {
 		te[7] = n12*n33*n41 - n13*n32*n41 + n13*n31*n42 - n11*n33*n42 - n12*n31*n43 + n11*n32*n43;
 		te[7] = n12*n33*n41 - n13*n32*n41 + n13*n31*n42 - n11*n33*n42 - n12*n31*n43 + n11*n32*n43;
 		te[11] = n13*n22*n41 - n12*n23*n41 - n13*n21*n42 + n11*n23*n42 + n12*n21*n43 - n11*n22*n43;
 		te[11] = n13*n22*n41 - n12*n23*n41 - n13*n21*n42 + n11*n23*n42 + n12*n21*n43 - n11*n22*n43;
 		te[15] = n12*n23*n31 - n13*n22*n31 + n13*n21*n32 - n11*n23*n32 - n12*n21*n33 + n11*n22*n33;
 		te[15] = n12*n23*n31 - n13*n22*n31 + n13*n21*n32 - n11*n23*n32 - n12*n21*n33 + n11*n22*n33;
-		this.multiplyScalar( 1 / m.determinant() );
+
+		var det = me[ 0 ] * te[ 0 ] + me[ 1 ] * te[ 4 ] + me[ 2 ] * te[ 8 ] + me[ 3 ] * te[ 12 ];
+
+		if ( det == 0 ) {
+
+			var msg = "Matrix4.getInverse(): can't invert matrix, determinant is 0";
+
+			if ( throwOnInvertible || false ) {
+
+				throw new Error( msg ); 
+
+			} else {
+
+				console.warn( msg );
+
+			}
+
+			this.identity();
+
+			return this;
+		}
+
+		this.multiplyScalar( 1 / det );
 
 
 		return this;
 		return this;
 
 
@@ -877,9 +875,9 @@ THREE.Matrix4.prototype = {
 
 
 		var te = this.elements;
 		var te = this.elements;
 
 
-		var scaleXSq =  te[0] * te[0] + te[1] * te[1] + te[2] * te[2];
-		var scaleYSq =  te[4] * te[4] + te[5] * te[5] + te[6] * te[6];
-		var scaleZSq =  te[8] * te[8] + te[9] * te[9] + te[10] * te[10];
+		var scaleXSq = te[0] * te[0] + te[1] * te[1] + te[2] * te[2];
+		var scaleYSq = te[4] * te[4] + te[5] * te[5] + te[6] * te[6];
+		var scaleZSq = te[8] * te[8] + te[9] * te[9] + te[10] * te[10];
 
 
 		return Math.sqrt( Math.max( scaleXSq, Math.max( scaleYSq, scaleZSq ) ) );
 		return Math.sqrt( Math.max( scaleXSq, Math.max( scaleYSq, scaleZSq ) ) );
 
 
@@ -1002,10 +1000,10 @@ THREE.Matrix4.prototype = {
 		var c = - ( far + near ) / ( far - near );
 		var c = - ( far + near ) / ( far - near );
 		var d = - 2 * far * near / ( far - near );
 		var d = - 2 * far * near / ( far - near );
 
 
-		te[0] = x;  te[4] = 0;  te[8] = a;   te[12] = 0;
-		te[1] = 0;  te[5] = y;  te[9] = b;   te[13] = 0;
-		te[2] = 0;  te[6] = 0;  te[10] = c;   te[14] = d;
-		te[3] = 0;  te[7] = 0;  te[11] = - 1; te[15] = 0;
+		te[0] = x;	te[4] = 0;	te[8] = a;	te[12] = 0;
+		te[1] = 0;	te[5] = y;	te[9] = b;	te[13] = 0;
+		te[2] = 0;	te[6] = 0;	te[10] = c;	te[14] = d;
+		te[3] = 0;	te[7] = 0;	te[11] = - 1;	te[15] = 0;
 
 
 		return this;
 		return this;
 
 
@@ -1033,16 +1031,15 @@ THREE.Matrix4.prototype = {
 		var y = ( top + bottom ) / h;
 		var y = ( top + bottom ) / h;
 		var z = ( far + near ) / p;
 		var z = ( far + near ) / p;
 
 
-		te[0] = 2 / w; te[4] = 0;     te[8] = 0;      te[12] = -x;
-		te[1] = 0;     te[5] = 2 / h; te[9] = 0;      te[13] = -y;
-		te[2] = 0;     te[6] = 0;     te[10] = -2 / p; te[14] = -z;
-		te[3] = 0;     te[7] = 0;     te[11] = 0;      te[15] = 1;
+		te[0] = 2 / w;	te[4] = 0;	te[8] = 0;	te[12] = -x;
+		te[1] = 0;	te[5] = 2 / h;	te[9] = 0;	te[13] = -y;
+		te[2] = 0;	te[6] = 0;	te[10] = -2/p;	te[14] = -z;
+		te[3] = 0;	te[7] = 0;	te[11] = 0;	te[15] = 1;
 
 
 		return this;
 		return this;
 
 
 	},
 	},
 
 
-
 	clone: function () {
 	clone: function () {
 
 
 		var te = this.elements;
 		var te = this.elements;

+ 48 - 7
src/math/Plane.js

@@ -74,6 +74,15 @@ THREE.Plane.prototype = {
 
 
 	},
 	},
 
 
+	negate: function () {
+
+		this.constant *= -1;
+		this.normal.negate();
+
+		return this;
+
+	},
+
 	distanceToPoint: function ( point ) {
 	distanceToPoint: function ( point ) {
 
 
 		return this.normal.dot( point ) + this.constant;
 		return this.normal.dot( point ) + this.constant;
@@ -112,6 +121,40 @@ THREE.Plane.prototype = {
 
 
 	},
 	},
 
 
+	intersectLine: function ( startPoint, endPoint, optionalTarget ) {
+
+		var result = optionalTarget || new THREE.Vector3();
+
+		var direction = THREE.Plane.__v1.sub( endPoint, startPoint );
+
+		var denominator = this.normal.dot( direction );
+
+		if ( denominator == 0 ) {
+
+			// line is coplanar, return origin
+			if( this.distanceToPoint( startPoint ) == 0 ) {
+
+				return result.copy( startPoint );
+
+			}
+
+			// Unsure if this is the correct method to handle this case.
+			return undefined;
+
+		}
+
+		var t = - ( startPoint.dot( this.normal ) + this.constant ) / denominator;
+
+		if( t < 0 || t > 1 ) {
+
+			return undefined;
+
+		}
+
+		return result.copy( direction ).multiplyScalar( t ).addSelf( startPoint );
+
+	},
+
 	coplanarPoint: function ( optionalTarget ) {
 	coplanarPoint: function ( optionalTarget ) {
 
 
 		var result = optionalTarget || new THREE.Vector3();
 		var result = optionalTarget || new THREE.Vector3();
@@ -119,22 +162,20 @@ THREE.Plane.prototype = {
 
 
 	},
 	},
 
 
-	transform: function( matrix, optionalNormalMatrix ) {
-
-		var newNormal = THREE.Plane.__v1, newCoplanarPoint = THREE.Plane.__v2;
+	transform: function ( matrix, optionalNormalMatrix ) {
 
 
 		// compute new normal based on theory here:
 		// compute new normal based on theory here:
 		// http://www.songho.ca/opengl/gl_normaltransform.html
 		// http://www.songho.ca/opengl/gl_normaltransform.html
 		optionalNormalMatrix = optionalNormalMatrix || new THREE.Matrix3().getInverse( matrix ).transpose();
 		optionalNormalMatrix = optionalNormalMatrix || new THREE.Matrix3().getInverse( matrix ).transpose();
-		newNormal = optionalNormalMatrix.multiplyVector3( newNormal.copy( this.normal ) );
+		var newNormal = THREE.Plane.__v1.copy( this.normal ).applyMatrix3( optionalNormalMatrix );
 
 
-		newCoplanarPoint = this.coplanarPoint( newCoplanarPoint );
-		newCoplanarPoint = matrix.multiplyVector3( newCoplanarPoint );
+		var newCoplanarPoint = this.coplanarPoint( THREE.Plane.__v2 );
+		newCoplanarPoint.applyMatrix4( matrix );
 
 
 		this.setFromNormalAndCoplanarPoint( newNormal, newCoplanarPoint );
 		this.setFromNormalAndCoplanarPoint( newNormal, newCoplanarPoint );
 
 
 		return this;
 		return this;
-		
+
 	},
 	},
 
 
 	translate: function ( offset ) {
 	translate: function ( offset ) {

+ 0 - 24
src/math/Quaternion.js

@@ -253,30 +253,6 @@ THREE.Quaternion.prototype = {
 
 
 	},
 	},
 
 
-	multiplyVector3: function ( vector, dest ) {
-
-		if ( !dest ) { dest = vector; }
-
-		var x    = vector.x,  y  = vector.y,  z  = vector.z,
-			qx   = this.x, qy = this.y, qz = this.z, qw = this.w;
-
-		// calculate quat * vector
-
-		var ix =  qw * x + qy * z - qz * y,
-			iy =  qw * y + qz * x - qx * z,
-			iz =  qw * z + qx * y - qy * x,
-			iw = -qx * x - qy * y - qz * z;
-
-		// calculate result * inverse quat
-
-		dest.x = ix * qw + iw * -qx + iy * -qz - iz * -qy;
-		dest.y = iy * qw + iw * -qy + iz * -qx - ix * -qz;
-		dest.z = iz * qw + iw * -qz + ix * -qy - iy * -qx;
-
-		return dest;
-
-	},
-
 	slerpSelf: function ( qb, t ) {
 	slerpSelf: function ( qb, t ) {
 
 
 		var x = this.x, y = this.y, z = this.z, w = this.w;
 		var x = this.x, y = this.y, z = this.z, w = this.w;

+ 3 - 3
src/math/Ray.js

@@ -133,8 +133,8 @@ THREE.Ray.prototype = {
 
 
 	transform: function ( matrix4 ) {
 	transform: function ( matrix4 ) {
 
 
-		this.direction = matrix4.multiplyVector3( this.direction.addSelf( this.origin ) );
-		this.origin = matrix4.multiplyVector3( this.origin );
+		this.direction.addSelf( this.origin ).applyMatrix4( matrix4 );
+		this.origin.applyMatrix4( matrix4 );
 		this.direction.subSelf( this.origin );
 		this.direction.subSelf( this.origin );
 
 
 		return this;
 		return this;
@@ -155,4 +155,4 @@ THREE.Ray.prototype = {
 };
 };
 
 
 THREE.Ray.__v1 = new THREE.Vector3();
 THREE.Ray.__v1 = new THREE.Vector3();
-THREE.Ray.__v2 = new THREE.Vector3();
+THREE.Ray.__v2 = new THREE.Vector3();

+ 10 - 2
src/math/Sphere.js

@@ -67,6 +67,14 @@ THREE.Sphere.prototype = {
 
 
 	},
 	},
 
 
+	intersectsSphere: function ( sphere ) {
+
+		var radiusSum = this.radius + sphere.radius;
+
+		return sphere.center.distanceToSquared( this.center ) <= ( radiusSum * radiusSum );
+
+	},
+
 	clampPoint: function ( point, optionalTarget ) {
 	clampPoint: function ( point, optionalTarget ) {
 
 
 		var deltaLengthSq = this.center.distanceToSquared( point );
 		var deltaLengthSq = this.center.distanceToSquared( point );
@@ -97,8 +105,8 @@ THREE.Sphere.prototype = {
 	},
 	},
 
 
 	transform: function ( matrix ) {
 	transform: function ( matrix ) {
-		
-		this.center = matrix.multiplyVector3( this.center );
+
+		this.center.applyMatrix4( matrix );
 		this.radius = this.radius * matrix.getMaxScaleOnAxis();
 		this.radius = this.radius * matrix.getMaxScaleOnAxis();
 
 
 		return this;
 		return this;

+ 1 - 0
src/math/Triangle.js

@@ -39,6 +39,7 @@ THREE.Triangle.normal = function( a, b, c, optionalTarget ) {
 };
 };
 
 
 // static/instance method to calculate barycoordinates
 // static/instance method to calculate barycoordinates
+// based on: http://www.blackpawn.com/texts/pointinpoly/default.html
 THREE.Triangle.barycoordFromPoint = function ( point, a, b, c, optionalTarget ) {
 THREE.Triangle.barycoordFromPoint = function ( point, a, b, c, optionalTarget ) {
 
 
 	THREE.Triangle.__v0.sub( c, a );
 	THREE.Triangle.__v0.sub( c, a );

+ 18 - 17
src/math/Vector2.js

@@ -42,28 +42,29 @@ THREE.Vector2.prototype = {
 	},
 	},
 
 
 
 
-    setComponent: function ( index, value ) {
+	setComponent: function ( index, value ) {
 
 
-        switch( index ) {
+		switch ( index ) {
 
 
-            case 0: this.x = value; break;
-            case 1: this.y = value; break;
-            default: throw new Error( "index is out of range: " + index );
+			case 0: this.x = value; break;
+			case 1: this.y = value; break;
+			default: throw new Error( "index is out of range: " + index );
 
 
-        }
+		}
 
 
-    },
+	},
 
 
-    getComponent: function ( index ) {
+	getComponent: function ( index ) {
 
 
-        switch( index ) {
+		switch ( index ) {
 
 
-            case 0: return this.x;
-            case 1: return this.y;
-            default: throw new Error( "index is out of range: " + index );
+			case 0: return this.x;
+			case 1: return this.y;
+			default: throw new Error( "index is out of range: " + index );
 
 
-    	}
-    },
+		}
+
+	},
 
 
 	copy: function ( v ) {
 	copy: function ( v ) {
 
 
@@ -255,8 +256,8 @@ THREE.Vector2.prototype = {
 	setLength: function ( l ) {
 	setLength: function ( l ) {
 
 
 		var oldLength = this.length();
 		var oldLength = this.length();
-		
-		if ( oldLength !== 0 && l !== oldLength  ) {
+
+		if ( oldLength !== 0 && l !== oldLength ) {
 
 
 			this.multiplyScalar( l / oldLength );
 			this.multiplyScalar( l / oldLength );
 		}
 		}
@@ -286,4 +287,4 @@ THREE.Vector2.prototype = {
 
 
 	}
 	}
 
 
-};
+};

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