diff --git a/SUB Control/README.md b/SUB Control/README.md index 78e74d6..03d9b92 100644 --- a/SUB Control/README.md +++ b/SUB Control/README.md @@ -12,10 +12,9 @@ arming, logging, output limiting, and parameter writes. It does not run a web server, open a browser tab, or require an internet connection. The WebView is frameless and uses the compact title bar drawn by the interface. -The vehicle rail includes a local STL viewer: choose **Load STL**, then drag to -orbit, use the mouse wheel to zoom, or switch between shaded and edge-focused -rendering. A cached STL copy is stored locally under the ignored `runtime/` -directory so the model can be restored on the next launch. +The vehicle rail includes a local STL viewer: choose **Load STL** to show a +fixed orthographic top-view silhouette. A cached STL copy is stored locally +under the ignored `runtime/` directory so the model can be restored on the next launch. STEP/STP CAD solids must first be tessellated/exported as STL because the embedded renderer intentionally does not include a full CAD kernel. diff --git a/SUB Control/web/app.js b/SUB Control/web/app.js index 611d18c..de997c3 100644 --- a/SUB Control/web/app.js +++ b/SUB Control/web/app.js @@ -28,7 +28,6 @@ $('#window-min').onclick=()=>api('minimize_window');$('#window-max').onclick=()= const modelInput=$('#model-input'),modelButton=$('#load-model'); modelButton.onclick=()=>{modelInput.value='';modelInput.click()}; modelInput.onchange=async()=>{const file=modelInput.files?.[0],old=modelButton.textContent;if(!file)return;try{if(!file.name.toLowerCase().endsWith('.stl'))throw new Error('Choose an STL mesh');if(file.size>30*1024*1024)throw new Error('The STL is larger than 30 MB; export a lighter mesh');modelButton.disabled=true;modelButton.textContent='Loading…';await new Promise(requestAnimationFrame);const buffer=await file.arrayBuffer(),result=window.rovModel.loadBuffer(buffer,file.name);modelButton.textContent='Replace STL';toast(`Loaded ${result.name} • ${result.triangles.toLocaleString()} triangles`);if(bridgeReady){const dataUrl=await new Promise((resolve,reject)=>{const reader=new FileReader();reader.onload=()=>resolve(reader.result);reader.onerror=()=>reject(reader.error);reader.readAsDataURL(file)});api('save_model',file.name,String(dataUrl).split(',')[1]).catch(error=>toast(`Model loaded, but could not be saved: ${error.message}`,true))}}catch(error){toast(`STL import failed: ${error.message}`,true)}finally{modelButton.disabled=false;if(modelButton.textContent==='Loading…')modelButton.textContent=old}}; -$('#model-style').onclick=e=>{const edges=window.rovModel.toggleStyle();e.currentTarget.textContent=edges?'Shaded':'Edges'}; $('#refresh').onclick=async()=>populatePorts(await api('refresh_ports'));$('#connect').onclick=async()=>{try{if(connected)await api('disconnect');else await api('connect',$('#port').value,+$('#baud').value,+$('#rate').value)}catch(e){toast(e.message,true)}}; $('#manual').onclick=()=>api('command','manual').catch(e=>toast(e.message,true));$('#arm').onclick=()=>openModal('arm-dialog');$('#confirm-arm').onclick=()=>{api('command','arm').catch(e=>toast(e.message,true));$('#arm-dialog').close()};$('#disarm').onclick=()=>api('command','disarm').catch(e=>toast(e.message,true));$('#logs').onclick=()=>api('open_logs'); $('#gain').oninput=e=>{$('#gain-value').textContent=`${e.target.value}%`;api('set_gain',+e.target.value)}; diff --git a/SUB Control/web/index.html b/SUB Control/web/index.html index ba232fc..c7a86fa 100644 --- a/SUB Control/web/index.html +++ b/SUB Control/web/index.html @@ -45,7 +45,6 @@