feat: add stereo waveform orbit rings

Two perpendicular line-loop rings orbit the sphere, the blue ring
modulated by CH1 and the orange ring by CH2, toggled with key 2.
This commit is contained in:
L'électron rare
2026-05-18 17:27:07 +02:00
parent eeb5726103
commit 9b82a90579
4 changed files with 76 additions and 0 deletions
+50
View File
@@ -0,0 +1,50 @@
#include "OrbitRings.h"
#include <cmath>
void OrbitRings::setup(int pointsPerRing) {
n_ = pointsPerRing;
ring1_.clear();
ring2_.clear();
ring1_.setMode(OF_PRIMITIVE_LINE_LOOP);
ring2_.setMode(OF_PRIMITIVE_LINE_LOOP);
for (int i = 0; i < n_; ++i) {
ring1_.addVertex(glm::vec3(0.0f));
ring2_.addVertex(glm::vec3(0.0f));
}
}
void OrbitRings::setWaveform(const std::vector<float>& ch1,
const std::vector<float>& ch2) {
const float twoPi = 6.28318530718f;
auto rebuild = [&](ofVboMesh& ring, const std::vector<float>& src,
bool xzPlane) {
const int n = static_cast<int>(src.size());
for (int i = 0; i < n_; ++i) {
const float theta = twoPi * static_cast<float>(i) / n_;
float s = 0.0f;
if (n > 0) {
int idx = static_cast<int>(
static_cast<long long>(i) * n / n_);
if (idx >= n) idx = n - 1;
s = src[idx];
}
const float r = baseRadius_ + amp_ * s;
const glm::vec3 p = xzPlane
? glm::vec3(r * std::cos(theta), 0.0f, r * std::sin(theta))
: glm::vec3(r * std::cos(theta), r * std::sin(theta), 0.0f);
ring.setVertex(i, p);
}
};
rebuild(ring1_, ch1, true);
rebuild(ring2_, ch2, false);
}
void OrbitRings::draw() {
ofPushStyle();
ofSetLineWidth(2.0f);
ofSetColor(80, 200, 255);
ring1_.draw();
ofSetColor(255, 140, 80);
ring2_.draw();
ofPopStyle();
}
+21
View File
@@ -0,0 +1,21 @@
#pragma once
#include "ofMain.h"
#include <vector>
// GL visual unit: two line-loop rings orbiting the sphere in
// perpendicular planes. Ring 1 follows CH1, ring 2 follows CH2; each
// point's orbit radius is modulated by the live waveform.
class OrbitRings {
public:
void setup(int pointsPerRing);
void setWaveform(const std::vector<float>& ch1,
const std::vector<float>& ch2);
void draw();
private:
int n_ = 0;
float baseRadius_ = 300.0f;
float amp_ = 70.0f;
ofVboMesh ring1_; // CH1, XZ plane
ofVboMesh ring2_; // CH2, XY plane
};
+3
View File
@@ -12,6 +12,7 @@ void ofApp::setup() {
cam_.setFarClip(5000.0f);
sphere_.setup(5, 512, 256, 1024);
rings_.setup(512);
hantek_.setSampleRate(16000000u);
const oscope::HantekStatus st = hantek_.start();
@@ -47,6 +48,7 @@ void ofApp::update() {
sphere_.pushSpectrogramColumn(analyzerCh1_.magDown(),
analyzerCh2_.magDown());
sphere_.setWaveform(buf1_, buf2_);
rings_.setWaveform(buf1_, buf2_);
}
void ofApp::draw() {
@@ -54,6 +56,7 @@ void ofApp::draw() {
ofPushMatrix();
ofRotateYDeg(ofGetElapsedTimef() * 6.0f);
if (layerA_) sphere_.drawSkin();
if (layerB_) rings_.draw();
ofPopMatrix();
cam_.end();
drawHud();
+2
View File
@@ -4,6 +4,7 @@
#include "AudioAnalyzer.h"
#include "DemoSignal.h"
#include "SphereViz.h"
#include "OrbitRings.h"
#include <string>
#include <vector>
@@ -23,6 +24,7 @@ private:
oscope::DemoSignal demo_{48000.0f};
SphereViz sphere_;
OrbitRings rings_;
ofEasyCam cam_;
std::vector<float> buf1_;