Browse Source

add controls to docs 3d viewer

Thomas Buck 7 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
 It's made for three hand-wound solenoids mounted to a tambourine.
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.
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
 ## Quick Start
15
 ## Quick Start
14
 
16
 
29
 
31
 
30
     make -Cbuild -j4
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
 ## Hardware Connections
38
 ## Hardware Connections
35
 
39
 

+ 1
- 1
docs/generate_docs.sh View File

85
     echo '    }' >> $1
85
     echo '    }' >> $1
86
     echo '</script>' >> $1
86
     echo '</script>' >> $1
87
     echo "<p>Status: \"<span id=\"3d_info_$2\">Preparing 3D model...</span>\"</p>" >> $1
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
     echo '<script type="module">' >> $1
89
     echo '<script type="module">' >> $1
90
     echo "    var info = document.getElementById(\"3d_info_$2\");" >> $1
90
     echo "    var info = document.getElementById(\"3d_info_$2\");" >> $1
91
     echo "    var view = document.getElementById(\"3d_viewer_$2\");" >> $1
91
     echo "    var view = document.getElementById(\"3d_viewer_$2\");" >> $1

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

1
 # Introduction
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
 import { VRMLLoader } from 'three/addons/loaders/VRMLLoader.js';
10
 import { VRMLLoader } from 'three/addons/loaders/VRMLLoader.js';
11
 
11
 
12
 // https://wejn.org/2020/12/cracking-the-threejs-object-fitting-nut/
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
     const boundingBox = new THREE.Box3();
14
     const boundingBox = new THREE.Box3();
15
     boundingBox.setFromObject( object );
15
     boundingBox.setFromObject( object );
16
 
16
 
61
     // offset the camera, if desired (to avoid filling the whole canvas)
61
     // offset the camera, if desired (to avoid filling the whole canvas)
62
     if( offset !== undefined && offset !== 0 ) cameraZ *= offset;
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
     // set the far plane of the camera so that it easily encompasses the whole object
66
     // set the far plane of the camera so that it easily encompasses the whole object
67
     const minZ = boundingBox.min.z;
67
     const minZ = boundingBox.min.z;
86
     const scene = new THREE.Scene();
86
     const scene = new THREE.Scene();
87
     scene.add(new THREE.AxesHelper(1));
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
     const renderer = new THREE.WebGLRenderer();
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
     controls.enableDamping = true;
95
     controls.enableDamping = true;
96
+    controls.autoRotate = true;
98
 
97
 
99
     if (path.endsWith(".stl")) {
98
     if (path.endsWith(".stl")) {
100
         const light_amb = new THREE.AmbientLight(0x424242);
99
         const light_amb = new THREE.AmbientLight(0x424242);
119
             function (geometry) {
118
             function (geometry) {
120
                 const mesh = new THREE.Mesh(geometry, material);
119
                 const mesh = new THREE.Mesh(geometry, material);
121
                 scene.add(mesh);
120
                 scene.add(mesh);
122
-                fitCameraToCenteredObject(camera, scene, 0, controls);
121
+                fitCameraToCenteredObject(camera, scene, 0, controls, 0);
123
             },
122
             },
124
             (xhr) => {
123
             (xhr) => {
125
                 const s = (xhr.loaded / xhr.total) * 100 + '% loaded';
124
                 const s = (xhr.loaded / xhr.total) * 100 + '% loaded';
140
             path,
139
             path,
141
             function (object) {
140
             function (object) {
142
                 scene.add(object);
141
                 scene.add(object);
143
-                fitCameraToCenteredObject(camera, scene, 0, controls);
142
+                fitCameraToCenteredObject(camera, scene, 0, controls, 0);
144
             },
143
             },
145
             (xhr) => {
144
             (xhr) => {
146
                 const s = (xhr.loaded / xhr.total) * 100 + '% loaded';
145
                 const s = (xhr.loaded / xhr.total) * 100 + '% loaded';
159
     }
158
     }
160
 
159
 
161
     camera.position.z = 50;
160
     camera.position.z = 50;
162
-
163
-    function render() {
164
-        renderer.render(scene, camera);
165
-    }
161
+    controls.update();
166
 
162
 
167
     function animate() {
163
     function animate() {
168
         requestAnimationFrame(animate);
164
         requestAnimationFrame(animate);
169
         controls.update();
165
         controls.update();
170
-        render();
166
+        renderer.render(scene, camera);
171
     }
167
     }
172
 
168
 
173
     animate();
169
     animate();
174
     status.textContent = "3D model ready!";
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
 (fp_lib_table
1
 (fp_lib_table
2
   (version 7)
2
   (version 7)
3
   (lib (name "chinese_modules")(type "KiCad")(uri "${KIPRJMOD}/chinese_modules.pretty")(options "")(descr ""))
3
   (lib (name "chinese_modules")(type "KiCad")(uri "${KIPRJMOD}/chinese_modules.pretty")(options "")(descr ""))
4
+)

Loading…
Cancel
Save