2011年4月27日水曜日

名言botの名言をひたすら表示するWebサイト


名言botの名言をただひたすらに表示し続けるサイトを作ってみました。
Macの方がフォントがきれいでよいです。

疲れた時とかにただ眺めてると元気になることもあるかも?

http://meigenlighting.appspot.com

2011年4月25日月曜日

Titanium Mobileでパーティクルっぽいことをしてみたけど失敗。


JavaScriptのパーティクルエンジンをたまたま発見したので、そのままTitanium Mobileで使えないかと思って試してみました。

元ネタはこちら

Unable to display content. Adobe Flash is required.

WebView内のcanvasにパーティクルを描画しています。
この動画で150個のパーティクルです。
まあ、この動画はCore i7のMacbook Proでの動きで、iPhone4の実機で動かすとせいぜい20-30個程度でしかまともに動きませんでした。

というわけで実験失敗。

2011年4月23日土曜日

iOS 4.3にしたらOpenCV 2.2が動かなくなった方は


iOS 4.3になって、OpenCV 2.2が動かない!って方はいらっしゃいませんか。

Accelrate.frameworkをリンクされている場合、代わりにOpenCV 2.2のlibopencv_lapack.aをリンクしてみて下さい。

元ネタはこちら

OpenCV2.2のiOS向けなユニバーサルバイナリを作るための最も簡単な方法


以前、OpenCV 2.2のiOS向けなユニバーサルバイナリを作るってのを書きましたが、もーっと簡単にarmv6/armv7/i386のユニバーサルバイナリを作る手順がありました。

1) https://github.com/BloodAxe/OpenCV-iOS-build-script から、BuildOpen.shをダウンロードします。
2) OpenCV 2.2 のソースをダウンロードします。
3) sh BuildOpen.sh <OpenCVのソースディレクトリ> <ビルド出力先ディレクトリ>

以上。かんたんですね!

2011年4月7日木曜日

メインスレッドで実行させるマクロに目からウロコ


Titanium Mobileのモジュールを作っているときに、あるメソッドをメインスレッドで実行する必要があったのですが、Titanium MobileのSDKにマクロが定義されています。

そのマクロが「いいね!」だったのでご紹介。
(すごいベタな手法なのかもしれませんが...)

#define ENSURE_UI_THREAD_1_ARG(x) ¥
if (![NSThread isMainThread]) { ¥
[self performSelectorOnMainThread:_cmd withObject:x waitUntilDone:WAIT_UNTIL_DONE_ON_UI_THREAD modes:[NSArray arrayWithObject:NSRunLoopCommonModes]]; ¥
return; ¥
} ¥

メインスレッド以外から実行された場合、自分自身をメインスレッドで呼び直します。
呼び直された際、[NSThread isMainThread]がTRUEなので、マクロ以降のコードが実行されると。

ちなみに_cmdってのが、実行中のメソッドのセレクタとなる暗黙な変数だそうで(知らなかった...)
詳しくはこちらを参照してください

使い方は、

- (void)hoge:(id)args
{
    ENSURE_UI_THREAD_1_ARG(args);

    // 以降はメインスレッドで実行される
}

他にも、メインスレッドで実行するためのマクロが用意されていますので、
ヘッダを参照してみて下さい。

勉強になった。

2011年4月6日水曜日

CALayerを使って独自のプロパティをアニメーションさせる


元ネタはこちら

OpenGL ESのシーン管理でカメラやら照明やらモデルやらをアニメーションするのに使えないかなと。
あと、角度をプロパティで定義して時計の針を表示したりとかにも使えますね。

[簡単な手順] (簡単すぎてすいません)

- CALayerを継承して独自のプロパティを追加したクラスの作成 -
1) CALayerを継承したクラスを作成する(例としてクラス名をCustomLayerとします)

2) 独自のプロパティを定義する

3) drawInContext:をオーバーライドし、独自のプロパティに従った描画を行うロジックを記述

4) needsDisplayForKey:をオーバーライドし、独自のプロパティに対してYESを返すようにしてあげる。独自のプロパティ以外はsuperにお任せする

5) initWithLayer:をオーバーライドし、アニメーションさせるプロパティをコピーするようにしてあげる
(これはアニメーションする際にレイヤーをコピーする?処理が含まれるため必要)

@implementation CustomLayer
@synthesize hoge;

- (id) initWithLayer:(id)layer {
    NSLog(@"initWithLayer called.");
    if((self = [super initWithLayer:layer])) {
        if([layer isKindOfClass:[CustomLayer class]]) {
            CustomLayer *other = (CustomLayer*)layer;
                self.hoge = other.hoge;
        }
    }
    return self;
}

- (void)drawInContext:(CGContextRef)ctx
{
    // self.hogeの内容が変わりながら呼び出される
}

+ (BOOL)needsDisplayForKey:(NSString *)key {
    if ([key isEqualToString:@"hoge"]) {
        return YES;
    }
    else {
       return [super needsDisplayForKey:key];
    }
}
@end

- UIViewに作成したレイヤーを登録する -
1) 適当なタイミングでレイヤーオブジェクトを生成し、子レイヤーとして登録する
UIViewControllerのviewDidLoadでやってみる場合
- (void)viewDidLoad
{
    [super viewDidLoad];
    customLayer = [[CustomLayer alloc] init];
    customLayer.bounds = self.view.bounds;
    [self.view.layer addSublayer:customLayer];
}

2) アニメーションの定義
- (void)animateHoge{
 CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:@"hoge"];
 anim.duration = 3.0;
 anim.fromValue = [NSNumber numberWithDouble:50.0];
 anim.toValue = [NSNumber numberWithDouble:150.0];
 anim.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    
        // これでアニメーションが開始される
 [customLayer addAnimation:anim forKey:@"animateHoge"];
    
 customLayer.hoge = 150.0;
}

3) animateHogeを呼んでみると、CustomLayerのdisplayが自動でぶわーっと呼び出され、
displayからdisplayContext:が呼び出され、アニメーションしながら表示されるという寸法ですね。

こんな感じで、カメラ/照明/モデルの回転とか移動とかをアニメーションしながらシーン描画できたらなあと。あ、もちろん表示の更新はCADisplayLink使ってやるつもりですが。んーなんかちょっと無理あるか?

2011年4月1日金曜日

Castmarkというアプリをリリースしました


先日、「TOEICを勉強するついでにアプリを作る」と言っていましたが、こないだAppStoreにリリースされました!

*こんなアプリ
- ブラウザからpodcastのフィードを選んで登録
- プレイリストから聴きたいコンテンツを選んで再生
- 再生中にメモを記録!スペルチェックできて英英辞書も引けます!
- あとで再生するときに記録したメモが記録した時間に表示されます