頭と尻尾はくれてやる!

iOSアプリなどの開発日記です


Blenderで作った3DのデータをSwiftでMetalに使いた〜い3

頭と尻尾はくれてやる!/ Blenderで作った3DのデータをSwiftでMetalに使いた〜い2
↑この続き。

その3 データファイルの形式を.swiftにする

できることならスッキリしたいってことでそもそものデータをswiftの形式にすればいいんじゃね?ってことで試してみたんだわ。
Blenderの出力ファイルを書き換える時にCではなく.swiftで出力するように修正。この時、中身の形式はこんなのになるようにしてみた。
import Foundation

class Robot3 { 

    let vertices: Int = 660
    let positions: [Float] = [
        -0.437199, 0.539412, -0.437199, 
        -0.437199, -0.539412, -0.437199, 
        -0.437199, 0.494338, -0.139248, 
        (略)
    ]
    init () {
    }
}
最初プロパティの宣言部では値を設定せずに宣言だけ、イニシャライザ内で値を設定してたけどデータが大きくなると落ちる、ということが発生したので宣言部で値も設定、イニシャライザは特になにもせず、ってなった。
データをこういう感じで作っておくと使う時は普通にオブジェクト作ってそのプロパティからアクセスできる。

とりあえず、しばらくこれでやってみるわ。
スポンサーサイト






World of Tanks Blitzって戦車の対戦ゲームがすごい

World of Tanks Blitz のスクショ

↑先日Appleが発表した今年のベストiOSアプリの中にあったので試しにダウンロードしてみたのがこのWorld of Tanks Blitzという7人対7人で戦車で対戦するゲーム。

このゲーム、かなり危険。時間泥棒アプリだ。面白過ぎる。

このゲームの面白さはホントの人間とリアルタイムで対戦するところなんだろうな(他の人は知らないけど)。
これがCPU相手だとそれほど面白いとは思わないわ。
そう言えば少し前の今週のAppで紹介されていたJELLIES!って線をつないでクラゲ(?)を囲むゲームも一人用はほとんどせずに対戦ばかりしてたし。
対戦するゲームって面白いけど作るのは敷居が高いよな、って思ってたんだけどさ、、、

[iOS] Game Center を使った対戦プログラミングの手順メモ - それはBooks
↑こういう記事を見るとマッチングの機能なんかもすでにあるんだね。自分で対戦するゲームなんて作ろうと思ったことなかったから調べたこともなかったけど。

まあそれでもゲームなんて作ること自体難易度高いし、対戦相手がすんなり見つかるほどダウンロードされる、っていうのも大変なんだろうな、、、とは思うもののいつかはゲームを作ってみたいと企んでいるんだけどね。


Blenderで作った3DのデータをSwiftでMetalに使いた〜い2

頭と尻尾はくれてやる!/ Blenderで作った3DのデータをSwiftでMetalに使いた〜い!
↑この続きね。

その2 Objective-Cのファイルをかます

Swiftのファイル ← Cのデータファイル
↑これだとダメだったので考えた苦肉の策がこちら↓
Swiftのファイル ← Objective-C ← Cのデータファイル

間にObjective-Cのファイルをかましてみたのよ。ヘッダーはプロパティを設定してるだけなので略。実装側はこんなの。
//ObjcRobot.m
#import "ObjcRobot.h"
#import "robot3.h"

@implementation ObjcRobot

- (instancetype)init
{
    self = [super init];
    if (self) {
        self.vertices = robot3Vertices;
        self.positions = &robot3Positions[0];
    }
    return self;
}
@end
これをSwfitから使う。
{
    let objcRobot = ObjcRobot()
    println("objcRobot.vertices = \(objcRobot.vertices)")
    println("objcRobot.positions[0] = \(objcRobot.positions[0])")
    println("objcRobot.positions[1] = \(objcRobot.positions[1])")
    println("objcRobot.positions[2] = \(objcRobot.positions[2])”)
}
結果のスクショ

↑ふむ、アクセスできる。

これを使ってメモリ割り当て。
vertexBuffer = device.newBufferWithBytes(objcRobot.positions, length: dataSize, options: nil)
描画成功

↑ちゃんと動いた。まだただ白いだけだけど(フラグメントシェーダで白を返してるだけ)。

でもさ、、、一つのオブジェクトを表示するのに
robot3.h , robot3.c , ObjcRobot.h , ObjcRobot.m
みたいに四つもファイルが必要になるんだよなあ。
Swiftを勉強し始めて思ったのはヘッダーファイルと実装ファイルの両方を書かなくていいのってラクだなあということ。
そう思うとこの方法もなんだかねえ、、、なんて思ってさ。

もういっちょ続く。





Blenderで作った3DのデータをSwiftでMetalに使いた〜い!

なんかタイトルがすイエんサーみたいだけど、まあタイトル通りなんだ。

今まではBlenderで作ったオブジェクトをWavefront(.obj)ってので出力、C++のコードで 〜.h/cってファイルを作成、そのファイルをXcodeで読み込んで、Objective-CのOpenGL ESで使っていたのよ。下のリンクの通りなんだけどね。

How To Export Blender Models to OpenGL ES: Part 1/3 - Ray Wenderlich

MetalフレームワークとSwiftで同じことをやってみようとしたんだけど、これがなかなかうまくいかなくてどうしたら正解なのかよくわからない。経過をシェアってことで。

その前に上記リンクにあるコードで作ったCの3Dのデータはこんな感じ。法線とテクスチャ座標は略。robot3の3はこちらの都合なので意味はないからスルーしてね。
//robot3.h

extern const int robot3Vertices;
extern const float robot3Positions[1980];


//robot3.c

#include "robot3.h”
const int robot3Vertices = 660;
const float robot3Positions[1980] = 
    {
        -0.437199, 0.539412, -0.437199, 
        -0.437199, -0.539412, -0.437199, 
        -0.437199, 0.494338, -0.139248, 
        (略)
    };
その1 ダイレクトにやってみる
最初は上のコードをそのまま読み込んで使おうとしたのよ。Swiftから読み込むためにプロジェクト名-Header.hってファイルに
#import "robot3.h"
としておく。この辺はSwiftとObjective-Cの相互利用とかで調べるといろいろわかると思う。

こんな感じで使おうとしたのよ。
{
    println("robot3Vertices = \(robot3Vertices)”)

    let positions = robot3Positions
    println("positions.0 = \(positions.0)")
    println("positions.1 = \(positions.1)")
    println("positions.2 = \(positions.2)")
}
結果スクショ

値を見ると確かに読み込めてる。
でもpositionsを使おうとしてもコンパイルエラー。

コンパイルエラーメッセージ

なに、このFloatの羅列は?

positionsの型を確認(option+クリックで表示されるよね)すると

タプルの型表示

なんじゃこりゃ?って最初は目が点になったけど、これタプルってやつだよね。Cの配列をSwiftで読み込もうとするとタプルになるってことか。

タプルへのアクセスは上のようにピリオドとインデックスでできるけど、問題はこのインデックスの部分に変数を使えないっぽいこと。

これじゃあ数千個もある各点をGPUへ渡すことができない、、、?


ってことでダイレクトにGPUに渡すのは無理っぽいのでひとひねりしようとしたんだけど、長くなったので次に。





  TopPage  



Copyright ©頭と尻尾はくれてやる!. Powered by FC2 Blog. Template by eriraha.