From c65c7914621d2155ff5dfbc13a19377903d94e10 Mon Sep 17 00:00:00 2001 From: Johan Nordberg Date: Fri, 14 Dec 2012 00:52:54 +0100 Subject: [PATCH] Initial Commit --- .gitignore | 113 +++++ .gitmodules | 6 + CeedGL | 1 + .../contents.xcworkspacedata | 10 + FingerMgmt/Classes/AppDelegate.h | 16 + FingerMgmt/Classes/AppDelegate.m | 71 ++++ FingerMgmt/Classes/CeedGL+Additions.h | 38 ++ FingerMgmt/Classes/CeedGL+Additions.m | 148 +++++++ FingerMgmt/Classes/TouchPoint.h | 25 ++ FingerMgmt/Classes/TouchPoint.m | 36 ++ FingerMgmt/Classes/TouchView.h | 18 + FingerMgmt/Classes/TouchView.m | 333 +++++++++++++++ FingerMgmt/Classes/TrackpadView.h | 15 + FingerMgmt/Classes/TrackpadView.m | 125 ++++++ FingerMgmt/FingerMgmt.h | 13 + .../FingerMgmt.xcodeproj/project.pbxproj | 386 ++++++++++++++++++ .../contents.xcworkspacedata | 7 + FingerMgmt/Info.plist | 34 ++ FingerMgmt/MainMenu.xib | 369 +++++++++++++++++ FingerMgmt/MultiTouch.h | 36 ++ FingerMgmt/Shaders/effect.fsh | 50 +++ FingerMgmt/Shaders/effect.vsh | 8 + FingerMgmt/Shaders/touchPoint.fsh | 65 +++ FingerMgmt/Shaders/touchPoint.vsh | 28 ++ FingerMgmt/Shaders/trails.fsh | 29 ++ FingerMgmt/Shaders/trails.vsh | 8 + FingerMgmt/main.m | 13 + FingerMgmt/prefix.pch | 6 + FingerMgmt/toichview-old.m | 81 ++++ KGNoise | 1 + 30 files changed, 2089 insertions(+) create mode 100644 .gitignore create mode 100644 .gitmodules create mode 160000 CeedGL create mode 100644 FingerMgmt.xcworkspace/contents.xcworkspacedata create mode 100644 FingerMgmt/Classes/AppDelegate.h create mode 100644 FingerMgmt/Classes/AppDelegate.m create mode 100644 FingerMgmt/Classes/CeedGL+Additions.h create mode 100644 FingerMgmt/Classes/CeedGL+Additions.m create mode 100644 FingerMgmt/Classes/TouchPoint.h create mode 100644 FingerMgmt/Classes/TouchPoint.m create mode 100644 FingerMgmt/Classes/TouchView.h create mode 100644 FingerMgmt/Classes/TouchView.m create mode 100644 FingerMgmt/Classes/TrackpadView.h create mode 100644 FingerMgmt/Classes/TrackpadView.m create mode 100644 FingerMgmt/FingerMgmt.h create mode 100644 FingerMgmt/FingerMgmt.xcodeproj/project.pbxproj create mode 100644 FingerMgmt/FingerMgmt.xcodeproj/project.xcworkspace/contents.xcworkspacedata create mode 100644 FingerMgmt/Info.plist create mode 100644 FingerMgmt/MainMenu.xib create mode 100644 FingerMgmt/MultiTouch.h create mode 100644 FingerMgmt/Shaders/effect.fsh create mode 100644 FingerMgmt/Shaders/effect.vsh create mode 100644 FingerMgmt/Shaders/touchPoint.fsh create mode 100644 FingerMgmt/Shaders/touchPoint.vsh create mode 100644 FingerMgmt/Shaders/trails.fsh create mode 100644 FingerMgmt/Shaders/trails.vsh create mode 100644 FingerMgmt/main.m create mode 100644 FingerMgmt/prefix.pch create mode 100644 FingerMgmt/toichview-old.m create mode 160000 KGNoise diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..93e8364 --- /dev/null +++ b/.gitignore @@ -0,0 +1,113 @@ +######################### +# .gitignore file for Xcode4 / OS X Source projects +# +# NB: if you are storing "built" products, this WILL NOT WORK, +# and you should use a different .gitignore (or none at all) +# This file is for SOURCE projects, where there are many extra +# files that we want to exclude +# +# For updates, see: http://stackoverflow.com/questions/49478/git-ignore-file-for-xcode-projects +######################### + +##### +# OS X temporary files that should never be committed + +.DS_Store +*.swp +*.lock +profile + + +#### +# Xcode temporary files that should never be committed +# +# NB: NIB/XIB files still exist even on Storyboard projects, so we want this... + +*~.nib + + +#### +# Xcode build files - +# +# NB: slash on the end, so we only remove the FOLDER, not any files that were badly named "DerivedData" + +DerivedData/ + +# NB: slash on the end, so we only remove the FOLDER, not any files that were badly named "build" + +build/ + + +##### +# Xcode private settings (window sizes, bookmarks, breakpoints, custom executables, smart groups) +# +# This is complicated: +# +# SOMETIMES you need to put this file in version control. +# Apple designed it poorly - if you use "custom executables", they are +# saved in this file. +# 99% of projects do NOT use those, so they do NOT want to version control this file. +# ..but if you're in the 1%, comment out the line "*.pbxuser" + +*.pbxuser +*.mode1v3 +*.mode2v3 +*.perspectivev3 +# NB: also, whitelist the default ones, some projects need to use these +!default.pbxuser +!default.mode1v3 +!default.mode2v3 +!default.perspectivev3 + + +#### +# Xcode 4 - semi-personal settings, often included in workspaces +# +# You can safely ignore the xcuserdata files - but do NOT ignore the files next to them +# + +xcuserdata + + +#### +# XCode 4 workspaces - more detailed +# +# Workspaces are important! They are a core feature of Xcode - don't exclude them :) +# +# Workspace layout is quite spammy. For reference: +# +# (root)/ +# (project-name).xcodeproj/ +# project.pbxproj +# project.xcworkspace/ +# contents.xcworkspacedata +# xcuserdata/ +# (your name)/xcuserdatad/ +# xcuserdata/ +# (your name)/xcuserdatad/ +# +# +# +# Xcode 4 workspaces - SHARED +# +# This is UNDOCUMENTED (google: "developer.apple.com xcshareddata" - 0 results +# But if you're going to kill personal workspaces, at least keep the shared ones... +# +# +!xcshareddata + + +#### +# Xcode 4 - Deprecated classes +# +# Allegedly, if you manually "deprecate" your classes, they get moved here. +# +# We're using source-control, so this is a "feature" that we do not want! + +*.moved-aside + + +#### +# UNKNOWN: recommended by others, but I can't discover what these files are +# +# ...none. Everything is now explained. diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..2a07ec4 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,6 @@ +[submodule "KGNoise"] + path = KGNoise + url = https://github.com/kgn/KGNoise.git +[submodule "CeedGL"] + path = CeedGL + url = https://github.com/rsebbe/CeedGL.git diff --git a/CeedGL b/CeedGL new file mode 160000 index 0000000..62f04ed --- /dev/null +++ b/CeedGL @@ -0,0 +1 @@ +Subproject commit 62f04edfcfa520ff811e62d1eeea2dca6ebe8b6a diff --git a/FingerMgmt.xcworkspace/contents.xcworkspacedata b/FingerMgmt.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..6865656 --- /dev/null +++ b/FingerMgmt.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,10 @@ + + + + + + + diff --git a/FingerMgmt/Classes/AppDelegate.h b/FingerMgmt/Classes/AppDelegate.h new file mode 100644 index 0000000..d07ff6e --- /dev/null +++ b/FingerMgmt/Classes/AppDelegate.h @@ -0,0 +1,16 @@ +// +// AppDelegate.h +// FingerMgmt +// +// Created by Johan Nordberg on 2012-12-14. +// Copyright (c) 2012 FFFF00 Agents AB. All rights reserved. +// + +#import "TrackpadView.h" + +@interface AppDelegate : NSObject + +@property (assign) IBOutlet NSWindow *window; +@property (assign) IBOutlet TrackpadView *trackpadView; + +@end diff --git a/FingerMgmt/Classes/AppDelegate.m b/FingerMgmt/Classes/AppDelegate.m new file mode 100644 index 0000000..63eb4b4 --- /dev/null +++ b/FingerMgmt/Classes/AppDelegate.m @@ -0,0 +1,71 @@ +// +// AppDelegate.m +// FingerMgmt +// +// Created by Johan Nordberg on 2012-12-14. +// Copyright (c) 2012 FFFF00 Agents AB. All rights reserved. +// + +#import "AppDelegate.h" +#import "TouchPoint.h" + +// header for MultitouchSupport.framework +#import "MultiTouch.h" + +static int touchCallback(int device, mtTouch *data, int num_fingers, double timestamp, int frame) { + + // create TouchPoint objects for all touches + NSMutableArray *points = [[NSMutableArray alloc] initWithCapacity:num_fingers]; + for (int i = 0; i < num_fingers; i++) { + TouchPoint *point = [[TouchPoint alloc] initWithTouch:&data[i]]; + [points addObject:point]; + } + + // forward array of TouchPoints to AppDelegate on the main thread + AppDelegate *delegate = (AppDelegate *)[NSApp delegate]; + [delegate performSelectorOnMainThread:@selector(didTouchWithPoints:) withObject:points waitUntilDone:NO]; + + // no idea what the return code should be, guessing 0 for success + return 0; +} + +@implementation AppDelegate + +- (void)applicationDidFinishLaunching:(NSNotification *)notification { + + // get a list of all multitouch devices + NSArray *deviceList = (NSArray *)CFBridgingRelease(MTDeviceCreateList()); + for (int i = 0; i < [deviceList count]; i++) { + // start sending touches to callback + MTDeviceRef device = (__bridge MTDeviceRef)[deviceList objectAtIndex:i]; + MTRegisterContactFrameCallback(device, touchCallback); + MTDeviceStart(device, 0); + } + +} + +- (void)didTouchWithPoints:(NSArray *)points { + self.trackpadView.touchView.touchPoints = points; +} + +/* + + This was just annoying + +- (void)applicationDidBecomeActive:(NSNotification *)notification { + CGPoint pos; + pos.x = _window.frame.origin.x + (_window.frame.size.width / 2); + pos.y = _window.frame.origin.y + (_window.frame.size.height / 2); + + CGDisplayHideCursor(kCGNullDirectDisplay); + CGDisplayMoveCursorToPoint(kCGDirectMainDisplay, pos); + CGAssociateMouseAndMouseCursorPosition(false); +} + +- (void)applicationWillResignActive:(NSNotification *)notification { + CGDisplayShowCursor(kCGNullDirectDisplay); + CGAssociateMouseAndMouseCursorPosition(true); +} +*/ + +@end diff --git a/FingerMgmt/Classes/CeedGL+Additions.h b/FingerMgmt/Classes/CeedGL+Additions.h new file mode 100644 index 0000000..6bd2dbb --- /dev/null +++ b/FingerMgmt/Classes/CeedGL+Additions.h @@ -0,0 +1,38 @@ +// +// CeedGL+Additions.h +// FingerMgmt +// +// Created by Johan Nordberg on 2012-12-18. +// Copyright (c) 2012 FFFF00 Agents AB. All rights reserved. +// + +#import + +@interface GLProgram (Additions) + ++ (GLProgram *)programNamed:(NSString *)name; + +@end + +@interface GLShader (Additions) + ++ (GLShader *)fragmentShaderNamed:(NSString *)name; ++ (GLShader *)vertexShaderNamed:(NSString *)name; + +@end + + +@interface GLTexture (Additions) + ++ (GLTexture *)textureNamed:(NSString *)name; ++ (GLTexture *)textureWithImage:(NSImage *)image; + +@end + + +@interface NSString (Additions) + ++ (NSString *)stringWithContentsOfResource:(NSString *)resource ofType:(NSString *)type encoding:(NSStringEncoding)encoding; ++ (NSString *)stringWithContentsOfResource:(NSString *)resource ofType:(NSString *)type; + +@end diff --git a/FingerMgmt/Classes/CeedGL+Additions.m b/FingerMgmt/Classes/CeedGL+Additions.m new file mode 100644 index 0000000..f009adc --- /dev/null +++ b/FingerMgmt/Classes/CeedGL+Additions.m @@ -0,0 +1,148 @@ +// +// CeedGL+Additions.m +// FingerMgmt +// +// Created by Johan Nordberg on 2012-12-18. +// Copyright (c) 2012 FFFF00 Agents AB. All rights reserved. +// + +#import "CeedGL+Additions.h" + + +@implementation GLTexture (Additions) + ++ (GLTexture *)textureNamed:(NSString *)name { + NSImage *image = [NSImage imageNamed:name]; + return [self textureWithImage:image]; +} + ++ (GLTexture *)textureWithImage:(NSImage *)image { + GLTexture *texture = [GLTexture texture]; + + if (![image isFlipped]) { + NSImage *drawImage = [[NSImage alloc] initWithSize:image.size]; + NSAffineTransform *transform = [NSAffineTransform transform]; + + [drawImage lockFocus]; + + [transform translateXBy:0 yBy:image.size.height]; + [transform scaleXBy:1 yBy:-1]; + [transform concat]; + + [image drawAtPoint:NSZeroPoint + fromRect:(NSRect){NSZeroPoint, image.size} + operation:NSCompositeCopy + fraction:1]; + + [drawImage unlockFocus]; + + image = drawImage; + } + + NSBitmapImageRep *bitmap = [[NSBitmapImageRep alloc] initWithData:[image TIFFRepresentation]]; + + [texture createHandle]; + [texture bind:GL_TEXTURE_2D]; + + // Set proper unpacking row length for bitmap. + glPixelStorei(GL_UNPACK_ROW_LENGTH, (GLint)[bitmap pixelsWide]); + + // Set byte aligned unpacking (needed for 3 byte per pixel bitmaps). + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + GLCheckError(); + + NSInteger samplesPerPixel = [bitmap samplesPerPixel]; + + // Nonplanar, RGB 24 bit bitmap, or RGBA 32 bit bitmap. + if(![bitmap isPlanar] && (samplesPerPixel == 3 || samplesPerPixel == 4)) { + glTexImage2D(GL_TEXTURE_2D, 0, + samplesPerPixel == 4 ? GL_RGBA8 : GL_RGB8, + (GLint)[bitmap pixelsWide], + (GLint)[bitmap pixelsHigh], + 0, + samplesPerPixel == 4 ? GL_RGBA : GL_RGB, + GL_UNSIGNED_BYTE, + [bitmap bitmapData]); + GLCheckError(); + } else { + [[NSException exceptionWithName:@"ImageFormat" reason:@"Unsupported image format" userInfo:nil] raise]; + return nil; + } + + return texture; + +} + +@end + +@implementation NSString (Additions) + ++ (NSString *)stringWithContentsOfResource:(NSString *)resource ofType:(NSString *)type encoding:(NSStringEncoding)encoding { + NSError *error; + + NSString *path = [[NSBundle mainBundle] pathForResource:resource ofType:type]; + NSString *string = [NSString stringWithContentsOfFile:path encoding:encoding error:&error]; + + if (error) { + NSLog(@"Failed loading bundle resource %@.%@: %@", resource, type, error); + } + + return string; +} ++ (NSString *)stringWithContentsOfResource:(NSString *)resource ofType:(NSString *)type { + return [NSString stringWithContentsOfResource:resource ofType:type encoding:NSUTF8StringEncoding]; +} +@end + +@implementation GLShader (Additions) + ++ (GLShader *)fragmentShaderNamed:(NSString *)name { + GLShader *shader = [GLShader fragmentShader]; + [shader setSource:[NSString stringWithContentsOfResource:name ofType:@"fsh"]]; + return shader; +} + ++ (GLShader *)vertexShaderNamed:(NSString *)name { + GLShader *shader = [GLShader vertexShader]; + [shader setSource:[NSString stringWithContentsOfResource:name ofType:@"vsh"]]; + return shader; +} + +@end + +@implementation GLProgram (Additions) + ++ (GLProgram *)programNamed:(NSString *)name { + NSError *error; + GLProgram *program = [GLProgram program]; + + GLShader *vshader = [GLShader vertexShaderNamed:name]; + GLShader *fshader = [GLShader fragmentShaderNamed:name]; + + if (![vshader compile:&error]) { + NSLog(@"Vertex shader compilation error: %@", error); + } + + if (![fshader compile:&error]) { + NSLog(@"Fragment shader compilation error: %@", error); + } + + [program attachShader:vshader]; + [program attachShader:fshader]; + + if (![program link:&error]) { + NSLog(@"Could not link program error: %@", error); + } + + return program; +} + +@end + + + diff --git a/FingerMgmt/Classes/TouchPoint.h b/FingerMgmt/Classes/TouchPoint.h new file mode 100644 index 0000000..91b8b37 --- /dev/null +++ b/FingerMgmt/Classes/TouchPoint.h @@ -0,0 +1,25 @@ +// +// TouchPoint.h +// FingerMgmt +// +// Created by Johan Nordberg on 2009-11-06. +// Copyright 2009 FFFF00 Agents AB. All rights reserved. +// + +#import "MultiTouch.h" + +@interface TouchPoint : NSObject + +@property (readonly) float x; +@property (readonly) float y; +@property (readonly) float minorAxis; +@property (readonly) float majorAxis; +@property (readonly) float angle; +@property (readonly) float size; +@property (readonly) float velX; +@property (readonly) float velY; +@property (readonly) float timestamp; + +- (id)initWithTouch:(mtTouch *)touch; + +@end diff --git a/FingerMgmt/Classes/TouchPoint.m b/FingerMgmt/Classes/TouchPoint.m new file mode 100644 index 0000000..92cbd14 --- /dev/null +++ b/FingerMgmt/Classes/TouchPoint.m @@ -0,0 +1,36 @@ +// +// TouchPoint.m +// FingerMgmt +// +// Created by Johan Nordberg on 2009-11-06. +// Copyright 2009 FFFF00 Agents AB. All rights reserved. +// + +#import "TouchPoint.h" + +@implementation TouchPoint + +@synthesize x, y; +@synthesize velX, velY; +@synthesize minorAxis; +@synthesize majorAxis; +@synthesize angle; +@synthesize size; +@synthesize timestamp; + +- (id)initWithTouch:(mtTouch *)touch { + if ((self = [self init])) { + x = touch->normalized.position.x; + y = touch->normalized.position.y; + minorAxis = touch->minorAxis; + majorAxis = touch->majorAxis; + angle = touch->angle; + size = touch->size; + velX = touch->normalized.velocity.x; + velY = touch->normalized.velocity.y; + timestamp = touch->timestamp; + } + return self; +} + +@end diff --git a/FingerMgmt/Classes/TouchView.h b/FingerMgmt/Classes/TouchView.h new file mode 100644 index 0000000..9ee8bf7 --- /dev/null +++ b/FingerMgmt/Classes/TouchView.h @@ -0,0 +1,18 @@ +// +// TouchView.h +// FingerMgmt +// +// Created by Johan Nordberg on 2012-12-14. +// Copyright (c) 2012 FFFF00 Agents AB. All rights reserved. +// + +#import +#import +#import "CeedGL+Additions.h" + +@interface TouchView : NSOpenGLView + +@property (nonatomic, strong) NSArray *touchPoints; +@property (nonatomic, strong) NSImage *mask; + +@end diff --git a/FingerMgmt/Classes/TouchView.m b/FingerMgmt/Classes/TouchView.m new file mode 100644 index 0000000..aa08d68 --- /dev/null +++ b/FingerMgmt/Classes/TouchView.m @@ -0,0 +1,333 @@ +// +// TouchView.m +// FingerMgmt +// +// Created by Johan Nordberg on 2012-12-14. +// Copyright (c) 2012 FFFF00 Agents AB. All rights reserved. +// + +#import "TouchView.h" +#import "TouchPoint.h" + +#define kNumCircleSegments 64 + +void makeOrtho(GLfloat *m, GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat znear, GLfloat zfar) { + GLfloat tx = - (right + left) / (right - left); + GLfloat ty = - (top + bottom) / (top - bottom); + GLfloat tz = - (zfar + znear) / (zfar - znear); + m[0] = 2 / (right - left); + m[1] = 0; + m[2] = 0; + m[3] = tx; + m[4] = 0; + m[5] = 2 / (top - bottom); + m[6] = 0; + m[7] = ty; + m[8] = 0; + m[9] = 0; + m[10] = -2 / (zfar - znear); + m[11] = tz; + m[12] = 0; + m[13] = 0; + m[14] = 0; + m[15] = 1; +} + +enum { + u_rotate, + u_translate, + u_size, + u_mode, + u_pass, + u_mix, + u_sigma, + u_blur, + u_mask, + u_velocity, +}; + +@interface TouchView () { + GLProgram *_program; + GLProgram *_effectProgram; + GLProgram *_trailsProgram; + + GLfloat _aspect; + + GLint _uniforms[10]; + + NSTimer *_timer; + + GLTexture *_maskTexture; + + GLuint _textures[4]; + GLuint _framebuffers[4]; + + GLuint _fsBuffer; + GLuint _fsTexBuffer; +} + +@end + +@implementation TouchView + +@synthesize touchPoints = _touchPoints; +@synthesize mask = _mask; + +- (BOOL)isOpaque { + return NO; +} + +- (void)setTouchPoints:(NSArray *)touchPoints { + _touchPoints = touchPoints; + [self setNeedsDisplay:YES]; +} + +- (void)prepareOpenGL { + _program = [GLProgram programNamed:@"touchPoint"]; + _effectProgram = [GLProgram programNamed:@"effect"]; + _trailsProgram = [GLProgram programNamed:@"trails"]; + + _uniforms[u_rotate] = glGetUniformLocation(_program.handle, "u_rotate"); + _uniforms[u_translate] = glGetUniformLocation(_program.handle, "u_translate"); + _uniforms[u_size] = glGetUniformLocation(_program.handle, "u_size"); + _uniforms[u_mode] = glGetUniformLocation(_program.handle, "u_mode"); + _uniforms[u_velocity] = glGetUniformLocation(_program.handle, "u_velocity"); + _uniforms[u_pass] = glGetUniformLocation(_effectProgram.handle, "u_pass"); + _uniforms[u_sigma] = glGetUniformLocation(_effectProgram.handle, "u_sigma"); + _uniforms[u_blur] = glGetUniformLocation(_effectProgram.handle, "u_blur"); + _uniforms[u_mix] = glGetUniformLocation(_trailsProgram.handle, "u_mix"); + _uniforms[u_mask] = glGetUniformLocation(_trailsProgram.handle, "u_mask"); + + GLint zeroOpacity = 0; + [[self openGLContext] setValues:&zeroOpacity forParameter:NSOpenGLCPSurfaceOpacity]; + + glDisable(GL_ALPHA_TEST); + glDisable(GL_DEPTH_TEST); + glDisable(GL_SCISSOR_TEST); + glDisable(GL_BLEND); + glDisable(GL_DITHER); + glDisable(GL_CULL_FACE); + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + glDepthMask(GL_FALSE); + glStencilMask(0); + glClearColor(0, 0, 0, 0); + glHint(GL_TRANSFORM_HINT_APPLE, GL_FASTEST); + + _timer = [NSTimer scheduledTimerWithTimeInterval:1.0 / 30 target:self selector:@selector(tick) userInfo:nil repeats:YES]; +} + +- (void)tick { + [self setNeedsDisplay:YES]; +} + +- (void)reshape { + [[self openGLContext] makeCurrentContext]; + + NSSize size = self.bounds.size; + glViewport(0, 0, size.width, size.height); + + GLfloat projection[16]; + _aspect = size.width / size.height; + makeOrtho(projection, 0, _aspect, 0, 1, -1.0f, 1.0f); + + [_program use]; + glUniformMatrix4fv([_program uniformLocationForName:@"u_projection"], 1, GL_TRUE, projection); + glUniform2f([_program uniformLocationForName:@"u_resolution"], size.width, size.height); + + [_effectProgram use]; + glUniformMatrix4fv([_effectProgram uniformLocationForName:@"u_projection"], 1, GL_TRUE, projection); + glUniform2f([_effectProgram uniformLocationForName:@"u_resolution"], size.width, size.height); + glUniform1i(glGetUniformLocation(_effectProgram.handle, "u_texture"), 0); + + [_trailsProgram use]; + glUniformMatrix4fv([_trailsProgram uniformLocationForName:@"u_projection"], 1, GL_TRUE, projection); + glUniform2f([_trailsProgram uniformLocationForName:@"u_resolution"], size.width, size.height); + glUniform1i(glGetUniformLocation(_trailsProgram.handle, "u_texture1"), 0); + glUniform1i(glGetUniformLocation(_trailsProgram.handle, "u_texture2"), 1); + + [self setupOffscreenRender]; + [self setupMask]; + [self setupDrawBuffers]; + + [self setNeedsDisplay:YES]; +} + +- (void)setupMask { + if (_mask) { + if (_maskTexture) [_maskTexture destroyHandle]; + _maskTexture = [GLTexture textureWithImage:_mask]; + } +} + +- (void)setupOffscreenRender { + NSSize size = self.bounds.size; + + for (int i = 0; i < 4; i++) { + if (_textures[i]) glDeleteTextures(1, &_textures[i]); + if (_framebuffers[i]) glDeleteFramebuffers(1, &_framebuffers[i]); + + glGenTextures(1, &_textures[i]); + glBindTexture(GL_TEXTURE_2D, _textures[i]); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + GLCheckError(); + + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size.width, size.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); + GLCheckError(); + + glGenFramebuffers(1, &_framebuffers[i]); + glBindFramebuffer(GL_FRAMEBUFFER, _framebuffers[i]); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, _textures[i], 0); + + if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { + NSLog(@"Failed to setup framebuffer!"); + } + + glClear(GL_COLOR_BUFFER_BIT); + } + + glBindFramebuffer(GL_FRAMEBUFFER, 0); +} + +- (void)setupDrawBuffers { + if (_fsBuffer) glDeleteBuffers(1, &_fsBuffer); + glGenBuffers(1, &_fsBuffer); + + GLfloat vertices[] = { + 0, 1, + _aspect, 1, + 0, 0, + _aspect, 0, + }; + + glBindBuffer(GL_ARRAY_BUFFER, _fsBuffer); + glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); +} + +#pragma mark Drawing + +- (void)drawTouches { + glBindBuffer(GL_ARRAY_BUFFER, 0); + glEnableVertexAttribArray(0); + for (TouchPoint *point in _touchPoints) { + [self drawTouchPoint:point]; + } +} + +- (void)drawTouchPoint:(TouchPoint *)point { + GLfloat vertices[kNumCircleSegments * 2]; + for (int i = 0; i < kNumCircleSegments * 2; i += 2) { + float theta = M_PI * (float)i / kNumCircleSegments; + vertices[i] = (cosf(theta) / point.minorAxis) * point.size; + vertices[i + 1] = (sinf(theta) / point.majorAxis) * point.size; + } + + glUniform2f(_uniforms[u_translate], point.x * _aspect, point.y); + glUniform1f(_uniforms[u_rotate], -point.angle); + glUniform1f(_uniforms[u_size], point.size); + glUniform2f(_uniforms[u_velocity], point.velX , point.velY); + + glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, vertices); + glDrawArrays(GL_TRIANGLE_FAN, 0, kNumCircleSegments); +} + +- (void)drawFull { + glBindBuffer(GL_ARRAY_BUFFER, _fsBuffer); + glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); +} + +- (void)drawRect:(NSRect)dirtyRect { + [[self openGLContext] makeCurrentContext]; + + // render touches to tex 0 + [_program use]; + glBindFramebuffer(GL_FRAMEBUFFER, _framebuffers[0]); + glClear(GL_COLOR_BUFFER_BIT); + glUniform1i(_uniforms[u_mode], 0); + [self drawTouches]; + + // mix tex 0(current frame) and tex 2(prev frame) to tex 1 + [_trailsProgram use]; + glUniform1i(_uniforms[u_mask], 0); + glUniform1f(_uniforms[u_mix], 0.95); + glBindFramebuffer(GL_FRAMEBUFFER, _framebuffers[1]); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, _textures[0]); + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, _textures[2]); + glClear(GL_COLOR_BUFFER_BIT); + [self drawFull]; + + // blur + [_effectProgram use]; + glUniform1f(_uniforms[u_blur], 10); + glUniform1f(_uniforms[u_sigma], 30); + + // first pass + glUniform1i(_uniforms[u_pass], 0); + glBindFramebuffer(GL_FRAMEBUFFER, _framebuffers[0]); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, _textures[1]); + glClear(GL_COLOR_BUFFER_BIT); + [self drawFull]; + + // second pass - renders to texture 2 (prev frame) + glUniform1i(_uniforms[u_pass], 1); + glBindFramebuffer(GL_FRAMEBUFFER, _framebuffers[2]); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, _textures[0]); + glClear(GL_COLOR_BUFFER_BIT); + [self drawFull]; + + // copy prev frame to tex 0 + [_trailsProgram use]; + glUniform1f(_uniforms[u_mix], 0); + glBindFramebuffer(GL_FRAMEBUFFER, _framebuffers[0]); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, _textures[2]); + glClear(GL_COLOR_BUFFER_BIT); + [self drawFull]; + + // draw dots on top + [_program use]; + glUniform1i(_uniforms[u_mode], 1); + [self drawTouches]; + + // antialias with blur + [_effectProgram use]; + glUniform1f(_uniforms[u_blur], 2); + glUniform1f(_uniforms[u_sigma], 1); + + glUniform1i(_uniforms[u_pass], 0); + glBindFramebuffer(GL_FRAMEBUFFER, _framebuffers[1]); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, _textures[0]); + glClear(GL_COLOR_BUFFER_BIT); + [self drawFull]; + + glUniform1i(_uniforms[u_pass], 1); + glBindFramebuffer(GL_FRAMEBUFFER, _framebuffers[0]); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, _textures[1]); + glClear(GL_COLOR_BUFFER_BIT); + [self drawFull]; + + // mask and draw to main buffer + [_trailsProgram use]; + glBindFramebuffer(GL_FRAMEBUFFER, 0); + glUniform1i(_uniforms[u_mask], 1); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, _textures[0]); + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, _maskTexture.handle); + glClear(GL_COLOR_BUFFER_BIT); + [self drawFull]; + + glSwapAPPLE(); +} + +@end diff --git a/FingerMgmt/Classes/TrackpadView.h b/FingerMgmt/Classes/TrackpadView.h new file mode 100644 index 0000000..2246323 --- /dev/null +++ b/FingerMgmt/Classes/TrackpadView.h @@ -0,0 +1,15 @@ +// +// TrackpadView.h +// FingerMgmt +// +// Created by Johan Nordberg on 2012-12-14. +// Copyright (c) 2012 FFFF00 Agents AB. All rights reserved. +// + +#import "TouchView.h" + +@interface TrackpadView : NSView + +@property (strong) TouchView *touchView; + +@end diff --git a/FingerMgmt/Classes/TrackpadView.m b/FingerMgmt/Classes/TrackpadView.m new file mode 100644 index 0000000..b37270a --- /dev/null +++ b/FingerMgmt/Classes/TrackpadView.m @@ -0,0 +1,125 @@ +// +// TrackpadView.m +// FingerMgmt +// +// Created by Johan Nordberg on 2012-12-14. +// Copyright (c) 2012 FFFF00 Agents AB. All rights reserved. +// + +#import "TrackpadView.h" + +@implementation TrackpadView + +@synthesize touchView = _touchView; + +- (id)initWithCoder:(NSCoder *)aDecoder { + self = [super initWithCoder:aDecoder]; + if (self) { + _touchView = [[TouchView alloc] initWithFrame:[self trackpadFrame]]; + [_touchView setMask:[self trackpadMask]]; + [self addSubview:_touchView]; + } + return self; +} + +- (void)resizeSubviewsWithOldSize:(NSSize)oldSize { + _touchView.frame = [self trackpadFrame]; + [_touchView setMask:[self trackpadMask]]; +} + +- (NSRect)trackpadFrame { + CGRect rv, bounds = NSRectToCGRect(self.bounds); + + CGSize trackpadSize = {kTrackpadWidth, kTrackpadHeight}; + CGFloat trackpadRatio = trackpadSize.width / trackpadSize.height; + CGFloat boundsRatio = bounds.size.width / bounds.size.height; + + rv = bounds; + if (trackpadRatio > boundsRatio) { + rv.size.height = bounds.size.width * trackpadSize.height / trackpadSize.width; + rv.origin.y += (bounds.size.height - rv.size.height) / 2; + } else { + rv.size.width = bounds.size.height * trackpadSize.width / trackpadSize.height; + rv.origin.x += (bounds.size.width - rv.size.width) / 2; + } + + return NSRectFromCGRect(CGRectInset(rv, kTrackpadPadding, kTrackpadPadding)); +} + +- (NSImage *)trackpadMask { + NSSize size = [self trackpadFrame].size; + NSRect frame = (NSRect){NSZeroPoint, size}; + NSImage *mask = [[NSImage alloc] initWithSize:size]; + NSBezierPath* path; + + [mask lockFocus]; + path = [NSBezierPath bezierPathWithRect:frame]; + [[NSColor whiteColor] setFill]; + [path fill]; + + [[NSColor blackColor] setFill]; + [[NSColor whiteColor] setStroke]; + [self drawTrackpadInFrame:frame]; + [mask unlockFocus]; + + return mask; +} + +- (void)drawRect:(NSRect)dirtyRect { + NSRect bounds = self.bounds; + + //// Color Declarations + NSColor* backgroundColor = [NSColor colorWithCalibratedRed: 0.912 green: 0.912 blue: 0.912 alpha: 1]; + NSColor* trackpadColor = [backgroundColor shadowWithLevel: 0.04]; + NSColor* borderColor = [trackpadColor highlightWithLevel: 0.4]; + + //// background Drawing + NSBezierPath* backgroundPath = [NSBezierPath bezierPathWithRect:bounds]; + [[backgroundColor colorWithNoiseWithOpacity:kNoiseAmount] setFill]; + [backgroundPath fill]; + + [[trackpadColor colorWithNoiseWithOpacity:kNoiseAmount] setFill]; + [borderColor setStroke]; + [self drawTrackpadInFrame:[self trackpadFrame]]; + +} + +- (void)drawTrackpadInFrame:(NSRect)frame { + NSShadow* innerShadow = [[NSShadow alloc] init]; + [innerShadow setShadowColor: [NSColor blackColor]]; + [innerShadow setShadowOffset: NSMakeSize(0.1, -1.1)]; + [innerShadow setShadowBlurRadius: 2]; + + //// trackpad Drawing + NSBezierPath* trackpadPath = [NSBezierPath bezierPathWithRoundedRect:frame xRadius: 14 yRadius: 14]; + [trackpadPath fill]; + + ////// trackpad Inner Shadow + NSRect trackpadBorderRect = NSInsetRect([trackpadPath bounds], -innerShadow.shadowBlurRadius, -innerShadow.shadowBlurRadius); + trackpadBorderRect = NSOffsetRect(trackpadBorderRect, -innerShadow.shadowOffset.width, -innerShadow.shadowOffset.height); + trackpadBorderRect = NSInsetRect(NSUnionRect(trackpadBorderRect, [trackpadPath bounds]), -1, -1); + + NSBezierPath* trackpadNegativePath = [NSBezierPath bezierPathWithRect: trackpadBorderRect]; + [trackpadNegativePath appendBezierPath: trackpadPath]; + [trackpadNegativePath setWindingRule: NSEvenOddWindingRule]; + + [NSGraphicsContext saveGraphicsState]; + { + NSShadow* innerShadowWithOffset = [innerShadow copy]; + CGFloat xOffset = innerShadowWithOffset.shadowOffset.width + round(trackpadBorderRect.size.width); + CGFloat yOffset = innerShadowWithOffset.shadowOffset.height; + innerShadowWithOffset.shadowOffset = NSMakeSize(xOffset + copysign(0.1, xOffset), yOffset + copysign(0.1, yOffset)); + [innerShadowWithOffset set]; + [[NSColor grayColor] setFill]; + [trackpadPath addClip]; + NSAffineTransform* transform = [NSAffineTransform transform]; + [transform translateXBy: -round(trackpadBorderRect.size.width) yBy: 0]; + [[transform transformBezierPath: trackpadNegativePath] fill]; + } + [NSGraphicsContext restoreGraphicsState]; + + [trackpadPath setLineWidth: 1]; + [trackpadPath stroke]; +} + +@end diff --git a/FingerMgmt/FingerMgmt.h b/FingerMgmt/FingerMgmt.h new file mode 100644 index 0000000..a90bc67 --- /dev/null +++ b/FingerMgmt/FingerMgmt.h @@ -0,0 +1,13 @@ +// +// FingerMgmt.h +// FingerMgmt +// +// Created by Johan Nordberg on 2012-12-14. +// Copyright (c) 2012 FFFF00 Agents AB. All rights reserved. +// + +#define kTrackpadWidth 526 +#define kTrackpadHeight 381 +#define kTrackpadPadding 35 + +#define kNoiseAmount 0.25 diff --git a/FingerMgmt/FingerMgmt.xcodeproj/project.pbxproj b/FingerMgmt/FingerMgmt.xcodeproj/project.pbxproj new file mode 100644 index 0000000..5e30a6e --- /dev/null +++ b/FingerMgmt/FingerMgmt.xcodeproj/project.pbxproj @@ -0,0 +1,386 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + A592586A1680293F00A6AD67 /* effect.fsh in Resources */ = {isa = PBXBuildFile; fileRef = A59258681680293F00A6AD67 /* effect.fsh */; }; + A592586B1680293F00A6AD67 /* effect.vsh in Resources */ = {isa = PBXBuildFile; fileRef = A59258691680293F00A6AD67 /* effect.vsh */; }; + A592586F16802A5600A6AD67 /* CeedGL+Additions.m in Sources */ = {isa = PBXBuildFile; fileRef = A592586E16802A5600A6AD67 /* CeedGL+Additions.m */; }; + A59BC9751681D246007BF672 /* trails.fsh in Resources */ = {isa = PBXBuildFile; fileRef = A59BC9731681D246007BF672 /* trails.fsh */; }; + A59BC9761681D246007BF672 /* trails.vsh in Resources */ = {isa = PBXBuildFile; fileRef = A59BC9741681D246007BF672 /* trails.vsh */; }; + A5BD4D2E167BF2A000658BE3 /* KGNoise.m in Sources */ = {isa = PBXBuildFile; fileRef = A5BD4D1C167BF2A000658BE3 /* KGNoise.m */; }; + A5BD4D4B167BF58000658BE3 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = A5BD4D48167BF58000658BE3 /* main.m */; }; + A5BD4D4F167BF58D00658BE3 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = A5BD4D4D167BF58D00658BE3 /* MainMenu.xib */; }; + A5BD4D64167BF86100658BE3 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = A5BD4D5D167BF86100658BE3 /* AppDelegate.m */; }; + A5BD4D65167BF86100658BE3 /* TouchPoint.m in Sources */ = {isa = PBXBuildFile; fileRef = A5BD4D5F167BF86100658BE3 /* TouchPoint.m */; }; + A5BD4D66167BF86100658BE3 /* TouchView.m in Sources */ = {isa = PBXBuildFile; fileRef = A5BD4D61167BF86100658BE3 /* TouchView.m */; }; + A5BD4D67167BF86100658BE3 /* TrackpadView.m in Sources */ = {isa = PBXBuildFile; fileRef = A5BD4D63167BF86100658BE3 /* TrackpadView.m */; }; + A5BD4D6E167C097100658BE3 /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A5BD4D6D167C097100658BE3 /* OpenGL.framework */; }; + A5BD4D6F167C0B1700658BE3 /* touchPoint.fsh in Resources */ = {isa = PBXBuildFile; fileRef = A5BD4D69167BF8F500658BE3 /* touchPoint.fsh */; }; + A5BD4D70167C0B1E00658BE3 /* touchPoint.vsh in Resources */ = {isa = PBXBuildFile; fileRef = A5BD4D6A167BF8F500658BE3 /* touchPoint.vsh */; }; + A5C08BFE167AC49B003ED945 /* MultitouchSupport.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A5C08BFD167AC49B003ED945 /* MultitouchSupport.framework */; }; + A5C4314816831837000EC677 /* CeedGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A5C4314716831837000EC677 /* CeedGL.framework */; }; + A5C4314B168319D8000EC677 /* CeedGL.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = A5C4314716831837000EC677 /* CeedGL.framework */; }; + A5F71D13167AA1D600FF0DF6 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A5F71D12167AA1D600FF0DF6 /* Cocoa.framework */; }; +/* End PBXBuildFile section */ + +/* Begin PBXCopyFilesBuildPhase section */ + A5C4314A168319BC000EC677 /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + A5C4314B168319D8000EC677 /* CeedGL.framework in CopyFiles */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + A59258681680293F00A6AD67 /* effect.fsh */ = {isa = PBXFileReference; explicitFileType = sourcecode.glsl; fileEncoding = 4; path = effect.fsh; sourceTree = ""; }; + A59258691680293F00A6AD67 /* effect.vsh */ = {isa = PBXFileReference; explicitFileType = sourcecode.glsl; fileEncoding = 4; path = effect.vsh; sourceTree = ""; }; + A592586D16802A5600A6AD67 /* CeedGL+Additions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "CeedGL+Additions.h"; path = "Classes/CeedGL+Additions.h"; sourceTree = SOURCE_ROOT; }; + A592586E16802A5600A6AD67 /* CeedGL+Additions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "CeedGL+Additions.m"; path = "Classes/CeedGL+Additions.m"; sourceTree = SOURCE_ROOT; }; + A59BC9731681D246007BF672 /* trails.fsh */ = {isa = PBXFileReference; explicitFileType = sourcecode.glsl; fileEncoding = 4; path = trails.fsh; sourceTree = ""; }; + A59BC9741681D246007BF672 /* trails.vsh */ = {isa = PBXFileReference; explicitFileType = sourcecode.glsl; fileEncoding = 4; path = trails.vsh; sourceTree = ""; }; + A5BD4D1B167BF2A000658BE3 /* KGNoise.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KGNoise.h; sourceTree = ""; }; + A5BD4D1C167BF2A000658BE3 /* KGNoise.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KGNoise.m; sourceTree = ""; }; + A5BD4D47167BF58000658BE3 /* FingerMgmt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FingerMgmt.h; sourceTree = SOURCE_ROOT; }; + A5BD4D48167BF58000658BE3 /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = SOURCE_ROOT; }; + A5BD4D49167BF58000658BE3 /* MultiTouch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MultiTouch.h; sourceTree = SOURCE_ROOT; }; + A5BD4D4A167BF58000658BE3 /* prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = prefix.pch; sourceTree = SOURCE_ROOT; }; + A5BD4D4C167BF58D00658BE3 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = SOURCE_ROOT; }; + A5BD4D4D167BF58D00658BE3 /* MainMenu.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = MainMenu.xib; sourceTree = SOURCE_ROOT; }; + A5BD4D5C167BF86100658BE3 /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = Classes/AppDelegate.h; sourceTree = SOURCE_ROOT; }; + A5BD4D5D167BF86100658BE3 /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AppDelegate.m; path = Classes/AppDelegate.m; sourceTree = SOURCE_ROOT; }; + A5BD4D5E167BF86100658BE3 /* TouchPoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TouchPoint.h; path = Classes/TouchPoint.h; sourceTree = SOURCE_ROOT; }; + A5BD4D5F167BF86100658BE3 /* TouchPoint.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TouchPoint.m; path = Classes/TouchPoint.m; sourceTree = SOURCE_ROOT; }; + A5BD4D60167BF86100658BE3 /* TouchView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TouchView.h; path = Classes/TouchView.h; sourceTree = SOURCE_ROOT; }; + A5BD4D61167BF86100658BE3 /* TouchView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TouchView.m; path = Classes/TouchView.m; sourceTree = SOURCE_ROOT; }; + A5BD4D62167BF86100658BE3 /* TrackpadView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TrackpadView.h; path = Classes/TrackpadView.h; sourceTree = SOURCE_ROOT; }; + A5BD4D63167BF86100658BE3 /* TrackpadView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TrackpadView.m; path = Classes/TrackpadView.m; sourceTree = SOURCE_ROOT; }; + A5BD4D69167BF8F500658BE3 /* touchPoint.fsh */ = {isa = PBXFileReference; explicitFileType = sourcecode.glsl; fileEncoding = 4; path = touchPoint.fsh; sourceTree = ""; }; + A5BD4D6A167BF8F500658BE3 /* touchPoint.vsh */ = {isa = PBXFileReference; explicitFileType = sourcecode.glsl; fileEncoding = 4; path = touchPoint.vsh; sourceTree = ""; }; + A5BD4D6D167C097100658BE3 /* OpenGL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGL.framework; path = System/Library/Frameworks/OpenGL.framework; sourceTree = SDKROOT; }; + A5C08BFD167AC49B003ED945 /* MultitouchSupport.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MultitouchSupport.framework; path = /System/Library/PrivateFrameworks/MultitouchSupport.framework; sourceTree = ""; }; + A5C4314716831837000EC677 /* CeedGL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CeedGL.framework; path = "../../../Library/Developer/Xcode/DerivedData/FingerMgmt-anhqnncqdtyzosehvqkcojuqfbmj/Build/Products/Debug/CeedGL.framework"; sourceTree = ""; }; + A5F71D0E167AA1D600FF0DF6 /* FingerMgmt.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = FingerMgmt.app; sourceTree = BUILT_PRODUCTS_DIR; }; + A5F71D12167AA1D600FF0DF6 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; }; + A5F71D15167AA1D600FF0DF6 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; }; + A5F71D17167AA1D600FF0DF6 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + A5F71D0B167AA1D600FF0DF6 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + A5BD4D6E167C097100658BE3 /* OpenGL.framework in Frameworks */, + A5C4314816831837000EC677 /* CeedGL.framework in Frameworks */, + A5C08BFE167AC49B003ED945 /* MultitouchSupport.framework in Frameworks */, + A5F71D13167AA1D600FF0DF6 /* Cocoa.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + A55B9EFE167AACB200436161 /* Other Sources */ = { + isa = PBXGroup; + children = ( + A5BD4D47167BF58000658BE3 /* FingerMgmt.h */, + A5BD4D48167BF58000658BE3 /* main.m */, + A5BD4D49167BF58000658BE3 /* MultiTouch.h */, + A5BD4D4A167BF58000658BE3 /* prefix.pch */, + ); + name = "Other Sources"; + sourceTree = ""; + }; + A5BD4D0B167BF2A000658BE3 /* KGNoise */ = { + isa = PBXGroup; + children = ( + A5BD4D1B167BF2A000658BE3 /* KGNoise.h */, + A5BD4D1C167BF2A000658BE3 /* KGNoise.m */, + ); + name = KGNoise; + path = ../KGNoise; + sourceTree = ""; + }; + A5BD4D68167BF8F500658BE3 /* Shaders */ = { + isa = PBXGroup; + children = ( + A59258681680293F00A6AD67 /* effect.fsh */, + A59258691680293F00A6AD67 /* effect.vsh */, + A5BD4D69167BF8F500658BE3 /* touchPoint.fsh */, + A5BD4D6A167BF8F500658BE3 /* touchPoint.vsh */, + A59BC9731681D246007BF672 /* trails.fsh */, + A59BC9741681D246007BF672 /* trails.vsh */, + ); + path = Shaders; + sourceTree = SOURCE_ROOT; + }; + A5F71D03167AA1D600FF0DF6 = { + isa = PBXGroup; + children = ( + A5F71D18167AA1D600FF0DF6 /* FingerMgmt */, + A5BD4D0B167BF2A000658BE3 /* KGNoise */, + A5F71D11167AA1D600FF0DF6 /* Frameworks */, + A5F71D0F167AA1D600FF0DF6 /* Products */, + ); + sourceTree = ""; + }; + A5F71D0F167AA1D600FF0DF6 /* Products */ = { + isa = PBXGroup; + children = ( + A5F71D0E167AA1D600FF0DF6 /* FingerMgmt.app */, + ); + name = Products; + sourceTree = ""; + }; + A5F71D11167AA1D600FF0DF6 /* Frameworks */ = { + isa = PBXGroup; + children = ( + A5C4314716831837000EC677 /* CeedGL.framework */, + A5F71D12167AA1D600FF0DF6 /* Cocoa.framework */, + A5F71D15167AA1D600FF0DF6 /* AppKit.framework */, + A5F71D17167AA1D600FF0DF6 /* Foundation.framework */, + A5C08BFD167AC49B003ED945 /* MultitouchSupport.framework */, + A5BD4D6D167C097100658BE3 /* OpenGL.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + A5F71D18167AA1D600FF0DF6 /* FingerMgmt */ = { + isa = PBXGroup; + children = ( + A5BD4D5C167BF86100658BE3 /* AppDelegate.h */, + A5BD4D5D167BF86100658BE3 /* AppDelegate.m */, + A5BD4D5E167BF86100658BE3 /* TouchPoint.h */, + A5BD4D5F167BF86100658BE3 /* TouchPoint.m */, + A5BD4D60167BF86100658BE3 /* TouchView.h */, + A5BD4D61167BF86100658BE3 /* TouchView.m */, + A5BD4D62167BF86100658BE3 /* TrackpadView.h */, + A5BD4D63167BF86100658BE3 /* TrackpadView.m */, + A592586D16802A5600A6AD67 /* CeedGL+Additions.h */, + A592586E16802A5600A6AD67 /* CeedGL+Additions.m */, + A5BD4D68167BF8F500658BE3 /* Shaders */, + A55B9EFE167AACB200436161 /* Other Sources */, + A5F71D19167AA1D600FF0DF6 /* Supporting Files */, + ); + path = FingerMgmt; + sourceTree = ""; + }; + A5F71D19167AA1D600FF0DF6 /* Supporting Files */ = { + isa = PBXGroup; + children = ( + A5BD4D4C167BF58D00658BE3 /* Info.plist */, + A5BD4D4D167BF58D00658BE3 /* MainMenu.xib */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + A5F71D0D167AA1D600FF0DF6 /* FingerMgmt */ = { + isa = PBXNativeTarget; + buildConfigurationList = A5F71D2C167AA1D600FF0DF6 /* Build configuration list for PBXNativeTarget "FingerMgmt" */; + buildPhases = ( + A5F71D0A167AA1D600FF0DF6 /* Sources */, + A5F71D0B167AA1D600FF0DF6 /* Frameworks */, + A5F71D0C167AA1D600FF0DF6 /* Resources */, + A5C4314A168319BC000EC677 /* CopyFiles */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = FingerMgmt; + productName = FingerMgmt; + productReference = A5F71D0E167AA1D600FF0DF6 /* FingerMgmt.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + A5F71D05167AA1D600FF0DF6 /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0450; + ORGANIZATIONNAME = "FFFF00 Agents AB"; + }; + buildConfigurationList = A5F71D08167AA1D600FF0DF6 /* Build configuration list for PBXProject "FingerMgmt" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + ); + mainGroup = A5F71D03167AA1D600FF0DF6; + productRefGroup = A5F71D0F167AA1D600FF0DF6 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + A5F71D0D167AA1D600FF0DF6 /* FingerMgmt */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + A5F71D0C167AA1D600FF0DF6 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + A5BD4D4F167BF58D00658BE3 /* MainMenu.xib in Resources */, + A592586A1680293F00A6AD67 /* effect.fsh in Resources */, + A592586B1680293F00A6AD67 /* effect.vsh in Resources */, + A5BD4D6F167C0B1700658BE3 /* touchPoint.fsh in Resources */, + A5BD4D70167C0B1E00658BE3 /* touchPoint.vsh in Resources */, + A59BC9751681D246007BF672 /* trails.fsh in Resources */, + A59BC9761681D246007BF672 /* trails.vsh in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + A5F71D0A167AA1D600FF0DF6 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + A5BD4D2E167BF2A000658BE3 /* KGNoise.m in Sources */, + A5BD4D4B167BF58000658BE3 /* main.m in Sources */, + A5BD4D64167BF86100658BE3 /* AppDelegate.m in Sources */, + A5BD4D65167BF86100658BE3 /* TouchPoint.m in Sources */, + A5BD4D66167BF86100658BE3 /* TouchView.m in Sources */, + A5BD4D67167BF86100658BE3 /* TrackpadView.m in Sources */, + A592586F16802A5600A6AD67 /* CeedGL+Additions.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + A5F71D2A167AA1D600FF0DF6 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = "$(ARCHS_STANDARD_64_BIT)"; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_OBJC_EXCEPTIONS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.6; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = macosx; + }; + name = Debug; + }; + A5F71D2B167AA1D600FF0DF6 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = "$(ARCHS_STANDARD_64_BIT)"; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = YES; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_ENABLE_OBJC_EXCEPTIONS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.6; + SDKROOT = macosx; + }; + name = Release; + }; + A5F71D2D167AA1D600FF0DF6 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + COMBINE_HIDPI_IMAGES = YES; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "\"$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks\"", + "\"../Frameworks\"", + "\"$(SRCROOT)/../../../Library/Developer/Xcode/DerivedData/FingerMgmt-anhqnncqdtyzosehvqkcojuqfbmj/Build/Products/Debug\"", + ); + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = prefix.pch; + INFOPLIST_FILE = Info.plist; + LD_RUNPATH_SEARCH_PATHS = "@executable_path/../Frameworks"; + MACOSX_DEPLOYMENT_TARGET = 10.6; + PRODUCT_NAME = "$(TARGET_NAME)"; + WRAPPER_EXTENSION = app; + }; + name = Debug; + }; + A5F71D2E167AA1D600FF0DF6 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + COMBINE_HIDPI_IMAGES = YES; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "\"$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks\"", + "\"../Frameworks\"", + "\"$(SRCROOT)/../../../Library/Developer/Xcode/DerivedData/FingerMgmt-anhqnncqdtyzosehvqkcojuqfbmj/Build/Products/Debug\"", + ); + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = prefix.pch; + INFOPLIST_FILE = Info.plist; + LD_RUNPATH_SEARCH_PATHS = "@executable_path/../Frameworks"; + MACOSX_DEPLOYMENT_TARGET = 10.6; + PRODUCT_NAME = "$(TARGET_NAME)"; + WRAPPER_EXTENSION = app; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + A5F71D08167AA1D600FF0DF6 /* Build configuration list for PBXProject "FingerMgmt" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + A5F71D2A167AA1D600FF0DF6 /* Debug */, + A5F71D2B167AA1D600FF0DF6 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + A5F71D2C167AA1D600FF0DF6 /* Build configuration list for PBXNativeTarget "FingerMgmt" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + A5F71D2D167AA1D600FF0DF6 /* Debug */, + A5F71D2E167AA1D600FF0DF6 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = A5F71D05167AA1D600FF0DF6 /* Project object */; +} diff --git a/FingerMgmt/FingerMgmt.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/FingerMgmt/FingerMgmt.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..ba4f99a --- /dev/null +++ b/FingerMgmt/FingerMgmt.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/FingerMgmt/Info.plist b/FingerMgmt/Info.plist new file mode 100644 index 0000000..fb17b16 --- /dev/null +++ b/FingerMgmt/Info.plist @@ -0,0 +1,34 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIconFile + + CFBundleIdentifier + com.yellowagents.${PRODUCT_NAME:rfc1034identifier} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + LSMinimumSystemVersion + ${MACOSX_DEPLOYMENT_TARGET} + NSHumanReadableCopyright + Copyright © 2012 FFFF00 Agents AB. All rights reserved. + NSMainNibFile + MainMenu + NSPrincipalClass + NSApplication + + diff --git a/FingerMgmt/MainMenu.xib b/FingerMgmt/MainMenu.xib new file mode 100644 index 0000000..5ff4982 --- /dev/null +++ b/FingerMgmt/MainMenu.xib @@ -0,0 +1,369 @@ + + + + 1060 + 12C3006 + 2844 + 1187.34 + 625.00 + + com.apple.InterfaceBuilder.CocoaPlugin + 2844 + + + NSCustomObject + NSMenu + NSMenuItem + NSView + NSWindowTemplate + + + com.apple.InterfaceBuilder.CocoaPlugin + + + PluginDependencyRecalculationVersion + + + + + NSApplication + + + FirstResponder + + + NSApplication + + + AMainMenu + + + + FingerMgmt + + 1048576 + 2147483647 + + NSImage + NSMenuCheckmark + + + NSImage + NSMenuMixedState + + submenuAction: + + FingerMgmt + + + + Hide FingerMgmt + h + 1048576 + 2147483647 + + + + + + Hide Others + h + 1572864 + 2147483647 + + + + + + Show All + + 1048576 + 2147483647 + + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Quit FingerMgmt + q + 1048576 + 2147483647 + + + + + _NSAppleMenu + + + + _NSMainMenu + + + 11 + 2 + {{335, 390}, {600, 440}} + 1954021376 + FingerMgmt + NSWindow + + + {300, 220} + + + 256 + {600, 440} + + {{0, 0}, {1440, 878}} + {300, 242} + {10000000000000, 10000000000000} + YES + + + AppDelegate + + + + + + + terminate: + + + + 449 + + + + delegate + + + + 495 + + + + hide: + + + + 367 + + + + hideOtherApplications: + + + + 368 + + + + unhideAllApplications: + + + + 370 + + + + window + + + + 532 + + + + trackpadView + + + + 537 + + + + + + 0 + + + + + + -2 + + + File's Owner + + + -1 + + + First Responder + + + -3 + + + Application + + + 29 + + + + + + + + 56 + + + + + + + + 57 + + + + + + + + + + + + 134 + + + + + 150 + + + + + 136 + + + + + 149 + + + + + 145 + + + + + 371 + + + + + + + + 372 + + + + + 494 + + + + + + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + + com.apple.InterfaceBuilder.CocoaPlugin + {{380, 496}, {480, 360}} + + TrackpadView + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + + + + + 537 + + + + + AppDelegate + NSObject + + TrackpadView + NSWindow + + + + trackpadView + TrackpadView + + + window + NSWindow + + + + IBProjectSource + ./Classes/AppDelegate.h + + + + TrackpadView + NSView + + IBProjectSource + ./Classes/TrackpadView.h + + + + + 0 + IBCocoaFramework + + com.apple.InterfaceBuilder.CocoaPlugin.macosx + + + YES + 3 + + {11, 11} + {10, 3} + + YES + + diff --git a/FingerMgmt/MultiTouch.h b/FingerMgmt/MultiTouch.h new file mode 100644 index 0000000..397a74a --- /dev/null +++ b/FingerMgmt/MultiTouch.h @@ -0,0 +1,36 @@ + +typedef struct { + float x; + float y; +} mtPoint; + +typedef struct { + mtPoint position; + mtPoint velocity; +} mtVector; + +typedef struct { + int frame; // the current frame + double timestamp; // event timestamp + int identifier; // identifier guaranteed unique for life of touch per device + int state; //the current state (not sure what the values mean) + int unknown1; //no idea what this does + int unknown2; //no idea what this does either + mtVector normalized; //the normalized position and vector of the touch (0,0 to 1,1) + float size; //the size of the touch (the area of your finger being tracked) + int unknown3; //no idea what this does + float angle; //the angle of the touch -| + float majorAxis; //the major axis of the touch -|-- an ellipsoid. you can track the angle of each finger! + float minorAxis; //the minor axis of the touch -| + mtVector unknown4; //not sure what this is for + int unknown5[2]; //no clue + float unknown6; //no clue +} mtTouch; + +typedef void *MTDeviceRef; //a reference pointer for the multitouch device +typedef int (*MTContactCallbackFunction)(int,mtTouch*,int,double,int); //the prototype for the callback function + +MTDeviceRef MTDeviceCreateDefault(); //returns a pointer to the default device (the trackpad) +CFMutableArrayRef MTDeviceCreateList(void); //returns a CFMutableArrayRef array of all multitouch devices +void* MTRegisterContactFrameCallback(MTDeviceRef, MTContactCallbackFunction); //registers a device's frame callback to your callback function +void MTDeviceStart(MTDeviceRef, int); //start sending events diff --git a/FingerMgmt/Shaders/effect.fsh b/FingerMgmt/Shaders/effect.fsh new file mode 100644 index 0000000..f20330f --- /dev/null +++ b/FingerMgmt/Shaders/effect.fsh @@ -0,0 +1,50 @@ +// effect.fsh + +// Based on Callum Hay's Gaussian Blur Shader +// http://callumhay.blogspot.com/2010/09/gaussian-blur-shader-glsl.html + +uniform sampler2D u_texture; +uniform vec2 u_resolution; +uniform int u_pass; +uniform float u_sigma; +uniform float u_blur; + +const float pi = 3.1415926535897932; + +void main() { + vec2 onePixel = vec2(1, 1) / u_resolution; + vec2 pos = gl_FragCoord.xy * onePixel; + + float blurSize; + vec2 blurVec; + if (u_pass == 0) { + blurVec = vec2(1, 0); + blurSize = onePixel.x; + } else { + blurVec = vec2(0, 1); + blurSize = onePixel.y; + } + + vec3 incr; + incr.x = 1.0 / (sqrt(2.0 * pi) * u_sigma); + incr.y = exp(-0.5 / (u_sigma * u_sigma)); + incr.z = incr.y * incr.y; + + vec4 avg = vec4( 0 ); + float sum = 0.0; + + avg += texture2D(u_texture, pos) * incr.x; + sum += incr.x; + incr.xy *= incr.yz; + + for (float i = 1.0; i <= u_blur; i++) { + avg += texture2D(u_texture, pos - i * blurSize * blurVec) * incr.x; + avg += texture2D(u_texture, pos + i * blurSize * blurVec) * incr.x; + sum += 2.0 * incr.x; + incr.xy *= incr.yz; + } + + vec4 col = avg / sum; + + gl_FragColor = col; +} diff --git a/FingerMgmt/Shaders/effect.vsh b/FingerMgmt/Shaders/effect.vsh new file mode 100644 index 0000000..4bdf719 --- /dev/null +++ b/FingerMgmt/Shaders/effect.vsh @@ -0,0 +1,8 @@ +// effect.vsh + +attribute vec2 a_position; +uniform mat4 u_projection; + +void main() { + gl_Position = u_projection * vec4(a_position, 0, 1); +} diff --git a/FingerMgmt/Shaders/touchPoint.fsh b/FingerMgmt/Shaders/touchPoint.fsh new file mode 100644 index 0000000..b7a0cee --- /dev/null +++ b/FingerMgmt/Shaders/touchPoint.fsh @@ -0,0 +1,65 @@ +// touchPoint.fsh + +uniform float u_size; +uniform vec2 u_translate; +uniform vec2 u_resolution; +uniform int u_mode; +uniform vec2 u_velocity; + +vec3 Lab2RGB(in vec3 lab); + +void main(void) { + vec2 center = vec2(u_translate.x * (u_resolution.y / u_resolution.x), u_translate.y); + vec2 position = (gl_FragCoord.xy / u_resolution); + + vec4 col; + if (u_mode == 0) { + float v = length(u_velocity); + col = vec4(Lab2RGB(vec3(37.0 + v * 2.0, 33.0 + v * 30.0, -34)), 1); + } else { + col = vec4(1, 1, 1, 1); + } + + gl_FragColor = col; +} + +vec3 Lab2RGB(in vec3 lab) { + //Thresholds + float T1 = 0.008856; + float T2 = 0.206893; + + float X,Y,Z; + + //Compute Y + bool XT, YT, ZT; + XT = false; YT=false; ZT=false; + + float fY = pow(((lab.x + 16.0) / 116.0),3.0); + if(fY > T1){ YT = true; } + if(YT){ fY = fY; } else{ fY = (lab.x / 903.3); } + Y = fY; + + //Alter fY slightly for further calculations + if(YT){ fY = pow(fY,1.0/3.0); } else{ fY = (7.787 * fY + 16.0/116.0); } + + //Compute X + float fX = ( lab.y / 500.0 ) + fY; + if(fX > T2){ XT = true; } + if(XT){ X = pow(fX,3.0); } else{X = ((fX - (16.0/116.0)) / 7.787); } + + //Compute Z + float fZ = fY - ( lab.z / 200.0 ); + if(fZ > T2){ ZT = true; } + if(ZT){ Z = pow(fZ,3.0); } else{ Z = ((fZ - (16.0/116.0)) / 7.787); } + + //Normalize for D65 white point + X = X * 0.950456; + Z = Z * 1.088754; + + //XYZ to RGB part + float R = 3.240479 * X + -1.537150 * Y + -0.498535 * Z; + float G = -0.969256 * X + 1.875991 * Y + 0.041556 * Z; + float B = 0.055648 * X + -0.204043 * Y + 1.057311 * Z; + + return vec3(R,G,B); +} \ No newline at end of file diff --git a/FingerMgmt/Shaders/touchPoint.vsh b/FingerMgmt/Shaders/touchPoint.vsh new file mode 100644 index 0000000..c3a77e1 --- /dev/null +++ b/FingerMgmt/Shaders/touchPoint.vsh @@ -0,0 +1,28 @@ +// touchPoint.vsh + +attribute vec2 a_position; + +uniform mat4 u_projection; +uniform vec2 u_translate; +uniform float u_rotate; + +mat3 makeRotation(float angle) { + float c = cos(angle); + float s = sin(angle); + return mat3(c, -s, 0, + s, c, 0, + 0, 0, 1); +} + +mat3 makeTranslation(vec2 t) { + return mat3(1, 0, 0, + 0, 1, 0, + t.x, t.y, 1); +} + +void main(void) { + mat3 transform = makeTranslation(u_translate) * makeRotation(u_rotate); + vec2 pos = (transform * vec3(a_position, 1)).xy; + + gl_Position = u_projection * vec4(pos, 0, 1); +} diff --git a/FingerMgmt/Shaders/trails.fsh b/FingerMgmt/Shaders/trails.fsh new file mode 100644 index 0000000..4b27bfb --- /dev/null +++ b/FingerMgmt/Shaders/trails.fsh @@ -0,0 +1,29 @@ +// trails.fsh + +uniform sampler2D u_texture1; +uniform sampler2D u_texture2; +uniform vec2 u_resolution; +uniform float u_mix; +uniform int u_mask; + +void main() { + vec2 onePixel = vec2(1, 1) / u_resolution; + vec2 pos = gl_FragCoord.xy * onePixel; + + vec4 col; + + if (u_mix == 0.0) { + col = texture2D(u_texture1, pos); + } else { + col = texture2D(u_texture1, pos); + col = max(col, texture2D(u_texture2, pos) * u_mix); + } + + if (u_mask == 1) { + vec4 mask = texture2D(u_texture2, pos); + col.a -= mask.r; + } + + gl_FragColor = col; +} + diff --git a/FingerMgmt/Shaders/trails.vsh b/FingerMgmt/Shaders/trails.vsh new file mode 100644 index 0000000..22c1f7d --- /dev/null +++ b/FingerMgmt/Shaders/trails.vsh @@ -0,0 +1,8 @@ +// trails.vsh + +attribute vec2 a_position; +uniform mat4 u_projection; + +void main() { + gl_Position = u_projection * vec4(a_position, 0, 1); +} diff --git a/FingerMgmt/main.m b/FingerMgmt/main.m new file mode 100644 index 0000000..6253964 --- /dev/null +++ b/FingerMgmt/main.m @@ -0,0 +1,13 @@ +// +// main.m +// FingerMgmt +// +// Created by Johan Nordberg on 2012-12-14. +// Copyright (c) 2012 FFFF00 Agents AB. All rights reserved. +// + +#import + +int main(int argc, char *argv[]) { + return NSApplicationMain(argc, (const char **)argv); +} diff --git a/FingerMgmt/prefix.pch b/FingerMgmt/prefix.pch new file mode 100644 index 0000000..8ce540c --- /dev/null +++ b/FingerMgmt/prefix.pch @@ -0,0 +1,6 @@ +#ifdef __OBJC__ + #import +#endif + +#import "FingerMgmt.h" +#import "KGNoise.h" diff --git a/FingerMgmt/toichview-old.m b/FingerMgmt/toichview-old.m new file mode 100644 index 0000000..b608492 --- /dev/null +++ b/FingerMgmt/toichview-old.m @@ -0,0 +1,81 @@ +// +// TouchView.m +// FingerMgmt +// +// Created by Johan Nordberg on 2012-12-14. +// Copyright (c) 2012 FFFF00 Agents AB. All rights reserved. +// + +#import "TouchView.h" +#import "TouchPoint.h" + +@interface TouchView () { + NSColor *_fillColor; + NSColor *_borderColor; + NSBitmapImageRep *_lastDraw; +} + +@end + +@implementation TouchView + +@synthesize touchPoints = _touchPoints; + +- (id)initWithFrame:(NSRect)frame { + self = [super initWithFrame:frame]; + if (self) { + _fillColor = [NSColor colorWithCalibratedRed:0.99 green:1 blue:0.97 alpha:1]; + _borderColor = [_fillColor shadowWithLevel:0.5]; + } + return self; +} + +- (void)setTouchPoints:(NSArray *)touchPoints { + _touchPoints = touchPoints; + [self setNeedsDisplay:YES]; +} + +- (void)drawRect:(NSRect)dirtyRect { + NSRect b = [self bounds]; + CGFloat w = b.size.width, h = b.size.height, smod = 0.8 + (w / kTrackpadWidth); + NSUInteger i, count = [_touchPoints count]; + + [_fillColor setFill]; + [_borderColor setStroke]; + + // NSGraphicsContext graphicsContextWithGraphicsPort:flipped + + for (i = 0; i < count; i++) { + TouchPoint *point = [_touchPoints objectAtIndex:i]; + NSBezierPath *path = [NSBezierPath bezierPath]; + + // Magnify weak touches to get a better visual effect + CGFloat s = logf(point.size * 12) * smod; + if (0.1 > s) s = 0.1; + + // Point size + CGFloat pw = point.majorAxis * s + 0.5; + CGFloat ph = point.minorAxis * s + 0.5; + + // Transformation that positions and rotates oval + NSAffineTransform *transformation = [NSAffineTransform transform]; + [transformation translateXBy:point.x * w yBy:point.y * h]; + [transformation rotateByRadians:point.angle]; + + // Draw and transform touch point oval + [path appendBezierPathWithOvalInRect:(NSRect){{-(pw / 2), -(ph / 2)}, {pw, ph}}]; + [path transformUsingAffineTransform:transformation]; + [path fill]; + [path setLineWidth:2]; + [path stroke]; + } + + // Draw + //NSImage *frame = [[NSImage alloc] initWithSize:b.size]; + + //CGContextRef context = [[NSGraphicsContext currentContext] graphicsPort]; + + +} + +@end diff --git a/KGNoise b/KGNoise new file mode 160000 index 0000000..8859b94 --- /dev/null +++ b/KGNoise @@ -0,0 +1 @@ +Subproject commit 8859b94f2d951afd0d977274c94ccc60edbfb50c