Created
January 12, 2021 18:49
-
-
Save sketchpunk/05db0f27e7989e76ef9d738c9aabdfcf to your computer and use it in GitHub Desktop.
TriMesh
This file contains hidden or 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
window.onload = function(){ | |
let mesh = new TriMesh(); | |
mesh.add( | |
[-0.1, 0.0, 0.1], | |
[0.1, 0.0, 0.1], | |
[0.1, 0.0, 0.-1], | |
).add( | |
[0.1, 0.0, 0.-1], | |
[-0.1, 0.0, 0.-1], | |
[-0.1, 0.0, 0.1], | |
); | |
console.log( mesh.output() ); | |
/* | |
idx : [0,1,2,2,3,0] | |
norm : [0,1,0, 0,1,0, 0,1,0, 0,1,0] | |
verts : [ -0.1,0.0,0.1, 0.1,0.0,0.1, 0.1,0.0,0.-1, -0.1,0.0,0.-1] | |
*/ | |
}; | |
class TriMesh{ | |
_idx = 0; | |
_indices = new Array(); | |
_map = new Map(); | |
constructor(){} | |
add( a, b, c ){ | |
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
// Get Vertex Info ( Create of doesn't exist ) | |
let ao = this.get_v( a ), | |
bo = this.get_v( b ), | |
co = this.get_v( c ); | |
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
// Save Triangle Index | |
this._indices.push( ao[6], bo[6], co[6] ); | |
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
// Compute Normal | |
let ax = b[0] - a[0], // ab = b - a | |
ay = b[1] - a[1], | |
az = b[2] - a[2], | |
bx = c[0] - a[0], // ac = c - a | |
by = c[1] - a[1], | |
bz = c[2] - a[2], | |
nx = ay * bz - az * by, // cross( ab, ac ); | |
ny = az * bx - ax * bz, | |
nz = ax * by - ay * bx, | |
li = 1 / Math.sqrt( nx*nx + ny*ny + nz*nz ); // 1 / len( n ) | |
// Normalize Direction | |
nx *= li; | |
ny *= li; | |
nz *= li; | |
// Add Normal to Cache, Will be normalized again for smooth shading | |
ao[ 3 ] += nx; | |
ao[ 4 ] += ny; | |
ao[ 5 ] += nz; | |
bo[ 3 ] += nx; | |
bo[ 4 ] += ny; | |
bo[ 5 ] += nz; | |
co[ 3 ] += nx; | |
co[ 4 ] += ny; | |
co[ 5 ] += nz; | |
return this; | |
} | |
get_v( v ){ | |
let x = Math.floor( v[0] * 1000 ), | |
y = Math.floor( v[1] * 1000 ), | |
z = Math.floor( v[2] * 1000 ), | |
k = x + "_" + y + "_" + z, | |
o = this._map.get( k ); | |
if( o ) return o; | |
o = [ | |
v[0], v[1], v[2], // XYZ | |
0, 0, 0, // Normal | |
this._idx++, // Vert Array Index | |
]; | |
this._map.set( k, o ); | |
return o; | |
} | |
output(){ | |
let cnt = this._idx * 3, | |
verts = new Float32Array( cnt ), | |
norm = new Float32Array( cnt ), | |
v, i, li; | |
for( v of this._map.values() ){ | |
i = v[ 6 ] * 3; // Index to Flat Vert Index | |
li = 1 / Math.sqrt( v[3]**2 + v[4]**2 + v[5]**2 ); | |
verts[ i ] = v[ 0 ]; // Save Vert to Flat Array | |
verts[ i+1 ] = v[ 1 ]; | |
verts[ i+2 ] = v[ 2 ]; | |
norm[ i ] = v[ 3 ] * li; // Normalize Normal before Saving | |
norm[ i+1 ] = v[ 4 ] * li; | |
norm[ i+2 ] = v[ 5 ] * li; | |
} | |
return { | |
verts : verts, | |
norm : norm, | |
idx : new Uint16Array( this._indices ), | |
}; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment