C++ 用 3D グラフィックアプリ向けの数学ライブラリ Lumino.Math

ゲーム等の3Dグラフィックアプリ開発では、ベクトルや行列等の線形代数は避けて通れません。
DirectX はヘルパー関数が充実していますが、それでも IK や視錐台カリングとかやりだすと微妙に足りなかったり、
OpenGL や DXライブラリを使おうとすると大半を自分で書き上げなければならなかったりといろいろ不満が残ります。

さて、実は世の中にはすでにいくつか有名な数学ライブラリが存在します。

しかし、実際のところゲーム向けにはややオーバースペック気味で、
インターフェイスも "ゲーム寄り" ではなく汎用的に作られた
ホントの "数学寄り" です。

というところで、DXライブラリ や DirectX に慣れ親しんだ人が使いやすい
数学ライブラリが欲しいなと思い、Lumino.Math を公開しました。

特徴・主な機能

用途

2~4次元ベクトル、4x4行列、クォータニオン、視錐台カリング、補間

API

C++ のクラスライブラリです。
DirectX9 時代の D3DXMath をクラス化したイメージで、
XNA や SlimDX のインターフェイスを意識しています。

マルチプラットフォーム

現在、Windows(VisualStudio, Cygwin) と Linux で動作を確認しています。

ライセンス

Zlib ライセンスです。
ソースコードを変更して再配布しない限り、著作権表示はしなくてもOKです。
(していただければ嬉しいですが)

使用例

// ヘッダファイルと名前空間
#include <LuminoMath.h>
using namespace Lumino;		// 全てのクラスは Lumino 名前空間に入っています
// ベクトルを正規化する
Vector3 v1(10, 20, 0);
Vector3 v2 = Vector3::Normalize(v2);	// 正規化した新しいベクトルを作る
v1.Normalize();				// 自分自身を正規化する
// ワールド・ビュー・プロジェクション行列を作る
Matrix world;
world  = Matrix::Scaling(2.0f);				// 拡縮率
world *= Matrix::RotationAxis(Vector3(0, 1, 0), 0.25f);	// 任意の軸を中心に回転する
world *= Matrix::Translation(10, 20, 0);		// 平行移動量

Matrix view = Matrix::LookAtLH(
	Vector3(10, 20, 30),	// 視点の位置
	Vector3(0, 0, 0),	// 注視点
	Vector3(0, 1, 0));	// 上方向

Matrix proj = Matrix::PerspectiveFovLH(
	0.25f,				// 視野角
	640.0f / 480.0f,		// アスペクト比
	1,				// 最近ビュー平面
	1000);				// 最遠ビュー平面

Matrix wvp = world * view * proj;
// 3D ベクトルを行列で座標変換する
Vector3 pos1(10, 20, 30);
Vector3 pos2 = Vector3::TransformCoord(pos1, wvp);
// オイラー角・回転行列・クォータニオンの相互変換
Matrix	m1		= Matrix::RotationYawPitchRoll(0.1f, 0.2f, 0.3f);
Vector3	angles	= Matrix::ToEulerAngles(m1);

Quaternion	q1	= Quaternion::RotationMatrix(m1);
Matrix		m2	= Matrix::RotationQuaternion(q1);

Quaternion	q2	= Quaternion::RotationYawPitchRoll(0.1f, 0.2f, 0.3f);
Vector3	angles	= Quaternion::ToEulerAngles(q2);
// エルミートスプライン補間
Vector3 posStart(10, 0, 0);	// 開始位置
Vector3 velStart(0.1f, 0, 0);	// 開始時の速度
Vector3 posEnd(0, 10, 0);	// 目的位置
Vector3 velEnd(0, 0, 0);	// 目的位置に着いたときの速度
Vector3 pos = Vector3::Hermite(posStart, velStart, posEnd, velEnd, 0.5f);	// ちょうど半分の時間のときの位置を返す
// 球面線形補間
Quaternion quaStart	= RotationAxis(Vector3(0, 1, 0), 0.1f);
Quaternion quaEnd	= RotationAxis(Vector3(0, 0, 1), 0.2f);
Quaternion q = Quaternion::Slerp(quaStart, quaEnd, 0.5f);

最後に

実際に 3D ゲーム制作や MMD モデルのレンダリング等で使用したライブラリですので
そこそこ過不足なくまとまっていると思いますが、なにか要望等ありましたら
コメントやこちらのサイト、GitHub まで連絡いただければと思います。