Fix normalized OSC coordinates and verify Motion pixel setter compatibility
这个提交包含在:
1 父节点
71a583e306
当前提交
22cd96a772
2 个文件已更改
+120
-33
没有与搜索条件相匹配的文件
+46
-13
@@ -12,11 +12,13 @@
|
||||
|
||||
@interface PGOSCAPI : NSObject <PROAPIAccessing>
|
||||
@property BOOL enabled, rejectRead, rejectPoint, rejectWrite, rejectUndo;
|
||||
@property BOOL disableOSC, disableParams, disableSetting, disableUndo;
|
||||
@property BOOL disableOSC, disableParams, disableSetting, disableUndo,pixelSetter;
|
||||
@property BOOL corruptReadback;
|
||||
@property CGRect bounds;
|
||||
@property double x,y,backing;
|
||||
@property NSUInteger writes,undoStarts,undoEnds;
|
||||
@property double lastX,lastY;
|
||||
@property double lastX,lastY,lastConvertX,lastConvertY;
|
||||
@property NSUInteger objectBoundsReads;
|
||||
@property CMTime lastTime;
|
||||
@end
|
||||
@implementation PGOSCAPI
|
||||
@@ -37,12 +39,17 @@
|
||||
}
|
||||
- (BOOL)setXValue:(double)x YValue:(double)y toParameter:(UInt32)identifier atTime:(CMTime)time {
|
||||
if(identifier!=PGSelection||_rejectWrite)return NO;
|
||||
_writes++;_lastX=x;_lastY=y;_lastTime=time;return YES;
|
||||
_writes++;_lastX=x;_lastY=y;
|
||||
_x=_pixelSetter ? .5+x/_bounds.size.width : x;
|
||||
_y=_pixelSetter ? .5+y/_bounds.size.height : y;
|
||||
if(_corruptReadback){_x=.12345;_y=.87654;}
|
||||
_lastTime=time;return YES;
|
||||
}
|
||||
- (CGRect)objectBounds {return _bounds;}
|
||||
- (CGRect)objectBounds {_objectBoundsReads++;return _bounds;}
|
||||
- (double)backingScaleFactor {return _backing;}
|
||||
- (void)convertPointFromSpace:(FxDrawingCoordinates)from fromX:(double)x fromY:(double)y toSpace:(FxDrawingCoordinates)to toX:(double *)tx toY:(double *)ty {
|
||||
*tx=x+200;*ty=y+100;
|
||||
// Match the SDK contract: OBJECT inputs are normalized; CANVAS is pixels.
|
||||
_lastConvertX=x;_lastConvertY=y;*tx=x*320;*ty=y*240;
|
||||
}
|
||||
- (BOOL)startUndoGroup:(NSString *)name {_undoStarts++;return !_rejectUndo;}
|
||||
- (BOOL)endUndoGroup {_undoEnds++;return YES;}
|
||||
@@ -83,19 +90,19 @@ int main(int argc,const char **argv) {@autoreleasepool {
|
||||
Check([control[@"supportedPlugins"] isEqual:@[filters.firstObject[@"uuid"]]],@"Dedicated OSC links to the released filter UUID");
|
||||
api.enabled=NO;[osc hitTestOSCAtMousePositionX:0 mousePositionY:0 activePart:&part atTime:time];Check(part==0,@"Disabled selection does not claim mouse events");
|
||||
[osc mouseDownAtPositionX:0 positionY:0 activePart:1 modifiers:0 forceUpdate:&update atTime:time];Check(!update && api.writes==0 && api.undoStarts==0,@"Disabled mouse-down writes nothing and opens no undo group");
|
||||
api.enabled=YES;[osc hitTestOSCAtMousePositionX:0 mousePositionY:0 activePart:&part atTime:time];Check(part==1,@"Enabled selection accepts a finite point in object bounds");
|
||||
api.enabled=YES;[osc hitTestOSCAtMousePositionX:0 mousePositionY:0 activePart:&part atTime:time];Check(part==1,@"Enabled selection accepts a finite normalized object point");
|
||||
[osc hitTestOSCAtMousePositionX:1000 mousePositionY:0 activePart:&part atTime:time];Check(part==0,@"Outside-object hit test is empty");
|
||||
[osc hitTestOSCAtMousePositionX:NAN mousePositionY:0 activePart:&part atTime:time];Check(part==0,@"Nonfinite hit coordinates are rejected");
|
||||
[osc hitTestOSCAtMousePositionX:0 mousePositionY:0 activePart:NULL atTime:time];Check(YES,@"Null hit-test output is safe");
|
||||
[osc mouseDownAtPositionX:0 positionY:0 activePart:0 modifiers:0 forceUpdate:&update atTime:time];Check(!update && api.writes==0,@"Inactive part does not start selection");
|
||||
update=YES;[osc mouseUpAtPositionX:0 positionY:0 activePart:1 modifiers:0 forceUpdate:&update atTime:time];Check(!update && api.undoEnds==0,@"Mouse-up without mouse-down leaves undo balanced");
|
||||
[osc mouseDownAtPositionX:-50 positionY:25 activePart:1 modifiers:0 forceUpdate:&update atTime:time];Check(update && fabs(api.lastX-.25)<1e-8 && fabs(api.lastY-.75)<1e-8,@"Mouse-down normalizes nonzero object bounds");
|
||||
[osc mouseDownAtPositionX:.25 positionY:.75 activePart:1 modifiers:0 forceUpdate:&update atTime:time];Check(update && fabs(api.lastX-.25)<1e-8 && fabs(api.lastY-.75)<1e-8,@"OBJECT mouse-down writes normalized point coordinates directly");
|
||||
Check(CMTimeCompare(api.lastTime,time)==0 && api.undoStarts==1,@"Selection writes use callback time and open one undo group");
|
||||
[osc mouseDraggedAtPositionX:500 positionY:-500 activePart:1 modifiers:0 forceUpdate:&update atTime:time];Check(update && api.lastX==1 && api.lastY==0,@"Dragging clamps normalized selection to the source");
|
||||
[osc mouseUpAtPositionX:0 positionY:0 activePart:1 modifiers:0 forceUpdate:&update atTime:time];Check(update && api.undoEnds==1,@"Gesture completes its matching undo group");
|
||||
NSUInteger writes=api.writes;[osc mouseDraggedAtPositionX:0 positionY:0 activePart:1 modifiers:0 forceUpdate:&update atTime:time];Check(!update && api.writes==writes,@"Stray drag after release writes nothing");
|
||||
api.bounds=CGRectMake(0,0,NAN,100);[osc hitTestOSCAtMousePositionX:0 mousePositionY:0 activePart:&part atTime:time];Check(part==0,@"Invalid host bounds produce an empty hit");
|
||||
update=YES;[osc mouseDownAtPositionX:0 positionY:0 activePart:1 modifiers:0 forceUpdate:&update atTime:time];Check(!update && api.writes==writes,@"Invalid bounds initialize forceUpdate and avoid parameter writes");api.bounds=CGRectMake(-100,-50,200,100);
|
||||
api.bounds=CGRectMake(0,0,NAN,100);[osc hitTestOSCAtMousePositionX:.5 mousePositionY:.5 activePart:&part atTime:time];Check(part==1,@"Normalized hit testing does not depend on document pixel bounds");
|
||||
update=YES;[osc mouseDownAtPositionX:NAN positionY:0 activePart:1 modifiers:0 forceUpdate:&update atTime:time];Check(!update && api.writes==writes,@"Nonfinite event initializes forceUpdate and avoids parameter writes");api.bounds=CGRectMake(-100,-50,200,100);
|
||||
api.rejectWrite=YES;[osc mouseDownAtPositionX:0 positionY:0 activePart:1 modifiers:0 forceUpdate:&update atTime:time];Check(!update && api.undoStarts==api.undoEnds,@"Rejected parameter write closes the opened undo group");api.rejectWrite=NO;
|
||||
api.rejectUndo=YES;NSUInteger ends=api.undoEnds;[osc mouseDownAtPositionX:0 positionY:0 activePart:1 modifiers:0 forceUpdate:&update atTime:time];[osc mouseUpAtPositionX:0 positionY:0 activePart:1 modifiers:0 forceUpdate:&update atTime:time];Check(api.undoEnds==ends,@"Failed undo start is never paired with an invalid end");api.rejectUndo=NO;
|
||||
for(int disabled=0;disabled<3;disabled++){
|
||||
@@ -107,10 +114,36 @@ int main(int argc,const char **argv) {@autoreleasepool {
|
||||
[osc keyUpAtPositionX:0 positionY:0 keyPressed:0 modifiers:0 forceUpdate:&update didHandle:&handled atTime:time];Check(!update && !handled,@"Unrecognized key-up clears outputs");
|
||||
PGOSCTile *tile=Tile();api.x=.25;api.y=.75;
|
||||
[osc drawOSCWithWidth:1920 height:1080 activePart:0 destinationImage:tile atTime:time];
|
||||
Check(AlphaAt(tile,150,125)>.9,@"Canvas conversion directly positions the visible handle despite effect/surface size mismatch");
|
||||
Check(AlphaAt(tile,80,180)>.9,@"Normalized selection converts to correct CANVAS pixels despite effect/surface size mismatch");
|
||||
Check(fabs(api.lastConvertX-.25)<1e-8 && fabs(api.lastConvertY-.75)<1e-8,@"Host receives normalized OBJECT coordinates rather than document pixel coordinates");
|
||||
Check(AlphaAt(tile,25,28)<.01,@"OSC surface is not incorrectly rescaled by effect image dimensions");
|
||||
api.enabled=NO;[osc drawOSCWithWidth:1920 height:1080 activePart:0 destinationImage:tile atTime:time];Check(AlphaAt(tile,150,125)<.01,@"Disabled drawing clears the prior handle");
|
||||
api.enabled=YES;api.backing=NAN;[osc drawOSCWithWidth:1920 height:1080 activePart:0 destinationImage:tile atTime:time];Check(AlphaAt(tile,150,125)>.9,@"Nonfinite backing scale uses a finite fallback");
|
||||
api.x=NAN;[osc drawOSCWithWidth:1920 height:1080 activePart:0 destinationImage:tile atTime:time];Check(AlphaAt(tile,150,125)<.01,@"Nonfinite stored selection does not create invalid drawing filters");
|
||||
api.enabled=NO;[osc drawOSCWithWidth:1920 height:1080 activePart:0 destinationImage:tile atTime:time];Check(AlphaAt(tile,80,180)<.01,@"Disabled drawing clears the prior handle");
|
||||
api.enabled=YES;api.backing=NAN;[osc drawOSCWithWidth:1920 height:1080 activePart:0 destinationImage:tile atTime:time];Check(AlphaAt(tile,80,180)>.9,@"Nonfinite backing scale uses a finite fallback");
|
||||
api.x=.5;api.y=.5;api.backing=1;
|
||||
[osc drawOSCWithWidth:1921 height:1080 activePart:0 destinationImage:tile atTime:time];
|
||||
Check(AlphaAt(tile,160,120)>.9 && AlphaAt(tile,0,0)<.01,@"Default .5/.5 selection draws in the center instead of a corner");
|
||||
Check(api.objectBoundsReads==1,@"Drawing reads object bounds once for diagnostics and never uses them to scale the normalized point");
|
||||
api.x=NAN;[osc drawOSCWithWidth:1920 height:1080 activePart:0 destinationImage:tile atTime:time];Check(AlphaAt(tile,80,180)<.01,@"Nonfinite stored selection does not create invalid drawing filters");
|
||||
api.x=.5;api.y=.5;
|
||||
[osc mouseDownAtPositionX:.8 positionY:.3 activePart:1 modifiers:0 forceUpdate:&update atTime:time];
|
||||
[osc mouseUpAtPositionX:.8 positionY:.3 activePart:1 modifiers:0 forceUpdate:&update atTime:time];
|
||||
[osc drawOSCWithWidth:1921 height:1080 activePart:0 destinationImage:tile atTime:time];
|
||||
Check(fabs(api.x-.8)<1e-8 && fabs(api.y-.3)<1e-8 && AlphaAt(tile,256,72)>.9,@"Click writes normalized selection and redraws the handle at that point");
|
||||
PGOSCAPI *motion=[PGOSCAPI new];motion.pixelSetter=YES;motion.bounds=CGRectMake(-1920,-1080,3840,2160);
|
||||
PGFaceSelectOSC *motionOSC=[[PGFaceSelectOSC alloc] initWithAPIManager:motion];
|
||||
[motionOSC mouseDownAtPositionX:.8 positionY:.3 activePart:1 modifiers:0 forceUpdate:&update atTime:time];
|
||||
Check(update && fabs(motion.x-.8)<1e-5 && fabs(motion.y-.3)<1e-5,@"Motion pixel-setter bridge is detected by verified parameter readback");
|
||||
Check(motion.writes==2 && fabs(motion.lastX-1152)<1e-5 && fabs(motion.lastY+432)<1e-5,@"Detected bridge receives the centered pixel inverse transform");
|
||||
NSUInteger beforeCached=motion.writes;
|
||||
[motionOSC mouseDraggedAtPositionX:.7 positionY:.4 activePart:1 modifiers:0 forceUpdate:&update atTime:time];
|
||||
Check(update && motion.writes==beforeCached+1 && fabs(motion.x-.7)<1e-5 && fabs(motion.y-.4)<1e-5,@"Pixel-setter mode is cached only on the same OSC instance");
|
||||
[motionOSC mouseUpAtPositionX:.7 positionY:.4 activePart:1 modifiers:0 forceUpdate:&update atTime:time];
|
||||
[motionOSC drawOSCWithWidth:3840 height:2160 activePart:0 destinationImage:tile atTime:time];
|
||||
Check(AlphaAt(tile,224,96)>.9,@"Motion-compatible setter and normalized drawing round-trip to the same visible point");
|
||||
Check(motion.undoStarts==1 && motion.undoEnds==1,@"Calibration writes remain in one balanced undo gesture");
|
||||
PGOSCAPI *bad=[PGOSCAPI new];bad.corruptReadback=YES;
|
||||
PGFaceSelectOSC *badOSC=[[PGFaceSelectOSC alloc] initWithAPIManager:bad];
|
||||
[badOSC mouseDownAtPositionX:.8 positionY:.3 activePart:1 modifiers:0 forceUpdate:&update atTime:time];
|
||||
Check(!update && bad.undoStarts==bad.undoEnds,@"Unrecognized readback response is reported as failure with balanced undo");
|
||||
printf("OSC adapter: %lu checks, %lu failures\n",(unsigned long)Checks,(unsigned long)Failures);return Failures?1:0;
|
||||
}}
|
||||
在新工单中引用
屏蔽一个用户