feat(of): kick violent + speed /10 + FX keys

User : "rendre le bias kick plus violent. ajuster la vitesse du
tunnel en /10 et ajouter des fx qui modifie les multiplicateur
avec le clavier (a→z)".

Approach:
- Vitesse base /10 : (0.6 + bpm*0.012) → (0.06 + bpm*0.0012).
  Le flow général est lent, le kick frappe d'autant plus fort.
- Kick punch ×4 (vs ×1.5) sur travel, ×1.4 (vs 0.6) sur panY,
  ×0.6 (vs 0.25) sur la composante roll. Sensation d'impact.
- TunnelVis::Mults — struct de 8 multiplicateurs (speed,
  kickBoost, rollAmp, panAmp, curveAmp, tileX, tileZ, dirLerp).
  Appliqués in-place dans update/draw.
- Bindings clavier ofApp::keyPressed : 9 paires down/up
    a/z  : speed
    s/x  : kickBoost
    d/c  : rollAmp
    e/v  : panAmp
    t/n  : curveAmp
    u/m  : tileX
    i/l  : tileZ
    o/h  : dirLerp
    j/y  : speed + kickBoost combinés (tout ralentir/accélérer)
    w    : reset all to 1.0
  Chaque pression × 0.83 (down) ou × 1.20 (up), clamp 0.05..12.
