Browse Source

add controls to docs 3d viewer

Thomas Buck 8 months ago
parent
commit
d5a8588415
5 changed files with 60 additions and 18 deletions
  1. 6
    2
      README.md
  2. 1
    1
      docs/generate_docs.sh
  3. 9
    1
      docs/src/introduction.md
  4. 43
    14
      docs/src/js/3d.js
  5. 1
    0
      pcb/fp-lib-table

+ 6
- 2
README.md View File

@@ -8,7 +8,9 @@ This is a simple drum machine / loopstation.
8 8
 It's made for three hand-wound solenoids mounted to a tambourine.
9 9
 It is controlled by a Raspberry Pi Pico on a custom PCB.
10 10
 
11
-See [this blog post for some more context](https://www.xythobuz.de/lars.html).
11
+Please take a look at [the auto-generated documentation](https://xythobuz.github.io/lars/).
12
+
13
+Also see [this blog post for some more context](https://www.xythobuz.de/lars.html).
12 14
 
13 15
 ## Quick Start
14 16
 
@@ -29,7 +31,9 @@ Then you can build new binaries like this:
29 31
 
30 32
     make -Cbuild -j4
31 33
 
32
-Flash as usual using the mass storage bootloader (hold BOOTSEL while pluggin in the Pico).
34
+For the first time, flash as usual using the mass storage bootloader (hold BOOTSEL while pluggin in the Pico).
35
+After the firmware has been flashed once you can just use the included `flash.sh` to avoid having to hold the button.
36
+Use `debug.sh` to open a serial console via USB.
33 37
 
34 38
 ## Hardware Connections
35 39
 

+ 1
- 1
docs/generate_docs.sh View File

@@ -85,7 +85,7 @@ plot_3d() {
85 85
     echo '    }' >> $1
86 86
     echo '</script>' >> $1
87 87
     echo "<p>Status: \"<span id=\"3d_info_$2\">Preparing 3D model...</span>\"</p>" >> $1
88
-    echo "<div id=\"3d_viewer_$2\" style=\"width: 100%; height: 100%; background-color: white; border: 1px solid black;\"></div>" >> $1
88
+    echo "<div id=\"3d_viewer_$2\" style=\"width: 100%; height: 100%; background-color: white; border: 1px solid black; position: relative;\"></div>" >> $1
89 89
     echo '<script type="module">' >> $1
90 90
     echo "    var info = document.getElementById(\"3d_info_$2\");" >> $1
91 91
     echo "    var view = document.getElementById(\"3d_viewer_$2\");" >> $1

+ 9
- 1
docs/src/introduction.md View File

@@ -1,5 +1,13 @@
1 1
 # Introduction
2 2
 
3
-**TODO** work in progress
3
+![PCB](https://github.com/xythobuz/lars/actions/workflows/kicad.yml/badge.svg)
4
+![Docs](https://github.com/xythobuz/lars/actions/workflows/docs.yml/badge.svg)
5
+![STLs](https://github.com/xythobuz/lars/actions/workflows/scad.yml/badge.svg)
6
+
7
+This is a simple drum machine / loopstation.
8
+It's made for three hand-wound solenoids mounted to a tambourine.
9
+It is controlled by a Raspberry Pi Pico on a custom PCB.
4 10
 
11
+See [this blog post for some more context](https://www.xythobuz.de/lars.html).
5 12
 
13
+**TODO** work in progress

+ 43
- 14
docs/src/js/3d.js View File

@@ -10,7 +10,7 @@ import { STLLoader } from 'three/addons/loaders/STLLoader.js'
10 10
 import { VRMLLoader } from 'three/addons/loaders/VRMLLoader.js';
11 11
 
12 12
 // https://wejn.org/2020/12/cracking-the-threejs-object-fitting-nut/
13
-function fitCameraToCenteredObject(camera, object, offset, orbitControls ) {
13
+function fitCameraToCenteredObject(camera, object, offset, orbitControls, yOffset) {
14 14
     const boundingBox = new THREE.Box3();
15 15
     boundingBox.setFromObject( object );
16 16
 
@@ -61,7 +61,7 @@ function fitCameraToCenteredObject(camera, object, offset, orbitControls ) {
61 61
     // offset the camera, if desired (to avoid filling the whole canvas)
62 62
     if( offset !== undefined && offset !== 0 ) cameraZ *= offset;
63 63
 
64
-    camera.position.set( 0, 0, cameraZ );
64
+    camera.position.set( 0, yOffset * cameraZ, cameraZ );
65 65
 
66 66
     // set the far plane of the camera so that it easily encompasses the whole object
67 67
     const minZ = boundingBox.min.z;
@@ -86,15 +86,14 @@ export function init_3d(path, container, status, div_width, div_height) {
86 86
     const scene = new THREE.Scene();
87 87
     scene.add(new THREE.AxesHelper(1));
88 88
 
89
-    const camera = new THREE.PerspectiveCamera( 75, width / height, 0.1, 1000 );
89
+    const camera = new THREE.PerspectiveCamera(75, width / height, 0.1, 1000);
90 90
 
91 91
     const renderer = new THREE.WebGLRenderer();
92
-    renderer.setSize( width, height );
92
+    renderer.setSize(width, height);
93 93
 
94
-    container.appendChild( renderer.domElement );
95
-
96
-    const controls = new OrbitControls( camera, renderer.domElement );
94
+    const controls = new OrbitControls(camera, renderer.domElement);
97 95
     controls.enableDamping = true;
96
+    controls.autoRotate = true;
98 97
 
99 98
     if (path.endsWith(".stl")) {
100 99
         const light_amb = new THREE.AmbientLight(0x424242);
@@ -119,7 +118,7 @@ export function init_3d(path, container, status, div_width, div_height) {
119 118
             function (geometry) {
120 119
                 const mesh = new THREE.Mesh(geometry, material);
121 120
                 scene.add(mesh);
122
-                fitCameraToCenteredObject(camera, scene, 0, controls);
121
+                fitCameraToCenteredObject(camera, scene, 0, controls, 0);
123 122
             },
124 123
             (xhr) => {
125 124
                 const s = (xhr.loaded / xhr.total) * 100 + '% loaded';
@@ -140,7 +139,7 @@ export function init_3d(path, container, status, div_width, div_height) {
140 139
             path,
141 140
             function (object) {
142 141
                 scene.add(object);
143
-                fitCameraToCenteredObject(camera, scene, 0, controls);
142
+                fitCameraToCenteredObject(camera, scene, 0, controls, 0);
144 143
             },
145 144
             (xhr) => {
146 145
                 const s = (xhr.loaded / xhr.total) * 100 + '% loaded';
@@ -159,17 +158,47 @@ export function init_3d(path, container, status, div_width, div_height) {
159 158
     }
160 159
 
161 160
     camera.position.z = 50;
162
-
163
-    function render() {
164
-        renderer.render(scene, camera);
165
-    }
161
+    controls.update();
166 162
 
167 163
     function animate() {
168 164
         requestAnimationFrame(animate);
169 165
         controls.update();
170
-        render();
166
+        renderer.render(scene, camera);
171 167
     }
172 168
 
173 169
     animate();
174 170
     status.textContent = "3D model ready!";
171
+
172
+    container.appendChild(renderer.domElement);
173
+
174
+    const div = document.createElement("div");
175
+    div.style.position = "absolute";
176
+    div.style.left = "5px";
177
+    div.style.top = "5px";
178
+    div.style.background = "white";
179
+    div.style.color = "black";
180
+    container.appendChild(div);
181
+
182
+    const chk_ar = document.createElement("input");
183
+    chk_ar.type = "checkbox";
184
+    chk_ar.checked = true;
185
+    chk_ar.addEventListener('change', function() {
186
+        controls.autoRotate = this.checked;
187
+    });
188
+
189
+    const div_ar = document.createElement("div");
190
+    div_ar.appendChild(chk_ar);
191
+    div_ar.appendChild(document.createTextNode("Auto-Rotate"));
192
+    div.appendChild(div_ar);
193
+
194
+    const btn_rst = document.createElement("input");
195
+    btn_rst.type = "button";
196
+    btn_rst.value = "Reset Camera";
197
+    btn_rst.addEventListener('click', function() {
198
+        fitCameraToCenteredObject(camera, scene, 0, controls, 0);
199
+    });
200
+
201
+    const div_rst = document.createElement("div");
202
+    div_rst.appendChild(btn_rst);
203
+    div.appendChild(div_rst);
175 204
 }

+ 1
- 0
pcb/fp-lib-table View File

@@ -1,3 +1,4 @@
1 1
 (fp_lib_table
2 2
   (version 7)
3 3
   (lib (name "chinese_modules")(type "KiCad")(uri "${KIPRJMOD}/chinese_modules.pretty")(options "")(descr ""))
4
+)

Loading…
Cancel
Save