Skip to content

Commit 186a7ca

Browse files
committed
2 parents 7f37979 + 74705b6 commit 186a7ca

File tree

4 files changed

+122
-177
lines changed

4 files changed

+122
-177
lines changed

index.html

Lines changed: 122 additions & 177 deletions
Original file line numberDiff line numberDiff line change
@@ -6,40 +6,59 @@
66
<meta charset="utf-8">
77
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
88
<!-- <link type="text/css" rel="stylesheet" href="main.css"> -->
9+
<style>
10+
html, body {
11+
margin: 0;
12+
}
13+
#overlay {
14+
position: absolute;
15+
top: 0;
16+
left: 0;
17+
width: 100%;
18+
color: #FFFFFF;
19+
padding: 0 1em;
20+
}
21+
</style>
922
</head>
1023

1124
<body>
12-
<div>
13-
<h1>Prototype Viewer MediaWiki 3D GLTF Data, STL data is already available </h1>
14-
<select id="selection" onchange="loadSelection()">
15-
<option value="">Please choose a model</option>
16-
<option value="3Ddata.glb">GLB Lion Cologne Zoo - https://codeforcologne.github.io/Denkmal-4D-Koeln/
17-
</option>
18-
<option value="stl_lion.stl">STL Lion Cologne Zoo - https://codeforcologne.github.io/Denkmal-4D-Koeln/
19-
</option>
20-
<option value="ganesha.glb">GLB Ganesha Cologne Zoo - https://codeforcologne.github.io/Denkmal-4D-Koeln/
21-
</option>
22-
<option value="ganesha_stl.stl">STL Ganesha Cologne Zoo - https://codeforcologne.github.io/Denkmal-4D-Koeln/
23-
</option>
24-
<option value="3D_Model_Hydria.stl">STL Hydria -https://commons.wikimedia.org/wiki/File:3D_Model_Hydria.stl
25-
</option>
26-
<option value="3D_model_of_an_African_elephant.stl">STL African_elephant
27-
-https://commons.wikimedia.org/wiki/File:3D_model_of_an_African_elephant.stl</option>
28-
<option value="Avocado.glb">GLB Avocado - KhronosGroup Models Testing</option>
29-
<option value="BarramundiFish.glb">GLB BarramundiFish - KhronosGroup Models Testing</option>
30-
<option value="LightsPunctualLamp.glb">LightsPunctualLamp - KhronosGroup Models Testing</option>
31-
<option value="Duck.glb">GLB Duck - KhronosGroup Models Testing</option>
32-
<option value="NodePerformanceTest.glb">Wait a little bit! NodePerformanceTest - KhronosGroup Models Testing
33-
</option>
34-
<option value="NodePerformanceTest_opt.glb">Wait a little bit! NodePerformanceTest - Optimized with
35-
gltf-transform -
36-
KhronosGroup Models Testing
37-
</option>
38-
<option value="grinkopf.glb">Wait a little bit! Grinkopf Cologne -
39-
https://codeforcologne.github.io/Denkmal-4D-Koeln/</option>
40-
<option value="grinkopf_opt.glb">Grinkopf Cologne - Optimized with gltf-transform
41-
https://codeforcologne.github.io/Denkmal-4D-Koeln/</option>
42-
<option value="coffeemat.glb">GLB coffeemat with KTX2 cpmpression - KhronosGroup Models Testing</option>
25+
<div id="overlay">
26+
<h1>Prototype Viewer MediaWiki 3D</h1>
27+
<p>GLTF and STL formats are supported</p>
28+
<select id="selection" onchange="loadSelection()" placeholder="Please choose a model">
29+
<option value="" disabled selected>Please choose a model</option>
30+
<optgroup label="STL">
31+
<option value="stl_lion.stl">Lion Cologne Zoo - https://codeforcologne.github.io/Denkmal-4D-Koeln/
32+
</option>
33+
<option value="ganesha_stl.stl">Ganesha Cologne Zoo - https://codeforcologne.github.io/Denkmal-4D-Koeln/
34+
</option>
35+
<option value="3D_Model_Hydria.stl">Hydria -https://commons.wikimedia.org/wiki/File:3D_Model_Hydria.stl
36+
</option>
37+
<option value="3D_model_of_an_African_elephant.stl">African_elephant
38+
-https://commons.wikimedia.org/wiki/File:3D_model_of_an_African_elephant.stl
39+
</option>
40+
</optgroup>
41+
<optgroup label="GLB">
42+
<option value="3Ddata.glb">Lion Cologne Zoo - https://codeforcologne.github.io/Denkmal-4D-Koeln/
43+
</option>
44+
<option value="ganesha.glb">Ganesha Cologne Zoo - https://codeforcologne.github.io/Denkmal-4D-Koeln/
45+
</option>
46+
<option value="Avocado.glb">Avocado - KhronosGroup Models Testing</option>
47+
<option value="BarramundiFish.glb">BarramundiFish - KhronosGroup Models Testing</option>
48+
<option value="LightsPunctualLamp.glb">LightsPunctualLamp - KhronosGroup Models Testing</option>
49+
<option value="Duck.glb">Duck - KhronosGroup Models Testing</option>
50+
<option value="NodePerformanceTest.glb">Wait a little bit! NodePerformanceTest - KhronosGroup Models Testing
51+
</option>
52+
<option value="NodePerformanceTest_opt.glb">Wait a little bit! NodePerformanceTest - Optimized with
53+
gltf-transform -
54+
KhronosGroup Models Testing
55+
</option>
56+
<option value="grinkopf.glb">Wait a little bit! Grinkopf Cologne -
57+
https://codeforcologne.github.io/Denkmal-4D-Koeln/</option>
58+
<option value="grinkopf_opt.glb">Grinkopf Cologne - Optimized with gltf-transform
59+
https://codeforcologne.github.io/Denkmal-4D-Koeln/</option>
60+
<option value="coffeemat.glb">coffeemat with KTX2 cpmpression - KhronosGroup Models Testing</option>
61+
</optgroup>
4362
</select>
4463
<button id="uploadButton">Upload a file</button>
4564
<p>Only simple GLB Models and KTX2 commpersion is supported</p>
@@ -57,10 +76,10 @@ <h1>Prototype Viewer MediaWiki 3D GLTF Data, STL data is already available </h1>
5776
loadFileViaFileAPI((contents, fileName) => {
5877
if (fileName.toLowerCase().endsWith('.stl')) {
5978
modeltype = 'stl';
60-
TD.initSTL(contents, 'browser');
79+
TD.init(contents, 'browser');
6180
} else if (fileName.toLowerCase().endsWith('.glb')) {
6281
modeltype = 'glb';
63-
TD.initGLB(contents, 'browser');
82+
TD.init(contents, 'browser');
6483
} else {
6584
console.error('Unsupported file type');
6685
}
@@ -101,11 +120,11 @@ <h1>Prototype Viewer MediaWiki 3D GLTF Data, STL data is already available </h1>
101120
var selection = document.getElementById("selection").value;
102121
if (selection.indexOf('glb') > -1) {
103122
modeltype = 'glb';
104-
TD.initGLB(selection, 'server');
123+
TD.init(selection, 'server');
105124
}
106125
if (selection.indexOf('stl') > -1) {
107126
modeltype = 'stl';
108-
TD.initSTL(selection, 'server');
127+
TD.init(selection, 'server');
109128
}
110129
}
111130

@@ -125,47 +144,8 @@ <h1>Prototype Viewer MediaWiki 3D GLTF Data, STL data is already available </h1>
125144

126145
const TD = ThreeD.prototype;
127146

128-
TD.getBoxSizeCenter = function (object) {
129-
// compute the box that contains the object (and objects in the graph below)
130-
const box = new THREE.Box3().setFromObject(object);
131-
const size = box.getSize(new THREE.Vector3()).length();
132-
const center = box.getCenter(new THREE.Vector3());
133-
console.log(size);
134-
console.log(center);
135-
return { size, center };
136-
137-
};
138-
139-
TD.moveCamera = function (sizeToFitOnScreen, boxSize, boxCenter, camera) {
140-
const halfSizeToFitOnScreen = sizeToFitOnScreen * 0.5;
141-
const halfFovY = THREE.MathUtils.degToRad(camera.fov * 0.5);
142-
const distance = halfSizeToFitOnScreen / Math.tan(halfFovY);
143147

144-
// compute a unit vector that points in the direction the camera is now
145-
// in hte xz plane from the center of the box
146-
const direction = new THREE.Vector3()
147-
.subVectors(camera.position, boxCenter)
148-
.multiply(new THREE.Vector3(1, 0, 1))
149-
.normalize();
150-
151-
// move the camera to a position distance units way from the center
152-
// in whatever direction the camera was from the center already
153-
// for the screenshots, it is good not too be too far away
154-
camera.position.copy(direction.multiplyScalar(distance + 3).add(boxCenter));
155-
156-
// pick some near and far values for the frustum that
157-
// will contain the box.
158-
camera.near = boxSize / 100; // eslint-disable-line no-param-reassign
159-
camera.far = boxSize * 100; // eslint-disable-line no-param-reassign
160-
161-
camera.updateProjectionMatrix();
162-
163-
// point the camera to look at the center of the box
164-
camera.lookAt(boxCenter.x, boxCenter.y, boxCenter.z);
165-
};
166-
167-
168-
TD.initSTL = function (model, source) {
148+
TD.init = function (model, source) {
169149

170150
this.modeltype = modeltype;
171151

@@ -187,8 +167,7 @@ <h1>Prototype Viewer MediaWiki 3D GLTF Data, STL data is already available </h1>
187167
document.getElementById('container').appendChild(this.renderer.domElement);
188168
this.manager = new THREE.LoadingManager();
189169
// camera
190-
this.camera = new THREE.PerspectiveCamera(60, dimensions.ratio, 0.001, 500000);
191-
this.camera.up.set(0, 0, 1);
170+
this.camera = new THREE.PerspectiveCamera(60, dimensions.ratio);
192171
// controls
193172
this.controls = new THREE.TrackballControls(this.camera, this.renderer.domElement);
194173
this.controls.rotateSpeed = 2;
@@ -202,82 +181,65 @@ <h1>Prototype Viewer MediaWiki 3D GLTF Data, STL data is already available </h1>
202181
const environment = new THREE.RoomEnvironment(this.renderer);
203182
const pmremGenerator = new THREE.PMREMGenerator(this.renderer);
204183
this.scene = new THREE.Scene();
205-
//this.scene.background = new THREE.Color(0xbbbbbb);
206-
this.scene.background = new THREE.Color(0x0000000);
207184
this.scene.environment = pmremGenerator.fromScene(environment).texture;
208185
environment.dispose();
209-
TD.load('stl', model, source);
186+
TD.load(this.modeltype, model, source);
210187

211188
};
212189

190+
TD.stageContent = function (object) {
191+
// Ensure all transform matrices are up to date.
192+
object.updateMatrixWorld();
213193

214-
TD.initGLB = function (model, source) {
215-
this.modeltype = modeltype;
216-
if (document.getElementById('container')) {
194+
// Compute axis-aligned bounding box (AABB) and center (x, y, z) in
195+
// world space. Size, defined here as a cheap approximation of
196+
// model's maximum span in any direction, is computed from the AABB.
197+
const box = new THREE.Box3().setFromObject(object);
198+
const center = box.getCenter(new THREE.Vector3());
199+
const size = box.getSize(new THREE.Vector3()).length();
217200

218-
this.scene.clear();
219-
const child = document.getElementById('container');
220-
document.body.removeChild(child);
201+
// Center content at the origin, (0, 0, 0).
202+
object.position.x -= center.x;
203+
object.position.y -= center.y;
204+
object.position.z -= center.z;
205+
206+
// In glTF, +Y=Up is required. In STL it's unclear, but for backward-
207+
// compatibility we keep +Z=Up. Because some three.js features assume
208+
// +Y=Up, apply a +Z to +Y conversion for STL.
209+
if (this.modeltype === 'stl') {
210+
const parent = new THREE.Object3D();
211+
parent.rotation.set(- Math.PI / 2, 0, 0);
212+
parent.add(object);
213+
object = parent;
221214
}
222-
container = document.createElement('div');
223-
container.id = 'container';
224-
document.body.appendChild(container);
225-
const dimensions = this.getDimensions();
226-
// renderer
227-
this.renderer = new THREE.WebGLRenderer({ antialias: true });
228-
// this.renderer.setClearColor(0x222222);
229-
this.renderer.setPixelRatio(window.devicePixelRatio);
230-
this.renderer.setSize(dimensions.width, dimensions.height);
231-
this.renderer.shadowMap.enabled = true;
232-
document.getElementById('container').appendChild(this.renderer.domElement);
233-
// camera
234-
this.camera = new THREE.PerspectiveCamera(60, dimensions.ratio, 0.001, 500000);
235-
//this.camera.up.set(0, 0, 1);
236-
// controls
237-
this.controls = new THREE.TrackballControls(this.camera, this.renderer.domElement);
238-
this.controls.rotateSpeed = 2;
239-
this.controls.zoomSpeed = 2;
240-
this.controls.panSpeed = 0.5;
241-
this.controls.addEventListener('change', this.render.bind(this));
242-
this.controls.addEventListener('start', this.controlsStart.bind(this));
243-
this.controls.addEventListener('end', this.controlsEnd.bind(this));
244-
// Scene and RoomEnvironment
245-
const environment = new THREE.RoomEnvironment(this.renderer);
246-
const pmremGenerator = new THREE.PMREMGenerator(this.renderer);
247-
this.scene = new THREE.Scene();
248-
this.scene.background = new THREE.Color(0xbbbbbb);
249-
//this.scene.background = new THREE.Color(0x0000000);
250-
this.scene.environment = pmremGenerator.fromScene(environment).texture;
251-
environment.dispose();
252-
TD.load('glb', model, source);
253-
};
254215

216+
// Prevent controls from dollying out farther than 10x size.
217+
this.controls.maxDistance = size * 10;
255218

256-
TD.center = function (object, modeltype) {
257-
258-
if (modeltype === 'stl') {
259-
if (object.type === 'Group') {
260-
this.center(object.children[0], 'stl');
261-
} else if (object.type === 'Mesh') {
262-
object.geometry.center();
263-
object.geometry.computeBoundingSphere();
264-
265-
const radius = object.geometry.boundingSphere.radius;
266-
267-
// `radius` is the edge of the object's sphere
268-
// We want to position our camera outside of that sphere.
269-
// We'll move `radius` (or more) in all directions (x, y, z), so that we're
270-
// looking at the object somewhat diagonally, which should always show something
271-
// useful (instead of possibly an uninteresting side or top...)
272-
// The exact position of the camera was arbitrarily decided by what looked
273-
// alright-ish for a few files I was testing with.
274-
// sketchfab.com has this at ( 0, -distance, 0 )
275-
// viewstl.com has this at ( 0, 0 distance )
276-
// openjscad.org has this at ( 0, -distance, distance )
277-
// thingiverse.com has this at ( -distance, -distance, distance )
278-
this.camera.position.set(-radius * 1.5, -radius * 1.5, radius);
279-
}
280-
}
219+
// Constrain camera near and far planes to factors of size. Planes
220+
// should fit the content tightly enough that depth buffer
221+
// precision is utilized well, but not so tight that the model
222+
// clips the near/far planes easily while interacting with controls.
223+
this.camera.near = size / 100;
224+
this.camera.far = size * 100;
225+
this.camera.updateProjectionMatrix();
226+
227+
// Default viewing angle is arbitrary and subjective, some models
228+
// may benefit from a more top-down or front-facing perspective. To
229+
// split the difference somewhat, we use a diagonal. Comparisons:
230+
// sketchfab.com: ( 0, -distance, 0 )
231+
// viewstl.com: ( 0, 0 distance )
232+
// openjscad.org: ( 0, -distance, distance )
233+
// thingiverse.com: ( -distance, -distance, distance )
234+
this.camera.position.x += size * 0.75;
235+
this.camera.position.y += size * 0.5;
236+
this.camera.position.z += size * 0.75;
237+
238+
// Rotate the camera to look at the object's center, (0, 0, 0).
239+
this.camera.lookAt(object.position);
240+
241+
// Add content to scene.
242+
this.scene.add(object);
281243
};
282244

283245

@@ -338,42 +300,25 @@ <h1>Prototype Viewer MediaWiki 3D GLTF Data, STL data is already available </h1>
338300
// this.progressBar.animateTo(5);
339301
this.promise.then((object) => {
340302
delete this.promise;
341-
// check for GLB
342-
if (this.modeltype === 'glb') {
343-
344-
object.scene.traverse(function (node) {
345-
console.log(node);
346-
if (node.material) {
347-
node.material.side = THREE.DoubleSide;
348-
}
349-
if (node.mesh) {
350-
node.castShadow = true;
351-
node.receiveShadow = true;
352-
}
353-
354-
});
355-
// Add the model to the scene
356-
this.scene.add(object.scene);
357-
// move camera
358-
let box = this.getBoxSizeCenter(object.scene);
359-
this.moveCamera(box.size * 0.5, box.size, box.center, this.camera);
360-
this.controls.maxDistance = box.size * 10;
361-
this.controls.target.copy(box.center);
362-
this.controls.update();
363-
}
364303

365-
if (this.modeltype === 'stl') {
366-
// this.progressBar.hide();
367-
object.castShadow = true;
368-
object.receiveShadow = true;
369-
this.center(object, 'stl');
370-
this.scene.add(object);
371-
this.camera.lookAt(this.scene.position);
372-
}
304+
// this.progressBar.hide();
305+
306+
const content = this.modeltype === 'glb' ? object.scene : object;
307+
308+
// STL contains a single mesh, GLB may contain more. Traverse
309+
// to handle both cases.
310+
content.traverse(function (node) {
311+
if (node.isMesh) {
312+
node.castShadow = true;
313+
node.receiveShadow = true;
314+
}
315+
});
316+
317+
this.stageContent(content);
318+
373319
container.appendChild(this.renderer.domElement);
374320
TD.animate();
375321

376-
377322
// mw.threed.base.wrap(this.$container);
378323
}).progress((progress) => {
379324
// this.progressBar.animateTo(progress);
@@ -479,10 +424,10 @@ <h1>Prototype Viewer MediaWiki 3D GLTF Data, STL data is already available </h1>
479424

480425

481426
if (modeltype === 'glb') {
482-
TD.initGLB('ganesha.glb', 'server');
427+
TD.init('ganesha.glb', 'server');
483428
}
484429
if (modeltype === 'stl') {
485-
TD.initSTL('3D_Model_Hydria.stl', 'server');
430+
TD.init('3D_Model_Hydria.stl', 'server');
486431
}
487432

488433

0 Bytes
Binary file not shown.

models/ganesha_stl.stl

-8.28 MB
Binary file not shown.

models/stl_lion.stl

-8.3 MB
Binary file not shown.

0 commit comments

Comments
 (0)