Skip to content

Instantly share code, notes, and snippets.

@sketchpunk
Created January 12, 2021 18:49
Show Gist options
  • Save sketchpunk/05db0f27e7989e76ef9d738c9aabdfcf to your computer and use it in GitHub Desktop.
Save sketchpunk/05db0f27e7989e76ef9d738c9aabdfcf to your computer and use it in GitHub Desktop.
TriMesh
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