ARToolKitをMacで使ってみる

ちょっとiPhoneから離れて、最近流行りの拡張現実(AR)を試してみたいなと思いました。
iPhoneとかでも話題になっているセカイカメラとか、
実際のリアル映像にバーチャルな世界を載せていくというやつです。

「へぇ〜すごいなぁ。でも簡単にはでけへんねやろうなぁ」と思っていたら
世の中には色々ありました。

その名もARToolKitです。これを使うとカメラで取得した画像に
3DCGをレンダリングさせることができるようになります。

Macでも動くようで、同梱のサンプルを簡単に試してみました。

まずは、ARToolKitのダウンロードページからARToolKit-2.72.1.tgzを
任意のディレクトリにダウンロードします。

その後、解凍します。

# tar -xvzf ARToolKit-2.72.1.tgz

解凍して出来たARToolKitディレクトリの中にあるARToolKit.xcodeprojをダブルクリックします。
これでXCodeが起動するので、「ビルドして実行」をクリックしビルドすると下記のような画面がでるはずです。

ここでOKを押します。

で、ARToolKitディレクトリ配下のpatterns/pattHiro.pdfを印刷します。
カメラに移す図形はこんな感じです。


それをカメラに表示させるとこんな感じで、立方体が表示されます。

すげえ〜!近未来や!!!

NavigationBarとSegmentationButtonを使ってみる

今回はNavigationBarとSegmentation Buttonを使用してみます。

今回作るのは、こんなアプリですね。

さてPageDemoという名前で「Windows-Based Application」で作成します。
そこでできたプロジェクト内のフォルダ「Classes」を選択し
「ファイル」→「新規ファイル」→「UIviewController subClass」を選択、RootViewControllerと名前を付けて保存します。

今回も、Interface Builderと分離は
Interface Buiderとの関係を断ち切る!
を参照して、実行しておいてください。

今回もソースを貼付けます。
まずは、RootViewControllerからです。
RootViewControllerとCreditsViewControllerの2クラスを作成します。

RootViewControllerは上記の画面そのもの、
CreditsViewControllerは上記の画面からNavigation Bar上のcreditsのボタンを押した際に遷移する画面になります。

RootViewController.h

#import <UIKit/UIKit.h>


@interface RootViewController : UIViewController {
	UITextView *textView;
	UIBarButtonItem *credits;
	UISegmentedControl *segmentedControl;
	UINavigationController *navigationController;
	int page;
}

-(void)setPage;
-(id)initWithAppDelegate:(id)appDelegate;

@end

@interface CreditsViewController : UIViewController
{
	UITextView *textView;
	UINavigationController *navigationController;
}

-(id)initWithAppDelegate:(id)appDelegate;

@end

RootViewController.m

#import "RootViewController.h"
#import "PageDemoAppDelegate.h"

@implementation RootViewController

-(id)initWithAppDelegate:(id)appDelegate{
	self = [super init];
	if(self != nil){
                // クレジットボタンを作成、押されたらcreditsメソッドを呼ぶ
		credits = [[[UIBarButtonItem alloc] 
				   initWithTitle:@"Credits" 
				   style:UIBarButtonItemStylePlain
				   target:appDelegate
				   action:@selector(credits)] autorelease];
        // navigation Barの右側にボタンを配置
		self.navigationItem.rightBarButtonItem = credits;
		
                //segmentedControlを作成 
		segmentedControl = [[UISegmentedControl alloc] initWithItems:nil];
		segmentedControl.segmentedControlStyle = UISegmentedControlStyleBar;

                //Bunnies(ボタンのINDEX=0)とPonies(ボタンのINDEX=1)のボタンを作成		
		[segmentedControl insertSegmentWithTitle:@"Bunnies" atIndex:0 animated:NO];
		[segmentedControl insertSegmentWithTitle:@"Ponies" atIndex:1 animated:NO];
		
        // 今選択されているボタンと異なるものを選択されたらcontrolPressedメソッドを呼ぶ
		[segmentedControl addTarget:self action:@selector(controlPressed:) forControlEvents:UIControlEventValueChanged];
		
                // Navigation Barの立ち取る部分にSegmantation Buttonを配置する
		self.navigationItem.titleView = segmentedControl;

        // 画面起動時にはBunniesが押された状態にする
		segmentedControl.selectedSegmentIndex = 0;
	}
	
	return self;
}