This commit is contained in:
L'électron rare
2026-05-07 20:05:53 +02:00
parent 0dd90e3f3c
commit ad8f42379e
3 changed files with 74 additions and 14 deletions
+41
View File
@@ -549,6 +549,47 @@ void ofApp::keyPressed(int key) {
postfx_.reloadShader();
ofLogNotice("ofApp") << "Shaders rechargés";
break;
// FX live — multiplicateurs tunnel par paires (down/up). Chaque
// pression scale ×0.83 (down) ou ×1.20 (up). Clamp 0.05..12.
// 'w' = reset all to 1.0 (n'écrase pas qwerty mode_ déjà mappés).
case 'a': case 'z': case 's': case 'x':
case 'd': case 'c': case 'e': case 'v':
case 't': case 'n': case 'u': case 'm':
case 'i': case 'l': case 'o': case 'h':
case 'j': case 'y':
case 'w': {
auto m = tunnel_->mults();
auto bump = [](float v, bool up) {
v *= up ? 1.20f : 0.83f;
return std::max(0.05f, std::min(12.0f, v));
};
switch (key) {
case 'a': m.speed = bump(m.speed, false); break;
case 'z': m.speed = bump(m.speed, true); break;
case 's': m.kickBoost = bump(m.kickBoost, false); break;
case 'x': m.kickBoost = bump(m.kickBoost, true); break;
case 'd': m.rollAmp = bump(m.rollAmp, false); break;
case 'c': m.rollAmp = bump(m.rollAmp, true); break;
case 'e': m.panAmp = bump(m.panAmp, false); break;
case 'v': m.panAmp = bump(m.panAmp, true); break;
case 't': m.curveAmp = bump(m.curveAmp, false); break;
case 'n': m.curveAmp = bump(m.curveAmp, true); break;
case 'u': m.tileX = bump(m.tileX, false); break;
case 'm': m.tileX = bump(m.tileX, true); break;
case 'i': m.tileZ = bump(m.tileZ, false); break;
case 'l': m.tileZ = bump(m.tileZ, true); break;
case 'o': m.dirLerp = bump(m.dirLerp, false); break;
case 'h': m.dirLerp = bump(m.dirLerp, true); break;
case 'j': m.speed = bump(m.speed, false);
m.kickBoost = bump(m.kickBoost, false); break;
case 'y': m.speed = bump(m.speed, true);
m.kickBoost = bump(m.kickBoost, true); break;
case 'w': m = oscope::TunnelVis::Mults{}; break;
}
tunnel_->setMults(m);
break;
}
default: break;
}
}
+17 -14
View File
@@ -22,18 +22,21 @@ void TunnelVis::update(const VisFrame& frame) {
const float dirTarget = (lead_ - bass_) > 0.05f ? 1.0f
: (bass_ - lead_) > 0.05f ? -1.0f
: direction_;
direction_ += (dirTarget - direction_) * 0.04f;
direction_ += (dirTarget - direction_) * 0.04f * mults_.dirLerp;
// Vitesse : base BPM + boost sur kick, signée par direction_.
const float speed = (0.6f + bpm_ * 0.012f + kick_ * 1.5f) * direction_;
// Vitesse : base BPM /10 (flow lent) + bias kick violent (kick frappe
// brutal sur cette base lente). Signée par direction_.
const float baseSpeed = 0.06f + bpm_ * 0.0012f; // /10 vs avant
const float kickPunch = kick_ * 4.0f * mults_.kickBoost; // violent
const float speed = (baseSpeed + kickPunch) * direction_ * mults_.speed;
travel_ += static_cast<float>(ofGetLastFrameTime()) * speed;
// 3D — Banking (roll) : la nef s'incline. Composante kinétique de base
// (oscillation sinusoïdale toujours présente) + composante audio.
const float t = ofGetElapsedTimef();
const float rollTarget = std::sin(t * 0.5f) * 0.35f
const float rollTarget = (std::sin(t * 0.5f) * 0.35f
+ (lead_ - bass_) * 1.2f
+ std::sin(t * 1.7f) * 0.25f * (kick_ + 0.15f);
+ std::sin(t * 1.7f) * 0.6f * (kick_ + 0.15f)) * mults_.rollAmp;
roll_ += (rollTarget - roll_) * 0.08f;
// 3D — Pan : le vanishing point se déplace vraiment, en figure de
@@ -43,12 +46,12 @@ void TunnelVis::update(const VisFrame& frame) {
+ std::sin(t * 0.83f) * 0.12f;
const float baseY = std::cos(t * 0.42f) * 0.25f
+ std::cos(t * 1.13f) * 0.10f;
const float panTargetX = baseX
const float panTargetX = (baseX
+ (snare_ - 0.4f) * 0.8f * snare_
+ (lead_ - bass_) * 0.4f;
const float panTargetY = baseY
- kick_ * 0.6f
- bass_ * 0.3f;
+ (lead_ - bass_) * 0.4f) * mults_.panAmp;
const float panTargetY = (baseY
- kick_ * 1.4f * mults_.kickBoost
- bass_ * 0.3f) * mults_.panAmp;
panX_ += (panTargetX - panX_) * 0.12f;
panY_ += (panTargetY - panY_) * 0.12f;
@@ -58,10 +61,10 @@ void TunnelVis::update(const VisFrame& frame) {
// qui garantit qu'il y a toujours un léger virage.
const float dt = static_cast<float>(ofGetLastFrameTime());
curvePhase_ += dt * (1.2f + bpm_ * 0.005f) * direction_;
const float curveTarget = 0.04f
const float curveTarget = (0.04f
+ std::abs(lead_ - bass_) * 0.10f
+ bass_ * 0.12f
+ std::sin(t * 0.21f) * 0.03f;
+ std::sin(t * 0.21f) * 0.03f) * mults_.curveAmp;
curveAmp_ += (curveTarget - curveAmp_) * 0.05f;
}
@@ -87,8 +90,8 @@ void TunnelVis::draw(int x, int y, int w, int h) {
// Taille de tile pilotée par les fréquences :
// - axe Z (profondeur) : bass loud → grosses tuiles (uTileZ bas)
// - axe angulaire : lead loud → tuiles fines (uTileX haut)
const float tileZ = ofLerp(3.0f, 0.5f, std::min(1.0f, bass_));
const float tileX = ofLerp(8.0f, 32.0f, std::min(1.0f, lead_));
const float tileZ = ofLerp(3.0f, 0.5f, std::min(1.0f, bass_)) * mults_.tileZ;
const float tileX = ofLerp(8.0f, 32.0f, std::min(1.0f, lead_)) * mults_.tileX;
shader_.setUniform1f("uTileZ", tileZ);
shader_.setUniform1f("uTileX", tileX);
shader_.setUniform1f("uDirection", direction_);
+16
View File
@@ -11,10 +11,25 @@ namespace oscope {
class TunnelVis : public Visualizer {
public:
/// Multiplicateurs live pilotables au clavier (cf. ofApp::keyPressed
/// a→z). 1.0 = défaut, > 1 boost, < 1 atténue.
struct Mults {
float speed = 1.0f;
float kickBoost = 1.0f;
float rollAmp = 1.0f;
float panAmp = 1.0f;
float curveAmp = 1.0f;
float tileX = 1.0f;
float tileZ = 1.0f;
float dirLerp = 1.0f;
};
void setup(int w, int h) override;
void update(const VisFrame& frame) override;
void draw(int x, int y, int w, int h) override;
void reloadShaders() override;
void setMults(const Mults& m) { mults_ = m; }
const Mults& mults() const { return mults_; }
private:
int w_ = 0, h_ = 0;
@@ -25,6 +40,7 @@ private:
float panY_ = 0.0f;
float curveAmp_ = 0.05f; // intensité du virage smoothée
float curvePhase_ = 0.0f; // avance avec travel pour défilement
Mults mults_;
float bpm_ = 120.0f, kick_ = 0.0f, bass_ = 0.0f, lead_ = 0.0f, pad_ = 0.0f;
float snare_ = 0.0f;
ofShader shader_;