Help us understand the problem. What is going on with this article?

iOSでCocos3dでNewtonで3D物理演算

More than 5 years have passed since last update.

NewtonGameDynamicsってあんまり日本では使ってる人を見ませんね。
でも、僕は好きです。

Newtonをビルド

おもむろにNewtonの最新版をチェックアウト。

core_Library200/projects/mac/OS10_xcode3.2.5/newton.xcodeproj
を開く。

ターゲットの設定から、BaseSDKをiOSに設定。しかし、このままではビルドが通らない。

なぜかプロジェクトに追加されていないソースファイルがあったので、
core_Library200/source/physics/dgMeshEffect2.cpp
core_Library200/source/physics/dgMeshEffect3.cpp
core_Library200/source/physics/dgMeshEffectSolidTree.cpp
あたりを追加。

さらに、core_Library200/source/newton/Newton.hの中からNewtonSceneCollisionCreateProxy()が宣言されている行を探し、これをコメントアウトする。

自分の環境では、LLVM GCC4.2でビルドするとうまく動かなかった。LLVM 3.1でビルドした。

XcodeのSchemeを編集し、iPhone/iPad実機用と、iOS Simulator用に別々にビルドする。
終わったら、ターミナルでビルドディレクトリを開き、armv7とi386のユニバーサルバイナリを作成する。

lipo -create -output libnewton.a release-iphoneos/libnewton.a release-iossimulator/libnewton.a

Cocos3Dで使う

先ほどビルドしたバイナリを、Cocos3Dプロジェクトに追加する。
core_Library200/source/newton にパスを通す。

core_Library200/projects/mac/iPhoneTranslator/iNewton.h に、Objective-CのNewtonラッパが置いてある。
だがこいつは使えない子。
大人しくNewton.hをインクルードして、通常のCのライブラリとして呼ぶことにする。

CC3Worldを継承したクラスのメンバに、NewtonWorld* newtonを追加して、こんな感じの関数を書く。

MyWorld.m
@implementation MyWorld

- (void)initializeWorld {
    newton = NewtonCreate();
    NewtonSetSolverModel(newton, 1);
}

- (void)dealloc {
    NewtonDestroyAllBodies(newton);
    NewtonDestroy(newton);
    [super dealloc];
}

- (void)updateBeforeTransform:(CC3NodeUpdatingVisitor*)visitor {
    NewtonUpdate(newton, visitor.deltaTime);
}

@end

CC3Nodeを継承したクラスのメンバに、NewtonBody* bodyを追加して、こんな感じの関数を書く。

MyNode.m
static void NewtonGravityCallback(const NewtonBody* body, float timestep, int thredindex) {
    const float GRAVITY = -9.8f;
    float Ixx, Iyy, Izz, mass;

    NewtonBodyGetMassMatrix(body, &mass, &Ixx, &Iyy, &Izz);
    float vector[] = {
        0.0f, GRAVITY * mass, 0.0f
    };
    NewtonBodySetForce(body, vector);
}

static void NewtonTransformCallback(const NewtonBody* body, const float* const matrix, int thredindex) {
    MyNode* node = (MyNode*)NewtonBodyGetUserData(body);
    float matrix[16];
    NewtonBodyGetMatrix(body, matrix);
    float quaternion[4];
    NewtonBodyGetRotation(body, quaternion);

    node.location = CC3VectorMake(matrix[12], matrix[13], matrix[14]);
    node.quaternion = CC3Vector4Make(quaternion[3], quaternion[0], quaternion[1], quaternion[2]);
    // ほんとは行列を直接代入したかったけど、やりかたがよくわからんかった
}

@implementation MyNode

- (void)setupPhysics:(NewtonWorld*)world {
    NewtonCollision* col = NewtonCreateBox(world, 1.0f, 1.0f, 1.0f, 0, NULL);
    body = NewtonCreateBody(world, col, self.transformMatrix.glMatrix);
    NewtonReleaseCollision(world, col);

    NewtonBodySetUserData(body, self);
    NewtonBodySetMassMatrix(body, 1.0f, 1.0f, 1.0f, 1.0f);
    NewtonBodySetForceAndTorqueCallback(body, &NewtonGravityCallback);
    NewtonBodySetTransformCallback(body, &NewtonTransformCallback);
}

@end

できたー!

まとめ

NewtonのMac/iOS対応は適当なので、自分でがんばろう!

追記

Quaternionを使う場合は、どこかで回転方向を逆にしないとうまく動かないかも。

YosukeM
C++、JavaScriptチョットワカル
http://likepolygon.com/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした