Browse Source

Merge branch 'zh_doc' of https://github.com/gogoend/three.js into zh_doc

gogoend 6 years ago
parent
commit
cf512097ed
100 changed files with 1195 additions and 3353 deletions
  1. 277 338
      build/three.js
  2. 176 307
      build/three.min.js
  3. 277 338
      build/three.module.js
  4. 1 1
      docs/api/en/math/Matrix4.html
  5. 9 1
      docs/api/zh/core/Raycaster.html
  6. 1 1
      docs/api/zh/math/Matrix4.html
  7. 1 1
      docs/list.js
  8. 2 2
      docs/manual/en/introduction/Creating-a-scene.html
  9. 6 1
      docs/manual/en/introduction/How-to-run-things-locally.html
  10. 2 2
      docs/manual/zh/introduction/Creating-a-scene.html
  11. 6 0
      docs/manual/zh/introduction/How-to-run-things-locally.html
  12. 28 29
      docs/manual/zh/introduction/How-to-use-post-processing.html
  13. 2 4
      editor/index.html
  14. 0 29
      editor/js/Loader.js
  15. 82 0
      editor/js/Sidebar.Material.js
  16. 2 0
      editor/js/Strings.js
  17. 72 0
      editor/js/commands/SetMaterialVectorCommand.js
  18. 3 10
      editor/js/libs/ui.three.js
  19. 2 4
      editor/sw.js
  20. 13 11
      examples/files.js
  21. 2 162
      examples/js/controls/OrbitControls.js
  22. 0 658
      examples/js/libs/ctm.js
  23. 0 517
      examples/js/libs/lzma.js
  24. 1 0
      examples/js/loaders/GLTFLoader.js
  25. 18 12
      examples/js/loaders/STLLoader.js
  26. 0 279
      examples/js/loaders/ctm/CTMLoader.js
  27. 0 19
      examples/js/loaders/ctm/CTMWorker.js
  28. 4 2
      examples/js/objects/Reflector.js
  29. 4 2
      examples/js/objects/Refractor.js
  30. 4 4
      examples/js/objects/Sky.js
  31. 2 162
      examples/jsm/controls/OrbitControls.js
  32. 1 0
      examples/jsm/loaders/GLTFLoader.js
  33. 18 12
      examples/jsm/loaders/STLLoader.js
  34. 0 20
      examples/jsm/loaders/ctm/CTMLoader.d.ts
  35. 0 288
      examples/jsm/loaders/ctm/CTMLoader.js
  36. 1 1
      examples/jsm/loaders/obj2/bridge/MtlObjBridge.d.ts
  37. 1 0
      examples/jsm/nodes/Nodes.js
  38. 9 2
      examples/jsm/nodes/core/FunctionNode.js
  39. 6 0
      examples/jsm/nodes/core/NodeBuilder.js
  40. 41 6
      examples/jsm/nodes/materials/nodes/StandardNode.js
  41. 19 7
      examples/jsm/nodes/misc/TextureCubeNode.js
  42. 11 0
      examples/jsm/nodes/utils/SubSlot.d.ts
  43. 79 0
      examples/jsm/nodes/utils/SubSlotNode.js
  44. 4 2
      examples/jsm/objects/Reflector.js
  45. 4 2
      examples/jsm/objects/Refractor.js
  46. 4 4
      examples/jsm/objects/Sky.js
  47. BIN
      examples/models/ctm/LeePerry.ctm
  48. BIN
      examples/models/ctm/WaltHead.ctm
  49. BIN
      examples/models/ctm/ben.ctm
  50. BIN
      examples/models/ctm/camaro/camaro.ctm
  51. 0 113
      examples/models/ctm/camaro/camaro.js
  52. BIN
      examples/models/ctm/camaro/car-ao.png
  53. BIN
      examples/models/ctm/camaro/plane-ao-256.png
  54. BIN
      examples/models/ctm/hand.ctm
  55. BIN
      examples/textures/carbon/Carbon.png
  56. BIN
      examples/textures/carbon/Carbon_Normal.png
  57. BIN
      examples/textures/cube/angus/cube_m00_c00.jpg
  58. BIN
      examples/textures/cube/angus/cube_m00_c01.jpg
  59. BIN
      examples/textures/cube/angus/cube_m00_c02.jpg
  60. BIN
      examples/textures/cube/angus/cube_m00_c03.jpg
  61. BIN
      examples/textures/cube/angus/cube_m00_c04.jpg
  62. BIN
      examples/textures/cube/angus/cube_m00_c05.jpg
  63. BIN
      examples/textures/cube/angus/cube_m01_c00.jpg
  64. BIN
      examples/textures/cube/angus/cube_m01_c01.jpg
  65. BIN
      examples/textures/cube/angus/cube_m01_c02.jpg
  66. BIN
      examples/textures/cube/angus/cube_m01_c03.jpg
  67. BIN
      examples/textures/cube/angus/cube_m01_c04.jpg
  68. BIN
      examples/textures/cube/angus/cube_m01_c05.jpg
  69. BIN
      examples/textures/cube/angus/cube_m02_c00.jpg
  70. BIN
      examples/textures/cube/angus/cube_m02_c01.jpg
  71. BIN
      examples/textures/cube/angus/cube_m02_c02.jpg
  72. BIN
      examples/textures/cube/angus/cube_m02_c03.jpg
  73. BIN
      examples/textures/cube/angus/cube_m02_c04.jpg
  74. BIN
      examples/textures/cube/angus/cube_m02_c05.jpg
  75. BIN
      examples/textures/cube/angus/cube_m03_c00.jpg
  76. BIN
      examples/textures/cube/angus/cube_m03_c01.jpg
  77. BIN
      examples/textures/cube/angus/cube_m03_c02.jpg
  78. BIN
      examples/textures/cube/angus/cube_m03_c03.jpg
  79. BIN
      examples/textures/cube/angus/cube_m03_c04.jpg
  80. BIN
      examples/textures/cube/angus/cube_m03_c05.jpg
  81. BIN
      examples/textures/cube/angus/cube_m04_c00.jpg
  82. BIN
      examples/textures/cube/angus/cube_m04_c01.jpg
  83. BIN
      examples/textures/cube/angus/cube_m04_c02.jpg
  84. BIN
      examples/textures/cube/angus/cube_m04_c03.jpg
  85. BIN
      examples/textures/cube/angus/cube_m04_c04.jpg
  86. BIN
      examples/textures/cube/angus/cube_m04_c05.jpg
  87. BIN
      examples/textures/cube/angus/cube_m05_c00.jpg
  88. BIN
      examples/textures/cube/angus/cube_m05_c01.jpg
  89. BIN
      examples/textures/cube/angus/cube_m05_c02.jpg
  90. BIN
      examples/textures/cube/angus/cube_m05_c03.jpg
  91. BIN
      examples/textures/cube/angus/cube_m05_c04.jpg
  92. BIN
      examples/textures/cube/angus/cube_m05_c05.jpg
  93. BIN
      examples/textures/cube/angus/cube_m06_c00.jpg
  94. BIN
      examples/textures/cube/angus/cube_m06_c01.jpg
  95. BIN
      examples/textures/cube/angus/cube_m06_c02.jpg
  96. BIN
      examples/textures/cube/angus/cube_m06_c03.jpg
  97. BIN
      examples/textures/cube/angus/cube_m06_c04.jpg
  98. BIN
      examples/textures/cube/angus/cube_m06_c05.jpg
  99. BIN
      examples/textures/cube/angus/cube_m07_c00.jpg
  100. BIN
      examples/textures/cube/angus/cube_m07_c01.jpg

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


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


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


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

@@ -56,7 +56,7 @@
 
 			This means that calling
 		<code>
