diff --git a/examples/canvas_lights_pointlights.html b/examples/canvas_lights_pointlights.html index cb88375d..248c2368 100644 --- a/examples/canvas_lights_pointlights.html +++ b/examples/canvas_lights_pointlights.html @@ -73,15 +73,26 @@ light3 = new THREE.PointLight( 0x80ff80 ); scene.addLight( light3 ); - particle1 = new THREE.Particle( new THREE.ParticleCircleMaterial( { color: 0xff0040 } ) ); + var PI2 = Math.PI * 2; + var program = function ( context, color ) { + + context.fillStyle = color.__styleString; + context.beginPath(); + context.arc( 0, 0, 1, 0, PI2, true ); + context.closePath(); + context.fill(); + + } + + particle1 = new THREE.Particle( new THREE.ParticleCanvasMaterial( { color: 0xff0040, program: program } ) ); particle1.scale.x = particle1.scale.y = particle1.scale.z = 0.5; scene.addObject( particle1 ); - particle2 = new THREE.Particle( new THREE.ParticleCircleMaterial( { color: 0x0040ff } ) ); + particle2 = new THREE.Particle( new THREE.ParticleCanvasMaterial( { color: 0x0040ff, program: program } ) ); particle2.scale.x = particle2.scale.y = particle2.scale.z = 0.5; scene.addObject( particle2 ); - particle3 = new THREE.Particle( new THREE.ParticleCircleMaterial( { color: 0x80ff80 } ) ); + particle3 = new THREE.Particle( new THREE.ParticleCanvasMaterial( { color: 0x80ff80, program: program } ) ); particle3.scale.x = particle3.scale.y = particle3.scale.z = 0.5; scene.addObject( particle3 ); diff --git a/examples/canvas_lights_pointlights_smooth.html b/examples/canvas_lights_pointlights_smooth.html index afed9b2f..e57fcc12 100644 --- a/examples/canvas_lights_pointlights_smooth.html +++ b/examples/canvas_lights_pointlights_smooth.html @@ -73,15 +73,26 @@ light3 = new THREE.PointLight( 0x80ff80 ); scene.addLight( light3 ); - particle1 = new THREE.Particle( new THREE.ParticleCircleMaterial( { color: 0xff0040 } ) ); + var PI2 = Math.PI * 2; + var program = function ( context, color ) { + + context.fillStyle = color.__styleString; + context.beginPath(); + context.arc( 0, 0, 1, 0, PI2, true ); + context.closePath(); + context.fill(); + + } + + particle1 = new THREE.Particle( new THREE.ParticleCanvasMaterial( { color: 0xff0040, program: program } ) ); particle1.scale.x = particle1.scale.y = particle1.scale.z = 0.5; scene.addObject( particle1 ); - particle2 = new THREE.Particle( new THREE.ParticleCircleMaterial( { color: 0x0040ff } ) ); + particle2 = new THREE.Particle( new THREE.ParticleCanvasMaterial( { color: 0x0040ff, program: program } ) ); particle2.scale.x = particle2.scale.y = particle2.scale.z = 0.5; scene.addObject( particle2 ); - particle3 = new THREE.Particle( new THREE.ParticleCircleMaterial( { color: 0x80ff80 } ) ); + particle3 = new THREE.Particle( new THREE.ParticleCanvasMaterial( { color: 0x80ff80, program: program } ) ); particle3.scale.x = particle3.scale.y = particle3.scale.z = 0.5; scene.addObject( particle3 ); diff --git a/examples/canvas_lines.html b/examples/canvas_lines.html index 436a56af..e9513b90 100644 --- a/examples/canvas_lines.html +++ b/examples/canvas_lines.html @@ -41,7 +41,7 @@ function init() { var container, separation = 100, amountX = 50, amountY = 50, - particles, particle, material; + particles, particle; container = document.createElement('div'); document.body.appendChild(container); @@ -57,7 +57,22 @@ // particles - material = new THREE.ParticleCircleMaterial( { color: 0xffffff } ); + var PI2 = Math.PI * 2; + var material = new THREE.ParticleCanvasMaterial( { + + color: 0xffffff, + program: function ( context, color ) { + + context.fillStyle = color.__styleString; + context.beginPath(); + context.arc( 0, 0, 1, 0, PI2, true ); + context.closePath(); + context.fill(); + + } + + } ); + var geometry = new THREE.Geometry(); for ( var i = 0; i < 100; i ++ ) { diff --git a/examples/canvas_lines_sphere.html b/examples/canvas_lines_sphere.html index 964fca60..9bec612a 100644 --- a/examples/canvas_lines_sphere.html +++ b/examples/canvas_lines_sphere.html @@ -44,7 +44,7 @@ function init() { var container, separation = 100, amountX = 50, amountY = 50, - particles, particle, material; + particles, particle; container = document.createElement('div'); document.body.appendChild(container); @@ -60,9 +60,23 @@ // particles - material = new THREE.ParticleCircleMaterial( { color: 0xffffff, opacity: 1 } ); + var PI2 = Math.PI * 2; + var material = new THREE.ParticleCanvasMaterial( { - for (var i = 0; i < 1000; i++) { + color: 0xffffff, + program: function ( context, color ) { + + context.fillStyle = color.__styleString; + context.beginPath(); + context.arc( 0, 0, 1, 0, PI2, true ); + context.closePath(); + context.fill(); + + } + + } ); + + for ( var i = 0; i < 1000; i ++ ) { particle = new THREE.Particle( material ); particle.position.x = Math.random() * 2 - 1; diff --git a/examples/canvas_materials.html b/examples/canvas_materials.html index d33c99bb..ff0ffaf9 100644 --- a/examples/canvas_materials.html +++ b/examples/canvas_materials.html @@ -111,7 +111,18 @@ } - particleLight = new THREE.Particle( new THREE.ParticleCircleMaterial( { color: 0xffffff } ) ); + var PI2 = Math.PI * 2; + var program = function ( context, color ) { + + context.fillStyle = color.__styleString; + context.beginPath(); + context.arc( 0, 0, 1, 0, PI2, true ); + context.closePath(); + context.fill(); + + } + + particleLight = new THREE.Particle( new THREE.ParticleCanvasMaterial( { color: 0xffffff, program: program } ) ); particleLight.scale.x = particleLight.scale.y = particleLight.scale.z = 4; scene.addObject( particleLight ); diff --git a/examples/canvas_performance.html b/examples/canvas_performance.html index 0afeb97d..3bf3b115 100644 --- a/examples/canvas_performance.html +++ b/examples/canvas_performance.html @@ -14,7 +14,7 @@ - + diff --git a/examples/canvas_sandbox.html b/examples/canvas_sandbox.html index 15f40b77..5e084b3a 100644 --- a/examples/canvas_sandbox.html +++ b/examples/canvas_sandbox.html @@ -51,7 +51,7 @@ - + @@ -174,7 +174,7 @@ for ( var i = 0; i < 10; i ++ ) { sphere = new THREE.Mesh( geometry, material ); - sphere.overdraw = true; + // sphere.overdraw = true; sphere.position.x = Math.random() * 1000 - 500; sphere.position.y = Math.random() * 1000 - 500; diff --git a/examples/misc_ubiquity_test.html b/examples/misc_ubiquity_test.html index ec136559..86fca7b8 100644 --- a/examples/misc_ubiquity_test.html +++ b/examples/misc_ubiquity_test.html @@ -52,7 +52,7 @@ - + @@ -205,18 +205,6 @@ mesh.scale.x = mesh.scale.y = mesh.scale.z = 2; scene.addObject( mesh ); - // PARTICLES - - for ( var i = 0; i < 100; i ++ ) { - - particle = new THREE.Particle( new THREE.ParticleCircleMaterial( { color: Math.random() * 0xffffff } ) ); - particle.position.x = Math.random() * 1000 - 500; - particle.position.y = Math.random() * 1000 - 500; - particle.position.z = Math.random() * 1000 - 500; - particle.scale.x = particle.scale.y = 10; - scene.addObject( particle ); - - } // LIGHTS diff --git a/examples/obj/Qrcode.js b/examples/obj/Qrcode.js index 2be1cddf..660200f9 100644 --- a/examples/obj/Qrcode.js +++ b/examples/obj/Qrcode.js @@ -1444,13 +1444,13 @@ var Qrcode = function () { function f3( a, b, c, material ) { - scope.faces.push( new THREE.Face3( a, b, c, null, material ) ); + scope.faces.push( new THREE.Face3( a, b, c, null, null, material ) ); } function f4( a, b, c, d, material ) { - scope.faces.push( new THREE.Face4( a, b, c, d, null, material ) ); + scope.faces.push( new THREE.Face4( a, b, c, d, null, null, material ) ); } diff --git a/examples/obj/WaltHead.js b/examples/obj/WaltHead.js index d445bf76..56ce5c26 100644 --- a/examples/obj/WaltHead.js +++ b/examples/obj/WaltHead.js @@ -4892,15 +4892,9 @@ var WaltHead = function () { } - function f3( a, b, c, nx, ny, nz ) { + function f3( a, b, c ) { - scope.faces.push( new THREE.Face3( a, b, c, (nx || ny || nz) ? new THREE.Vector3( nx, ny, nz ) : null ) ); - - } - - function f4( a, b, c, d, nx, ny, nz ) { - - scope.faces.push( new THREE.Face4( a, b, c, d, (nx || ny || nz) ? new THREE.Vector3( nx, ny, nz ) : null ) ); + scope.faces.push( new THREE.Face3( a, b, c ) ); } diff --git a/src/extras/geometries/Sphere.js b/src/extras/geometries/Sphere.js index 354cf4eb..cf25cb04 100644 --- a/src/extras/geometries/Sphere.js +++ b/src/extras/geometries/Sphere.js @@ -6,7 +6,7 @@ var Sphere = function ( radius, segmentsWidth, segmentsHeight ) { THREE.Geometry.call( this ); - + var gridX = segmentsWidth || 8, gridY = segmentsHeight || 6; diff --git a/src/renderers/CanvasRenderer.js b/src/renderers/CanvasRenderer.js index 16d52fb7..c24fa9f6 100644 --- a/src/renderers/CanvasRenderer.js +++ b/src/renderers/CanvasRenderer.js @@ -20,7 +20,7 @@ THREE.CanvasRenderer = function () { _contextFillStyle = null, _contextLineWidth = 1, - _v1, _v2, _v3, + _v1, _v2, _v3, _v4, _v1x, _v1y, _v2x, _v2y, _v3x, _v3y, _color = new THREE.Color(), @@ -31,7 +31,7 @@ THREE.CanvasRenderer = function () { _near, _far, - _bitmap, + _bitmap, _uvs, _uv1x, _uv1y, _uv2x, _uv2y, _uv3x, _uv3y, _clipRect = new THREE.Rectangle(), @@ -248,6 +248,15 @@ THREE.CanvasRenderer = function () { } + } else if ( element instanceof THREE.RenderableFace4 ) { + + _v1 = element.v1; _v2 = element.v2; _v3 = element.v3; _v4 = element.v4; + + _v1.positionScreen.x *= _canvasWidthHalf; _v1.positionScreen.y *= _canvasHeightHalf; + _v2.positionScreen.x *= _canvasWidthHalf; _v2.positionScreen.y *= _canvasHeightHalf; + _v3.positionScreen.x *= _canvasWidthHalf; _v3.positionScreen.y *= _canvasHeightHalf; + _v4.positionScreen.x *= _canvasWidthHalf; _v4.positionScreen.y *= _canvasHeightHalf; + } /* @@ -495,11 +504,12 @@ THREE.CanvasRenderer = function () { if ( material instanceof THREE.MeshBasicMaterial ) { - if ( material.map/* && !material.wireframe*/ ) { + if ( material.map/* && !material.wireframe*/ ) { if ( material.map.mapping instanceof THREE.UVMapping ) { - texturePath( _v1x, _v1y, _v2x, _v2y, _v3x, _v3y, material.map.image, element.uvs[ 0 ].u, element.uvs[ 0 ].v, element.uvs[ 1 ].u, element.uvs[ 1 ].v, element.uvs[ 2 ].u, element.uvs[ 2 ].v ); + _uvs = element.uvs[ 0 ]; + texturePath( _v1x, _v1y, _v2x, _v2y, _v3x, _v3y, material.map.image, _uvs[ 0 ].u, _uvs[ 0 ].v, _uvs[ 1 ].u, _uvs[ 1 ].v, _uvs[ 2 ].u, _uvs[ 2 ].v ); } @@ -544,7 +554,8 @@ THREE.CanvasRenderer = function () { if ( material.map.mapping instanceof THREE.UVMapping ) { - texturePath( _v1x, _v1y, _v2x, _v2y, _v3x, _v3y, material.map.image, element.uvs[ 0 ].u, element.uvs[ 0 ].v, element.uvs[ 1 ].u, element.uvs[ 1 ].v, element.uvs[ 2 ].u, element.uvs[ 2 ].v ); + _uvs = element.uvs[ 0 ]; + texturePath( _v1x, _v1y, _v2x, _v2y, _v3x, _v3y, material.map.image, _uvs[ 0 ].u, _uvs[ 0 ].v, _uvs[ 1 ].u, _uvs[ 1 ].v, _uvs[ 2 ].u, _uvs[ 2 ].v ); } @@ -675,6 +686,37 @@ THREE.CanvasRenderer = function () { function texturePath( x0, y0, x1, y1, x2, y2, bitmap, u0, v0, u1, v1, u2, v2 ) { + /* + // http://tulrich.com/geekstuff/canvas/jsgl.js + + var m11, m12, m21, m22, dx, dy, denom, + width = bitmap.width - 1, + height = bitmap.height - 1; + + u0 *= width; v0 *= height; + u1 *= width; v1 *= height; + u2 *= width; v2 *= height; + + _context.save(); + + denom = u0 * (v2 - v1) - u1 * v2 + u2 * v1 + (u1 - u2) * v0; + + if ( denom == 0 ) return; + + m11 = - (v0 * (x2 - x1) - v1 * x2 + v2 * x1 + (v1 - v2) * x0) / denom; + m12 = (v1 * y2 + v0 * (y1 - y2) - v2 * y1 + (v2 - v1) * y0) / denom; + m21 = (u0 * (x2 - x1) - u1 * x2 + u2 * x1 + (u1 - u2) * x0) / denom; + m22 = - (u1 * y2 + u0 * (y1 - y2) - u2 * y1 + (u2 - u1) * y0) / denom; + dx = (u0 * (v2 * x1 - v1 * x2) + v0 * (u1 * x2 - u2 * x1) + (u2 * v1 - u1 * v2) * x0) / denom; + dy = (u0 * (v2 * y1 - v1 * y2) + v0 * (u1 * y2 - u2 * y1) + (u2 * v1 - u1 * v2) * y0) / denom; + + _context.transform( m11, m12, m21, m22, dx, dy ); + + _context.clip(); + _context.drawImage( bitmap, 0, 0 ); + _context.restore(); + */ + // http://extremelysatisfactorytotalitarianism.com/blog/?p=2120 var a, b, c, d, e, f, det, idet, diff --git a/src/renderers/Projector.js b/src/renderers/Projector.js index 2d22ab2a..aad7f40d 100644 --- a/src/renderers/Projector.js +++ b/src/renderers/Projector.js @@ -8,7 +8,7 @@ THREE.Projector = function() { var _object, _objectCount, _objectPool = [], _vertex, _vertexCount, _vertexPool = [], - _face3, _face32, _face3Count, _face3Pool = [], + _face, _face3Count, _face3Pool = [], _face4Count, _face4Pool = [], _line, _lineCount, _linePool = [], _particle, _particleCount, _particlePool = [], @@ -95,13 +95,14 @@ THREE.Projector = function() { this.projectScene = function ( scene, camera, sort ) { var renderList = [], near = camera.near, far = camera.far, - o, ol, v, vl, f, fl, n, nl, objects, object, - objectMatrix, objectMaterials, - objectMatrixRotation, + o, ol, v, vl, f, fl, n, nl, c, cl, u, ul, objects, object, + objectMatrix, objectMatrixRotation, objectMaterials, objectOverdraw, geometry, vertices, vertex, vertexPositionScreen, - faces, face, faceVertexNormals, faceVertexUvs, normal, v1, v2, v3, v4; + faces, face, faceVertexNormals, normal, faceVertexUvs, uvs, + v1, v2, v3, v4; _face3Count = 0; + _face4Count = 0; _lineCount = 0; _particleCount = 0; @@ -124,6 +125,7 @@ THREE.Projector = function() { objectMatrixRotation = object.matrixRotationWorld; objectMaterials = object.materials; + objectOverdraw = object.overdraw; _vertexCount = 0; @@ -132,6 +134,7 @@ THREE.Projector = function() { geometry = object.geometry; vertices = geometry.vertices; faces = geometry.faces; + faceVertexUvs = geometry.faceVertexUvs; for ( v = 0, vl = vertices.length; v < vl; v ++ ) { @@ -160,59 +163,70 @@ THREE.Projector = function() { v2 = _vertexPool[ face.b ]; v3 = _vertexPool[ face.c ]; - if ( v1.visible && v2.visible && v3.visible ) { + if ( !v1.visible || !v2.visible || !v3.visible ) continue; - if ( ( object.doubleSided || ( object.flipSided != - ( v3.positionScreen.x - v1.positionScreen.x ) * ( v2.positionScreen.y - v1.positionScreen.y ) - - ( v3.positionScreen.y - v1.positionScreen.y ) * ( v2.positionScreen.x - v1.positionScreen.x ) < 0 ) ) ) { + if ( object.doubleSided || ( object.flipSided != + ( v3.positionScreen.x - v1.positionScreen.x ) * ( v2.positionScreen.y - v1.positionScreen.y ) - + ( v3.positionScreen.y - v1.positionScreen.y ) * ( v2.positionScreen.x - v1.positionScreen.x ) < 0 ) ) { - _face3 = getNextFaceInPool(); + _face = getNextFace3InPool(); - _face3.v1.copy( v1 ); - _face3.v2.copy( v2 ); - _face3.v3.copy( v3 ); + _face.v1.copy( v1 ); + _face.v2.copy( v2 ); + _face.v3.copy( v3 ); - _face3.normalWorld.copy( face.normal ); - objectMatrixRotation.multiplyVector3( _face3.normalWorld ); + _face.normalWorld.copy( face.normal ); + objectMatrixRotation.multiplyVector3( _face.normalWorld ); - _face3.centroidWorld.copy( face.centroid ); - objectMatrix.multiplyVector3( _face3.centroidWorld ); + _face.centroidWorld.copy( face.centroid ); + objectMatrix.multiplyVector3( _face.centroidWorld ); - _face3.centroidScreen.copy( _face3.centroidWorld ); - _projScreenMatrix.multiplyVector3( _face3.centroidScreen ); + _face.centroidScreen.copy( _face.centroidWorld ); + _projScreenMatrix.multiplyVector3( _face.centroidScreen ); - faceVertexNormals = face.vertexNormals; - _face3VertexNormals = _face3.vertexNormalsWorld; + faceVertexNormals = face.vertexNormals; - for ( n = 0; n < 3; n ++ ) { + for ( n = 0, nl = faceVertexNormals.length; n < nl; n ++ ) { - normal = _face3VertexNormals[ n ]; - normal.copy( faceVertexNormals[ n ] ); - objectMatrixRotation.multiplyVector3( normal ); - - } - - faceVertexUvs = geometry.faceVertexUvs[ 0 ][ f ]; - - if ( faceVertexUvs ) { - - _face3.uvs[ 0 ] = faceVertexUvs[ 0 ]; - _face3.uvs[ 1 ] = faceVertexUvs[ 1 ]; - _face3.uvs[ 2 ] = faceVertexUvs[ 2 ]; - - } - - _face3.meshMaterials = objectMaterials; - _face3.faceMaterials = face.materials; - - _face3.z = _face3.centroidScreen.z; - - renderList.push( _face3 ); + normal = _face.vertexNormalsWorld[ n ]; + normal.copy( faceVertexNormals[ n ] ); + objectMatrixRotation.multiplyVector3( normal ); } + for ( c = 0, cl = faceVertexUvs.length; c < cl; c ++ ) { + + uvs = faceVertexUvs[ c ][ f ]; + + if ( !uvs ) continue; + + for ( u = 0, ul = uvs.length; u < ul; u ++ ) { + + _face.uvs[ c ][ u ] = uvs[ u ]; + + } + + } + + _face.meshMaterials = objectMaterials; + _face.faceMaterials = face.materials; + _face.overdraw = objectOverdraw; + + _face.z = _face.centroidScreen.z; + + renderList.push( _face ); + } + } else if ( face instanceof THREE.Face4 ) { + + v1 = _vertexPool[ face.a ]; + v2 = _vertexPool[ face.b ]; + v3 = _vertexPool[ face.c ]; + v4 = _vertexPool[ face.d ]; + + if ( !v1.visible || !v2.visible || !v3.visible || !v4.visible ) continue; + } /* else if ( face instanceof THREE.Face4 ) { v1 = vertices[ face.a ]; v2 = vertices[ face.b ]; v3 = vertices[ face.c ]; v4 = vertices[ face.d ]; @@ -403,7 +417,7 @@ THREE.Projector = function() { } - function getNextFaceInPool() { + function getNextFace3InPool() { var face = _face3Pool[ _face3Count ] = _face3Pool[ _face3Count ] || new THREE.RenderableFace3(); @@ -413,6 +427,16 @@ THREE.Projector = function() { } + function getNextFace4InPool() { + + var face = _face4Pool[ _face4Count ] = _face4Pool[ _face4Count ] || new THREE.RenderableFace4(); + + _face4Count ++; + + return face; + + } + function getNextLineInPool() { var line = _linePool[ _lineCount ] = _linePool[ _lineCount ] || new THREE.RenderableLine(); diff --git a/src/renderers/renderables/RenderableFace3.js b/src/renderers/renderables/RenderableFace3.js index 2a461c7c..c86eae54 100644 --- a/src/renderers/renderables/RenderableFace3.js +++ b/src/renderers/renderables/RenderableFace3.js @@ -16,7 +16,8 @@ THREE.RenderableFace3 = function () { this.meshMaterials = null; this.faceMaterials = null; - this.uvs = []; + this.overdraw = false; + this.uvs = [[]]; this.z = null;