Last active
August 29, 2015 13:56
-
-
Save zz85/9087239 to your computer and use it in GitHub Desktop.
Exploring ParametricGeometry2
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* @author zz85 / https://github.com/zz85 | |
* Parametric Surfaces Geometry | |
* based on the brilliant article by @prideout http://prideout.net/blog/?p=44 | |
* | |
* new THREE.ParametricGeometry( parametricFunction, uSegments, ySegements ); | |
* | |
*/ | |
THREE.ParametricGeometry2 = function ( func, slices, stacks ) { | |
THREE.Geometry2.call( this, slices * stacks * 2 * 3 ); | |
// Buffer needed is slices * stacks * 2 triangles * 3 vertices | |
var vertices = this.vertices; | |
var normals = this.normals; | |
var uvs = this.uvs; | |
var i, il, j, p; | |
var u, v; | |
var offset = 0; | |
var stackCount = stacks + 1; | |
var sliceCount = slices + 1; | |
var verts = []; | |
for ( i = 0; i <= stacks; i ++ ) { | |
v = i / stacks; | |
for ( j = 0; j <= slices; j ++ ) { | |
u = j / slices; | |
p = func( u, v ); | |
verts.push( p ); | |
} | |
} | |
var a, b, c, d; | |
var uva, uvb, uvc, uvd; | |
var uvOffset = 0; | |
function verts_push() { | |
for (var i=0; i < arguments.length; i++) { | |
vertices[ offset++ ] = arguments[i]; | |
} | |
} | |
function uvs_push() { | |
for (var i=0; i < arguments.length; i++) { | |
uvs[ uvOffset++ ] = arguments[i]; | |
} | |
} | |
uva = new THREE.Vector2(); | |
uvb = new THREE.Vector2(); | |
uvc = new THREE.Vector2(); | |
uvd = new THREE.Vector2(); | |
for ( i = 0; i < stacks; i ++ ) { | |
for ( j = 0; j < slices; j ++ ) { | |
a = i * sliceCount + j; | |
b = i * sliceCount + j + 1; | |
c = (i + 1) * sliceCount + j + 1; | |
d = (i + 1) * sliceCount + j; | |
var va = verts[ a ], | |
vb = verts[ b ], | |
vc = verts[ c ], | |
vd = verts[ d ]; | |
verts_push( va.x, va.y, va.z, | |
vb.x, vb.y, vb.z, | |
vd.x, vd.y, vd.z ); | |
verts_push( vb.x, vb.y, vb.z, | |
vc.x, vc.y, vc.z, | |
vd.x, vd.y, vd.z ); | |
// Equivalent of | |
// faces.push( new THREE.Face3( a, b, d ) ); | |
// faces.push( new THREE.Face3( b, c, d ) ); | |
uva.set( j / slices, i / stacks ); | |
uvb.set( (j + 1 ) / slices, i / stacks ); | |
uvc.set( ( j + 1 ) / slices, ( i + 1 ) / stacks ); | |
uvd.set( j / slices, ( i + 1 ) / stacks ); | |
uvs_push( uva.x, uva.y, uvb.x, uvb.y, uvd.x, uvd.y ); | |
uvs_push( uvb.x, uvb.y, uvc.x, uvc.y, uvd.x, uvd.y ); | |
// uvs.push( [ uva, uvb, uvd ] ); | |
// uvs.push( [ uvb.clone(), uvc, uvd.clone() ] ); | |
} | |
} | |
var normal = new THREE.Vector3(); | |
var cb = new THREE.Vector3(), ab = new THREE.Vector3(); | |
var vA = new THREE.Vector3(), vB = new THREE.Vector3(), vC = new THREE.Vector3(); | |
/* Yeah compute all face normals given all vertices are triangles */ | |
function computeFaceNormals() { | |
var l = vertices.length / 3 / 3; | |
var j; | |
var m = 0; | |
for (var i = 0; i < l; i++ ) { | |
j = i * 3 * 3; | |
vA.set( vertices[ j++ ], vertices[ j++ ], vertices[ j++ ] ); | |
vB.set( vertices[ j++ ], vertices[ j++ ], vertices[ j++ ] ); | |
vC.set( vertices[ j++ ], vertices[ j++ ], vertices[ j++ ] ); | |
cb.subVectors( vC, vB ); | |
ab.subVectors( vA, vB ); | |
cb.cross( ab ).normalize(); | |
normal.copy( cb ); | |
normals[ m++ ] = normal.x; | |
normals[ m++ ] = normal.y; | |
normals[ m++ ] = normal.z; | |
} | |
} | |
// this.computeCentroids(); | |
computeFaceNormals(); | |
// this.computeVertexNormals(); | |
}; | |
THREE.ParametricGeometry2.prototype = Object.create( THREE.Geometry2.prototype ); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment