Browse Source

play around with three.js and stl and vrml loading

Thomas Buck 9 months ago
parent
commit
814409e131
1 changed files with 183 additions and 0 deletions
  1. 183
    0
      docs/src/pcb1.md

+ 183
- 0
docs/src/pcb1.md View File

@@ -5,3 +5,186 @@ It's a single sided PCB layout suitable for hand etching at home.
5 5
 
6 6
 [![hand etching prototype pcb](https://www.xythobuz.de/img/lars_13_small.jpg)](https://www.xythobuz.de/img/lars_13.jpg)
7 7
 [![assembled prototype](https://www.xythobuz.de/img/lars_10_small.jpg)](https://www.xythobuz.de/img/lars_10.jpg)
8
+
9
+
10
+
11
+
12
+<div id="threejstarget" style="width: 600px; height: 400px; background-color: white; border: 1px solid black;"></div>
13
+
14
+<script type="importmap">
15
+  {
16
+    "imports": {
17
+      "three": "https://cdn.jsdelivr.net/npm/three@0.163.0/build/three.module.js",
18
+      "three/addons/": "https://cdn.jsdelivr.net/npm/three@0.163.0/examples/jsm/"
19
+    }
20
+  }
21
+</script>
22
+
23
+<script type="module">
24
+
25
+
26
+import * as THREE from 'three';
27
+import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
28
+import { STLLoader } from 'three/addons/loaders/STLLoader.js'
29
+import { VRMLLoader } from 'three/addons/loaders/VRMLLoader.js';
30
+
31
+const container = document.getElementById('threejstarget');
32
+
33
+const width = 600;
34
+const height = 400;
35
+
36
+const scene = new THREE.Scene();
37
+scene.add(new THREE.AxesHelper(3));
38
+
39
+const camera = new THREE.PerspectiveCamera( 75, width / height, 0.1, 1000 );
40
+
41
+const renderer = new THREE.WebGLRenderer();
42
+renderer.setSize( width, height );
43
+
44
+container.appendChild( renderer.domElement );
45
+
46
+const light = new THREE.DirectionalLight( 0xffffff, 0.5 );
47
+light.position.set(0, 1, 0);
48
+scene.add(light);
49
+
50
+const light42 = new THREE.DirectionalLight( 0xffffff, 0.5 );
51
+light42.position.set(1, 0, 0);
52
+scene.add(light42);
53
+
54
+const light23 = new THREE.DirectionalLight( 0xffffff, 0.5 );
55
+light23.position.set(0, 0, 1);
56
+scene.add(light23);
57
+
58
+const lightb = new THREE.DirectionalLight( 0xffffff, 0.5 );
59
+lightb.position.set(0, -1, 0);
60
+scene.add(lightb);
61
+
62
+const light42b = new THREE.DirectionalLight( 0xffffff, 0.5 );
63
+light42b.position.set(-1, 0, 0);
64
+scene.add(light42b);
65
+
66
+const light23b = new THREE.DirectionalLight( 0xffffff, 0.5 );
67
+light23b.position.set(0, 0, -1);
68
+scene.add(light23b);
69
+
70
+const light2 = new THREE.AmbientLight(0x101010);
71
+light2.position.set(100, 100, 100);
72
+scene.add(light2);
73
+
74
+const material = new THREE.MeshStandardMaterial();
75
+//material.roughness = 0.42;
76
+
77
+const loader = new STLLoader();
78
+loader.load(
79
+    'actuator_all.stl',
80
+    function (geometry) {
81
+        const mesh = new THREE.Mesh(geometry, material)
82
+        scene.add(mesh)
83
+    },
84
+    (xhr) => {
85
+        console.log((xhr.loaded / xhr.total) * 100 + '% loaded')
86
+    },
87
+    (error) => {
88
+        console.log(error)
89
+    }
90
+);
91
+
92
+/*
93
+const loader = new VRMLLoader();
94
+loader.load(
95
+    //'drumkit.wrl',
96
+    'dispensy.wrl',
97
+    function (object) {
98
+        scene.add(object);
99
+});
100
+*/
101
+
102
+const controls = new OrbitControls( camera, renderer.domElement );
103
+controls.enableDamping = true;
104
+
105
+// https://wejn.org/2020/12/cracking-the-threejs-object-fitting-nut/
106
+const fitCameraToCenteredObject = function (camera, object, offset, orbitControls ) {
107
+    const boundingBox = new THREE.Box3();
108
+    boundingBox.setFromObject( object );
109
+
110
+    var middle = new THREE.Vector3();
111
+    var size = new THREE.Vector3();
112
+    boundingBox.getSize(size);
113
+
114
+    // figure out how to fit the box in the view:
115
+    // 1. figure out horizontal FOV (on non-1.0 aspects)
116
+    // 2. figure out distance from the object in X and Y planes
117
+    // 3. select the max distance (to fit both sides in)
118
+    //
119
+    // The reason is as follows:
120
+    //
121
+    // Imagine a bounding box (BB) is centered at (0,0,0).
122
+    // Camera has vertical FOV (camera.fov) and horizontal FOV
123
+    // (camera.fov scaled by aspect, see fovh below)
124
+    //
125
+    // Therefore if you want to put the entire object into the field of view,
126
+    // you have to compute the distance as: z/2 (half of Z size of the BB
127
+    // protruding towards us) plus for both X and Y size of BB you have to
128
+    // figure out the distance created by the appropriate FOV.
129
+    //
130
+    // The FOV is always a triangle:
131
+    //
132
+    //  (size/2)
133
+    // +--------+
134
+    // |       /
135
+    // |      /
136
+    // |     /
137
+    // | F° /
138
+    // |   /
139
+    // |  /
140
+    // | /
141
+    // |/
142
+    //
143
+    // F° is half of respective FOV, so to compute the distance (the length
144
+    // of the straight line) one has to: `size/2 / Math.tan(F)`.
145
+    //
146
+    // FTR, from https://threejs.org/docs/#api/en/cameras/PerspectiveCamera
147
+    // the camera.fov is the vertical FOV.
148
+
149
+    const fov = camera.fov * ( Math.PI / 180 );
150
+    const fovh = 2*Math.atan(Math.tan(fov/2) * camera.aspect);
151
+    let dx = size.z / 2 + Math.abs( size.x / 2 / Math.tan( fovh / 2 ) );
152
+    let dy = size.z / 2 + Math.abs( size.y / 2 / Math.tan( fov / 2 ) );
153
+    let cameraZ = Math.max(dx, dy);
154
+
155
+    // offset the camera, if desired (to avoid filling the whole canvas)
156
+    if( offset !== undefined && offset !== 0 ) cameraZ *= offset;
157
+
158
+    camera.position.set( 0, 0, cameraZ );
159
+
160
+    // set the far plane of the camera so that it easily encompasses the whole object
161
+    const minZ = boundingBox.min.z;
162
+    const cameraToFarEdge = ( minZ < 0 ) ? -minZ + cameraZ : cameraZ - minZ;
163
+
164
+    camera.far = cameraToFarEdge * 3;
165
+    camera.updateProjectionMatrix();
166
+
167
+    if ( orbitControls !== undefined ) {
168
+        // set camera to rotate around the center
169
+        orbitControls.target = new THREE.Vector3(0, 0, 0);
170
+
171
+        // prevent camera from zooming out far enough to create far plane cutoff
172
+        orbitControls.maxDistance = cameraToFarEdge * 2;
173
+    }
174
+};
175
+
176
+//camera.position.z = 50;
177
+fitCameraToCenteredObject(camera, scene, 0, controls)
178
+
179
+function render() {
180
+    renderer.render(scene, camera);
181
+}
182
+
183
+function animate() {
184
+    requestAnimationFrame(animate);
185
+    controls.update();
186
+    render();
187
+}
188
+
189
+animate();
190
+</script>

Loading…
Cancel
Save