@sohale/implisolid
Version:
A Solid Modelling Kernel in Javascript based on Implicit Surfaces, for MP5 file format
368 lines (272 loc) • 11.4 kB
HTML
<html>
<head>
<meta charset="utf-8"/>
</head>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r77/three.js"></script>
<script type="text/javascript" src="./controls/OrbitControls.js"></script>
<body>
Geometry that can be changed. (updated).
<br>
<script>;
var WIREFRAME = false;
var main;
var global_time = 0;
/*
MyBufferGeometry = function ( verts, faces ) {
//console.log(faces);
console.log("MyBufferGeometry");
THREE.BufferGeometry.call( this );
this.type = 'MyBufferGeometry';
this.parameters = {
//width: width,
//height: height,
//depth: depth,
//widthSegments: widthSegments,
//heightSegments: heightSegments,
//depthSegments: depthSegments
};
var vertexCount = verts.length/3;
var facecount = faces.length/3;
var indexCount = facecount*3;
console.log("vertexCount="+vertexCount+ " , facecount=" + facecount+ " facecount*3="+(facecount*3));
// buffers
var indices = new ( indexCount > 65535 ? Uint32Array : Uint16Array )( indexCount );
var vertices = new Float32Array( vertexCount * 3 );
var normals = new Float32Array( vertexCount * 3 );
var uvs = new Float32Array( vertexCount * 2 );
// offset variables
//var vertexBufferOffset = 0;
//var uvBufferOffset = 0;
//var indexBufferOffset = 0;
//var numberOfVertices = 0;
// group variables
//var groupStart = 0;
// build each side of the box geometry
//output: vertices, normals, uvs, indices
nans_warnings = 0;
//console.log("vertexCount " + vertexCount)
SCALE = 1.
for(var i=0; i < vertexCount; i++)
{
for(var di = 0; di < 3; di++)
vertices[i*3+di] = verts[i*3+di] * SCALE;
x = verts[i*3+0];
y = verts[i*3+1];
z = verts[i*3+2];
//console.log(x+" , " + y + " , " + z);
d = Math.sqrt(x*x+y*y+z*z);
d=d+0.;
//if(d==0) d=1.;
if(isNaN(d)) {
d=1.;x=1.;y=1.;z=1.;
console.log("Warning");
}
//console.log("x y z"+x+" "+y+" "+z+" / "+ d)
sgn = +1;
normals[i*3 + 0] = x/d*sgn;
normals[i*3 + 1] = y/d*sgn;
normals[i*3 + 2] = z/d*sgn;
if(isNaN(x/d))
nans_warnings ++;
d2 = Math.sqrt(x*x+y*y);
uvs[i*2+0] = x/d2;
uvs[i*2+1] = y/d2;
}
for(var i=0; i < facecount; i++)
for(var si=0; si<3; si++)
indices[i*3+si] = faces[i*3+si];
//console.log(indices);
materialIndex = 0;
this.addGroup( 0, facecount*3, materialIndex ); //not sure about *3 . Why??
if(nans_warnings > 0)
console.error("WARNING: NaN in vertices. "+nans_warnings/978+" out of "+vertexCount/978+ " subtract:"+(vertexCount-nans_warnings)/978);
//this.addGroup( groupStart, groupCount, materialIndex ); //groupCount is same as indices' index.
//modified, but not output: indexBufferOffset, vertexBufferOffset, uvBufferOffset, numberOfVertices, groupStart
// build geometry
this.setIndex( new THREE.BufferAttribute( indices, 3 ) );
this.addAttribute( 'position', new THREE.BufferAttribute( vertices, 3 ) );
this.addAttribute( 'normal', new THREE.BufferAttribute( normals, 3 ) );
this.addAttribute( 'uv', new THREE.BufferAttribute( uvs, 2 ) );
// helper functions
function calculateVertexCount ( w, h, d ) {
var vertices = 0;
// calculate the amount of vertices for each side (plane)
vertices += (w + 1) * (h + 1) * 2; // xy
vertices += (w + 1) * (d + 1) * 2; // xz
vertices += (d + 1) * (h + 1) * 2; // zy
return vertices;
}
function calculateIndexCount ( w, h, d ) {
var index = 0;
// calculate the amount of squares for each side
index += w * h * 2; // xy
index += w * d * 2; // xz
index += d * h * 2; // zy
return index * 6; // two triangles per square => six vertices per square
}
};
MyBufferGeometry.prototype = Object.create( THREE.BufferGeometry.prototype );
MyBufferGeometry.prototype.constructor = MyBufferGeometry;
*/
/*
MyGeometry = function (verts, faces) {
//vects, faces
THREE.Geometry.call( this );
this.type = 'ImplicitGeometry'; //?
this.parameters = {
//width: width,
//height: height,
//depth: depth,
//widthSegments: widthSegments,
//heightSegments: heightSegments,
//depthSegments: depthSegments
};
//faces = faces.subarray(0, 300);
this.fromBufferGeometry( new MyBufferGeometry( verts, faces ) );
//this.mergeVertices();
};
MyGeometry.prototype = Object.create( THREE.Geometry.prototype );
MyGeometry.prototype.constructor = MyGeometry;
*/
// MyLiveUpdatableGeometry
function LiveGeometry() {
var material = undefined;
THREE.ImmediateRenderObject.call( this, material );
this.setVF = function(verts, faces){
}
};
LiveGeometry.prototype = Object.create( THREE.Geometry.prototype );
LiveGeometry.prototype.constructor = LiveGeometry;
var materials_list;
main_mesh = null;
var meshf = null;
var mesh2 = null;
var o;
function init2() {
scene = new THREE.Scene();
//canvas_width = 300; canvas_height = 300;
var canvas_width = window.innerWidth, canvas_height = window.innerHeight;
camera = new THREE.PerspectiveCamera( 75, canvas_width / canvas_height, 1, 10000 );
camera.position.z = 1000;
materials_list = look_nice(scene);
material = new THREE.MeshBasicMaterial( { color: 0xff0000, wireframe: true, opacity:0.3, transparent: true, } );
//geometry = new LiveGeometry();
geometry = new THREE.BoxGeometry( 200, 200, 200 );
main_mesh = new THREE.Mesh( geometry, material );
main_mesh.position.set( 0, 0, 0 );
main_mesh.scale.set( 300, 300, 300 );
scene.add( main_mesh );
o = new THREE.ImmediateRenderObject(materials_list[3]);
meshf = new THREE.Mesh( geometry, materials_list[3] );
meshf.position.set( 0, 0, 0 );
meshf.scale.set( 300, 300, 300 );
scene.add( meshf );
var geo2 = new THREE.BoxGeometry( 20, 20, 20 );
mesh2 = new THREE.Mesh( geo2, material );
mesh2.position.set( 0, 0, 0 );
scene.add( mesh2 );
var dirLight = new THREE.DirectionalLight(0xffffff, 1);
dirLight.position.set(100, 100, 50);
scene.add(dirLight);
console.log("RENDERER");
renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setSize( canvas_width, canvas_height );
document.body.appendChild( renderer.domElement );
function doKeyPressListener(event){
if ( event.keyCode == 32 ) {
update_mc();
}
else
console.log(event.keyCode);
}
window.addEventListener( "keydown", doKeyPressListener, false );
// CONTROLS
//see https://github.com/mrdoob/three.js/blob/master/examples/webgl_geometry_teapot.html
var cameraControls = new THREE.OrbitControls( camera, renderer.domElement );
cameraControls.target.set( 0, 0, 0 );
cameraControls.addEventListener( 'change', function () {;} );
}
function update_mc(){
var geometry = make_geometry();
meshf = new THREE.Mesh( geometry, materials_list[3] );
meshf.position.set( 0, 0, 0 );
meshf.scale.set( 300, 300, 300 );
scene.add( meshf );
}
//based on http://threejs.org/examples/#webgl_materials
function generateTexture() {
var canvas = document.createElement( 'canvas' );
canvas.width = 256;
canvas.height = 256;
var context = canvas.getContext( '2d' );
var image = context.getImageData( 0, 0, 256, 256 );
var x = 0, y = 0;
for ( var i = 0, j = 0, l = image.data.length; i < l; i += 4, j ++ ) {
x = j % 256;
y = x == 0 ? y + 1 : y;
image.data[ i ] = 255;
image.data[ i + 1 ] = 255;
image.data[ i + 2 ] = 255;
image.data[ i + 3 ] = Math.floor( x ^ y );
}
context.putImageData( image, 0, 0 );
return canvas;
}
function look_nice(scene){
var materials = [];
// Grid
var line_material = new THREE.LineBasicMaterial( { color: 0x303030 } ),
geometry = new THREE.Geometry(),
floor = -75, step = 25;
for ( var i = 0; i <= 40; i ++ ) {
geometry.vertices.push( new THREE.Vector3( - 500, floor, i * step - 500 ) );
geometry.vertices.push( new THREE.Vector3( 500, floor, i * step - 500 ) );
geometry.vertices.push( new THREE.Vector3( i * step - 500, floor, -500 ) );
geometry.vertices.push( new THREE.Vector3( i * step - 500, floor, 500 ) );
}
var line = new THREE.LineSegments( geometry, line_material );
scene.add( line );
// Materials
var texture = new THREE.Texture( generateTexture() );
texture.needsUpdate = true;
materials.push( new THREE.MeshLambertMaterial( { map: texture, transparent: true } ) );
materials.push( new THREE.MeshLambertMaterial( { color: 0xdddddd, shading: THREE.FlatShading } ) );
materials.push( new THREE.MeshPhongMaterial( { color: 0xdddddd, specular: 0x009900, shininess: 30, shading: THREE.FlatShading } ) );
materials.push( new THREE.MeshNormalMaterial( ) );
materials.push( new THREE.MeshBasicMaterial( { color: 0xffaa00, transparent: true, blending: THREE.AdditiveBlending } ) );
//materials.push( new THREE.MeshBasicMaterial( { color: 0xff0000, blending: THREE.SubtractiveBlending } ) );
materials.push( new THREE.MeshLambertMaterial( { color: 0xdddddd, shading: THREE.SmoothShading } ) );
materials.push( new THREE.MeshPhongMaterial( { color: 0xdddddd, specular: 0x009900, shininess: 30, shading: THREE.SmoothShading, map: texture, transparent: true } ) );
materials.push( new THREE.MeshNormalMaterial( { shading: THREE.SmoothShading } ) );
materials.push( new THREE.MeshBasicMaterial( { color: 0xffaa00, wireframe: true } ) );
materials.push( new THREE.MeshDepthMaterial() );
materials.push( new THREE.MeshLambertMaterial( { color: 0x666666, emissive: 0xff0000, shading: THREE.SmoothShading } ) );
materials.push( new THREE.MeshPhongMaterial( { color: 0x000000, specular: 0x666666, emissive: 0xff0000, shininess: 10, shading: THREE.SmoothShading, opacity: 0.9, transparent: true } ) );
materials.push( new THREE.MeshBasicMaterial( { map: texture, transparent: true } ) );
return materials;
}
function animate() {
requestAnimationFrame( animate );
var SPEED = 3. / 10;
if(main_mesh){
main_mesh.rotation.x += 0.01*SPEED;
main_mesh.rotation.y += 0.02*SPEED;
meshf.rotation.x += 0.01*SPEED;
meshf.rotation.y += 0.02*SPEED;
}
mesh2.rotation.z += 0.01*SPEED;
mesh2.rotation.y += 0.02*SPEED;
//materials_list[ materials.length - 2 ].emissive.setHSL( 0.54, 1, 0.35 * ( 0.5 + 0.5 * Math.sin( 35 * timer ) ) );
//materials_list[ materials.length - 3 ].emissive.setHSL( 0.04, 1, 0.35 * ( 0.5 + 0.5 * Math.cos( 35 * timer ) ) );
renderer.render( scene, camera );
}
var scene, camera, renderer;
var geometry, material, main_mesh, mesh2, meshf;
window.setTimeout(function()
{
//init1();
init2();
animate();
}, 10);
</script>