Files
2023-06-25 20:40:16 -07:00

117 lines
3.4 KiB
HTML

<!doctype html>
<html lang="en">
<head>
<title>Manifold - three.js Example</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="shortcut icon" type="image/png" href="https://elalish.github.io/manifold/samples/models/favicon.png" />
<style>
body {
margin: 0;
background-color: #f7f7f7;
font-family: 'Rubik', sans-serif;
font-size: 16px;
line-height: 24px;
color: rgba(0, 0, 0, .87);
font-weight: 400;
-webkit-font-smoothing: antialiased;
}
p {
max-width: 700px;
margin: 1em;
text-align: left;
}
canvas {
display: block;
width: 100vw;
height: 100vw;
max-width: 600px;
max-height: 600px;
}
</style>
</head>
<body>
<p>This demonstrates the minimum code to connect Manifold to a three.js rendering. A slightly more complex example
involving GLTF export and &lt;model-viewer&gt; can be found <a href="model-viewer.html">here</a>. </p>
<select>
<option value="difference" selected>Difference</option>
<option value="intersection">Intersection</option>
<option value="union">Union</option>
</select><br />
<canvas id="output"></canvas>
</body>
<script type="module">
import * as THREE from 'three';
import { mergeVertices } from 'three/examples/jsm/utils/BufferGeometryUtils.js';
import Module from './built/manifold.js';
const wasm = await Module();
wasm.setup();
const { Manifold, Mesh } = wasm;
// we have manifold module, let's do some three.js
const camera = new THREE.PerspectiveCamera(30, 1, 0.01, 10);
camera.position.z = 1;
const scene = new THREE.Scene();
const mesh = new THREE.Mesh(undefined, new THREE.MeshNormalMaterial({
flatShading: true
}));
scene.add(mesh);
const icosahedron = simplify(new THREE.IcosahedronGeometry(0.16));
const manifold_1 = Manifold.cube([0.2, 0.2, 0.2], true);
const manifold_2 = new Manifold(geometry2mesh(icosahedron));
const csg = function (operation) {
mesh.geometry?.dispose();
mesh.geometry = mesh2geometry(Manifold[operation](manifold_1, manifold_2).getMesh());
};
document.querySelector('select').onchange = function (event) {
csg(event.target.value);
};
csg('difference');
const output = document.querySelector("#output");
const renderer = new THREE.WebGLRenderer({ canvas: output, antialias: true });
const dim = output.getBoundingClientRect();
renderer.setSize(dim.width, dim.height);
renderer.setAnimationLoop(function (time) {
mesh.rotation.x = time / 2000;
mesh.rotation.y = time / 1000;
renderer.render(scene, camera);
});
// functions to convert between three.js and wasm
function geometry2mesh(geometry) {
const vertProperties = geometry.attributes.position.array;
const triVerts = geometry.index.array;
return new Mesh({ numProp: 3, vertProperties, triVerts });
}
function mesh2geometry(mesh) {
const geometry = new THREE.BufferGeometry();
geometry.setAttribute('position', new THREE.BufferAttribute(mesh.vertProperties, 3));
geometry.setIndex(new THREE.BufferAttribute(mesh.triVerts, 1));
return geometry;
}
// most of three.js geometries aren't manifolds, so...
function simplify(geometry) {
delete geometry.attributes.normal;
delete geometry.attributes.uv;
const simplified = mergeVertices(geometry);
simplified.computeVertexNormals();
return simplified;
}
</script>
</html>