-var m = new Matrix4();
+var m = new THREE.Matrix4();
 
 m.set( 11, 12, 13, 14,
        21, 22, 23, 24,

+ 9 - 1
docs/api/zh/core/Raycaster.html

@@ -103,9 +103,17 @@
 			这个值不应当为负,并且应当比near属性小。
 		</p>
 
+		<h3>[property:Camera camera]</h3>
+		<p>
+		The camera to use when raycasting against view-dependent objects such as billboarded objects like [page:Sprites]. This field
+		can be set manually or is set when calling "setFromCamera".
+
+		Defaults to null.
+		</p>
+
 		<h3>[property:Object params]</h3>
 		<p>
-			具有以下属性的物体:<code>
+			具有以下属性的对象:<code>
 {
 	Mesh: {},
 	Line: {},

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

@@ -51,7 +51,7 @@
 
 				这意味着
 		<code>
-var m = new Matrix4();
+var m = new THREE.Matrix4();
 
 m.set( 11, 12, 13, 14,
        21, 22, 23, 24,

+ 1 - 1
docs/list.js

@@ -458,7 +458,7 @@ var list = {
 				"如何更新场景": "manual/zh/introduction/How-to-update-things",
 				"如何废置对象": "manual/zh/introduction/How-to-dispose-of-objects",
 				"如何创建VR内容": "manual/zh/introduction/How-to-create-VR-content",
-				"How to use post-processing": "manual/zh/introduction/How-to-use-post-processing",
+				"如何使用后期处理": "manual/zh/introduction/How-to-use-post-processing",
 				"矩阵变换": "manual/zh/introduction/Matrix-transformations",
 				"动画系统": "manual/zh/introduction/Animation-system"
 			},

+ 2 - 2
docs/manual/en/introduction/Creating-a-scene.html

@@ -20,7 +20,7 @@
 		&lt;!DOCTYPE html&gt;
 		&lt;html&gt;
 			&lt;head&gt;
-				&lt;meta charset=utf-8&gt;
+				&lt;meta charset="utf-8"&gt;
 				&lt;title&gt;My first three.js app&lt;/title&gt;
 				&lt;style&gt;
 					body { margin: 0; }
@@ -118,7 +118,7 @@
 		<h2>The result</h2>
 		<p>Congratulations! You have now completed your first three.js application. It's simple, you have to start somewhere.</p>
 
-		<p>The full code is available below. Play around with it to get a better understanding of how it works.</p>
+		<p>The full code is available below and as an editable [link:https://jsfiddle.net/mkba0ecu/ live example]. Play around with it to get a better understanding of how it works.</p>
 
 		<code>
 		&lt;html&gt;

+ 6 - 1
docs/manual/en/introduction/How-to-run-things-locally.html

@@ -121,7 +121,12 @@ ruby -r webrick -e "s = WEBrick::HTTPServer.new(:Port => 8000, :DocumentRoot =>
 					</li>
 				</ol>
 			</div>
-
+			<h3>IIS</h3>
+			<div>
+				<p>If you are using Microsoft IIS as web server. Please add a MIME type settings regarding .fbx externsion before loading.</p>
+				<code>File name externsion: fbx        MIME Type: text/plain</code>
+				<p>By default, IIS blocks .fbx, .obj files downloads. You have to configure IIS to enable these kind of files can be download.</p>
+			</div>
 			<p>
 				Other simple alternatives are [link:http://stackoverflow.com/q/12905426/24874 discussed here]
 				on Stack Overflow.

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

@@ -20,7 +20,7 @@
 		&lt;!DOCTYPE html&gt;
 		&lt;html&gt;
 			&lt;head&gt;
-				&lt;meta charset=utf-8&gt;
+				&lt;meta charset="utf-8"&gt;
 				&lt;title&gt;My first three.js app&lt;/title&gt;
 				&lt;style&gt;
 					body { margin: 0; }
@@ -119,7 +119,7 @@
 		<h2>结果</h2>
 		<p>祝贺你!你现在已经成功完成了你的第一个Three.js应用程序。虽然它很简单,但现在你已经有了一个入门的起点。</p>
 
-		<p>下面是完整的代码,运行或者修改代码从而有助于你更好的理解它是如何工作的。</p>
+		<p>下面是完整的代码,可在[link:https://jsfiddle.net/mkba0ecu/ live example]运行、编辑;运行或者修改代码有助于你更好的理解它是如何工作的。</p>
 
 		<code>
 		&lt;html&gt;

+ 6 - 0
docs/manual/zh/introduction/How-to-run-things-locally.html

@@ -116,6 +116,12 @@ ruby -r webrick -e "s = WEBrick::HTTPServer.new(:Port => 8000, :DocumentRoot =>
 					</li>
 				</ol>
 			</div>
+			<h3>IIS</h3>
+			<div>
+				<p>如果你正在使用Microsoft IIS来作为网站服务器,在服务器载入之前,请为.fbx扩展名增加MIME类型。</p>
+				<code>File name externsion: fbx        MIME Type: text/plain</code>
+				<p>在默认情况下,IIS阻止 .fbx、 .obj 文件的下载,因此你必须对IIS进行配置,使得这些类型的文件可以被下载。</p>
+			</div>
 
 			<p>
                 其它简单的替代方案你可以在Stack Overflow上找到:[link:http://stackoverflow.com/q/12905426/24874 click here]。

+ 28 - 29
docs/manual/zh/introduction/How-to-use-post-processing.html

@@ -8,24 +8,24 @@
 		<link type="text/css" rel="stylesheet" href="page.css" />
 	</head>
 	<body>
-		<h1>How to use post-processing</h1>
+		<h1>如何使用后期处理(How to use post-processing</h1>
 
 		<p>
-			Many three.js applications render their 3D objects directly to the screen. Sometimes, however, you want to apply one or more graphical
-			effects like Depth-Of-Field, Bloom, Film Grain or various types of Anti-aliasing. Post-processing is a widely used approach
-			to implement such effects. First, the scene is rendered to a render target which represents a buffer in the video card's memory.
-			In the next step one ore more post-processing passes apply filters and effects to the image buffer before it is eventually rendered to
-			the screen.
+			很多three.js应用程序是直接将三维物体渲染到屏幕上的。
+			有时,你或许希望应用一个或多个图形效果,例如景深、发光、胶片微粒或是各种类型的抗锯齿。
+			后期处理是一种被广泛使用、用于来实现这些效果的方式。
+			首先,场景被渲染到一个渲染目标上,渲染目标表示的是一块在显存中的缓冲区。
+			接下来,在图像最终被渲染到屏幕之前,一个或多个后期处理过程将滤镜和效果应用到图像缓存区。
 		</p>
 		<p>
-			three.js provides a complete post-processing solution via [page:EffectComposer] to implement such a workflow.
+			three.js通过[page:EffectComposer](效果合成器),提供了一个完整的后期处理解决方案来实现这样的工作流程。
 		</p>
 
-		<h2>Workflow</h2>
+		<h2>工作流程</h2>
 
 		<p>
-			The first step in the process is to import all necessary files from the examples directory. The guide assumes your are using the official
-			[link:https://www.npmjs.com/package/three npm package] of three.js. For our basic demo in this guide we need the following files.
+			首先,我们要做的是从示例(examples)文件夹导入所有必需的文件。本指南假设你正在使用three.js官方npm包([link:https://www.npmjs.com/package/three npm package])。
+			在本指南的基础示例中,我们需要下列文件。
 		</p>
 
 		<code>
@@ -35,7 +35,7 @@
 		</code>
 
 		<p>
-			After all files are successfully imported, we can create our composer by passing in an instance of [page:WebGLRenderer].
+			当这些文件被成功导入后,我们便可以通过传入一个[page:WebGLRenderer]的实例,来创建我们的合成器了。
 		</p>
 
 		<code>
@@ -43,8 +43,8 @@
 		</code>
 
 		<p>
-			When using a composer, it's necessary to change the application's animation loop. Instead of calling the render method of
-			[page:WebGLRenderer], we now use the respective counterpart of [page:EffectComposer].
+			在使用合成器时,我们需要对应用程序的动画循环进行更改。
+			现在我们不再调用[page:WebGLRenderer]的render方法,而是使用[page:EffectComposer]中对应的render方法。
 		</p>
 
 		<code>
@@ -58,10 +58,10 @@
 		</code>
 
 		<p>
-			Our composer is now ready so it's possible to configure the chain of post-processing passes. These passes are responsible for creating
-			the final visual output of the application. They are processed in order of their addition/insertion. In our example, the instance of *RenderPass*
-			is executed first and then the instance of *GlitchPass*. The last enabled pass in the chain is automatically rendered to the screen. The setup
-			of the passes looks like so:
+			我们的合成器已经准备好了,现在我们就可以来配置后期处理过程链了。
+			这些过程负责创建应用程序的最终视觉输出,它们按照添加/插入的顺序来进行处理。
+			在我们的示例中,*RenderPass*实例首先被执行,然后是*GlitchPass*。在链中的最后一个过程将自动被渲染到屏幕上。
+			这些过程的设置类似这样:
 		</p>
 
 		<code>
@@ -73,23 +73,23 @@
 		</code>
 
 		<p>
-			*RenderPass* is normally placed at the beginning of the chain in order to provide the rendered scene as an input for the next post-processing step. In our case,
-			*GlitchPass* is going to use these image data to apply a wild glitch effect. Check out this [link:https://threejs.org/examples/webgl_postprocessing_glitch live example]
-			to see it in action.
+			*RenderPass*通常位于过程链的开始,以便将渲染好的场景作为输入来提供给下一个后期处理步骤。
+			在我们的示例中,*GlitchPass*将会使用这些图像数据,来应用一个疯狂的故障效果。参见这个示例:
+			[link:https://threejs.org/examples/webgl_postprocessing_glitch live example]来看一看它的实际效果。
 		</p>
 
-		<h2>Built-in Passes</h2>
+		<h2>内置过程</h2>
 
 		<p>
-			You can use a wide range of pre-defined post-processing passes provided by the engine. They are located in the
-			[link:https://github.com/mrdoob/three.js/tree/dev/examples/jsm/postprocessing postprocessing] directory.
+			你可以使用由本引擎提供的各种预定义好的后期处理过程,
+			它们位于[link:https://github.com/mrdoob/three.js/tree/dev/examples/jsm/postprocessing postprocessing]目录中。
 		</p>
 
-		<h2>Custom Passes</h2>
+		<h2>自定义过程</h2>
 
 		<p>
-			Sometimes you want to write a custom post-processing shader and include it into the chain of post-processing passes. For this scenario,
-			you can utilize *ShaderPass*. After importing the file and your custom shader, you can use the following code to setup the pass.
+			有时你或许想要自己写一个自定义后期处理着色器,并将其包含到后期处理过程链中。
+			对于这个需求,你可以使用*ShaderPass*。在引入该文件以及你的自定义着色期后,可以使用下列代码来设置该过程:
 		</p>
 
 		<code>
@@ -103,9 +103,8 @@
 		</code>
 
 		<p>
-			The repository provides a file called [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/shaders/CopyShader.js CopyShader] which is a
-			good starting code for your own custom shader. *CopyShader* just copies the image contents of the [page:EffectComposer]'s read buffer
-			to its write buffer without applying any effects.
+			本仓库中提供了一个名为[link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/shaders/CopyShader.js CopyShader]的文件,
+			这是你自定义自己的着色器的一个很好的起始代码。*CopyShader*仅仅是拷贝了读缓冲区中的图像内容到写缓冲区,不会应用任何效果。
 		</p>
 
 	</body>

+ 2 - 4
editor/index.html

@@ -22,8 +22,6 @@
 		<script src="../examples/js/libs/chevrotain.min.js"></script> <!-- VRML -->
 		<script src="../examples/js/libs/jszip.min.js"></script>
 		<script src="../examples/js/libs/inflate.min.js"></script> <!-- FBX -->
-		<script src="../examples/js/libs/lzma.js"></script> <!-- CTM -->
-		<script src="../examples/js/libs/ctm.js"></script> <!-- CTM -->
 
 		<script src="../examples/js/loaders/AMFLoader.js"></script>
 		<script src="../examples/js/loaders/AWDLoader.js"></script>
@@ -45,7 +43,6 @@
 		<script src="../examples/js/loaders/TDSLoader.js"></script>
 		<script src="../examples/js/loaders/VRMLLoader.js"></script>
 		<script src="../examples/js/loaders/VTKLoader.js"></script>
-		<script src="../examples/js/loaders/ctm/CTMLoader.js"></script>
 
 		<script src="../examples/js/exporters/ColladaExporter.js"></script>
 		<script src="../examples/js/exporters/GLTFExporter.js"></script>
@@ -170,9 +167,10 @@
 		<script src="js/commands/RemoveScriptCommand.js"></script>
 		<script src="js/commands/SetScriptValueCommand.js"></script>
 		<script src="js/commands/SetMaterialCommand.js"></script>
-		<script src="js/commands/SetMaterialValueCommand.js"></script>
 		<script src="js/commands/SetMaterialColorCommand.js"></script>
 		<script src="js/commands/SetMaterialMapCommand.js"></script>
+		<script src="js/commands/SetMaterialValueCommand.js"></script>
+		<script src="js/commands/SetMaterialVectorCommand.js"></script>
 		<script src="js/commands/SetSceneCommand.js"></script>
 
 		<script>

+ 0 - 29
editor/js/Loader.js

@@ -140,35 +140,6 @@ var Loader = function ( editor ) {
 
 				break;
 
-			case 'ctm':
-
-				reader.addEventListener( 'load', function ( event ) {
-
-					var data = new Uint8Array( event.target.result );
-
-					var stream = new CTM.Stream( data );
-					stream.offset = 0;
-
-					var loader = new THREE.CTMLoader();
-					loader.createModel( new CTM.File( stream ), function ( geometry ) {
-
-						geometry.sourceType = "ctm";
-						geometry.sourceFile = file.name;
-
-						var material = new THREE.MeshStandardMaterial();
-
-						var mesh = new THREE.Mesh( geometry, material );
-						mesh.name = filename;
-
-						editor.execute( new AddObjectCommand( editor, mesh ) );
-
-					} );
-
-				}, false );
-				reader.readAsArrayBuffer( file );
-
-				break;
-
 			case 'dae':
 
 				reader.addEventListener( 'load', function ( event ) {

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

@@ -340,13 +340,33 @@ Sidebar.Material = function ( editor ) {
 	var materialNormalMapRow = new UI.Row();
 	var materialNormalMapEnabled = new UI.Checkbox( false ).onChange( update );
 	var materialNormalMap = new UI.Texture().onChange( update );
+	var materialNormalScaleX = new UI.Number( 1 ).setWidth( '30px' ).onChange( update );
+	var materialNormalScaleY = new UI.Number( 1 ).setWidth( '30px' ).onChange( update );
 
 	materialNormalMapRow.add( new UI.Text( strings.getKey( 'sidebar/material/normalmap' ) ).setWidth( '90px' ) );
 	materialNormalMapRow.add( materialNormalMapEnabled );
 	materialNormalMapRow.add( materialNormalMap );
+	materialNormalMapRow.add( materialNormalScaleX );
+	materialNormalMapRow.add( materialNormalScaleY );
 
 	container.add( materialNormalMapRow );
 
+	// clearcoat normal map
+
+	var materialClearCoatNormalMapRow = new UI.Row();
+	var materialClearCoatNormalMapEnabled = new UI.Checkbox( false ).onChange( update );
+	var materialClearCoatNormalMap = new UI.Texture().onChange( update );
+	var materialClearCoatNormalScaleX = new UI.Number( 1 ).setWidth( '30px' ).onChange( update );
+	var materialClearCoatNormalScaleY = new UI.Number( 1 ).setWidth( '30px' ).onChange( update );
+
+	materialClearCoatNormalMapRow.add( new UI.Text( strings.getKey( 'sidebar/material/clearcoatnormalmap' ) ).setWidth( '90px' ) );
+	materialClearCoatNormalMapRow.add( materialClearCoatNormalMapEnabled );
+	materialClearCoatNormalMapRow.add( materialClearCoatNormalMap );
+	materialClearCoatNormalMapRow.add( materialClearCoatNormalScaleX );
+	materialClearCoatNormalMapRow.add( materialClearCoatNormalScaleY );
+
+	container.add( materialClearCoatNormalMapRow );
+
 	// displacement map
 
 	var materialDisplacementMapRow = new UI.Row();
@@ -778,6 +798,17 @@ Sidebar.Material = function ( editor ) {
 
 					}
 
+					if ( material.normalScale.x !== materialNormalScaleX.getValue() ||
+						material.normalScale.y !== materialNormalScaleY.getValue() ) {
+
+						var value = [
+							materialNormalScaleX.getValue(),
+							materialNormalScaleY.getValue()
+						];
+						editor.execute( new SetMaterialVectorCommand( editor, currentObject, 'normalScale', value, currentMaterialSlot ) );
+
+					}
+
 				} else {
 
 					if ( normalMapEnabled ) textureWarning = true;
@@ -786,6 +817,39 @@ Sidebar.Material = function ( editor ) {
 
 			}
 
+			if ( material.clearCoatNormalMap !== undefined ) {
+
+				var clearCoatNormalMapEnabled = materialClearCoatNormalMapEnabled.getValue() === true;
+
+				if ( objectHasUvs ) {
+
+					var clearCoatNormalMap = clearCoatNormalMapEnabled ? materialClearCoatNormalMap.getValue() : null;
+
+					if ( material.clearCoatNormalMap !== clearCoatNormalMap ) {
+
+						editor.execute( new SetMaterialMapCommand( editor, currentObject, 'clearCoatNormalMap', clearCoatNormalMap, currentMaterialSlot ) );
+
+					}
+
+					if ( material.clearCoatNormalScale.x !== materialClearCoatNormalScaleX.getValue() ||
+						material.clearCoatNormalScale.y !== materialClearCoatNormalScaleY.getValue() ) {
+
+						var value = [
+							materialClearCoatNormalScaleX.getValue(),
+							materialClearCoatNormalScaleY.getValue()
+						];
+						editor.execute( new SetMaterialVectorCommand( editor, currentObject, 'clearCoatNormalScale', value, currentMaterialSlot ) );
+
+					}
+
+				} else {
+
+					if ( clearCoatNormalMapEnabled ) textureWarning = true;
+
+				}
+
+			}
+
 			if ( material.displacementMap !== undefined ) {
 
 				var displacementMapEnabled = materialDisplacementMapEnabled.getValue() === true;
@@ -1313,6 +1377,24 @@ Sidebar.Material = function ( editor ) {
 
 			}
 
+			materialNormalScaleX.setValue( material.normalScale.x );
+			materialNormalScaleY.setValue( material.normalScale.y );
+
+		}
+
+		if ( material.clearCoatNormalMap !== undefined ) {
+
+			materialClearCoatNormalMapEnabled.setValue( material.clearCoatNormalMap !== null );
+
+			if ( material.clearCoatNormalMap !== null || resetTextureSelectors ) {
+
+				materialClearCoatNormalMap.setValue( material.clearCoatNormalMap );
+
+			}
+
+			materialClearCoatNormalScaleX.setValue( material.clearCoatNormalScale.x );
+			materialClearCoatNormalScaleY.setValue( material.clearCoatNormalScale.y );
+
 		}
 
 		if ( material.displacementMap !== undefined ) {

+ 2 - 0
editor/js/Strings.js

@@ -236,6 +236,7 @@ var Strings = function ( config ) {
 			'sidebar/material/alphamap': 'Alpha Map',
 			'sidebar/material/bumpmap': 'Bump Map',
 			'sidebar/material/normalmap': 'Normal Map',
+			'sidebar/material/clearcoatnormalmap': 'ClearCoat Normal Map',
 			'sidebar/material/displacemap': 'Displace Map',
 			'sidebar/material/roughmap': 'Rough. Map',
 			'sidebar/material/metalmap': 'Metal. Map',
@@ -507,6 +508,7 @@ var Strings = function ( config ) {
 			'sidebar/material/alphamap': '透明贴图',
 			'sidebar/material/bumpmap': '凹凸贴图',
 			'sidebar/material/normalmap': '法线贴图',
+			'sidebar/material/clearcoatnormalmap': 'ClearCoat Normal Map',
 			'sidebar/material/displacemap': '置换贴图',
 			'sidebar/material/roughmap': '粗糙贴图',
 			'sidebar/material/metalmap': '金属贴图',

+ 72 - 0
editor/js/commands/SetMaterialVectorCommand.js

@@ -0,0 +1,72 @@
+/**
+ * @author dforrer / https://github.com/dforrer
+ * Developed as part of a project at University of Applied Sciences and Arts Northwestern Switzerland (www.fhnw.ch)
+ */
+
+var SetMaterialVectorCommand = function ( editor, object, attributeName, newValue, materialSlot ) {
+
+	Command.call( this, editor );
+
+	this.type = 'SetMaterialColorCommand';
+	this.name = 'Set Material.' + attributeName;
+	this.updatable = true;
+
+	this.object = object;
+	this.material = this.editor.getObjectMaterial( object, materialSlot );
+
+	this.oldValue = ( this.material !== undefined ) ? this.material[ attributeName ].toArray() : undefined;
+	this.newValue = newValue;
+
+	this.attributeName = attributeName;
+
+};
+
+SetMaterialVectorCommand.prototype = {
+
+	execute: function () {
+
+		this.material[ this.attributeName ].fromArray( this.newValue );
+
+		this.editor.signals.materialChanged.dispatch( this.material );
+
+	},
+
+	undo: function () {
+
+		this.material[ this.attributeName ].fromArray( this.oldValue );
+
+		this.editor.signals.materialChanged.dispatch( this.material );
+
+	},
+
+	update: function ( cmd ) {
+
+		this.newValue = cmd.newValue;
+
+	},
+
+	toJSON: function () {
+
+		var output = Command.prototype.toJSON.call( this );
+
+		output.objectUuid = this.object.uuid;
+		output.attributeName = this.attributeName;
+		output.oldValue = this.oldValue;
+		output.newValue = this.newValue;
+
+		return output;
+
+	},
+
+	fromJSON: function ( json ) {
+
+		Command.prototype.fromJSON.call( this, json );
+
+		this.object = this.editor.objectByUuid( json.objectUuid );
+		this.attributeName = json.attributeName;
+		this.oldValue = json.oldValue;
+		this.newValue = json.newValue;
+
+	}
+
+};

+ 3 - 10
editor/js/libs/ui.three.js

@@ -41,12 +41,6 @@ UI.Texture = function ( mapping ) {
 	}, false );
 	dom.appendChild( canvas );
 
-	var name = document.createElement( 'input' );
-	name.disabled = true;
-	name.style.width = '64px';
-	name.style.border = '1px solid #ccc';
-	dom.appendChild( name );
-
 	function loadFile( file ) {
 
 		if ( file.type.match( 'image.*' ) ) {
@@ -122,7 +116,6 @@ UI.Texture.prototype.getValue = function () {
 UI.Texture.prototype.setValue = function ( texture ) {
 
 	var canvas = this.dom.children[ 0 ];
-	var name = this.dom.children[ 1 ];
 	var context = canvas.getContext( '2d' );
 
 	if ( texture !== null ) {
@@ -131,21 +124,21 @@ UI.Texture.prototype.setValue = function ( texture ) {
 
 		if ( image !== undefined && image.width > 0 ) {
 
-			name.value = texture.sourceFile;
+			canvas.title = texture.sourceFile;
 
 			var scale = canvas.width / image.width;
 			context.drawImage( image, 0, 0, image.width * scale, image.height * scale );
 
 		} else {
 
-			name.value = texture.sourceFile + ' (error)';
+			canvas.title = texture.sourceFile + ' (error)';
 			context.clearRect( 0, 0, canvas.width, canvas.height );
 
 		}
 
 	} else {
 
-		name.value = '';
+		canvas.title = 'empty';
 
 		if ( context !== null ) {
 

+ 2 - 4
editor/sw.js

@@ -13,8 +13,6 @@ const staticAssets = [
 	'../examples/js/libs/chevrotain.min.js',
 	'../examples/js/libs/jszip.min.js',
 	'../examples/js/libs/inflate.min.js',
-	'../examples/js/libs/lzma.js',
-	'../examples/js/libs/ctm.js',
 
 	'../examples/js/loaders/AMFLoader.js',
 	'../examples/js/loaders/AWDLoader.js',
@@ -36,7 +34,6 @@ const staticAssets = [
 	'../examples/js/loaders/TDSLoader.js',
 	'../examples/js/loaders/VRMLLoader.js',
 	'../examples/js/loaders/VTKLoader.js',
-	'../examples/js/loaders/ctm/CTMLoader.js',
 
 	'../examples/js/exporters/ColladaExporter.js',
 	'../examples/js/exporters/GLTFExporter.js',
@@ -169,9 +166,10 @@ const staticAssets = [
 	'./js/commands/RemoveScriptCommand.js',
 	'./js/commands/SetScriptValueCommand.js',
 	'./js/commands/SetMaterialCommand.js',
-	'./js/commands/SetMaterialValueCommand.js',
 	'./js/commands/SetMaterialColorCommand.js',
 	'./js/commands/SetMaterialMapCommand.js',
+	'./js/commands/SetMaterialValueCommand.js',
+	'./js/commands/SetMaterialVectorCommand.js',
 	'./js/commands/SetSceneCommand.js',
 
 	//

+ 13 - 11
examples/files.js

@@ -85,8 +85,6 @@ var files = {
 		"webgl_loader_collada",
 		"webgl_loader_collada_kinematics",
 		"webgl_loader_collada_skinning",
-		"webgl_loader_ctm",
-		"webgl_loader_ctm_materials",
 		"webgl_loader_draco",
 		"webgl_loader_fbx",
 		"webgl_loader_fbx_nurbs",
@@ -103,7 +101,6 @@ var files = {
 		"webgl_loader_mmd",
 		"webgl_loader_mmd_pose",
 		"webgl_loader_mmd_audio",
-		"webgl_loader_nodes",
 		"webgl_loader_nrrd",
 		"webgl_loader_obj",
 		"webgl_loader_obj_mtl",
@@ -147,24 +144,23 @@ var files = {
 		"webgl_materials_bumpmap_skin",
 		"webgl_materials_cars",
 		"webgl_materials_channels",
+		"webgl_materials_clearcoat_normalmap",
 		"webgl_materials_compile",
 		"webgl_materials_cubemap",
 		"webgl_materials_cubemap_balls_reflection",
 		"webgl_materials_cubemap_balls_refraction",
 		"webgl_materials_cubemap_dynamic",
 		"webgl_materials_cubemap_refraction",
+		"webgl_materials_cubemap_mipmaps",
 		"webgl_materials_curvature",
 		"webgl_materials_displacementmap",
 		"webgl_materials_envmaps",
 		"webgl_materials_envmaps_exr",
 		"webgl_materials_envmaps_hdr",
-		"webgl_materials_envmaps_hdr_nodes",
 		"webgl_materials_envmaps_parallax",
-		"webgl_materials_envmaps_pmrem_nodes",
 		"webgl_materials_grass",
 		"webgl_materials_lightmap",
 		"webgl_materials_matcap",
-		"webgl_materials_nodes",
 		"webgl_materials_normalmap",
 		"webgl_materials_normalmap_object_space",
 		"webgl_materials_parallaxmap",
@@ -191,7 +187,6 @@ var files = {
 		"webgl_materials_wireframe",
 		"webgl_math_orientation_transform",
 		"webgl_mirror",
-		"webgl_mirror_nodes",
 		"webgl_modifier_simplifier",
 		"webgl_modifier_subdivision",
 		"webgl_modifier_tessellation",
@@ -212,7 +207,6 @@ var files = {
 		"webgl_panorama_equirectangular",
 		"webgl_performance",
 		"webgl_performance_doublesided",
-		"webgl_performance_nodes",
 		"webgl_performance_static",
 		"webgl_points_billboards",
 		"webgl_points_dynamic",
@@ -240,7 +234,6 @@ var files = {
 		"webgl_shadowmesh",
 		"webgl_skinning_simple",
 		"webgl_sprites",
-		"webgl_sprites_nodes",
 		"webgl_terrain_dynamic",
 		"webgl_test_memory",
 		"webgl_test_memory2",
@@ -250,6 +243,17 @@ var files = {
 		"webgl_water",
 		"webgl_water_flowmap"
 	],
+	"webgl / nodes": [
+		"webgl_loader_nodes",
+		"webgl_materials_envmaps_hdr_nodes",
+		"webgl_materials_envmaps_pmrem_nodes",
+		"webgl_materials_nodes",
+		"webgl_mirror_nodes",
+		"webgl_performance_nodes",
+		"webgl_postprocessing_nodes",
+		"webgl_postprocessing_nodes_pass",
+		"webgl_sprites_nodes",
+	],
 	"webgl / postprocessing": [
 		"webgl_postprocessing",
 		"webgl_postprocessing_advanced",
@@ -265,8 +269,6 @@ var files = {
 		"webgl_postprocessing_masking",
 		"webgl_postprocessing_ssaa",
 		"webgl_postprocessing_ssaa_unbiased",
-		"webgl_postprocessing_nodes",
-		"webgl_postprocessing_nodes_pass",
 		"webgl_postprocessing_outline",
 		"webgl_postprocessing_pixel",
 		"webgl_postprocessing_procedural",

+ 2 - 162
examples/js/controls/OrbitControls.js

@@ -460,32 +460,24 @@ THREE.OrbitControls = function ( object, domElement ) {
 
 	function handleMouseDownRotate( event ) {
 
-		//console.log( 'handleMouseDownRotate' );
-
 		rotateStart.set( event.clientX, event.clientY );
 
 	}
 
 	function handleMouseDownDolly( event ) {
 
-		//console.log( 'handleMouseDownDolly' );
-
 		dollyStart.set( event.clientX, event.clientY );
 
 	}
 
 	function handleMouseDownPan( event ) {
 
-		//console.log( 'handleMouseDownPan' );
-
 		panStart.set( event.clientX, event.clientY );
 
 	}
 
 	function handleMouseMoveRotate( event ) {
 
-		//console.log( 'handleMouseMoveRotate' );
-
 		rotateEnd.set( event.clientX, event.clientY );
 
 		rotateDelta.subVectors( rotateEnd, rotateStart ).multiplyScalar( scope.rotateSpeed );
@@ -504,8 +496,6 @@ THREE.OrbitControls = function ( object, domElement ) {
 
 	function handleMouseMoveDolly( event ) {
 
-		//console.log( 'handleMouseMoveDolly' );
-
 		dollyEnd.set( event.clientX, event.clientY );
 
 		dollyDelta.subVectors( dollyEnd, dollyStart );
@@ -528,8 +518,6 @@ THREE.OrbitControls = function ( object, domElement ) {
 
 	function handleMouseMovePan( event ) {
 
-		//console.log( 'handleMouseMovePan' );
-
 		panEnd.set( event.clientX, event.clientY );
 
 		panDelta.subVectors( panEnd, panStart ).multiplyScalar( scope.panSpeed );
@@ -544,14 +532,12 @@ THREE.OrbitControls = function ( object, domElement ) {
 
 	function handleMouseUp( /*event*/ ) {
 
-		// console.log( 'handleMouseUp' );
+		// no-op
 
 	}
 
 	function handleMouseWheel( event ) {
 
-		// console.log( 'handleMouseWheel' );
-
 		if ( event.deltaY < 0 ) {
 
 			dollyOut( getZoomScale() );
@@ -568,8 +554,6 @@ THREE.OrbitControls = function ( object, domElement ) {
 
 	function handleKeyDown( event ) {
 
-		// console.log( 'handleKeyDown' );
-
 		var needsUpdate = false;
 
 		switch ( event.keyCode ) {
@@ -610,8 +594,6 @@ THREE.OrbitControls = function ( object, domElement ) {
 
 	function handleTouchStartRotate( event ) {
 
-		//console.log( 'handleTouchStartRotate' );
-
 		if ( event.touches.length == 1 ) {
 
 			rotateStart.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );
@@ -629,8 +611,6 @@ THREE.OrbitControls = function ( object, domElement ) {
 
 	function handleTouchStartPan( event ) {
 
-		//console.log( 'handleTouchStartPan' );
-
 		if ( event.touches.length == 1 ) {
 
 			panStart.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );
@@ -648,8 +628,6 @@ THREE.OrbitControls = function ( object, domElement ) {
 
 	function handleTouchStartDolly( event ) {
 
-		//console.log( 'handleTouchStartDolly' );
-
 		var dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX;
 		var dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY;
 
@@ -661,8 +639,6 @@ THREE.OrbitControls = function ( object, domElement ) {
 
 	function handleTouchStartDollyPan( event ) {
 
-		//console.log( 'handleTouchStartDollyPan' );
-
 		if ( scope.enableZoom ) handleTouchStartDolly( event );
 
 		if ( scope.enablePan ) handleTouchStartPan( event );
@@ -671,8 +647,6 @@ THREE.OrbitControls = function ( object, domElement ) {
 
 	function handleTouchStartDollyRotate( event ) {
 
-		//console.log( 'handleTouchStartDollyRotate' );
-
 		if ( scope.enableZoom ) handleTouchStartDolly( event );
 
 		if ( scope.enableRotate ) handleTouchStartRotate( event );
@@ -681,8 +655,6 @@ THREE.OrbitControls = function ( object, domElement ) {
 
 	function handleTouchMoveRotate( event ) {
 
-		//console.log( 'handleTouchMoveRotate' );
-
 		if ( event.touches.length == 1 ) {
 
 			rotateEnd.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );
@@ -710,8 +682,6 @@ THREE.OrbitControls = function ( object, domElement ) {
 
 	function handleTouchMovePan( event ) {
 
-		//console.log( 'handleTouchMoveRotate' );
-
 		if ( event.touches.length == 1 ) {
 
 			panEnd.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );
@@ -735,8 +705,6 @@ THREE.OrbitControls = function ( object, domElement ) {
 
 	function handleTouchMoveDolly( event ) {
 
-		//console.log( 'handleTouchMoveRotate' );
-
 		var dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX;
 		var dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY;
 
@@ -754,8 +722,6 @@ THREE.OrbitControls = function ( object, domElement ) {
 
 	function handleTouchMoveDollyPan( event ) {
 
-		//console.log( 'handleTouchMoveDollyPan' );
-
 		if ( scope.enableZoom ) handleTouchMoveDolly( event );
 
 		if ( scope.enablePan ) handleTouchMovePan( event );
@@ -764,8 +730,6 @@ THREE.OrbitControls = function ( object, domElement ) {
 
 	function handleTouchMoveDollyRotate( event ) {
 
-		//console.log( 'handleTouchMoveDollyPan' );
-
 		if ( scope.enableZoom ) handleTouchMoveDolly( event );
 
 		if ( scope.enableRotate ) handleTouchMoveRotate( event );
@@ -774,7 +738,7 @@ THREE.OrbitControls = function ( object, domElement ) {
 
 	function handleTouchEnd( /*event*/ ) {
 
-		//console.log( 'handleTouchEnd' );
+		// no-op
 
 	}
 
@@ -1181,130 +1145,6 @@ THREE.OrbitControls = function ( object, domElement ) {
 THREE.OrbitControls.prototype = Object.create( THREE.EventDispatcher.prototype );
 THREE.OrbitControls.prototype.constructor = THREE.OrbitControls;
 
-Object.defineProperties( THREE.OrbitControls.prototype, {
-
-	center: {
-
-		get: function () {
-
-			console.warn( 'THREE.OrbitControls: .center has been renamed to .target' );
-			return this.target;
-
-		}
-
-	},
-
-	// backward compatibility
-
-	noZoom: {
-
-		get: function () {
-
-			console.warn( 'THREE.OrbitControls: .noZoom has been deprecated. Use .enableZoom instead.' );
-			return ! this.enableZoom;
-
-		},
-
-		set: function ( value ) {
-
-			console.warn( 'THREE.OrbitControls: .noZoom has been deprecated. Use .enableZoom instead.' );
-			this.enableZoom = ! value;
-
-		}
-
-	},
-
-	noRotate: {
-
-		get: function () {
-
-			console.warn( 'THREE.OrbitControls: .noRotate has been deprecated. Use .enableRotate instead.' );
-			return ! this.enableRotate;
-
-		},
-
-		set: function ( value ) {
-
-			console.warn( 'THREE.OrbitControls: .noRotate has been deprecated. Use .enableRotate instead.' );
-			this.enableRotate = ! value;
-
-		}
-
-	},
-
-	noPan: {
-
-		get: function () {
-
-			console.warn( 'THREE.OrbitControls: .noPan has been deprecated. Use .enablePan instead.' );
-			return ! this.enablePan;
-
-		},
-
-		set: function ( value ) {
-
-			console.warn( 'THREE.OrbitControls: .noPan has been deprecated. Use .enablePan instead.' );
-			this.enablePan = ! value;
-
-		}
-
-	},
-
-	noKeys: {
-
-		get: function () {
-
-			console.warn( 'THREE.OrbitControls: .noKeys has been deprecated. Use .enableKeys instead.' );
-			return ! this.enableKeys;
-
-		},
-
-		set: function ( value ) {
-
-			console.warn( 'THREE.OrbitControls: .noKeys has been deprecated. Use .enableKeys instead.' );
-			this.enableKeys = ! value;
-
-		}
-
-	},
-
-	staticMoving: {
-
-		get: function () {
-
-			console.warn( 'THREE.OrbitControls: .staticMoving has been deprecated. Use .enableDamping instead.' );
-			return ! this.enableDamping;
-
-		},
-
-		set: function ( value ) {
-
-			console.warn( 'THREE.OrbitControls: .staticMoving has been deprecated. Use .enableDamping instead.' );
-			this.enableDamping = ! value;
-
-		}
-
-	},
-
-	dynamicDampingFactor: {
-
-		get: function () {
-
-			console.warn( 'THREE.OrbitControls: .dynamicDampingFactor has been renamed. Use .dampingFactor instead.' );
-			return this.dampingFactor;
-
-		},
-
-		set: function ( value ) {
-
-			console.warn( 'THREE.OrbitControls: .dynamicDampingFactor has been renamed. Use .dampingFactor instead.' );
-			this.dampingFactor = value;
-
-		}
-
-	}
-
-} );
 
 // This set of controls performs orbiting, dollying (zooming), and panning.
 // Unlike TrackballControls, it maintains the "up" direction object.up (+Y by default).

+ 0 - 658
examples/js/libs/ctm.js

@@ -1,658 +0,0 @@
-/*
-Copyright (c) 2011 Juan Mellado
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-*/
-
-/*
-References:
-- "OpenCTM: The Open Compressed Triangle Mesh file format" by Marcus Geelnard
-  http://openctm.sourceforge.net/
-*/
-
-var CTM = CTM || {};
-
-// browserify support
-if ( typeof module === 'object' ) {
-
-	module.exports = CTM;
-
-}
-
-CTM.CompressionMethod = {
-  RAW: 0x00574152,
-  MG1: 0x0031474d,
-  MG2: 0x0032474d
-};
-
-CTM.Flags = {
-  NORMALS: 0x00000001
-};
-
-CTM.File = function(stream) {
-	this.load(stream);
-};
-
-CTM.File.prototype.load = function(stream) {
-	this.header = new CTM.FileHeader(stream);
-
-	this.body = new CTM.FileBody(this.header);
-
-	this.getReader().read(stream, this.body);
-};
-
-CTM.File.prototype.getReader = function() {
-	var reader;
-
-	switch (this.header.compressionMethod){
-		case CTM.CompressionMethod.RAW:
-			reader = new CTM.ReaderRAW();
-			break;
-		case CTM.CompressionMethod.MG1:
-			reader = new CTM.ReaderMG1();
-			break;
-		case CTM.CompressionMethod.MG2:
-			reader = new CTM.ReaderMG2();
-			break;
-	}
-
-	return reader;
-};
-
-CTM.FileHeader = function(stream) {
-	stream.readInt32(); //magic "OCTM"
-	this.fileFormat = stream.readInt32();
-	this.compressionMethod = stream.readInt32();
-	this.vertexCount = stream.readInt32();
-	this.triangleCount = stream.readInt32();
-	this.uvMapCount = stream.readInt32();
-	this.attrMapCount = stream.readInt32();
-	this.flags = stream.readInt32();
-	this.comment = stream.readString();
-};
-
-CTM.FileHeader.prototype.hasNormals = function() {
-	return this.flags & CTM.Flags.NORMALS;
-};
-
-CTM.FileBody = function(header) {
-	var i = header.triangleCount * 3,
-      v = header.vertexCount * 3,
-      n = header.hasNormals() ? header.vertexCount * 3 : 0,
-      u = header.vertexCount * 2,
-      a = header.vertexCount * 4,
-      j = 0;
-
-	var data = new ArrayBuffer(
-    (i + v + n + (u * header.uvMapCount) + (a * header.attrMapCount) ) * 4);
-
-	this.indices = new Uint32Array(data, 0, i);
-
-	this.vertices = new Float32Array(data, i * 4, v);
-
-	if ( header.hasNormals() ) {
-		this.normals = new Float32Array(data, (i + v) * 4, n);
-	}
-
-	if (header.uvMapCount) {
-		this.uvMaps = [];
-		for (j = 0; j < header.uvMapCount; ++ j) {
-			this.uvMaps[j] = { uv: new Float32Array(data,
-        (i + v + n + (j * u) ) * 4, u) };
-		}
-	}
-
-	if (header.attrMapCount) {
-		this.attrMaps = [];
-		for (j = 0; j < header.attrMapCount; ++ j) {
-			this.attrMaps[j] = { attr: new Float32Array(data,
-        (i + v + n + (u * header.uvMapCount) + (j * a) ) * 4, a) };
-		}
-	}
-};
-
-CTM.FileMG2Header = function(stream) {
-	stream.readInt32(); //magic "MG2H"
-	this.vertexPrecision = stream.readFloat32();
-	this.normalPrecision = stream.readFloat32();
-	this.lowerBoundx = stream.readFloat32();
-	this.lowerBoundy = stream.readFloat32();
-	this.lowerBoundz = stream.readFloat32();
-	this.higherBoundx = stream.readFloat32();
-	this.higherBoundy = stream.readFloat32();
-	this.higherBoundz = stream.readFloat32();
-	this.divx = stream.readInt32();
-	this.divy = stream.readInt32();
-	this.divz = stream.readInt32();
-
-	this.sizex = (this.higherBoundx - this.lowerBoundx) / this.divx;
-	this.sizey = (this.higherBoundy - this.lowerBoundy) / this.divy;
-	this.sizez = (this.higherBoundz - this.lowerBoundz) / this.divz;
-};
-
-CTM.ReaderRAW = function() {
-};
-
-CTM.ReaderRAW.prototype.read = function(stream, body) {
-	this.readIndices(stream, body.indices);
-	this.readVertices(stream, body.vertices);
-
-	if (body.normals) {
-		this.readNormals(stream, body.normals);
-	}
-	if (body.uvMaps) {
-		this.readUVMaps(stream, body.uvMaps);
-	}
-	if (body.attrMaps) {
-		this.readAttrMaps(stream, body.attrMaps);
-	}
-};
-
-CTM.ReaderRAW.prototype.readIndices = function(stream, indices) {
-	stream.readInt32(); //magic "INDX"
-	stream.readArrayInt32(indices);
-};
-
-CTM.ReaderRAW.prototype.readVertices = function(stream, vertices) {
-	stream.readInt32(); //magic "VERT"
-	stream.readArrayFloat32(vertices);
-};
-
-CTM.ReaderRAW.prototype.readNormals = function(stream, normals) {
-	stream.readInt32(); //magic "NORM"
-	stream.readArrayFloat32(normals);
-};
-
-CTM.ReaderRAW.prototype.readUVMaps = function(stream, uvMaps) {
-	var i = 0;
-	for (; i < uvMaps.length; ++ i) {
-		stream.readInt32(); //magic "TEXC"
-
-		uvMaps[i].name = stream.readString();
-		uvMaps[i].filename = stream.readString();
-		stream.readArrayFloat32(uvMaps[i].uv);
-	}
-};
-
-CTM.ReaderRAW.prototype.readAttrMaps = function(stream, attrMaps) {
-	var i = 0;
-	for (; i < attrMaps.length; ++ i) {
-		stream.readInt32(); //magic "ATTR"
-
-		attrMaps[i].name = stream.readString();
-		stream.readArrayFloat32(attrMaps[i].attr);
-	}
-};
-
-CTM.ReaderMG1 = function() {
-};
-
-CTM.ReaderMG1.prototype.read = function(stream, body) {
-	this.readIndices(stream, body.indices);
-	this.readVertices(stream, body.vertices);
-
-	if (body.normals) {
-		this.readNormals(stream, body.normals);
-	}
-	if (body.uvMaps) {
-		this.readUVMaps(stream, body.uvMaps);
-	}
-	if (body.attrMaps) {
-		this.readAttrMaps(stream, body.attrMaps);
-	}
-};
-
-CTM.ReaderMG1.prototype.readIndices = function(stream, indices) {
-	stream.readInt32(); //magic "INDX"
-	stream.readInt32(); //packed size
-
-	var interleaved = new CTM.InterleavedStream(indices, 3);
-	LZMA.decompress(stream, stream, interleaved, interleaved.data.length);
-
-	CTM.restoreIndices(indices, indices.length);
-};
-
-CTM.ReaderMG1.prototype.readVertices = function(stream, vertices) {
-	stream.readInt32(); //magic "VERT"
-	stream.readInt32(); //packed size
-
-	var interleaved = new CTM.InterleavedStream(vertices, 1);
-	LZMA.decompress(stream, stream, interleaved, interleaved.data.length);
-};
-
-CTM.ReaderMG1.prototype.readNormals = function(stream, normals) {
-	stream.readInt32(); //magic "NORM"
-	stream.readInt32(); //packed size
-
-	var interleaved = new CTM.InterleavedStream(normals, 3);
-	LZMA.decompress(stream, stream, interleaved, interleaved.data.length);
-};
-
-CTM.ReaderMG1.prototype.readUVMaps = function(stream, uvMaps) {
-	var i = 0;
-	for (; i < uvMaps.length; ++ i) {
-		stream.readInt32(); //magic "TEXC"
-
-		uvMaps[i].name = stream.readString();
-		uvMaps[i].filename = stream.readString();
-
-		stream.readInt32(); //packed size
-
-		var interleaved = new CTM.InterleavedStream(uvMaps[i].uv, 2);
-		LZMA.decompress(stream, stream, interleaved, interleaved.data.length);
-	}
-};
-
-CTM.ReaderMG1.prototype.readAttrMaps = function(stream, attrMaps) {
-	var i = 0;
-	for (; i < attrMaps.length; ++ i) {
-		stream.readInt32(); //magic "ATTR"
-
-		attrMaps[i].name = stream.readString();
-
-		stream.readInt32(); //packed size
-
-		var interleaved = new CTM.InterleavedStream(attrMaps[i].attr, 4);
-		LZMA.decompress(stream, stream, interleaved, interleaved.data.length);
-	}
-};
-
-CTM.ReaderMG2 = function() {
-};
-
-CTM.ReaderMG2.prototype.read = function(stream, body) {
-	this.MG2Header = new CTM.FileMG2Header(stream);
-
-	this.readVertices(stream, body.vertices);
-	this.readIndices(stream, body.indices);
-
-	if (body.normals) {
-		this.readNormals(stream, body);
-	}
-	if (body.uvMaps) {
-		this.readUVMaps(stream, body.uvMaps);
-	}
-	if (body.attrMaps) {
-		this.readAttrMaps(stream, body.attrMaps);
-	}
-};
-
-CTM.ReaderMG2.prototype.readVertices = function(stream, vertices) {
-	stream.readInt32(); //magic "VERT"
-	stream.readInt32(); //packed size
-
-	var interleaved = new CTM.InterleavedStream(vertices, 3);
-	LZMA.decompress(stream, stream, interleaved, interleaved.data.length);
-
-	var gridIndices = this.readGridIndices(stream, vertices);
-
-	CTM.restoreVertices(vertices, this.MG2Header, gridIndices, this.MG2Header.vertexPrecision);
-};
-
-CTM.ReaderMG2.prototype.readGridIndices = function(stream, vertices) {
-	stream.readInt32(); //magic "GIDX"
-	stream.readInt32(); //packed size
-
-	var gridIndices = new Uint32Array(vertices.length / 3);
-
-	var interleaved = new CTM.InterleavedStream(gridIndices, 1);
-	LZMA.decompress(stream, stream, interleaved, interleaved.data.length);
-
-	CTM.restoreGridIndices(gridIndices, gridIndices.length);
-
-	return gridIndices;
-};
-
-CTM.ReaderMG2.prototype.readIndices = function(stream, indices) {
-	stream.readInt32(); //magic "INDX"
-	stream.readInt32(); //packed size
-
-	var interleaved = new CTM.InterleavedStream(indices, 3);
-	LZMA.decompress(stream, stream, interleaved, interleaved.data.length);
-
-	CTM.restoreIndices(indices, indices.length);
-};
-
-CTM.ReaderMG2.prototype.readNormals = function(stream, body) {
-	stream.readInt32(); //magic "NORM"
-	stream.readInt32(); //packed size
-
-	var interleaved = new CTM.InterleavedStream(body.normals, 3);
-	LZMA.decompress(stream, stream, interleaved, interleaved.data.length);
-
-	var smooth = CTM.calcSmoothNormals(body.indices, body.vertices);
-
-	CTM.restoreNormals(body.normals, smooth, this.MG2Header.normalPrecision);
-};
-
-CTM.ReaderMG2.prototype.readUVMaps = function(stream, uvMaps) {
-	var i = 0;
-	for (; i < uvMaps.length; ++ i) {
-		stream.readInt32(); //magic "TEXC"
-
-		uvMaps[i].name = stream.readString();
-		uvMaps[i].filename = stream.readString();
-
-		var precision = stream.readFloat32();
-
-		stream.readInt32(); //packed size
-
-		var interleaved = new CTM.InterleavedStream(uvMaps[i].uv, 2);
-		LZMA.decompress(stream, stream, interleaved, interleaved.data.length);
-
-		CTM.restoreMap(uvMaps[i].uv, 2, precision);
-	}
-};
-
-CTM.ReaderMG2.prototype.readAttrMaps = function(stream, attrMaps) {
-	var i = 0;
-	for (; i < attrMaps.length; ++ i) {
-		stream.readInt32(); //magic "ATTR"
-
-		attrMaps[i].name = stream.readString();
-
-		var precision = stream.readFloat32();
-
-		stream.readInt32(); //packed size
-
-		var interleaved = new CTM.InterleavedStream(attrMaps[i].attr, 4);
-		LZMA.decompress(stream, stream, interleaved, interleaved.data.length);
-
-		CTM.restoreMap(attrMaps[i].attr, 4, precision);
-	}
-};
-
-CTM.restoreIndices = function(indices, len) {
-	var i = 3;
-	if (len > 0) {
-		indices[2] += indices[0];
-		indices[1] += indices[0];
-	}
-	for (; i < len; i += 3) {
-		indices[i] += indices[i - 3];
-
-		if (indices[i] === indices[i - 3]) {
-			indices[i + 1] += indices[i - 2];
-		}else {
-			indices[i + 1] += indices[i];
-		}
-
-		indices[i + 2] += indices[i];
-	}
-};
-
-CTM.restoreGridIndices = function(gridIndices, len) {
-	var i = 1;
-	for (; i < len; ++ i) {
-		gridIndices[i] += gridIndices[i - 1];
-	}
-};
-
-CTM.restoreVertices = function(vertices, grid, gridIndices, precision) {
-	var gridIdx, delta, x, y, z,
-      intVertices = new Uint32Array(vertices.buffer, vertices.byteOffset, vertices.length),
-      ydiv = grid.divx, zdiv = ydiv * grid.divy,
-      prevGridIdx = 0x7fffffff, prevDelta = 0,
-      i = 0, j = 0, len = gridIndices.length;
-
-	for (; i < len; j += 3) {
-		x = gridIdx = gridIndices[i ++];
-
-		z = ~~(x / zdiv);
-		x -= ~~(z * zdiv);
-		y = ~~(x / ydiv);
-		x -= ~~(y * ydiv);
-
-		delta = intVertices[j];
-		if (gridIdx === prevGridIdx) {
-			delta += prevDelta;
-		}
-
-		vertices[j]     = grid.lowerBoundx +
-      x * grid.sizex + precision * delta;
-		vertices[j + 1] = grid.lowerBoundy +
-      y * grid.sizey + precision * intVertices[j + 1];
-		vertices[j + 2] = grid.lowerBoundz +
-      z * grid.sizez + precision * intVertices[j + 2];
-
-		prevGridIdx = gridIdx;
-		prevDelta = delta;
-	}
-};
-
-CTM.restoreNormals = function(normals, smooth, precision) {
-	var ro, phi, theta, sinPhi,
-      nx, ny, nz, by, bz, len,
-      intNormals = new Uint32Array(normals.buffer, normals.byteOffset, normals.length),
-      i = 0, k = normals.length,
-      PI_DIV_2 = 3.141592653589793238462643 * 0.5;
-
-	for (; i < k; i += 3) {
-		ro = intNormals[i] * precision;
-		phi = intNormals[i + 1];
-
-		if (phi === 0) {
-			normals[i]     = smooth[i]     * ro;
-			normals[i + 1] = smooth[i + 1] * ro;
-			normals[i + 2] = smooth[i + 2] * ro;
-		}else {
-
-			if (phi <= 4) {
-				theta = (intNormals[i + 2] - 2) * PI_DIV_2;
-			}else {
-				theta = ( (intNormals[i + 2] * 4 / phi) - 2) * PI_DIV_2;
-			}
-
-			phi *= precision * PI_DIV_2;
-			sinPhi = ro * Math.sin(phi);
-
-			nx = sinPhi * Math.cos(theta);
-			ny = sinPhi * Math.sin(theta);
-			nz = ro * Math.cos(phi);
-
-			bz = smooth[i + 1];
-			by = smooth[i] - smooth[i + 2];
-
-			len = Math.sqrt(2 * bz * bz + by * by);
-			if (len > 1e-20) {
-				by /= len;
-				bz /= len;
-			}
-
-			normals[i] = smooth[i] * nz + (smooth[i + 1] * bz - smooth[i + 2] * by) * ny - bz * nx;
-			normals[i + 1] = smooth[i + 1] * nz - (smooth[i + 2] + smooth[i]) * bz  * ny + by * nx;
-			normals[i + 2] = smooth[i + 2] * nz + (smooth[i] * by + smooth[i + 1] * bz) * ny + bz * nx;
-		}
-	}
-};
-
-CTM.restoreMap = function(map, count, precision) {
-	var delta, value,
-      intMap = new Uint32Array(map.buffer, map.byteOffset, map.length),
-      i = 0, j, len = map.length;
-
-	for (; i < count; ++ i) {
-		delta = 0;
-
-		for (j = i; j < len; j += count) {
-			value = intMap[j];
-
-			delta += value & 1 ? -( (value + 1) >> 1) : value >> 1;
-
-			map[j] = delta * precision;
-		}
-	}
-};
-
-CTM.calcSmoothNormals = function(indices, vertices) {
-	var smooth = new Float32Array(vertices.length),
-      indx, indy, indz, nx, ny, nz,
-      v1x, v1y, v1z, v2x, v2y, v2z, len,
-      i, k;
-
-	for (i = 0, k = indices.length; i < k;) {
-		indx = indices[i ++] * 3;
-		indy = indices[i ++] * 3;
-		indz = indices[i ++] * 3;
-
-		v1x = vertices[indy]     - vertices[indx];
-		v2x = vertices[indz]     - vertices[indx];
-		v1y = vertices[indy + 1] - vertices[indx + 1];
-		v2y = vertices[indz + 1] - vertices[indx + 1];
-		v1z = vertices[indy + 2] - vertices[indx + 2];
-		v2z = vertices[indz + 2] - vertices[indx + 2];
-
-		nx = v1y * v2z - v1z * v2y;
-		ny = v1z * v2x - v1x * v2z;
-		nz = v1x * v2y - v1y * v2x;
-
-		len = Math.sqrt(nx * nx + ny * ny + nz * nz);
-		if (len > 1e-10) {
-			nx /= len;
-			ny /= len;
-			nz /= len;
-		}
-
-		smooth[indx]     += nx;
-		smooth[indx + 1] += ny;
-		smooth[indx + 2] += nz;
-		smooth[indy]     += nx;
-		smooth[indy + 1] += ny;
-		smooth[indy + 2] += nz;
-		smooth[indz]     += nx;
-		smooth[indz + 1] += ny;
-		smooth[indz + 2] += nz;
-	}
-
-	for (i = 0, k = smooth.length; i < k; i += 3) {
-		len = Math.sqrt(smooth[i] * smooth[i] +
-      smooth[i + 1] * smooth[i + 1] +
-      smooth[i + 2] * smooth[i + 2]);
-
-		if (len > 1e-10) {
-			smooth[i]     /= len;
-			smooth[i + 1] /= len;
-			smooth[i + 2] /= len;
-		}
-	}
-
-	return smooth;
-};
-
-CTM.isLittleEndian = (function() {
-	var buffer = new ArrayBuffer(2),
-      bytes = new Uint8Array(buffer),
-      ints = new Uint16Array(buffer);
-
-	bytes[0] = 1;
-
-	return ints[0] === 1;
-}());
-
-CTM.InterleavedStream = function(data, count) {
-	this.data = new Uint8Array(data.buffer, data.byteOffset, data.byteLength);
-	this.offset = CTM.isLittleEndian ? 3 : 0;
-	this.count = count * 4;
-	this.len = this.data.length;
-};
-
-CTM.InterleavedStream.prototype.writeByte = function(value) {
-	this.data[this.offset] = value;
-
-	this.offset += this.count;
-	if (this.offset >= this.len) {
-
-		this.offset -= this.len - 4;
-		if (this.offset >= this.count) {
-
-			this.offset -= this.count + (CTM.isLittleEndian ? 1 : -1);
-		}
-	}
-};
-
-CTM.Stream = function(data) {
-	this.data = data;
-	this.offset = 0;
-};
-
-CTM.Stream.prototype.TWO_POW_MINUS23 = Math.pow(2, -23);
-
-CTM.Stream.prototype.TWO_POW_MINUS126 = Math.pow(2, -126);
-
-CTM.Stream.prototype.readByte = function() {
-	return this.data[this.offset ++] & 0xff;
-};
-
-CTM.Stream.prototype.readInt32 = function() {
-	var i = this.readByte();
-	i |= this.readByte() << 8;
-	i |= this.readByte() << 16;
-	return i | (this.readByte() << 24);
-};
-
-CTM.Stream.prototype.readFloat32 = function() {
-	var m = this.readByte();
-	m += this.readByte() << 8;
-
-	var b1 = this.readByte();
-	var b2 = this.readByte();
-
-	m += (b1 & 0x7f) << 16;
-	var e = ( (b2 & 0x7f) << 1) | ( (b1 & 0x80) >>> 7);
-	var s = b2 & 0x80 ? -1 : 1;
-
-	if (e === 255) {
-		return m !== 0 ? NaN : s * Infinity;
-	}
-	if (e > 0) {
-		return s * (1 + (m * this.TWO_POW_MINUS23) ) * Math.pow(2, e - 127);
-	}
-	if (m !== 0) {
-		return s * m * this.TWO_POW_MINUS126;
-	}
-	return s * 0;
-};
-
-CTM.Stream.prototype.readString = function() {
-	var len = this.readInt32();
-
-	this.offset += len;
-
-	return String.fromCharCode.apply(null, this.data.subarray(this.offset - len, this.offset));
-};
-
-CTM.Stream.prototype.readArrayInt32 = function(array) {
-	var i = 0, len = array.length;
-
-	while (i < len) {
-		array[i ++] = this.readInt32();
-	}
-
-	return array;
-};
-
-CTM.Stream.prototype.readArrayFloat32 = function(array) {
-	var i = 0, len = array.length;
-
-	while (i < len) {
-		array[i ++] = this.readFloat32();
-	}
-
-	return array;
-};

+ 0 - 517
examples/js/libs/lzma.js

@@ -1,517 +0,0 @@
-
-var LZMA = LZMA || {};
-
-// browserify support
-if ( typeof module === 'object' ) {
-
-	module.exports = LZMA;
-
-}
-
-LZMA.OutWindow = function() {
-	this._windowSize = 0;
-};
-
-LZMA.OutWindow.prototype.create = function(windowSize) {
-	if ( (!this._buffer) || (this._windowSize !== windowSize) ) {
-		this._buffer = [];
-	}
-	this._windowSize = windowSize;
-	this._pos = 0;
-	this._streamPos = 0;
-};
-
-LZMA.OutWindow.prototype.flush = function() {
-	var size = this._pos - this._streamPos;
-	if (size !== 0) {
-		while (size --) {
-			this._stream.writeByte(this._buffer[this._streamPos ++]);
-		}
-		if (this._pos >= this._windowSize) {
-			this._pos = 0;
-		}
-		this._streamPos = this._pos;
-	}
-};
-
-LZMA.OutWindow.prototype.releaseStream = function() {
-	this.flush();
-	this._stream = null;
-};
-
-LZMA.OutWindow.prototype.setStream = function(stream) {
-	this.releaseStream();
-	this._stream = stream;
-};
-
-LZMA.OutWindow.prototype.init = function(solid) {
-	if (!solid) {
-		this._streamPos = 0;
-		this._pos = 0;
-	}
-};
-
-LZMA.OutWindow.prototype.copyBlock = function(distance, len) {
-	var pos = this._pos - distance - 1;
-	if (pos < 0) {
-		pos += this._windowSize;
-	}
-	while (len --) {
-		if (pos >= this._windowSize) {
-			pos = 0;
-		}
-		this._buffer[this._pos ++] = this._buffer[pos ++];
-		if (this._pos >= this._windowSize) {
-			this.flush();
-		}
-	}
-};
-
-LZMA.OutWindow.prototype.putByte = function(b) {
-	this._buffer[this._pos ++] = b;
-	if (this._pos >= this._windowSize) {
-		this.flush();
-	}
-};
-
-LZMA.OutWindow.prototype.getByte = function(distance) {
-	var pos = this._pos - distance - 1;
-	if (pos < 0) {
-		pos += this._windowSize;
-	}
-	return this._buffer[pos];
-};
-
-LZMA.RangeDecoder = function() {
-};
-
-LZMA.RangeDecoder.prototype.setStream = function(stream) {
-	this._stream = stream;
-};
-
-LZMA.RangeDecoder.prototype.releaseStream = function() {
-	this._stream = null;
-};
-
-LZMA.RangeDecoder.prototype.init = function() {
-	var i = 5;
-
-	this._code = 0;
-	this._range = -1;
-
-	while (i --) {
-		this._code = (this._code << 8) | this._stream.readByte();
-	}
-};
-
-LZMA.RangeDecoder.prototype.decodeDirectBits = function(numTotalBits) {
-	var result = 0, i = numTotalBits, t;
-
-	while (i --) {
-		this._range >>>= 1;
-		t = (this._code - this._range) >>> 31;
-		this._code -= this._range & (t - 1);
-		result = (result << 1) | (1 - t);
-
-		if ( (this._range & 0xff000000) === 0) {
-			this._code = (this._code << 8) | this._stream.readByte();
-			this._range <<= 8;
-		}
-	}
-
-	return result;
-};
-
-LZMA.RangeDecoder.prototype.decodeBit = function(probs, index) {
-	var prob = probs[index],
-      newBound = (this._range >>> 11) * prob;
-
-	if ( (this._code ^ 0x80000000) < (newBound ^ 0x80000000) ) {
-		this._range = newBound;
-		probs[index] += (2048 - prob) >>> 5;
-		if ( (this._range & 0xff000000) === 0) {
-			this._code = (this._code << 8) | this._stream.readByte();
-			this._range <<= 8;
-		}
-		return 0;
-	}
-
-	this._range -= newBound;
-	this._code -= newBound;
-	probs[index] -= prob >>> 5;
-	if ( (this._range & 0xff000000) === 0) {
-		this._code = (this._code << 8) | this._stream.readByte();
-		this._range <<= 8;
-	}
-	return 1;
-};
-
-LZMA.initBitModels = function(probs, len) {
-	while (len --) {
-		probs[len] = 1024;
-	}
-};
-
-LZMA.BitTreeDecoder = function(numBitLevels) {
-	this._models = [];
-	this._numBitLevels = numBitLevels;
-};
-
-LZMA.BitTreeDecoder.prototype.init = function() {
-	LZMA.initBitModels(this._models, 1 << this._numBitLevels);
-};
-
-LZMA.BitTreeDecoder.prototype.decode = function(rangeDecoder) {
-	var m = 1, i = this._numBitLevels;
-
-	while (i --) {
-		m = (m << 1) | rangeDecoder.decodeBit(this._models, m);
-	}
-	return m - (1 << this._numBitLevels);
-};
-
-LZMA.BitTreeDecoder.prototype.reverseDecode = function(rangeDecoder) {
-	var m = 1, symbol = 0, i = 0, bit;
-
-	for (; i < this._numBitLevels; ++ i) {
-		bit = rangeDecoder.decodeBit(this._models, m);
-		m = (m << 1) | bit;
-		symbol |= bit << i;
-	}
-	return symbol;
-};
-
-LZMA.reverseDecode2 = function(models, startIndex, rangeDecoder, numBitLevels) {
-	var m = 1, symbol = 0, i = 0, bit;
-
-	for (; i < numBitLevels; ++ i) {
-		bit = rangeDecoder.decodeBit(models, startIndex + m);
-		m = (m << 1) | bit;
-		symbol |= bit << i;
-	}
-	return symbol;
-};
-
-LZMA.LenDecoder = function() {
-	this._choice = [];
-	this._lowCoder = [];
-	this._midCoder = [];
-	this._highCoder = new LZMA.BitTreeDecoder(8);
-	this._numPosStates = 0;
-};
-
-LZMA.LenDecoder.prototype.create = function(numPosStates) {
-	for (; this._numPosStates < numPosStates; ++ this._numPosStates) {
-		this._lowCoder[this._numPosStates] = new LZMA.BitTreeDecoder(3);
-		this._midCoder[this._numPosStates] = new LZMA.BitTreeDecoder(3);
-	}
-};
-
-LZMA.LenDecoder.prototype.init = function() {
-	var i = this._numPosStates;
-	LZMA.initBitModels(this._choice, 2);
-	while (i --) {
-		this._lowCoder[i].init();
-		this._midCoder[i].init();
-	}
-	this._highCoder.init();
-};
-
-LZMA.LenDecoder.prototype.decode = function(rangeDecoder, posState) {
-	if (rangeDecoder.decodeBit(this._choice, 0) === 0) {
-		return this._lowCoder[posState].decode(rangeDecoder);
-	}
-	if (rangeDecoder.decodeBit(this._choice, 1) === 0) {
-		return 8 + this._midCoder[posState].decode(rangeDecoder);
-	}
-	return 16 + this._highCoder.decode(rangeDecoder);
-};
-
-LZMA.Decoder2 = function() {
-	this._decoders = [];
-};
-
-LZMA.Decoder2.prototype.init = function() {
-	LZMA.initBitModels(this._decoders, 0x300);
-};
-
-LZMA.Decoder2.prototype.decodeNormal = function(rangeDecoder) {
-	var symbol = 1;
-
-	do {
-		symbol = (symbol << 1) | rangeDecoder.decodeBit(this._decoders, symbol);
-	}while (symbol < 0x100);
-
-	return symbol & 0xff;
-};
-
-LZMA.Decoder2.prototype.decodeWithMatchByte = function(rangeDecoder, matchByte) {
-	var symbol = 1, matchBit, bit;
-
-	do {
-		matchBit = (matchByte >> 7) & 1;
-		matchByte <<= 1;
-		bit = rangeDecoder.decodeBit(this._decoders, ( (1 + matchBit) << 8) + symbol);
-		symbol = (symbol << 1) | bit;
-		if (matchBit !== bit) {
-			while (symbol < 0x100) {
-				symbol = (symbol << 1) | rangeDecoder.decodeBit(this._decoders, symbol);
-			}
-			break;
-		}
-	}while (symbol < 0x100);
-
-	return symbol & 0xff;
-};
-
-LZMA.LiteralDecoder = function() {
-};
-
-LZMA.LiteralDecoder.prototype.create = function(numPosBits, numPrevBits) {
-	var i;
-
-	if (this._coders
-    && (this._numPrevBits === numPrevBits)
-    && (this._numPosBits === numPosBits) ) {
-		return;
-	}
-	this._numPosBits = numPosBits;
-	this._posMask = (1 << numPosBits) - 1;
-	this._numPrevBits = numPrevBits;
-
-	this._coders = [];
-
-	i = 1 << (this._numPrevBits + this._numPosBits);
-	while (i --) {
-		this._coders[i] = new LZMA.Decoder2();
-	}
-};
-
-LZMA.LiteralDecoder.prototype.init = function() {
-	var i = 1 << (this._numPrevBits + this._numPosBits);
-	while (i --) {
-		this._coders[i].init();
-	}
-};
-
-LZMA.LiteralDecoder.prototype.getDecoder = function(pos, prevByte) {
-	return this._coders[( (pos & this._posMask) << this._numPrevBits)
-    + ( (prevByte & 0xff) >>> (8 - this._numPrevBits) )];
-};
-
-LZMA.Decoder = function() {
-	this._outWindow = new LZMA.OutWindow();
-	this._rangeDecoder = new LZMA.RangeDecoder();
-	this._isMatchDecoders = [];
-	this._isRepDecoders = [];
-	this._isRepG0Decoders = [];
-	this._isRepG1Decoders = [];
-	this._isRepG2Decoders = [];
-	this._isRep0LongDecoders = [];
-	this._posSlotDecoder = [];
-	this._posDecoders = [];
-	this._posAlignDecoder = new LZMA.BitTreeDecoder(4);
-	this._lenDecoder = new LZMA.LenDecoder();
-	this._repLenDecoder = new LZMA.LenDecoder();
-	this._literalDecoder = new LZMA.LiteralDecoder();
-	this._dictionarySize = -1;
-	this._dictionarySizeCheck = -1;
-
-	this._posSlotDecoder[0] = new LZMA.BitTreeDecoder(6);
-	this._posSlotDecoder[1] = new LZMA.BitTreeDecoder(6);
-	this._posSlotDecoder[2] = new LZMA.BitTreeDecoder(6);
-	this._posSlotDecoder[3] = new LZMA.BitTreeDecoder(6);
-};
-
-LZMA.Decoder.prototype.setDictionarySize = function(dictionarySize) {
-	if (dictionarySize < 0) {
-		return false;
-	}
-	if (this._dictionarySize !== dictionarySize) {
-		this._dictionarySize = dictionarySize;
-		this._dictionarySizeCheck = Math.max(this._dictionarySize, 1);
-		this._outWindow.create( Math.max(this._dictionarySizeCheck, 4096) );
-	}
-	return true;
-};
-
-LZMA.Decoder.prototype.setLcLpPb = function(lc, lp, pb) {
-	var numPosStates = 1 << pb;
-
-	if (lc > 8 || lp > 4 || pb > 4) {
-		return false;
-	}
-
-	this._literalDecoder.create(lp, lc);
-
-	this._lenDecoder.create(numPosStates);
-	this._repLenDecoder.create(numPosStates);
-	this._posStateMask = numPosStates - 1;
-
-	return true;
-};
-
-LZMA.Decoder.prototype.init = function() {
-	var i = 4;
-
-	this._outWindow.init(false);
-
-	LZMA.initBitModels(this._isMatchDecoders, 192);
-	LZMA.initBitModels(this._isRep0LongDecoders, 192);
-	LZMA.initBitModels(this._isRepDecoders, 12);
-	LZMA.initBitModels(this._isRepG0Decoders, 12);
-	LZMA.initBitModels(this._isRepG1Decoders, 12);
-	LZMA.initBitModels(this._isRepG2Decoders, 12);
-	LZMA.initBitModels(this._posDecoders, 114);
-
-	this._literalDecoder.init();
-
-	while (i --) {
-		this._posSlotDecoder[i].init();
-	}
-
-	this._lenDecoder.init();
-	this._repLenDecoder.init();
-	this._posAlignDecoder.init();
-	this._rangeDecoder.init();
-};
-
-LZMA.Decoder.prototype.decode = function(inStream, outStream, outSize) {
-	var state = 0, rep0 = 0, rep1 = 0, rep2 = 0, rep3 = 0, nowPos64 = 0, prevByte = 0,
-      posState, decoder2, len, distance, posSlot, numDirectBits;
-
-	this._rangeDecoder.setStream(inStream);
-	this._outWindow.setStream(outStream);
-
-	this.init();
-
-	while (outSize < 0 || nowPos64 < outSize) {
-		posState = nowPos64 & this._posStateMask;
-
-		if (this._rangeDecoder.decodeBit(this._isMatchDecoders, (state << 4) + posState) === 0) {
-			decoder2 = this._literalDecoder.getDecoder(nowPos64 ++, prevByte);
-
-			if (state >= 7) {
-				prevByte = decoder2.decodeWithMatchByte(this._rangeDecoder, this._outWindow.getByte(rep0) );
-			}else {
-				prevByte = decoder2.decodeNormal(this._rangeDecoder);
-			}
-			this._outWindow.putByte(prevByte);
-
-			state = state < 4 ? 0 : state - (state < 10 ? 3 : 6);
-
-		}else {
-
-			if (this._rangeDecoder.decodeBit(this._isRepDecoders, state) === 1) {
-				len = 0;
-				if (this._rangeDecoder.decodeBit(this._isRepG0Decoders, state) === 0) {
-					if (this._rangeDecoder.decodeBit(this._isRep0LongDecoders, (state << 4) + posState) === 0) {
-						state = state < 7 ? 9 : 11;
-						len = 1;
-					}
-				}else {
-					if (this._rangeDecoder.decodeBit(this._isRepG1Decoders, state) === 0) {
-						distance = rep1;
-					}else {
-						if (this._rangeDecoder.decodeBit(this._isRepG2Decoders, state) === 0) {
-							distance = rep2;
-						}else {
-							distance = rep3;
-							rep3 = rep2;
-						}
-						rep2 = rep1;
-					}
-					rep1 = rep0;
-					rep0 = distance;
-				}
-				if (len === 0) {
-					len = 2 + this._repLenDecoder.decode(this._rangeDecoder, posState);
-					state = state < 7 ? 8 : 11;
-				}
-			}else {
-				rep3 = rep2;
-				rep2 = rep1;
-				rep1 = rep0;
-
-				len = 2 + this._lenDecoder.decode(this._rangeDecoder, posState);
-				state = state < 7 ? 7 : 10;
-
-				posSlot = this._posSlotDecoder[len <= 5 ? len - 2 : 3].decode(this._rangeDecoder);
-				if (posSlot >= 4) {
-
-					numDirectBits = (posSlot >> 1) - 1;
-					rep0 = (2 | (posSlot & 1) ) << numDirectBits;
-
-					if (posSlot < 14) {
-						rep0 += LZMA.reverseDecode2(this._posDecoders,
-                rep0 - posSlot - 1, this._rangeDecoder, numDirectBits);
-					}else {
-						rep0 += this._rangeDecoder.decodeDirectBits(numDirectBits - 4) << 4;
-						rep0 += this._posAlignDecoder.reverseDecode(this._rangeDecoder);
-						if (rep0 < 0) {
-							if (rep0 === -1) {
-								break;
-							}
-							return false;
-						}
-					}
-				}else {
-					rep0 = posSlot;
-				}
-			}
-
-			if (rep0 >= nowPos64 || rep0 >= this._dictionarySizeCheck) {
-				return false;
-			}
-
-			this._outWindow.copyBlock(rep0, len);
-			nowPos64 += len;
-			prevByte = this._outWindow.getByte(0);
-		}
-	}
-
-	this._outWindow.flush();
-	this._outWindow.releaseStream();
-	this._rangeDecoder.releaseStream();
-
-	return true;
-};
-
-LZMA.Decoder.prototype.setDecoderProperties = function(properties) {
-	var value, lc, lp, pb, dictionarySize;
-
-	if (properties.size < 5) {
-		return false;
-	}
-
-	value = properties.readByte();
-	lc = value % 9;
-	value = ~~(value / 9);
-	lp = value % 5;
-	pb = ~~(value / 5);
-
-	if ( !this.setLcLpPb(lc, lp, pb) ) {
-		return false;
-	}
-
-	dictionarySize = properties.readByte();
-	dictionarySize |= properties.readByte() << 8;
-	dictionarySize |= properties.readByte() << 16;
-	dictionarySize += properties.readByte() * 16777216;
-
-	return this.setDictionarySize(dictionarySize);
-};
-
-LZMA.decompress = function(properties, inStream, outStream, outSize) {
-	var decoder = new LZMA.Decoder();
-
-	if ( !decoder.setDecoderProperties(properties) ) {
-		throw "Incorrect stream properties";
-	}
-
-	if ( !decoder.decode(inStream, outStream, outSize) ) {
-		throw "Error in data stream";
-	}
-
-	return true;
-};

+ 1 - 0
examples/js/loaders/GLTFLoader.js

@@ -2140,6 +2140,7 @@ THREE.GLTFLoader = ( function () {
 				pointsMaterial.color.copy( material.color );
 				pointsMaterial.map = material.map;
 				pointsMaterial.lights = false; // PointsMaterial doesn't support lights yet
+				pointsMaterial.sizeAttenuation = false; // glTF spec says points should be 1px
 
 				this.cache.add( cacheKey, pointsMaterial );
 

+ 18 - 12
examples/js/loaders/STLLoader.js

@@ -3,6 +3,7 @@
  * @author mrdoob / http://mrdoob.com/
  * @author gero3 / https://github.com/gero3
  * @author Mugen87 / https://github.com/Mugen87
+ * @author neverhood311 / https://github.com/neverhood311
  *
  * Description: A THREE loader for STL ASCII files, as created by Solidworks and other CAD programs.
  *
@@ -148,7 +149,7 @@ THREE.STLLoader.prototype = {
 					( reader.getUint8( index + 5 ) == 0x3D /*'='*/ ) ) {
 
 					hasColors = true;
-					colors = [];
+					colors = new Float32Array( faces * 3 * 3 );
 
 					defaultR = reader.getUint8( index + 6 ) / 255;
 					defaultG = reader.getUint8( index + 7 ) / 255;
@@ -164,8 +165,8 @@ THREE.STLLoader.prototype = {
 
 			var geometry = new THREE.BufferGeometry();
 
-			var vertices = [];
-			var normals = [];
+			var vertices = new Float32Array( faces * 3 * 3 );
+			var normals = new Float32Array( faces * 3 * 3 );
 
 			for ( var face = 0; face < faces; face ++ ) {
 
@@ -199,16 +200,21 @@ THREE.STLLoader.prototype = {
 				for ( var i = 1; i <= 3; i ++ ) {
 
 					var vertexstart = start + i * 12;
+					var componentIdx = ( face * 3 * 3 ) + ( ( i - 1 ) * 3 );
+					
+					vertices[ componentIdx ] = reader.getFloat32( vertexstart, true );
+					vertices[ componentIdx + 1 ] = reader.getFloat32( vertexstart + 4, true );
+					vertices[ componentIdx + 2 ] = reader.getFloat32( vertexstart + 8, true );
 
-					vertices.push( reader.getFloat32( vertexstart, true ) );
-					vertices.push( reader.getFloat32( vertexstart + 4, true ) );
-					vertices.push( reader.getFloat32( vertexstart + 8, true ) );
-
-					normals.push( normalX, normalY, normalZ );
+					normals[ componentIdx ] = normalX;
+					normals[ componentIdx + 1 ] = normalY;
+					normals[ componentIdx + 2 ] = normalZ;
 
 					if ( hasColors ) {
 
-						colors.push( r, g, b );
+						colors[ componentIdx ] = r;
+						colors[ componentIdx + 1 ] = g;
+						colors[ componentIdx + 2 ] = b;
 
 					}
 
@@ -216,12 +222,12 @@ THREE.STLLoader.prototype = {
 
 			}
 
-			geometry.addAttribute( 'position', new THREE.BufferAttribute( new Float32Array( vertices ), 3 ) );
-			geometry.addAttribute( 'normal', new THREE.BufferAttribute( new Float32Array( normals ), 3 ) );
+			geometry.addAttribute( 'position', new THREE.BufferAttribute( vertices, 3 ) );
+			geometry.addAttribute( 'normal', new THREE.BufferAttribute( normals, 3 ) );
 
 			if ( hasColors ) {
 
-				geometry.addAttribute( 'color', new THREE.BufferAttribute( new Float32Array( colors ), 3 ) );
+				geometry.addAttribute( 'color', new THREE.BufferAttribute( colors, 3 ) );
 				geometry.hasColors = true;
 				geometry.alpha = alpha;
 

+ 0 - 279
examples/js/loaders/ctm/CTMLoader.js

@@ -1,279 +0,0 @@
-/**
- * Loader for CTM encoded models generated by OpenCTM tools:
- *	http://openctm.sourceforge.net/
- *
- * Uses js-openctm library by Juan Mellado
- *	http://code.google.com/p/js-openctm/
- *
- * @author alteredq / http://alteredqualia.com/
- *
- * OpenCTM LICENSE:
- *
- * Copyright (c) 2009-2010 Marcus Geelnard
- *
- * This software is provided 'as-is', without any express or implied
- * warranty. In no event will the authors be held liable for any damages
- * arising from the use of this software.
- *
- * Permission is granted to anyone to use this software for any purpose,
- * including commercial applications, and to alter it and redistribute it
- * freely, subject to the following restrictions:
- *
- *     1. The origin of this software must not be misrepresented; you must not
- *    claim that you wrote the original software. If you use this software
- *    in a product, an acknowledgment in the product documentation would be
- *    appreciated but is not required.
- *
- *    2. Altered source versions must be plainly marked as such, and must not
- *    be misrepresented as being the original software.
- *
- *    3. This notice may not be removed or altered from any source
- *    distribution.
- *
- */
-
-/* global CTM */
-
-THREE.CTMLoader = function () {
-
-	this.workerPath = null;
-
-};
-
-THREE.CTMLoader.prototype.constructor = THREE.CTMLoader;
-
-THREE.CTMLoader.prototype.setWorkerPath = function ( workerPath ) {
-
-	this.workerPath = workerPath;
-
-};
-
-// Load multiple CTM parts defined in JSON
-
-THREE.CTMLoader.prototype.loadParts = function ( url, callback, parameters ) {
-
-	parameters = parameters || {};
-
-	var scope = this;
-
-	var xhr = new XMLHttpRequest();
-
-	var basePath = parameters.basePath ? parameters.basePath : THREE.LoaderUtils.extractUrlBase( url );
-
-	xhr.onreadystatechange = function () {
-
-		if ( xhr.readyState === 4 ) {
-
-			if ( xhr.status === 200 || xhr.status === 0 ) {
-
-				var jsonObject = JSON.parse( xhr.responseText );
-
-				var materials = [], geometries = [], counter = 0;
-
-				function callbackFinal( geometry ) {
-
-					counter += 1;
-
-					geometries.push( geometry );
-
-					if ( counter === jsonObject.offsets.length ) {
-
-						callback( geometries, materials );
-
-					}
-
-				}
-
-
-				// init materials
-
-				for ( var i = 0; i < jsonObject.materials.length; i ++ ) {
-
-					materials[ i ] = THREE.Loader.prototype.createMaterial( jsonObject.materials[ i ], basePath );
-
-				}
-
-				// load joined CTM file
-
-				var partUrl = basePath + jsonObject.data;
-				var parametersPart = { useWorker: parameters.useWorker, worker: parameters.worker, offsets: jsonObject.offsets };
-				scope.load( partUrl, callbackFinal, parametersPart );
-
-			}
-
-		}
-
-	};
-
-	xhr.open( "GET", url, true );
-	xhr.setRequestHeader( "Content-Type", "text/plain" );
-	xhr.send( null );
-
-};
-
-// Load CTMLoader compressed models
-//	- parameters
-//		- url (required)
-//		- callback (required)
-
-THREE.CTMLoader.prototype.load = function ( url, callback, parameters ) {
-
-	parameters = parameters || {};
-
-	var scope = this;
-
-	var offsets = parameters.offsets !== undefined ? parameters.offsets : [ 0 ];
-
-	var xhr = new XMLHttpRequest(),
-		callbackProgress = null;
-
-	var length = 0;
-
-	xhr.onreadystatechange = function () {
-
-		if ( xhr.readyState === 4 ) {
-
-			if ( xhr.status === 200 || xhr.status === 0 ) {
-
-				var binaryData = new Uint8Array( xhr.response );
-
-				var s = Date.now();
-
-				if ( parameters.useWorker ) {
-
-					var worker = parameters.worker || new Worker( scope.workerPath );
-
-					worker.onmessage = function ( event ) {
-
-						var files = event.data;
-
-						for ( var i = 0; i < files.length; i ++ ) {
-
-							var ctmFile = files[ i ];
-
-							var e1 = Date.now();
-							// console.log( "CTM data parse time [worker]: " + (e1-s) + " ms" );
-
-							scope._createGeometry( ctmFile, callback );
-
-							var e = Date.now();
-							console.log( "model load time [worker]: " + ( e - e1 ) + " ms, total: " + ( e - s ) );
-
-						}
-
-
-					};
-
-					worker.postMessage( { "data": binaryData, "offsets": offsets }, [ binaryData.buffer ] );
-
-				} else {
-
-					for ( var i = 0; i < offsets.length; i ++ ) {
-
-						var stream = new CTM.Stream( binaryData );
-						stream.offset = offsets[ i ];
-
-						var ctmFile = new CTM.File( stream );
-
-						scope._createGeometry( ctmFile, callback );
-
-					}
-
-					//var e = Date.now();
-					//console.log( "CTM data parse time [inline]: " + (e-s) + " ms" );
-
-				}
-
-			} else {
-
-				console.error( "Couldn't load [" + url + "] [" + xhr.status + "]" );
-
-			}
-
-		} else if ( xhr.readyState === 3 ) {
-
-			if ( callbackProgress ) {
-
-				if ( length === 0 ) {
-
-					length = xhr.getResponseHeader( "Content-Length" );
-
-				}
-
-				callbackProgress( { total: length, loaded: xhr.responseText.length } );
-
-			}
-
-		} else if ( xhr.readyState === 2 ) {
-
-			length = xhr.getResponseHeader( "Content-Length" );
-
-		}
-
-	};
-
-	xhr.open( "GET", url, true );
-	xhr.responseType = "arraybuffer";
-
-	xhr.send( null );
-
-};
-
-
-THREE.CTMLoader.prototype._createGeometry = function ( file, callback ) {
-
-	var geometry = new THREE.BufferGeometry();
-
-	var indices = file.body.indices;
-	var positions = file.body.vertices;
-	var normals = file.body.normals;
-
-	var uvs, colors;
-
-	var uvMaps = file.body.uvMaps;
-
-	if ( uvMaps !== undefined && uvMaps.length > 0 ) {
-
-		uvs = uvMaps[ 0 ].uv;
-
-	}
-
-	var attrMaps = file.body.attrMaps;
-
-	if ( attrMaps !== undefined && attrMaps.length > 0 && attrMaps[ 0 ].name === 'Color' ) {
-
-		colors = attrMaps[ 0 ].attr;
-
-	}
-
-	geometry.setIndex( new THREE.BufferAttribute( indices, 1 ) );
-	geometry.addAttribute( 'position', new THREE.BufferAttribute( positions, 3 ) );
-
-	if ( normals !== undefined ) {
-
-		geometry.addAttribute( 'normal', new THREE.BufferAttribute( normals, 3 ) );
-
-	}
-
-	if ( uvs !== undefined ) {
-
-		geometry.addAttribute( 'uv', new THREE.BufferAttribute( uvs, 2 ) );
-
-	}
-
-	if ( colors !== undefined ) {
-
-		geometry.addAttribute( 'color', new THREE.BufferAttribute( colors, 4 ) );
-
-	}
-
-	// compute vertex normals if not present in the CTM model
-	if ( geometry.attributes.normal === undefined ) {
-
-		geometry.computeVertexNormals();
-
-	}
-
-	callback( geometry );
-
-};

+ 0 - 19
examples/js/loaders/ctm/CTMWorker.js

@@ -1,19 +0,0 @@
-importScripts( "../../libs/lzma.js", "../../libs/ctm.js" );
-
-self.onmessage = function ( event ) {
-
-	var files = [];
-
-	for ( var i = 0; i < event.data.offsets.length; i ++ ) {
-
-		var stream = new CTM.Stream( event.data.data );
-		stream.offset = event.data.offsets[ i ];
-
-		files[ i ] = new CTM.File( stream, [ event.data.data.buffer ] );
-
-	}
-
-	self.postMessage( files );
-	self.close();
-
-};

+ 4 - 2
examples/js/objects/Reflector.js

@@ -170,9 +170,11 @@ THREE.Reflector = function ( geometry, options ) {
 
 		// Restore viewport
 
-		if ( camera.isArrayCamera ) {
+		var viewport = camera.viewport;
 
-			renderer.state.viewport( camera.viewport );
+		if ( viewport !== undefined ) {
+
+			renderer.state.viewport( viewport );
 
 		}
 

+ 4 - 2
examples/js/objects/Refractor.js

@@ -205,9 +205,11 @@ THREE.Refractor = function ( geometry, options ) {
 
 		// restore viewport
 
-		if ( camera.isArrayCamera ) {
+		var viewport = camera.viewport;
 
-			renderer.state.viewport( camera.viewport );
+		if ( viewport !== undefined ) {
+
+			renderer.state.viewport( viewport );
 
 		}
 

+ 4 - 4
examples/js/objects/Sky.js

@@ -39,7 +39,8 @@ THREE.Sky.SkyShader = {
 		"rayleigh": { value: 1 },
 		"mieCoefficient": { value: 0.005 },
 		"mieDirectionalG": { value: 0.8 },
-		"sunPosition": { value: new THREE.Vector3() }
+		"sunPosition": { value: new THREE.Vector3() },
+		"up": { value: new THREE.Vector3( 0, 1, 0 ) }
 	},
 
 	vertexShader: [
@@ -47,6 +48,7 @@ THREE.Sky.SkyShader = {
 		'uniform float rayleigh;',
 		'uniform float turbidity;',
 		'uniform float mieCoefficient;',
+		'uniform vec3 up;',
 
 		'varying vec3 vWorldPosition;',
 		'varying vec3 vSunDirection;',
@@ -55,8 +57,6 @@ THREE.Sky.SkyShader = {
 		'varying vec3 vBetaM;',
 		'varying float vSunE;',
 
-		'const vec3 up = vec3( 0.0, 1.0, 0.0 );',
-
 		// constants for atmospheric scattering
 		'const float e = 2.71828182845904523536028747135266249775724709369995957;',
 		'const float pi = 3.141592653589793238462643383279502884197169;',
@@ -126,6 +126,7 @@ THREE.Sky.SkyShader = {
 
 		'uniform float luminance;',
 		'uniform float mieDirectionalG;',
+		'uniform vec3 up;',
 
 		'const vec3 cameraPos = vec3( 0.0, 0.0, 0.0 );',
 
@@ -138,7 +139,6 @@ THREE.Sky.SkyShader = {
 		// optical length at zenith for molecules
 		'const float rayleighZenithLength = 8.4E3;',
 		'const float mieZenithLength = 1.25E3;',
-		'const vec3 up = vec3( 0.0, 1.0, 0.0 );',
 		// 66 arc seconds -> degrees, and the cosine of that
 		'const float sunAngularDiameterCos = 0.999956676946448443553574619906976478926848692873900859324;',
 

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

@@ -470,32 +470,24 @@ var OrbitControls = function ( object, domElement ) {
 
 	function handleMouseDownRotate( event ) {
 
-		//console.log( 'handleMouseDownRotate' );
-
 		rotateStart.set( event.clientX, event.clientY );
 
 	}
 
 	function handleMouseDownDolly( event ) {
 
-		//console.log( 'handleMouseDownDolly' );
-
 		dollyStart.set( event.clientX, event.clientY );
 
 	}
 
 	function handleMouseDownPan( event ) {
 
-		//console.log( 'handleMouseDownPan' );
-
 		panStart.set( event.clientX, event.clientY );
 
 	}
 
 	function handleMouseMoveRotate( event ) {
 
-		//console.log( 'handleMouseMoveRotate' );
-
 		rotateEnd.set( event.clientX, event.clientY );
 
 		rotateDelta.subVectors( rotateEnd, rotateStart ).multiplyScalar( scope.rotateSpeed );
@@ -514,8 +506,6 @@ var OrbitControls = function ( object, domElement ) {
 
 	function handleMouseMoveDolly( event ) {
 
-		//console.log( 'handleMouseMoveDolly' );
-
 		dollyEnd.set( event.clientX, event.clientY );
 
 		dollyDelta.subVectors( dollyEnd, dollyStart );
@@ -538,8 +528,6 @@ var OrbitControls = function ( object, domElement ) {
 
 	function handleMouseMovePan( event ) {
 
-		//console.log( 'handleMouseMovePan' );
-
 		panEnd.set( event.clientX, event.clientY );
 
 		panDelta.subVectors( panEnd, panStart ).multiplyScalar( scope.panSpeed );
@@ -554,14 +542,12 @@ var OrbitControls = function ( object, domElement ) {
 
 	function handleMouseUp( /*event*/ ) {
 
-		// console.log( 'handleMouseUp' );
+		// no-op
 
 	}
 
 	function handleMouseWheel( event ) {
 
-		// console.log( 'handleMouseWheel' );
-
 		if ( event.deltaY < 0 ) {
 
 			dollyOut( getZoomScale() );
@@ -578,8 +564,6 @@ var OrbitControls = function ( object, domElement ) {
 
 	function handleKeyDown( event ) {
 
-		// console.log( 'handleKeyDown' );
-
 		var needsUpdate = false;
 
 		switch ( event.keyCode ) {
@@ -620,8 +604,6 @@ var OrbitControls = function ( object, domElement ) {
 
 	function handleTouchStartRotate( event ) {
 
-		//console.log( 'handleTouchStartRotate' );
-
 		if ( event.touches.length == 1 ) {
 
 			rotateStart.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );
@@ -639,8 +621,6 @@ var OrbitControls = function ( object, domElement ) {
 
 	function handleTouchStartPan( event ) {
 
-		//console.log( 'handleTouchStartPan' );
-
 		if ( event.touches.length == 1 ) {
 
 			panStart.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );
@@ -658,8 +638,6 @@ var OrbitControls = function ( object, domElement ) {
 
 	function handleTouchStartDolly( event ) {
 
-		//console.log( 'handleTouchStartDolly' );
-
 		var dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX;
 		var dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY;
 
@@ -671,8 +649,6 @@ var OrbitControls = function ( object, domElement ) {
 
 	function handleTouchStartDollyPan( event ) {
 
-		//console.log( 'handleTouchStartDollyPan' );
-
 		if ( scope.enableZoom ) handleTouchStartDolly( event );
 
 		if ( scope.enablePan ) handleTouchStartPan( event );
@@ -681,8 +657,6 @@ var OrbitControls = function ( object, domElement ) {
 
 	function handleTouchStartDollyRotate( event ) {
 
-		//console.log( 'handleTouchStartDollyRotate' );
-
 		if ( scope.enableZoom ) handleTouchStartDolly( event );
 
 		if ( scope.enableRotate ) handleTouchStartRotate( event );
@@ -691,8 +665,6 @@ var OrbitControls = function ( object, domElement ) {
 
 	function handleTouchMoveRotate( event ) {
 
-		//console.log( 'handleTouchMoveRotate' );
-
 		if ( event.touches.length == 1 ) {
 
 			rotateEnd.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );
@@ -720,8 +692,6 @@ var OrbitControls = function ( object, domElement ) {
 
 	function handleTouchMovePan( event ) {
 
-		//console.log( 'handleTouchMoveRotate' );
-
 		if ( event.touches.length == 1 ) {
 
 			panEnd.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );
@@ -745,8 +715,6 @@ var OrbitControls = function ( object, domElement ) {
 
 	function handleTouchMoveDolly( event ) {
 
-		//console.log( 'handleTouchMoveRotate' );
-
 		var dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX;
 		var dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY;
 
@@ -764,8 +732,6 @@ var OrbitControls = function ( object, domElement ) {
 
 	function handleTouchMoveDollyPan( event ) {
 
-		//console.log( 'handleTouchMoveDollyPan' );
-
 		if ( scope.enableZoom ) handleTouchMoveDolly( event );
 
 		if ( scope.enablePan ) handleTouchMovePan( event );
@@ -774,8 +740,6 @@ var OrbitControls = function ( object, domElement ) {
 
 	function handleTouchMoveDollyRotate( event ) {
 
-		//console.log( 'handleTouchMoveDollyPan' );
-
 		if ( scope.enableZoom ) handleTouchMoveDolly( event );
 
 		if ( scope.enableRotate ) handleTouchMoveRotate( event );
@@ -784,7 +748,7 @@ var OrbitControls = function ( object, domElement ) {
 
 	function handleTouchEnd( /*event*/ ) {
 
-		//console.log( 'handleTouchEnd' );
+		// no-op
 
 	}
 
@@ -1191,130 +1155,6 @@ var OrbitControls = function ( object, domElement ) {
 OrbitControls.prototype = Object.create( EventDispatcher.prototype );
 OrbitControls.prototype.constructor = OrbitControls;
 
-Object.defineProperties( OrbitControls.prototype, {
-
-	center: {
-
-		get: function () {
-
-			console.warn( 'THREE.OrbitControls: .center has been renamed to .target' );
-			return this.target;
-
-		}
-
-	},
-
-	// backward compatibility
-
-	noZoom: {
-
-		get: function () {
-
-			console.warn( 'THREE.OrbitControls: .noZoom has been deprecated. Use .enableZoom instead.' );
-			return ! this.enableZoom;
-
-		},
-
-		set: function ( value ) {
-
-			console.warn( 'THREE.OrbitControls: .noZoom has been deprecated. Use .enableZoom instead.' );
-			this.enableZoom = ! value;
-
-		}
-
-	},
-
-	noRotate: {
-
-		get: function () {
-
-			console.warn( 'THREE.OrbitControls: .noRotate has been deprecated. Use .enableRotate instead.' );
-			return ! this.enableRotate;
-
-		},
-
-		set: function ( value ) {
-
-			console.warn( 'THREE.OrbitControls: .noRotate has been deprecated. Use .enableRotate instead.' );
-			this.enableRotate = ! value;
-
-		}
-
-	},
-
-	noPan: {
-
-		get: function () {
-
-			console.warn( 'THREE.OrbitControls: .noPan has been deprecated. Use .enablePan instead.' );
-			return ! this.enablePan;
-
-		},
-
-		set: function ( value ) {
-
-			console.warn( 'THREE.OrbitControls: .noPan has been deprecated. Use .enablePan instead.' );
-			this.enablePan = ! value;
-
-		}
-
-	},
-
-	noKeys: {
-
-		get: function () {
-
-			console.warn( 'THREE.OrbitControls: .noKeys has been deprecated. Use .enableKeys instead.' );
-			return ! this.enableKeys;
-
-		},
-
-		set: function ( value ) {
-
-			console.warn( 'THREE.OrbitControls: .noKeys has been deprecated. Use .enableKeys instead.' );
-			this.enableKeys = ! value;
-
-		}
-
-	},
-
-	staticMoving: {
-
-		get: function () {
-
-			console.warn( 'THREE.OrbitControls: .staticMoving has been deprecated. Use .enableDamping instead.' );
-			return ! this.enableDamping;
-
-		},
-
-		set: function ( value ) {
-
-			console.warn( 'THREE.OrbitControls: .staticMoving has been deprecated. Use .enableDamping instead.' );
-			this.enableDamping = ! value;
-
-		}
-
-	},
-
-	dynamicDampingFactor: {
-
-		get: function () {
-
-			console.warn( 'THREE.OrbitControls: .dynamicDampingFactor has been renamed. Use .dampingFactor instead.' );
-			return this.dampingFactor;
-
-		},
-
-		set: function ( value ) {
-
-			console.warn( 'THREE.OrbitControls: .dynamicDampingFactor has been renamed. Use .dampingFactor instead.' );
-			this.dampingFactor = value;
-
-		}
-
-	}
-
-} );
 
 // This set of controls performs orbiting, dollying (zooming), and panning.
 // Unlike TrackballControls, it maintains the "up" direction object.up (+Y by default).

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

@@ -2205,6 +2205,7 @@ var GLTFLoader = ( function () {
 				pointsMaterial.color.copy( material.color );
 				pointsMaterial.map = material.map;
 				pointsMaterial.lights = false; // PointsMaterial doesn't support lights yet
+				pointsMaterial.sizeAttenuation = false; // glTF spec says points should be 1px
 
 				this.cache.add( cacheKey, pointsMaterial );
 

+ 18 - 12
examples/jsm/loaders/STLLoader.js

@@ -3,6 +3,7 @@
  * @author mrdoob / http://mrdoob.com/
  * @author gero3 / https://github.com/gero3
  * @author Mugen87 / https://github.com/Mugen87
+ * @author neverhood311 / https://github.com/neverhood311
  *
  * Description: A THREE loader for STL ASCII files, as created by Solidworks and other CAD programs.
  *
@@ -158,7 +159,7 @@ STLLoader.prototype = {
 					( reader.getUint8( index + 5 ) == 0x3D /*'='*/ ) ) {
 
 					hasColors = true;
-					colors = [];
+					colors = new Float32Array( faces * 3 * 3 );
 
 					defaultR = reader.getUint8( index + 6 ) / 255;
 					defaultG = reader.getUint8( index + 7 ) / 255;
@@ -174,8 +175,8 @@ STLLoader.prototype = {
 
 			var geometry = new BufferGeometry();
 
-			var vertices = [];
-			var normals = [];
+			var vertices = new Float32Array( faces * 3 * 3 );
+			var normals = new Float32Array( faces * 3 * 3 );
 
 			for ( var face = 0; face < faces; face ++ ) {
 
@@ -209,16 +210,21 @@ STLLoader.prototype = {
 				for ( var i = 1; i <= 3; i ++ ) {
 
 					var vertexstart = start + i * 12;
+					var componentIdx = ( face * 3 * 3 ) + ( ( i - 1 ) * 3 );
+					
+					vertices[ componentIdx ] = reader.getFloat32( vertexstart, true );
+					vertices[ componentIdx + 1 ] = reader.getFloat32( vertexstart + 4, true );
+					vertices[ componentIdx + 2 ] = reader.getFloat32( vertexstart + 8, true );
 
-					vertices.push( reader.getFloat32( vertexstart, true ) );
-					vertices.push( reader.getFloat32( vertexstart + 4, true ) );
-					vertices.push( reader.getFloat32( vertexstart + 8, true ) );
-
-					normals.push( normalX, normalY, normalZ );
+					normals[ componentIdx ] = normalX;
+					normals[ componentIdx + 1 ] = normalY;
+					normals[ componentIdx + 2 ] = normalZ;
 
 					if ( hasColors ) {
 
-						colors.push( r, g, b );
+						colors[ componentIdx ] = r;
+						colors[ componentIdx + 1 ] = g;
+						colors[ componentIdx + 2 ] = b;
 
 					}
 
@@ -226,12 +232,12 @@ STLLoader.prototype = {
 
 			}
 
-			geometry.addAttribute( 'position', new BufferAttribute( new Float32Array( vertices ), 3 ) );
-			geometry.addAttribute( 'normal', new BufferAttribute( new Float32Array( normals ), 3 ) );
+			geometry.addAttribute( 'position', new BufferAttribute( vertices, 3 ) );
+			geometry.addAttribute( 'normal', new BufferAttribute( normals, 3 ) );
 
 			if ( hasColors ) {
 
-				geometry.addAttribute( 'color', new BufferAttribute( new Float32Array( colors ), 3 ) );
+				geometry.addAttribute( 'color', new BufferAttribute( colors, 3 ) );
 				geometry.hasColors = true;
 				geometry.alpha = alpha;
 

+ 0 - 20
examples/jsm/loaders/ctm/CTMLoader.d.ts

@@ -1,20 +0,0 @@
-import {
-  BufferGeometry,
-  Material
-} from '../../../../src/Three';
-
-export interface CTMLoaderParameters {
-  basePath?: string;
-  offsets?: number[];
-  useWorker?: boolean;
-  worker?: object;
-}
-
-export class CTMLoader {
-  constructor();
-  workerPath: string;
-
-  load(url: string, onLoad: (geometry: BufferGeometry) => void, parameters: CTMLoaderParameters): void;
-  loadParts(url: string, onLoad: (geometries: BufferGeometry[], materials: Material[]) => void, parameters: CTMLoaderParameters): void;
-  setWorkerPath(value: string): this;
-}

+ 0 - 288
examples/jsm/loaders/ctm/CTMLoader.js

@@ -1,288 +0,0 @@
-/**
- * Loader for CTM encoded models generated by OpenCTM tools:
- *	http://openctm.sourceforge.net/
- *
- * Uses js-openctm library by Juan Mellado
- *	http://code.google.com/p/js-openctm/
- *
- * @author alteredq / http://alteredqualia.com/
- *
- * OpenCTM LICENSE:
- *
- * Copyright (c) 2009-2010 Marcus Geelnard
- *
- * This software is provided 'as-is', without any express or implied
- * warranty. In no event will the authors be held liable for any damages
- * arising from the use of this software.
- *
- * Permission is granted to anyone to use this software for any purpose,
- * including commercial applications, and to alter it and redistribute it
- * freely, subject to the following restrictions:
- *
- *     1. The origin of this software must not be misrepresented; you must not
- *    claim that you wrote the original software. If you use this software
- *    in a product, an acknowledgment in the product documentation would be
- *    appreciated but is not required.
- *
- *    2. Altered source versions must be plainly marked as such, and must not
- *    be misrepresented as being the original software.
- *
- *    3. This notice may not be removed or altered from any source
- *    distribution.
- *
- */
-
-import {
-	BufferAttribute,
-	BufferGeometry,
-	Loader,
-	LoaderUtils
-} from "../../../../build/three.module.js";
-
-/* global CTM */
-
-var CTMLoader = function () {
-
-	this.workerPath = null;
-
-};
-
-CTMLoader.prototype.constructor = CTMLoader;
-
-CTMLoader.prototype.setWorkerPath = function ( workerPath ) {
-
-	this.workerPath = workerPath;
-
-};
-
-// Load multiple CTM parts defined in JSON
-
-CTMLoader.prototype.loadParts = function ( url, callback, parameters ) {
-
-	parameters = parameters || {};
-
-	var scope = this;
-
-	var xhr = new XMLHttpRequest();
-
-	var basePath = parameters.basePath ? parameters.basePath : LoaderUtils.extractUrlBase( url );
-
-	xhr.onreadystatechange = function () {
-
-		if ( xhr.readyState === 4 ) {
-
-			if ( xhr.status === 200 || xhr.status === 0 ) {
-
-				var jsonObject = JSON.parse( xhr.responseText );
-
-				var materials = [], geometries = [], counter = 0;
-
-				function callbackFinal( geometry ) {
-
-					counter += 1;
-
-					geometries.push( geometry );
-
-					if ( counter === jsonObject.offsets.length ) {
-
-						callback( geometries, materials );
-
-					}
-
-				}
-
-
-				// init materials
-
-				for ( var i = 0; i < jsonObject.materials.length; i ++ ) {
-
-					materials[ i ] = Loader.prototype.createMaterial( jsonObject.materials[ i ], basePath );
-
-				}
-
-				// load joined CTM file
-
-				var partUrl = basePath + jsonObject.data;
-				var parametersPart = { useWorker: parameters.useWorker, worker: parameters.worker, offsets: jsonObject.offsets };
-				scope.load( partUrl, callbackFinal, parametersPart );
-
-			}
-
-		}
-
-	};
-
-	xhr.open( "GET", url, true );
-	xhr.setRequestHeader( "Content-Type", "text/plain" );
-	xhr.send( null );
-
-};
-
-// Load CTMLoader compressed models
-//	- parameters
-//		- url (required)
-//		- callback (required)
-
-CTMLoader.prototype.load = function ( url, callback, parameters ) {
-
-	parameters = parameters || {};
-
-	var scope = this;
-
-	var offsets = parameters.offsets !== undefined ? parameters.offsets : [ 0 ];
-
-	var xhr = new XMLHttpRequest(),
-		callbackProgress = null;
-
-	var length = 0;
-
-	xhr.onreadystatechange = function () {
-
-		if ( xhr.readyState === 4 ) {
-
-			if ( xhr.status === 200 || xhr.status === 0 ) {
-
-				var binaryData = new Uint8Array( xhr.response );
-
-				var s = Date.now();
-
-				if ( parameters.useWorker ) {
-
-					var worker = parameters.worker || new Worker( scope.workerPath );
-
-					worker.onmessage = function ( event ) {
-
-						var files = event.data;
-
-						for ( var i = 0; i < files.length; i ++ ) {
-
-							var ctmFile = files[ i ];
-
-							var e1 = Date.now();
-							// console.log( "CTM data parse time [worker]: " + (e1-s) + " ms" );
-
-							scope._createGeometry( ctmFile, callback );
-
-							var e = Date.now();
-							console.log( "model load time [worker]: " + ( e - e1 ) + " ms, total: " + ( e - s ) );
-
-						}
-
-
-					};
-
-					worker.postMessage( { "data": binaryData, "offsets": offsets }, [ binaryData.buffer ] );
-
-				} else {
-
-					for ( var i = 0; i < offsets.length; i ++ ) {
-
-						var stream = new CTM.Stream( binaryData );
-						stream.offset = offsets[ i ];
-
-						var ctmFile = new CTM.File( stream );
-
-						scope._createGeometry( ctmFile, callback );
-
-					}
-
-					//var e = Date.now();
-					//console.log( "CTM data parse time [inline]: " + (e-s) + " ms" );
-
-				}
-
-			} else {
-
-				console.error( "Couldn't load [" + url + "] [" + xhr.status + "]" );
-
-			}
-
-		} else if ( xhr.readyState === 3 ) {
-
-			if ( callbackProgress ) {
-
-				if ( length === 0 ) {
-
-					length = xhr.getResponseHeader( "Content-Length" );
-
-				}
-
-				callbackProgress( { total: length, loaded: xhr.responseText.length } );
-
-			}
-
-		} else if ( xhr.readyState === 2 ) {
-
-			length = xhr.getResponseHeader( "Content-Length" );
-
-		}
-
-	};
-
-	xhr.open( "GET", url, true );
-	xhr.responseType = "arraybuffer";
-
-	xhr.send( null );
-
-};
-
-
-CTMLoader.prototype._createGeometry = function ( file, callback ) {
-
-	var geometry = new BufferGeometry();
-
-	var indices = file.body.indices;
-	var positions = file.body.vertices;
-	var normals = file.body.normals;
-
-	var uvs, colors;
-
-	var uvMaps = file.body.uvMaps;
-
-	if ( uvMaps !== undefined && uvMaps.length > 0 ) {
-
-		uvs = uvMaps[ 0 ].uv;
-
-	}
-
-	var attrMaps = file.body.attrMaps;
-
-	if ( attrMaps !== undefined && attrMaps.length > 0 && attrMaps[ 0 ].name === 'Color' ) {
-
-		colors = attrMaps[ 0 ].attr;
-
-	}
-
-	geometry.setIndex( new BufferAttribute( indices, 1 ) );
-	geometry.addAttribute( 'position', new BufferAttribute( positions, 3 ) );
-
-	if ( normals !== undefined ) {
-
-		geometry.addAttribute( 'normal', new BufferAttribute( normals, 3 ) );
-
-	}
-
-	if ( uvs !== undefined ) {
-
-		geometry.addAttribute( 'uv', new BufferAttribute( uvs, 2 ) );
-
-	}
-
-	if ( colors !== undefined ) {
-
-		geometry.addAttribute( 'color', new BufferAttribute( colors, 4 ) );
-
-	}
-
-	// compute vertex normals if not present in the CTM model
-	if ( geometry.attributes.normal === undefined ) {
-
-		geometry.computeVertexNormals();
-
-	}
-
-	callback( geometry );
-
-};
-
-export { CTMLoader };

+ 1 - 1
examples/jsm/loaders/obj2/bridge/MtlObjBridge.d.ts

@@ -4,5 +4,5 @@ import {
 
 export namespace MtlObjBridge {
   export function link(processResult: object, assetLoader: object): void;
-  export function addMaterialsFromMtlLoader(materialCreator: MaterialCreator): void;
+  export function addMaterialsFromMtlLoader(materialCreator: MaterialCreator): object;
 }

+ 1 - 0
examples/jsm/nodes/Nodes.js

@@ -82,6 +82,7 @@ export { VelocityNode } from './utils/VelocityNode.js';
 export { UVTransformNode } from './utils/UVTransformNode.js';
 export { MaxMIPLevelNode } from './utils/MaxMIPLevelNode.js';
 export { ColorSpaceNode } from './utils/ColorSpaceNode.js';
+export { SubSlotNode } from './utils/SubSlotNode.js';
 
 // effects
 

+ 9 - 2
examples/jsm/nodes/core/FunctionNode.js

@@ -12,6 +12,7 @@ var declarationRegexp = /^([a-z_0-9]+)\s([a-z_0-9]+)\s*\((.*?)\)/i,
 function FunctionNode( src, includes, extensions, keywords, type ) {
 
 	this.isMethod = type === undefined;
+	this.isInterface = false;
 
 	TempNode.call( this, type );
 
@@ -139,7 +140,11 @@ FunctionNode.prototype.generate = function ( builder, output ) {
 
 	} else if ( this.isMethod ) {
 
-		builder.include( this, false, src );
+		if ( ! this.isInterface ) {
+
+			builder.include( this, false, src );
+
+		}
 
 		return this.name;
 
@@ -181,7 +186,7 @@ FunctionNode.prototype.parse = function ( src, includes, extensions, keywords )
 					var qualifier = inputs[ i ++ ];
 					var type, name;
 
-					if ( qualifier == 'in' || qualifier == 'out' || qualifier == 'inout' ) {
+					if ( qualifier === 'in' || qualifier === 'out' || qualifier === 'inout' ) {
 
 						type = inputs[ i ++ ];
 
@@ -204,6 +209,8 @@ FunctionNode.prototype.parse = function ( src, includes, extensions, keywords )
 
 			}
 
+			this.isInterface = this.src.indexOf('{') === -1;
+
 		} else {
 
 			this.type = '';

+ 6 - 0
examples/jsm/nodes/core/NodeBuilder.js

@@ -449,6 +449,12 @@ NodeBuilder.prototype = {
 
 	},
 
+	require: function ( name ) {
+
+		this.requires[ name ] = true;
+
+	},
+
 	isDefined: function ( name ) {
 
 		return this.defines[ name ] !== undefined;

+ 41 - 6
examples/jsm/nodes/materials/nodes/StandardNode.js

@@ -20,6 +20,8 @@ function StandardNode() {
 	this.roughness = new FloatNode( 0.5 );
 	this.metalness = new FloatNode( 0.5 );
 
+	this.energyPreservation = true;
+
 }
 
 StandardNode.prototype = Object.create( Node.prototype );
@@ -153,7 +155,20 @@ StandardNode.prototype.build = function ( builder ) {
 		if ( this.shadow ) this.shadow.analyze( builder );
 		if ( this.emissive ) this.emissive.analyze( builder, { slot: 'emissive' } );
 
-		if ( this.environment ) this.environment.analyze( builder, { cache: 'env', context: contextEnvironment, slot: 'environment' } ); // isolate environment from others inputs ( see TextureNode, CubeTextureNode )
+		if ( this.environment ) {
+
+			// isolate environment from others inputs ( see TextureNode, CubeTextureNode )
+			// environment.analyze will detect if there is a need of calculate irradiance
+
+			this.environment.analyze( builder, { cache: 'radiance', context: contextEnvironment, slot: 'radiance' } ); 
+
+			if ( builder.requires.irradiance ) {
+
+				this.environment.analyze( builder, { cache: 'irradiance', context: contextEnvironment, slot: 'irradiance' } ); 
+
+			}
+
+		}
 
 		// build code
 
@@ -179,7 +194,21 @@ StandardNode.prototype.build = function ( builder ) {
 		var shadow = this.shadow ? this.shadow.flow( builder, 'c' ) : undefined;
 		var emissive = this.emissive ? this.emissive.flow( builder, 'c', { slot: 'emissive' } ) : undefined;
 
-		var environment = this.environment ? this.environment.flow( builder, 'c', { cache: 'env', context: contextEnvironment, slot: 'environment' } ) : undefined;
+		var environment;
+
+		if ( this.environment ) {
+
+			environment = {
+				radiance: this.environment.flow( builder, 'c', { cache: 'radiance', context: contextEnvironment, slot: 'radiance' } )
+			};
+
+			if ( builder.requires.irradiance ) {
+
+				environment.irradiance = this.environment.flow( builder, 'c', { cache: 'irradiance', context: contextEnvironment, slot: 'irradiance' } );
+
+			}
+
+		}
 
 		var clearCoatEnv = useClearCoat && environment ? this.environment.flow( builder, 'c', { cache: 'clearCoat', context: contextEnvironment, slot: 'environment' } ) : undefined;
 
@@ -371,7 +400,13 @@ StandardNode.prototype.build = function ( builder ) {
 
 		if ( environment ) {
 
-			output.push( environment.code );
+			output.push( environment.radiance.code );
+
+			if ( builder.requires.irradiance ) {
+
+				output.push( environment.irradiance.code );
+
+			}
 
 			if ( clearCoatEnv ) {
 
@@ -382,11 +417,11 @@ StandardNode.prototype.build = function ( builder ) {
 
 			}
 
-			output.push( "radiance += " + environment.result + ";" );
+			output.push( "radiance += " + environment.radiance.result + ";" );
 
-			if ( environment.extra.irradiance ) {
+			if ( builder.requires.irradiance ) {
 
-				output.push( "irradiance += PI * " + environment.extra.irradiance + ";" );
+				output.push( "irradiance += PI * " + environment.irradiance.result + ";" );
 
 			}
 

+ 19 - 7
examples/jsm/nodes/misc/TextureCubeNode.js

@@ -11,17 +11,19 @@ import { NormalNode } from '../accessors/NormalNode.js';
 import { ColorSpaceNode } from '../utils/ColorSpaceNode.js';
 import { BlinnExponentToRoughnessNode } from '../bsdfs/BlinnExponentToRoughnessNode.js';
 
-function TextureCubeNode( value, textureSize ) {
+function TextureCubeNode( value, textureSize, uv, bias ) {
 
 	TempNode.call( this, 'v4' );
 
 	this.value = value;
 	this.textureSize = textureSize || new FloatNode( 1024 );
+	this.uv = uv || new ReflectNode( ReflectNode.VECTOR );
+	this.bias = bias || new BlinnExponentToRoughnessNode();
 
 	this.radianceCache = { uv: new TextureCubeUVNode(
-		new ReflectNode( ReflectNode.VECTOR ),
+		this.uv,
 		this.textureSize,
-		new BlinnExponentToRoughnessNode()
+		this.bias
 	) };
 
 	this.irradianceCache = { uv: new TextureCubeUVNode(
@@ -79,12 +81,12 @@ TextureCubeNode.prototype.generate = function ( builder, output ) {
 
 	if ( builder.isShader( 'fragment' ) ) {
 
-		var radiance = this.generateTextureCubeUV( builder, this.radianceCache );
-		var irradiance = this.generateTextureCubeUV( builder, this.irradianceCache );
+		builder.require( 'irradiance' );
 
-		builder.context.extra.irradiance = irradiance;
+		var cache = builder.slot === 'irradiance' ? this.irradianceCache : this.radianceCache;
+		var result = this.generateTextureCubeUV( builder, cache );
 
-		return builder.format( 'vec4( ' + radiance + ', 1.0 )', this.getType( builder ), output );
+		return builder.format( 'vec4( ' + result + ', 1.0 )', this.getType( builder ), output );
 
 	} else {
 
@@ -96,6 +98,16 @@ TextureCubeNode.prototype.generate = function ( builder, output ) {
 
 };
 
+TextureCubeNode.prototype.copy = function ( source ) {
+
+	TempNode.prototype.copy.call( this, source );
+
+	this.value = source.value;
+
+	return this;
+
+};
+
 TextureCubeNode.prototype.toJSON = function ( meta ) {
 
 	var data = this.getJSONNode( meta );

+ 11 - 0
examples/jsm/nodes/utils/SubSlot.d.ts

@@ -0,0 +1,11 @@
+import { TempNode } from '../core/TempNode';
+import { NodeBuilder } from '../core/NodeBuilder';
+
+export class SubSlots extends TempNode {
+  constructor(slots?: object);
+
+  slots: Node[];
+
+  generate(builder: NodeBuilder, output: string): string;
+  copy(source: SubSlots): this;
+}

+ 79 - 0
examples/jsm/nodes/utils/SubSlotNode.js

@@ -0,0 +1,79 @@
+/**
+ * @author sunag / http://www.sunag.com.br/
+ */
+
+import { TempNode } from '../core/TempNode.js';
+
+function SubSlotNode( slots ) {
+
+	TempNode.call( this );
+
+	this.slots = slots || {};
+
+}
+
+SubSlotNode.prototype = Object.create( TempNode.prototype );
+SubSlotNode.prototype.constructor = SubSlotNode;
+SubSlotNode.prototype.nodeType = "SubSlot";
+
+SubSlotNode.prototype.getType = function ( builder, output ) {
+
+	return output;
+
+};
+
+SubSlotNode.prototype.generate = function ( builder, output ) {
+
+	if ( this.slots[ builder.slot ] ) {
+
+		return this.slots[ builder.slot ].build( builder, output )
+
+	}
+
+	return builder.format( '0.0', 'f', output );
+
+};
+
+SubSlotNode.prototype.copy = function ( source ) {
+
+	TempNode.prototype.copy.call( this, source );
+
+	for ( var prop in source.slots ) {
+
+		this.slots[ prop ] = source.slots[ prop ];
+
+	}
+
+	return this;
+
+};
+
+SubSlotNode.prototype.toJSON = function ( meta ) {
+
+	var data = this.getJSONNode( meta );
+
+	if ( ! data ) {
+
+		data = this.createJSONNode( meta );
+
+		data.slots = {};
+
+		for ( var prop in this.slots ) {
+
+			var slot = this.slots[ prop ];
+
+			if ( slot ) {
+
+				data.slots[ prop ] = slot.toJSON( meta ).uuid;
+
+			}
+
+		}
+
+	}
+
+	return data;
+
+};
+
+export { SubSlotNode };

+ 4 - 2
examples/jsm/objects/Reflector.js

@@ -186,9 +186,11 @@ var Reflector = function ( geometry, options ) {
 
 		// Restore viewport
 
-		if ( camera.isArrayCamera ) {
+		var viewport = camera.viewport;
 
-			renderer.state.viewport( camera.viewport );
+		if ( viewport !== undefined ) {
+
+			renderer.state.viewport( viewport );
 
 		}
 

+ 4 - 2
examples/jsm/objects/Refractor.js

@@ -222,9 +222,11 @@ var Refractor = function ( geometry, options ) {
 
 		// restore viewport
 
-		if ( camera.isArrayCamera ) {
+		var viewport = camera.viewport;
 
-			renderer.state.viewport( camera.viewport );
+		if ( viewport !== undefined ) {
+
+			renderer.state.viewport( viewport );
 
 		}
 

+ 4 - 4
examples/jsm/objects/Sky.js

@@ -48,7 +48,8 @@ Sky.SkyShader = {
 		"rayleigh": { value: 1 },
 		"mieCoefficient": { value: 0.005 },
 		"mieDirectionalG": { value: 0.8 },
-		"sunPosition": { value: new Vector3() }
+		"sunPosition": { value: new Vector3() },
+		"up": { value: new Vector3( 0, 1, 0 ) }
 	},
 
 	vertexShader: [
@@ -56,6 +57,7 @@ Sky.SkyShader = {
 		'uniform float rayleigh;',
 		'uniform float turbidity;',
 		'uniform float mieCoefficient;',
+		'uniform vec3 up;',
 
 		'varying vec3 vWorldPosition;',
 		'varying vec3 vSunDirection;',
@@ -64,8 +66,6 @@ Sky.SkyShader = {
 		'varying vec3 vBetaM;',
 		'varying float vSunE;',
 
-		'const vec3 up = vec3( 0.0, 1.0, 0.0 );',
-
 		// constants for atmospheric scattering
 		'const float e = 2.71828182845904523536028747135266249775724709369995957;',
 		'const float pi = 3.141592653589793238462643383279502884197169;',
@@ -135,6 +135,7 @@ Sky.SkyShader = {
 
 		'uniform float luminance;',
 		'uniform float mieDirectionalG;',
+		'uniform vec3 up;',
 
 		'const vec3 cameraPos = vec3( 0.0, 0.0, 0.0 );',
 
@@ -147,7 +148,6 @@ Sky.SkyShader = {
 		// optical length at zenith for molecules
 		'const float rayleighZenithLength = 8.4E3;',
 		'const float mieZenithLength = 1.25E3;',
-		'const vec3 up = vec3( 0.0, 1.0, 0.0 );',
 		// 66 arc seconds -> degrees, and the cosine of that
 		'const float sunAngularDiameterCos = 0.999956676946448443553574619906976478926848692873900859324;',
 

BIN
examples/models/ctm/LeePerry.ctm


BIN
examples/models/ctm/WaltHead.ctm


BIN
examples/models/ctm/ben.ctm


BIN
examples/models/ctm/camaro/camaro.ctm


+ 0 - 113
examples/models/ctm/camaro/camaro.js

@@ -1,113 +0,0 @@
-{
-"data" : "camaro.ctm",
-
-"offsets": [ 0, 39262, 79223, 83542, 94677, 95890, 144902, 470461 ],
-
-"materials" :
-	[
-	{
-	"DbgColor" : 15658734,
-	"DbgIndex" : 0,
-	"DbgName" : "Body_car-ao",
-	"colorDiffuse" : [0.1816, 0.3264, 0.3704],
-	"colorSpecular" : [2.0, 2.0, 2.0],
-	"illumination" : 2,
-	"mapDiffuse" : "car-ao.png",
-	"opticalDensity" : 1.0,
-	"specularCoef" : 778.431373,
-	"opacity" : 1.0
-	},
-
-	{
-	"DbgColor" : 15597568,
-	"DbgIndex" : 1,
-	"DbgName" : "tire_car-ao",
-	"colorDiffuse" : [0.2168, 0.2168, 0.2104],
-	"colorSpecular" : [0.1, 0.1, 0.1],
-	"illumination" : 2,
-	"mapDiffuse" : "car-ao.png",
-	"opticalDensity" : 1.0,
-	"specularCoef" : 15.686275,
-	"opacity" : 1.0
-	},
-
-	{
-	"DbgColor" : 60928,
-	"DbgIndex" : 2,
-	"DbgName" : "black2_car-ao",
-	"colorDiffuse" : [0.0, 0.0, 0.0],
-	"colorSpecular" : [0.0, 0.0, 0.0],
-	"illumination" : 2,
-	"mapDiffuse" : "car-ao.png",
-	"opticalDensity" : 1.0,
-	"specularCoef" : 0.0,
-	"opacity" : 1.0
-	},
-
-	{
-	"DbgColor" : 238,
-	"DbgIndex" : 3,
-	"DbgName" : "tireling_car-ao",
-	"colorDiffuse" : [0.4, 0.4, 0.4],
-	"colorSpecular" : [0.2, 0.2, 0.2],
-	"illumination" : 2,
-	"mapDiffuse" : "car-ao.png",
-	"opticalDensity" : 1.0,
-	"specularCoef" : 15.686275,
-	"opacity" : 1.0
-	},
-
-	{
-	"DbgColor" : 15658496,
-	"DbgIndex" : 4,
-	"DbgName" : "glass_car-ao",
-	"colorDiffuse" : [0.16, 0.248, 0.2448],
-	"colorSpecular" : [2.0, 2.0, 2.0],
-	"illumination" : 2,
-	"mapDiffuse" : "car-ao.png",
-	"opticalDensity" : 1.0,
-	"specularCoef" : 778.431373,
-	"opacity" : 0.34
-	},
-
-	{
-	"DbgColor" : 61166,
-	"DbgIndex" : 5,
-	"DbgName" : "black_car-ao",
-	"colorDiffuse" : [0.0816, 0.0816, 0.0816],
-	"colorSpecular" : [0.2, 0.2, 0.2],
-	"illumination" : 2,
-	"mapDiffuse" : "car-ao.png",
-	"opticalDensity" : 1.0,
-	"specularCoef" : 3.921569,
-	"opacity" : 1.0
-	},
-
-	{
-	"DbgColor" : 15597806,
-	"DbgIndex" : 6,
-	"DbgName" : "mirror_car-ao",
-	"colorDiffuse" : [0.24, 0.24, 0.24],
-	"colorSpecular" : [2.0, 2.0, 2.0],
-	"illumination" : 2,
-	"mapDiffuse" : "car-ao.png",
-	"opticalDensity" : 1.0,
-	"specularCoef" : 778.431373,
-	"opacity" : 1.0
-	},
-
-
-	{
-	"DbgColor" : 3744854,
-	"DbgIndex" : 8,
-	"DbgName" : "Material.001_plane-ao-256",
-	"colorDiffuse" : [0.798635, 0.776149, 0.8],
-	"colorSpecular" : [0.5, 0.5, 0.5],
-	"illumination" : 2,
-	"mapDiffuse" : "plane-ao-256.png",
-	"opticalDensity" : 1.0,
-	"specularCoef" : 96.078431,
-	"opacity" : 1.0
-	}
-	]
-}

BIN
examples/models/ctm/camaro/car-ao.png


BIN
examples/models/ctm/camaro/plane-ao-256.png


BIN
examples/models/ctm/hand.ctm


BIN
examples/textures/carbon/Carbon.png


BIN
examples/textures/carbon/Carbon_Normal.png


BIN
examples/textures/cube/angus/cube_m00_c00.jpg


BIN
examples/textures/cube/angus/cube_m00_c01.jpg


BIN
examples/textures/cube/angus/cube_m00_c02.jpg


BIN
examples/textures/cube/angus/cube_m00_c03.jpg


BIN
examples/textures/cube/angus/cube_m00_c04.jpg


BIN
examples/textures/cube/angus/cube_m00_c05.jpg


BIN
examples/textures/cube/angus/cube_m01_c00.jpg


BIN
examples/textures/cube/angus/cube_m01_c01.jpg


BIN
examples/textures/cube/angus/cube_m01_c02.jpg


BIN
examples/textures/cube/angus/cube_m01_c03.jpg


BIN
examples/textures/cube/angus/cube_m01_c04.jpg


BIN
examples/textures/cube/angus/cube_m01_c05.jpg


BIN
examples/textures/cube/angus/cube_m02_c00.jpg


BIN
examples/textures/cube/angus/cube_m02_c01.jpg


BIN
examples/textures/cube/angus/cube_m02_c02.jpg


BIN
examples/textures/cube/angus/cube_m02_c03.jpg


BIN
examples/textures/cube/angus/cube_m02_c04.jpg


BIN
examples/textures/cube/angus/cube_m02_c05.jpg


BIN
examples/textures/cube/angus/cube_m03_c00.jpg


BIN
examples/textures/cube/angus/cube_m03_c01.jpg


BIN
examples/textures/cube/angus/cube_m03_c02.jpg


BIN
examples/textures/cube/angus/cube_m03_c03.jpg


BIN
examples/textures/cube/angus/cube_m03_c04.jpg


BIN
examples/textures/cube/angus/cube_m03_c05.jpg


BIN
examples/textures/cube/angus/cube_m04_c00.jpg


BIN
examples/textures/cube/angus/cube_m04_c01.jpg


BIN
examples/textures/cube/angus/cube_m04_c02.jpg


BIN
examples/textures/cube/angus/cube_m04_c03.jpg


BIN
examples/textures/cube/angus/cube_m04_c04.jpg


BIN
examples/textures/cube/angus/cube_m04_c05.jpg


BIN
examples/textures/cube/angus/cube_m05_c00.jpg


BIN
examples/textures/cube/angus/cube_m05_c01.jpg


BIN
examples/textures/cube/angus/cube_m05_c02.jpg


BIN
examples/textures/cube/angus/cube_m05_c03.jpg


BIN
examples/textures/cube/angus/cube_m05_c04.jpg


BIN
examples/textures/cube/angus/cube_m05_c05.jpg


BIN
examples/textures/cube/angus/cube_m06_c00.jpg


BIN
examples/textures/cube/angus/cube_m06_c01.jpg


BIN
examples/textures/cube/angus/cube_m06_c02.jpg


BIN
examples/textures/cube/angus/cube_m06_c03.jpg


BIN
examples/textures/cube/angus/cube_m06_c04.jpg


BIN
examples/textures/cube/angus/cube_m06_c05.jpg


BIN
examples/textures/cube/angus/cube_m07_c00.jpg


BIN
examples/textures/cube/angus/cube_m07_c01.jpg


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