107 lines
3.5 KiB
HTML
107 lines
3.5 KiB
HTML
<!--
|
|
############################################################################################
|
|
# Hellen-One: A 3D-component VRML rendering client script.
|
|
# (c) andreika <prometheus.pcb@gmail.com>
|
|
############################################################################################
|
|
--><html><head>
|
|
<style>
|
|
html, body, div, canvas {
|
|
margin: 0;
|
|
padding: 0;
|
|
background-color: transparent;
|
|
}
|
|
</style></head><body><script type="module">
|
|
|
|
// these are replaced with the real data by the parent script
|
|
var dpi = ___SCREEN_DPI___;
|
|
var vrmlData = "___VRML_DATA___";
|
|
|
|
// the distance from the camera to the board doesn't really matter because of the otho-projection
|
|
var dist = 100;
|
|
var minDist = 0.001;
|
|
|
|
// the far clipping plane is intentionally set to be less than the dist - to clip the board surface!
|
|
var boardSurfaceClippingThreshold = 0.001;
|
|
|
|
var gzHeader = "data:application/x-gzip;base64,";
|
|
|
|
// use the official Three.js public distribution
|
|
import * as THREE from 'https://unpkg.com/three@0.119.0/build/three.module.js';
|
|
import { VRMLLoader } from 'https://unpkg.com/three@0.119.0/examples/jsm/loaders/VRMLLoader.js';
|
|
|
|
import * as fflate from 'https://unpkg.com/three@0.128.0/examples/jsm/libs/fflate.module.js';
|
|
|
|
console.log('Starting...');
|
|
|
|
// this var is checked by the parent Node.js script
|
|
document.done = false;
|
|
// these are used in the parent caller script
|
|
document.compImgWidth = 0;
|
|
document.compImgHeight = 0;
|
|
|
|
var renderer;
|
|
|
|
function load() {
|
|
return new Promise((resolve, reject) => {
|
|
|
|
if (vrmlData.substring(0, gzHeader.length) === gzHeader) {
|
|
console.log('Decompressing GZip...');
|
|
vrmlData = vrmlData.substring(gzHeader.length);
|
|
var vrmlDataBytes = fflate.strToU8(atob(vrmlData), true);
|
|
var vrmlDataUncompressed = fflate.gunzipSync(vrmlDataBytes);
|
|
var vrmlDataUncompressedB64 = btoa(fflate.strFromU8(vrmlDataUncompressed));
|
|
vrmlData = "data:application/octet-stream;base64," + vrmlDataUncompressedB64;
|
|
console.log('Decompressed ' + vrmlDataUncompressed.length + ' bytes...');
|
|
}
|
|
|
|
console.log('Loading VRML...');
|
|
var loader = new VRMLLoader();
|
|
loader.load(vrmlData, function (object) {
|
|
console.log('Scene and camera setup...');
|
|
var box = new THREE.Box3().setFromObject(object);
|
|
var centerPos = new THREE.Vector3();
|
|
box.getCenter(centerPos);
|
|
|
|
var scene = new THREE.Scene();
|
|
scene.add(object);
|
|
|
|
// get the board size
|
|
var boxSize = new THREE.Vector3();
|
|
box.getSize(boxSize);
|
|
|
|
// the bounding size is in mm (metric), and DPI is 'imperial'
|
|
// we need width/height in pixels (rounded)
|
|
document.compImgWidth = parseInt(dpi * boxSize.x / 25.4 + 0.5);
|
|
document.compImgHeight = parseInt(dpi * boxSize.y / 25.4 + 0.5);
|
|
|
|
// setup the camera
|
|
var w2 = boxSize.x / 2;
|
|
var h2 = boxSize.y / 2;
|
|
var camera = new THREE.OrthographicCamera(-w2, w2, h2, -h2, minDist, dist - boardSurfaceClippingThreshold);
|
|
camera.position.set(centerPos.x, centerPos.y, dist);
|
|
scene.add(camera);
|
|
|
|
console.log('Rendering a static frame...');
|
|
renderer.setSize(document.compImgWidth, document.compImgHeight);
|
|
renderer.render(scene, camera);
|
|
|
|
// notify async consumers
|
|
resolve();
|
|
document.done = true;
|
|
});
|
|
});
|
|
}
|
|
|
|
async function run() {
|
|
console.log('Init renderer...');
|
|
renderer = new THREE.WebGLRenderer({antialias: true, alpha: true, logarithmicDepthBuffer: true, preserveDrawingBuffer: true});
|
|
renderer.setClearColor(0x000000, 0);
|
|
document.body.appendChild(renderer.domElement);
|
|
|
|
await load();
|
|
console.log('Exiting script...');
|
|
}
|
|
|
|
run();
|
|
</script></body></html>
|