-(void)controlPressed:(id) sender{
        // setPageメソッドを呼ぶ
	[self setPage];
}

-(void)setPage{
        // 押されたボタンのINDEXを取得
	int index = segmentedControl.selectedSegmentIndex;
	
	if(index == 0){      // Bunnies(ボタンのINDEX=0)が押されてたら
		textView.text = @"OMG Bunnies!";
	}else{               // Ponies(ボタンのINDEX=1)が押されてたら
		textView.text = @"OMG Ponies!";
	}
}

- (void)loadView {
	CGRect bounds = [[UIScreen mainScreen] applicationFrame];
	
	[super loadView];
	
	textView = [[UITextView alloc] initWithFrame:bounds];
	textView.editable = NO;
	
	[self setPage];
	self.view = textView;
}

- (void)dealloc {
	[textView release];
    [super dealloc];
}

@end

@implementation CreditsViewController

// Creditsの画面が出された時
-(id)initWithAppDelegate:(id)appDelegate{
	self = 	[super init];
        // Backボタンを作成する。押されたらbackメソッドを呼ぶ
	if(self != nil){
		UIBarButtonItem *back = [[[UIBarButtonItem alloc] 
						initWithTitle:@"Back" 
						style:UIBarButtonItemStylePlain 
						target:appDelegate 
						action:@selector(back)] autorelease];
                // Navigation Barの"Back Button"として登録する
		self.navigationItem.backBarButtonItem = back;
	}
	
	return self;
}

-(void)loadView{
	[super loadView];
	
	textView = [[UITextView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]];
	textView.editable = NO;
	
	textView.text = @"iPhone SDK Application Development\n"
					"Copyright (c) 2008, O'Reilly Media";
	
	self.view = textView;
}

- (void)dealloc {
	[textView release];
    [super dealloc];
}

@end

今日もコメントを書いておいたので、感じは掴めると思います。

最後にDelegateのソースですが、こちらも昨日と同様、基本的に作成したViewControllerをインスタンス化してwindowにsubviewとして貼付けてるだけです。

PageDemoAppDelegate.h

#import <UIKit/UIKit.h>
#import "RootViewController.h"

@interface PageDemoAppDelegate : NSObject <UIApplicationDelegate> {
    UIWindow *window;
	RootViewController *viewController;
	CreditsViewController *creditsViewController;
	UINavigationController *navigationController;
}

@property (nonatomic, retain) IBOutlet UIWindow *window;
@property (nonatomic, retain) IBOutlet RootViewController *viewController;
@property (nonatomic, retain) IBOutlet CreditsViewController *creditsViewController;
@property (nonatomic, retain) IBOutlet UINavigationController *navigationController;

@end

RootViewController.m

#import "PageDemoAppDelegate.h"
#import "RootViewController.h"

@implementation PageDemoAppDelegate

@synthesize window;
@synthesize viewController;
@synthesize creditsViewController;
@synthesize navigationController;

- (void)applicationDidFinishLaunching:(UIApplication *)application {    

	window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
	
	viewController = [[RootViewController alloc] initWithAppDelegate:self];
	creditsViewController = [[CreditsViewController alloc] initWithAppDelegate:self];
	navigationController = [[UINavigationController alloc] initWithRootViewController:viewController];
	
	[window addSubview:[navigationController view]];
	
    // Override point for customization after application launch
    [window makeKeyAndVisible];
}


- (void)dealloc {
	[navigationController release];
	[viewController release];
	[creditsViewController release];
    [window release];
    [super dealloc];
}

-(void) credits{
        // 次画面に遷移する際には、navigationControllerのpushViewControllerを使う
	[navigationController pushViewController:creditsViewController animated:YES];
}

-(void) back{
        // 前画面に遷移する際には、navigationControllerのpopViewControllerAnimatedを使う
	[navigationController popViewControllerAnimated:YES];
}


@end