LoginSignup
16
16

More than 5 years have passed since last update.

cocos2d-xのSprite3Dで3Dモデルの回転軸を変える

Last updated at Posted at 2014-07-23

cocos2d-x 3.1から実装されたSprite3Dを使ってて偶然発見したマニアックな知見を共有

3DSprite

例えば、歯車のようなモデルを表示して、回転させたいと思う。

モデルはBlenderで作成した。

Size visibleSize = Director::getInstance()->getVisibleSize();

auto gear = Sprite3D::create("model/gear.obj");
gear->setPosition(visibleSize.width / 2.0, visibleSize.height / 2.0);
auto rotation = RotateBy::create(10, Vec3(0, 360, 0));
gear->runAction(RepeatForever::create(rotation));
this->addChild(gear);

うまく回転する

問題:傾けたモデルを回転させようとすると軸がおかしくなる

しかし、このままだと見栄えが悪いので、おもむろに歯車を傾けて回転するようにしたい。

そっちの方が立体感が出てカッコイイ

Size visibleSize = Director::getInstance()->getVisibleSize();

auto gear = Sprite3D::create("model/gear.obj");
gear->setPosition(visibleSize.width / 2.0, visibleSize.height / 2.0);

// X軸、Z軸に対して30度ずつ回転
gear->setRotation3D(Vec3(30, 0, 30));

auto rotation = RotateBy::create(10, Vec3(0, 360, 0));
gear->runAction(RepeatForever::create(rotation));
this->addChild(gear);

回るけどなにやら回転軸がおかしい!

モデル自体のY軸ではなく、絶対座標のY軸が回転軸として使われてしまっているような挙動をする。これじゃない!

解決策

中のコード見て、なんとか解決しないかなぁとか、PR送ろうかなぁと思っていたんですが、なかなか手に負えず。
これは難しい問題だと思いきや、意外と簡単な方法で解決した。

Size visibleSize = Director::getInstance()->getVisibleSize();

auto gear = Sprite3D::create("model/gear.obj");

// 空の親ノードを作る
auto wrapper = Node::create();    
wrapper->setPosition(visibleSize.width / 2.0, visibleSize.height / 2.0);

// 親ノードを回転させる
wrapper->setRotation3D(Vec3(30, 0, 30));

auto rotation = RotateBy::create(10, Vec3(0, 360, 0));
// 回転アニメーションは歯車に付ける
gear->runAction(RepeatForever::create(rotation));

wrapper->addChild(gear);
this->addChild(wrapper);


上手く行った!

空ノードを作り、そちらを回転させてから、子ノードに対して回転アニメーションを適応させたら上手く行った。

Unityとかで良くやる、Empty GameObjectでモデルをラップして回転させる、みたいなテクニックがほぼそのまま使えるようだ。
position3Drotation3Dは、なぜかSprite3DではなくNodeのメソッドになっていたのはこういうことだったのか。

どうでもいいですけど、cocos2d::Sprite3Dみたいなネームスペース気持ち悪いですね。3D機能が充実したら分離されるのだろうか・・・・・・。

16
16
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
16
16