Browse Source

Extended CanvasRenderer to be able to handle decals (MeshBitmapUVMappingMaterials as secondary materials).

For decals you need to set "decalIndex" property of the material (corresponding to materials index of the original mesh UV material).

Added multimaterials example.

Fixed forgotten sphere smoothing in OBJ converter example.
alteredq 15 years ago
parent
commit
dde831bf6f

File diff suppressed because it is too large
+ 0 - 1
build/Three.js


File diff suppressed because it is too large
+ 0 - 1
build/ThreeDebug.js


+ 392 - 0
examples/materials_test.html

@@ -0,0 +1,392 @@
+<!DOCTYPE HTML>
+<html lang="en">
+	<head>
+		<title>three.js - multi-materials test</title>
+		<meta charset="utf-8">
+		<style type="text/css">
+			body {
+				background:#fff;
+                padding:0;
+				margin:0;
+				overflow:hidden;
+                font-family:georgia;
+                text-align:center;
+			}
+            h1 { }
+            a { color:skyblue }
+            canvas { pointer-events:none; z-index:10; position:relative; }
+            #log { position:absolute; top:50px; text-align:left; display:block; z-index:100 }
+            #d { text-align:center; margin:1em 0 -15.7em 0; z-index:0; position:relative; display:block }
+            .button { background:#000; color:#fff; padding:0.2em 0.5em; cursor:pointer }
+            .inactive { background:#999; color:#eee }
+		</style>
+	</head>
+	
+    <body>
+        <div id="d">
+            <h1>Multi-materials test</h1>
+
+            <span id="rcanvas" class="button inactive">2d canvas renderer</span>
+            <span id="rwebgl" class="button">WebGL renderer</span>
+            <br/>
+
+            <p>Model by <a href="http://sketchup.google.com/3dwarehouse/details?mid=2c6fd128fca34052adc5f5b98d513da1">Reallusion iClone</a> 
+            
+            <p>Using a modified version of <a href="http://github.com/alteredq/three.js">Three.js</a> by mrdoob.
+            
+            <br/>
+            <p>Best viewed in Chrome 7/8 or Firefox 4 using WebGL renderer.
+            <p>Canvas renderer is very slow on anything other than Chrome.
+            <p>Multi-materials currently work only in canvas renderer.
+        </div>
+        
+        <div id="log"></div>
+
+		<!--
+        <script type="text/javascript" src="../build/Three.js"></script> 
+        -->
+
+		<script type="text/javascript" src="../src/Three.js"></script>
+		<script type="text/javascript" src="../src/core/Color.js"></script>
+		<script type="text/javascript" src="../src/core/Vector2.js"></script>
+		<script type="text/javascript" src="../src/core/Vector3.js"></script>
+		<script type="text/javascript" src="../src/core/Vector4.js"></script>
+		<script type="text/javascript" src="../src/core/Rectangle.js"></script>
+		<script type="text/javascript" src="../src/core/Matrix4.js"></script>
+		<script type="text/javascript" src="../src/core/Vertex.js"></script>
+		<script type="text/javascript" src="../src/core/Face3.js"></script>
+		<script type="text/javascript" src="../src/core/Face4.js"></script>
+		<script type="text/javascript" src="../src/core/UV.js"></script>
+		<script type="text/javascript" src="../src/core/Geometry.js"></script>
+		<script type="text/javascript" src="../src/cameras/Camera.js"></script>
+		<script type="text/javascript" src="../src/lights/Light.js"></script>
+		<script type="text/javascript" src="../src/lights/AmbientLight.js"></script>
+		<script type="text/javascript" src="../src/lights/DirectionalLight.js"></script>
+		<script type="text/javascript" src="../src/lights/PointLight.js"></script>
+		<script type="text/javascript" src="../src/objects/Object3D.js"></script>
+		<script type="text/javascript" src="../src/objects/Mesh.js"></script>
+		<script type="text/javascript" src="../src/objects/Particle.js"></script>
+		<script type="text/javascript" src="../src/objects/Line.js"></script>
+		<script type="text/javascript" src="../src/materials/LineColorMaterial.js"></script>
+		<script type="text/javascript" src="../src/materials/MeshBitmapUVMappingMaterial.js"></script>
+		<script type="text/javascript" src="../src/materials/MeshColorFillMaterial.js"></script>
+		<script type="text/javascript" src="../src/materials/MeshColorStrokeMaterial.js"></script>
+		<script type="text/javascript" src="../src/materials/MeshFaceColorFillMaterial.js"></script>
+		<script type="text/javascript" src="../src/materials/MeshFaceColorStrokeMaterial.js"></script>
+		<script type="text/javascript" src="../src/materials/ParticleCircleMaterial.js"></script>
+		<script type="text/javascript" src="../src/materials/ParticleBitmapMaterial.js"></script>
+		<script type="text/javascript" src="../src/scenes/Scene.js"></script>
+		<script type="text/javascript" src="../src/renderers/Projector.js"></script>
+		<script type="text/javascript" src="../src/renderers/CanvasRenderer.js"></script>
+		<script type="text/javascript" src="../src/renderers/SVGRenderer.js"></script>
+		<script type="text/javascript" src="../src/renderers/WebGLRenderer.js"></script>
+		<script type="text/javascript" src="../src/renderers/renderables/RenderableFace3.js"></script>
+		<script type="text/javascript" src="../src/renderers/renderables/RenderableFace4.js"></script>
+		<script type="text/javascript" src="../src/renderers/renderables/RenderableParticle.js"></script>
+		<script type="text/javascript" src="../src/renderers/renderables/RenderableLine.js"></script>
+		<!--
+        -->
+		
+		<script type="text/javascript" src="geometry/primitives/Sphere.js"></script>
+		<script type="text/javascript" src="geometry/primitives/Plane.js"></script>
+
+		<script type="text/javascript" src="js/Stats.js"></script>
+
+		<script type="text/javascript">
+
+			var SCREEN_WIDTH = window.innerWidth/2;
+			var SCREEN_HEIGHT = window.innerHeight;
+			var FLOOR = -250;
+
+			var container;
+			var stats;
+
+			var camera;
+			var scene;
+			var canvasRenderer, webglRenderer;
+
+			var mesh, zmesh, geometry;
+            
+            var directionalLight, pointLight;
+            
+			var mouseX = 0;
+			var mouseY = 0;
+
+			var windowHalfX = window.innerWidth >> 1;
+			var windowHalfY = window.innerHeight >> 1;
+
+            var render_canvas = 1, render_gl = 1;
+            var has_gl = 0;
+            
+            var bcanvas = document.getElementById("rcanvas");
+            var bwebgl = document.getElementById("rwebgl");
+            
+			document.addEventListener('mousemove', onDocumentMouseMove, false);
+
+			init();
+            
+			loop();
+            
+            //render_canvas = !has_gl;
+            bwebgl.style.display = has_gl ? "inline" : "none";
+            bcanvas.className = render_canvas ? "button" : "button inactive";
+            
+			setInterval(loop, 1000/60);
+            
+			function init() {
+
+				container = document.createElement('div');
+				document.body.appendChild(container);
+
+				camera = new THREE.Camera( 75, SCREEN_WIDTH / SCREEN_HEIGHT, 1, 100000 );
+                camera.position.z = 500;
+                camera.updateMatrix();
+
+				scene = new THREE.Scene();
+                
+                // SPHERES
+                
+                sphere = new Sphere( 100, 16, 8, 1 );
+                for (var i=0; i<10; i++) {
+                    mesh = new THREE.Mesh( sphere, [new THREE.MeshColorFillMaterial( 0xffffff ), new THREE.MeshColorStrokeMaterial(0x000000, 1, 1.5)] );
+                    mesh.position.x = 500 * (Math.random() - 0.5);
+                    mesh.position.y = 500 * (Math.random() - 0.5);
+                    mesh.position.z = 500 * (Math.random() - 0.5);
+                    mesh.scale.x = mesh.scale.y = mesh.scale.z = 0.25 * (Math.random() + 0.5);
+                    //mesh.doubleSided = true;
+                    mesh.overdraw = true;
+                    mesh.updateMatrix();
+                    scene.add(mesh);
+                }
+                
+
+				// LIGHTS
+
+                var ambient = new THREE.AmbientLight( 0x101010 );
+				scene.addLight( ambient );
+
+                directionalLight = new THREE.DirectionalLight( 0xffffff );
+                directionalLight.position.y = -70;
+                directionalLight.position.z = 100;
+				directionalLight.position.normalize();
+				scene.addLight( directionalLight );
+
+				pointLight = new THREE.PointLight( 0xffaa00 );
+                pointLight.position.x = 0;
+                pointLight.position.y = 0;
+                pointLight.position.z = 120;
+				//scene.addLight( pointLight );
+
+
+                mesh = new THREE.Mesh( sphere, new THREE.MeshColorFillMaterial( 0xff0000 ) );
+                mesh.scale.x = mesh.scale.y = mesh.scale.z = 0.1;
+                mesh.position = pointLight.position;
+                mesh.updateMatrix();
+                scene.add(mesh);
+
+
+                if( render_canvas ) {
+                    canvasRenderer = new THREE.CanvasRenderer();
+                    canvasRenderer.setSize( SCREEN_WIDTH, SCREEN_HEIGHT );
+                    container.appendChild( canvasRenderer.domElement );
+                }
+
+                if ( render_gl ) {
+                    try {
+                        webglRenderer = new THREE.WebGLRenderer();
+                        webglRenderer.setSize( SCREEN_WIDTH, SCREEN_HEIGHT );
+                        container.appendChild( webglRenderer.domElement );
+                        has_gl = 1;
+                    }
+                    catch (e) {
+                    }
+                }
+
+				stats = new Stats();
+				stats.domElement.style.position = 'absolute';
+				stats.domElement.style.top = '0px';
+                stats.domElement.style.zIndex = 100;
+				container.appendChild( stats.domElement );
+                
+                bcanvas.addEventListener("click", toggleCanvas, false);
+                bwebgl.addEventListener("click", toggleWebGL, false);
+
+                function createModel2() {
+                    
+                    // MESH
+                    
+                    geometry = new Female02( "obj/female02" );
+                    
+                    // full-mesh wireframe overlay
+                    //geometry.materials.push ( new THREE.MeshColorStrokeMaterial(0xff0000, 1, 1.5) );
+                    
+                    // full-mesh color overlay
+                    //geometry.materials.push ( new THREE.MeshColorFillMaterial(0xff00ff, 0.5) );
+                    
+                    // PROCEDURAL TEXTURES (decals)
+                    
+                    var x1 = document.createElement( "canvas" );
+                    var xc1 = x1.getContext("2d");
+                    x1.width = x1.height = 256;
+                                    
+                    xc1.shadowBlur = 3;
+                    xc1.shadowColor = "#000";
+                    xc1.font = "7pt arial";
+                    xc1.fillStyle = "hsla("+0+",90%,50%,1);"
+                    xc1.fillText("Three", 57, 29);
+                    
+                    xc1.fillStyle = "hsla("+0+",90%,50%,0.15);"
+                    xc1.fillRect(40, 70, 60, 50);
+                    
+                    for(var i=0;i<500;i++) {
+                        xc1.fillStyle = "hsla("+60*Math.random()+",90%,50%,0.5);"
+                        xc1.fillRect(40+60*Math.random(), 118+10*Math.random(), 2, 10);
+                    }
+
+                    var x2 = document.createElement( "canvas" );
+                    var xc2 = x2.getContext("2d");
+                    x2.width = x2.height = 128;
+                    xc2.fillStyle = "rgba(0,0,0,0.5)";
+                    for(var i=0;i<14;i++) {
+                        xc2.fillRect(0, 5+i*4, 54, 2);
+                        xc2.fillRect(i*4, 5, 2, 54);
+                    }
+
+                    var xm1 = new THREE.MeshBitmapUVMappingMaterial( x1 );
+                    xm1.loaded = 1;
+                    xm1.decalIndex = 0; // index of the original UV mapped material 
+
+                    var xm2 = new THREE.MeshBitmapUVMappingMaterial( x2 );
+                    xm2.loaded = 1;
+                    xm2.decalIndex = 1; // index of the original UV mapped material 
+                    
+                    geometry.materials.push ( xm1 );
+                    geometry.materials.push ( xm2 );
+
+                    zmesh = new THREE.Mesh( geometry, geometry.materials, 1 );
+                    zmesh.position.x = -80;
+                    zmesh.position.z = 50;
+                    zmesh.position.y = FLOOR;
+                    zmesh.scale.x = zmesh.scale.y = zmesh.scale.z = 3;
+                    zmesh.overdraw = true;
+                    zmesh.updateMatrix();
+                    scene.add(zmesh);
+
+                    // PLANES with all materials from the model
+                    
+                    createMaterialsPalette( geometry.materials, 100, 0 );
+                }
+
+                loadAsync( "obj/female02/female02.js", createModel2);
+
+			}
+
+            function loadAsync( url, callback ) {
+                
+                var el = document.createElement( 'script' );
+                el.type = 'text/javascript';
+                el.onload = callback;
+                el.src = url;
+                document.getElementsByTagName("head")[0].appendChild(el);
+
+            }
+            
+            function createMaterialsPalette( materials, size, bottom ) {
+                
+                for ( var i=0; i<materials.length; ++i ) {
+                    
+                    // material
+                    mesh = new THREE.Mesh( new Plane( size, size ), materials[i] );
+                    mesh.position.x = i * (size + 5) - ( ( materials.length - 1 )* ( size + 5 )/2);
+                    mesh.position.y = FLOOR + size/2 + bottom;
+                    mesh.position.z = -100;
+                    mesh.scale.x = mesh.scale.y = mesh.scale.z = 1;
+                    mesh.doubleSided = true;
+                    mesh.updateMatrix();
+                    scene.add(mesh);
+                    
+                    // number
+                    var x = document.createElement( "canvas" );
+                    var xc = x.getContext("2d");
+                    x.width = x.height = 128;
+                    xc.shadowColor = "#000";
+                    xc.shadowBlur = 7;
+                    xc.fillStyle = "orange";
+                    xc.font = "50pt arial bold";
+                    xc.fillText(i, 10, 64);
+                    
+                    var xm = new THREE.MeshBitmapUVMappingMaterial( x );
+                    xm.loaded = 1;
+                    
+                    mesh = new THREE.Mesh( new Plane( size, size ), xm );
+                    mesh.position.x = i * (size + 5) - ( ( materials.length - 1 )* ( size + 5 )/2);
+                    mesh.position.y = FLOOR + size/2 + bottom;
+                    mesh.position.z = -99;
+                    mesh.scale.x = mesh.scale.y = mesh.scale.z = 1;
+                    mesh.doubleSided = true;
+                    mesh.updateMatrix();
+                    scene.add(mesh);
+                }
+                
+            }
+            
+			function onDocumentMouseMove(event) {
+
+				mouseX = ( event.clientX - windowHalfX );
+				mouseY = ( event.clientY - windowHalfY );
+
+			}
+            
+			function loop() {
+
+				camera.position.x += ( mouseX - camera.position.x ) * .05;
+				camera.position.y += ( - mouseY - camera.position.y ) * .05;
+				camera.updateMatrix();
+                
+				if ( render_canvas ) canvasRenderer.render( scene, camera );
+				if ( render_gl && has_gl ) webglRenderer.render( scene, camera );
+
+				stats.update();
+
+			}
+
+            function log(text) {
+            
+                var e = document.getElementById("log");
+                e.innerHTML = text + "<br/>" + e.innerHTML;
+                
+            }
+            
+            function toggleCanvas() {
+            
+                render_canvas = !render_canvas;
+                bcanvas.className = render_canvas ? "button" : "button inactive";
+                
+                render_gl = !render_canvas;
+                bwebgl.className = render_gl ? "button" : "button inactive";
+                
+                if( has_gl )
+                    webglRenderer.domElement.style.display = render_gl ? "block" : "none";
+                
+                canvasRenderer.domElement.style.display = render_canvas ? "block" : "none";
+                
+            }
+            
+            function toggleWebGL() {
+            
+                render_gl = !render_gl;
+                bwebgl.className = render_gl ? "button" : "button inactive";
+                
+                render_canvas = !render_gl;
+                bcanvas.className = render_canvas ? "button" : "button inactive";
+                
+                if( has_gl )
+                    webglRenderer.domElement.style.display = render_gl ? "block" : "none";
+                    
+                canvasRenderer.domElement.style.display = render_canvas ? "block" : "none";
+                
+            }
+		</script>
+
+	</body>
+</html>

File diff suppressed because it is too large
+ 0 - 98
examples/obj/female02/female02.js


File diff suppressed because it is too large
+ 0 - 84
examples/obj/male02/male02.js


+ 1 - 4
examples/obj_convert_test.html

@@ -87,9 +87,6 @@
 		<script type="text/javascript" src="../src/renderers/renderables/RenderableLine.js"></script>
 		<script type="text/javascript" src="../src/renderers/renderables/RenderableLine.js"></script>
         -->
         -->
 		
 		
-        <!--
-		<script type="text/javascript" src="obj/female02/female02.js"></script>
-        -->
 
 
 		<script type="text/javascript" src="geometry/primitives/Sphere.js"></script>
 		<script type="text/javascript" src="geometry/primitives/Sphere.js"></script>
 		<script type="text/javascript" src="geometry/primitives/Plane.js"></script>
 		<script type="text/javascript" src="geometry/primitives/Plane.js"></script>
@@ -187,7 +184,7 @@
                 
                 
                 // SPHERES
                 // SPHERES
                 
                 
-                sphere = new Sphere( 100, 16, 8 );
+                sphere = new Sphere( 100, 16, 8, 1 );
                 for (var i=0; i<10; i++) {
                 for (var i=0; i<10; i++) {
                     mesh = new THREE.Mesh( sphere, new THREE.MeshColorFillMaterial( 0xffdddddd ) );
                     mesh = new THREE.Mesh( sphere, new THREE.MeshColorFillMaterial( 0xffdddddd ) );
                     mesh.position.x = 500 * (Math.random() - 0.5);
                     mesh.position.x = 500 * (Math.random() - 0.5);

+ 3 - 0
src/materials/MeshBitmapUVMappingMaterial.js

@@ -6,6 +6,9 @@ THREE.MeshBitmapUVMappingMaterial = function ( bitmap ) {
 
 
 	this.bitmap = bitmap;
 	this.bitmap = bitmap;
 
 
+    this.loaded = 0;
+    this.decalIndex = -1;
+    
 	this.toString = function () {
 	this.toString = function () {
 
 
 		return 'THREE.MeshBitmapUVMappingMaterial ( bitmap: ' + this.bitmap + ' )';
 		return 'THREE.MeshBitmapUVMappingMaterial ( bitmap: ' + this.bitmap + ' )';

+ 4 - 2
src/renderers/CanvasRenderer.js

@@ -345,7 +345,8 @@ THREE.CanvasRenderer = function () {
 						_bboxRect.inflate( _context.lineWidth );
 						_bboxRect.inflate( _context.lineWidth );
 
 
 
 
-					} else if ( material instanceof THREE.MeshBitmapUVMappingMaterial && m == element.materialIndex ) {
+					} else if ( material instanceof THREE.MeshBitmapUVMappingMaterial && 
+                                ( m == element.materialIndex || element.materialIndex == material.decalIndex ) ) {
 
 
 						bitmap = material.bitmap;
 						bitmap = material.bitmap;
 						bitmapWidth = bitmap.width - 1;
 						bitmapWidth = bitmap.width - 1;
@@ -523,7 +524,8 @@ THREE.CanvasRenderer = function () {
 
 
 						_bboxRect.inflate( _context.lineWidth );
 						_bboxRect.inflate( _context.lineWidth );
 
 
-					} else if ( material instanceof THREE.MeshBitmapUVMappingMaterial && m == element.materialIndex ) {
+					} else if ( material instanceof THREE.MeshBitmapUVMappingMaterial &&                                 
+                                ( m == element.materialIndex || element.materialIndex == material.decalIndex ) ) {
 
 
 						bitmap = material.bitmap;
 						bitmap = material.bitmap;
 						bitmapWidth = bitmap.width - 1;
 						bitmapWidth = bitmap.width - 1;

+ 1 - 1
utils/REVISION

@@ -1 +1 @@
-19
+20

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