fix(sound): concert advance via body wrists
CI build oscope-of / build-check (push) Has been cancelled
CI build oscope-of / build-check (push) Has been cancelled
The hand-based arms-crossed gesture could never fire: hand L/R is position-sorted (rx>=lx always), and at full-body distance MediaPipe doesnt detect the hands at all (crossing also occludes them). Detect the advance from the body wrists instead: new /pose/wrist OSCdef -> ~poseWrist, and detectCross fires when the right wrist swaps clearly left of the left wrist (a clear X), performer centered, wrists at chest height. Verified headless (wrist-cross advance 1->2).
This commit is contained in:
@@ -495,6 +495,7 @@ OSCdef(\poseLeave, { |msg|
|
||||
~poseState.removeAt(pid);
|
||||
~poseKin.removeAt(pid);
|
||||
~poseCenter.removeAt(pid);
|
||||
~poseWrist !? { ~poseWrist.removeAt(pid) };
|
||||
}, '/pose/leave');
|
||||
|
||||
OSCdef(\poseHands, { |msg|
|
||||
@@ -509,6 +510,17 @@ OSCdef(\poseHands, { |msg|
|
||||
~handFeat[\dist] = msg[10];
|
||||
}, '/pose/hands');
|
||||
|
||||
// Body wrists (skeleton, tracked even when hands are occluded/too small).
|
||||
// /pose/wrist <pid> <l|r> <x> <y> (anatomical L/R from MediaPipe pose)
|
||||
~poseWrist = ~poseWrist ? Dictionary.new;
|
||||
OSCdef(\poseWrist, { |msg|
|
||||
var pid = msg[1].asInteger;
|
||||
var e = ~poseWrist[pid] ? ();
|
||||
if(msg[2].asString[0] == $l) { e[\lx] = msg[3]; e[\ly] = msg[4]; }
|
||||
{ e[\rx] = msg[3]; e[\ry] = msg[4]; };
|
||||
~poseWrist[pid] = e;
|
||||
}, '/pose/wrist');
|
||||
|
||||
~poseCenter = ~poseCenter ? Dictionary.new;
|
||||
OSCdef(\poseCenter, { |msg|
|
||||
var pid = msg[1].asInteger;
|
||||
|
||||
@@ -57,13 +57,17 @@
|
||||
|
||||
// geste bras-croises : main D a gauche de main G, a mi-hauteur, maintenu
|
||||
~concert[\detectCross] = { |pose, now|
|
||||
var hf = pose[\hands];
|
||||
var ry = (hf[\ry] ? 0); var ly = (hf[\ly] ? 0);
|
||||
var crossed = pose[\hasBody] and: {
|
||||
((hf[\rx] ? 0.5) < ((hf[\lx] ? 0.5) - 0.08))
|
||||
and: { (ry >= 0.25) and: { ry <= 0.75 } }
|
||||
and: { (ly >= 0.25) and: { ly <= 0.75 } }
|
||||
};
|
||||
// Detect via BODY WRISTS (skeleton), not hands: at full-body distance the
|
||||
// hands aren't detected and crossing occludes them. Clear X cross = the
|
||||
// right wrist swaps to the LEFT of the left wrist. Require the performer
|
||||
// centered (not at a frame edge) + wrists at chest height.
|
||||
var w = (~poseWrist.notNil.if({ ~poseWrist.values.detect({ |v| v.notNil }) })) ? ();
|
||||
var lx = (w[\lx] ? 0.5); var rx = (w[\rx] ? 0.5);
|
||||
var ly = (w[\ly] ? 0.5); var ry = (w[\ry] ? 0.5);
|
||||
var centered = (lx > 0.15) and: { lx < 0.85 } and: { rx > 0.15 } and: { rx < 0.85 };
|
||||
var midH = (ly > 0.2) and: { ly < 0.85 } and: { ry > 0.2 } and: { ry < 0.85 };
|
||||
var crossed = pose[\hasBody] and: { centered } and: { midH }
|
||||
and: { rx < (lx - 0.10) };
|
||||
if(crossed) {
|
||||
if(~concert[\crossT] <= 0) { ~concert[\crossT] = now };
|
||||
if(((now - ~concert[\crossT]) >= ~ccCrossHold)
|
||||
|
||||
Reference in New Issue
Block a user