グラフィックス(SDL + OpenGL, OpenSceneGraph)

OpenSceneGraph/0_9_X/5.アニメーションを定義する

最終更新: 2015-04-20 (月) 08:44:43 (1584d)

概要

このページでは、 osg::PositionAttitudeTransformosg::NodeCallback クラスを使用して キューブの大きさを大きくしたり小さくしたりするアニメーションを定義する方法について説明する。

スクリーンショット

上図は、本サンプルプログラムのスクリーンショットである。

ソースコード

filemain.cppアプリケーションのエントリポイントおよびプログラム全体
fileSampleVC6.zipVC6 のプロジェクト(ソース含む)
fileSampleVC7.zipVC7 のプロジェクト(ソース含む)

解説

osg::Node オブジェクトの位置や大きさを変換する osg::PositionAttitudeTransform クラス

描画対象の位置や大きさを変更したい場合、osg::PositionAttitudeTransform クラスを使用する。 osg::PositionAttitudeTransform クラスは、 自分が所有する全てのオブジェクトに対して座標変換を行う osg::Transform クラスの子クラスであり、 osg::Group クラスの派生クラスなので複数の osg::Node オブジェクトをグループ化し、それらの座標変換を制御できる。

本サンプルでは、キューブを表す osg::Geode オブジェクトを一つ構築する。 そして、このキューブの大きさを制御するための osg::PositionAttitudeTransform オブジェクトを一つ構築する。 二つのオブジェクトを構築しているコードとして filemain.cpp の一部を以下に示す。

static osg::Node* createSceneData() {
	// アニメーションを設定する
	osg::PositionAttitudeTransform* scene = new osg::PositionAttitudeTransform();
	scene->addChild(createCube());
	scene->setUpdateCallback(new SizeAnimation());

	// ...

	return scene;
}

createCube は、キューブの osg::Node オブジェクトを構築する関数だ。 osg::PositionAttitudeTransform クラスのオブジェクトである scene オブジェクトは、 キューブを大きさの制御対象とするために addChild メソッドを使ってキューブを表す osg::Node オブジェクトをグループ化している。 この関数で生成された シーングラフを以下に示す。

本サンプルのシーングラフ

最後の setUpdateCallback メソッドは、時間による大きさの変更を行うために osg::NodeCallback クラスの子クラス SizeAnimation を関連付けている。

時間による変化を記述する osg::NodeCallback クラス

時間によってモデルを変更したい場合、osg::NodeCallback クラスを使用する。 osg::NodeCallback クラスは、時間によるモデルの変更を行うためのメソッドを一つ持つ。 そのメソッドは viewer.update メソッド呼び出し時に呼び出され、そこで関連付けられた osg::Node オブジェクトを操作できる。 今回は先ほど生成した osg::PositionAttitudeTransform クラスのオブジェクトである scene オブジェクトを関連付け、 時間によってモデルの大きさを変更するようメソッドを記述する。 osg::PositionAttitudeTransform クラスの子クラス SizeAnimation のコードとして filemain.cpp の一部を以下に示す。

class SizeAnimation : public osg::NodeCallback {
public:
	SizeAnimation() {
	}

public:
	void operator () (osg::Node* node, osg::NodeVisitor* nv) {
		osg::PositionAttitudeTransform* transform = dynamic_cast<osg::PositionAttitudeTransform*>(node);
		if (transform) {
			// 時間によりサイズを調節する
			const double angle = (360.0 / 5.0) * nv->getFrameStamp()->getReferenceTime();
			const double scale = 0.5 * (cos(angle * 3.1415926535 / 180.0) + 1.0) / 2.0 + 0.5;
			transform->setScale(osg::Vec3(scale, scale, scale));
		}
	}
};

osg::NodeCallback クラスは、抽象メソッドとして operator () を持っている。 このメソッドが時間によるモデルの変更を行うためのメソッドであり、SizeAnimation クラスはそれをオーバーライドする。 このメソッドは二つの引数を受け取る。 一つは変更対象となる osg::Node オブジェクトであり、もう一つは osg::NodeVisitor オブジェクトである。 今回変更対象となるオブジェクトのクラスは、 osg::PositionAttitudeTransform クラスとわかっているため dynamic_cast を使用してキャストする。 osg::NodeVisitor クラスは時間の情報を持っており、それを使用して時間により変化するサイズを算出している。

以上。

コメント

コメントはありません。 コメント/OpenSceneGraph/0_9_X/5.アニメーションを定義する

お名前: