//------------------------------------------------------------------------------
// Lamp : Open source game middleware
// Copyright (C) 2004  Junpei Ohtani ( Email : junpee@users.sourceforge.jp )
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//------------------------------------------------------------------------------

/** @file
 * 軸沿いボックステスト実装
 * @author Junpee
 */

#include "Test/stdafx.h"
#include "Geometry/Primitive/AxisAlignedBoxTest.h"
#include "Geometry/Primitive/AxisAlignedBox.h"

//------------------------------------------------------------------------------
// コンストラクタ
AxisAlignedBoxTest::AxisAlignedBoxTest(String name) : TestCase(name){
}
//------------------------------------------------------------------------------
// テストスィートの取得
Test* AxisAlignedBoxTest::suite(){
	TestSuite* suite = new TestSuite("AxisAlignedBoxTest");
	suite->addTest(new TestCaller(AxisAlignedBoxTest, testConstructor));
	suite->addTest(new TestCaller(AxisAlignedBoxTest, testFixedNumber));
	suite->addTest(new TestCaller(AxisAlignedBoxTest, testSetValue));
	suite->addTest(new TestCaller(AxisAlignedBoxTest, testGetValue));
	suite->addTest(new TestCaller(AxisAlignedBoxTest, testBoxArithmetic));
	suite->addTest(new TestCaller(AxisAlignedBoxTest, testTransform));
	suite->addTest(new TestCaller(AxisAlignedBoxTest, testLogicalOperation));
	suite->addTest(new TestCaller(AxisAlignedBoxTest, testToString));
	return suite;
}
//------------------------------------------------------------------------------
// コンストラクタテスト
void AxisAlignedBoxTest::testConstructor(){
	TestEquals(24, (int)sizeof(AxisAlignedBox));
	AxisAlignedBox box0(-1.f, -2.f, -3.f, 1.f, 2.f, 3.f);
	AxisAlignedBox box1(Vector3(-1.f, -2.f, -3.f), Vector3(1.f, 2.f, 3.f));
	TestAssert(box0 == box1);
	AxisAlignedBox box2(box1);
	TestAssert(box0 == box2);
	box1 = box2;
	TestAssert(box0 == box1);
	AxisAlignedBox box3(AxisAlignedBox::zero);
	TestAssert(box3 == AxisAlignedBox(0.f, 0.f, 0.f, 0.f, 0.f, 0.f));
	float array[] = { -1.f, -2.f, -3.f, 1.f, 2.f, 3.f };
	AxisAlignedBox box4(array);
	TestAssert(box0 == box4);
}
//------------------------------------------------------------------------------
// 定数テスト
void AxisAlignedBoxTest::testFixedNumber(){
	AxisAlignedBox box0(0.f, 0.f, 0.f, 0.f, 0.f, 0.f);
	TestAssert(box0 == AxisAlignedBox::zero);
	AxisAlignedBox box1(-0.5f, -0.5f, -0.5f, 0.5f, 0.5f, 0.5f);
	TestAssert(box1 == AxisAlignedBox::unit);
}
//------------------------------------------------------------------------------
// 値の設定テスト
void AxisAlignedBoxTest::testSetValue(){
	AxisAlignedBox box0(-1.f, -2.f, -3.f, 1.f, 2.f, 3.f);
	AxisAlignedBox box1;
	box1.set(-1.f, -2.f, -3.f, 1.f, 2.f, 3.f);
	TestAssert(box0 == box1);
	box1.set(Vector3(-1.f, -2.f, -3.f), Vector3(1.f, 2.f, 3.f));
	TestAssert(box0 == box1);
	float array[] = { -1.f, -2.f, -3.f, 1.f, 2.f, 3.f };
	box1.set(array);
	TestAssert(box0 == box1);
}
//------------------------------------------------------------------------------
// 値の取得テスト
void AxisAlignedBoxTest::testGetValue(){
	AxisAlignedBox box0(-1.f, -2.f, -3.f, 1.f, 2.f, 3.f);
	TestAssert(box0.getMinimum() == Vector3(-1.f, -2.f, -3.f));
	TestAssert(box0.getMaximum() == Vector3(1.f, 2.f, 3.f));
	TestAssert(box0.getSize() == Vector3(2.f, 4.f, 6.f));
	TestAssert(box0.getCenter() == Vector3(0.f, 0.f, 0.f));

	TestAssert(box0.getCorner(0) == Vector3(-1.f, -2.f, -3.f));
	TestAssert(box0.getCorner(1) == Vector3(-1.f, 2.f, -3.f));
	TestAssert(box0.getCorner(2) == Vector3(1.f, 2.f, -3.f));
	TestAssert(box0.getCorner(3) == Vector3(1.f, -2.f, -3.f));
	TestAssert(box0.getCorner(4) == Vector3(1.f, 2.f, 3.f));
	TestAssert(box0.getCorner(5) == Vector3(-1.f, 2.f, 3.f));
	TestAssert(box0.getCorner(6) == Vector3(-1.f, -2.f, 3.f));
	TestAssert(box0.getCorner(7) == Vector3(1.f, -2.f, 3.f));

	Vector3 corner[8];
	box0.getCornerArray(corner);
	TestAssert(corner[0] == Vector3(-1.f, -2.f, -3.f));
	TestAssert(corner[1] == Vector3(-1.f, 2.f, -3.f));
	TestAssert(corner[2] == Vector3(1.f, 2.f, -3.f));
	TestAssert(corner[3] == Vector3(1.f, -2.f, -3.f));
	TestAssert(corner[4] == Vector3(1.f, 2.f, 3.f));
	TestAssert(corner[5] == Vector3(-1.f, 2.f, 3.f));
	TestAssert(corner[6] == Vector3(-1.f, -2.f, 3.f));
	TestAssert(corner[7] == Vector3(1.f, -2.f, 3.f));
}
//------------------------------------------------------------------------------
// ボックス演算
void AxisAlignedBoxTest::testBoxArithmetic(){
	AxisAlignedBox box0(-1.f, -2.f, -3.f, 1.f, 2.f, 3.f);
	AxisAlignedBox box1(AxisAlignedBox::zero);
	box1.merge(box0);
	TestAssert(box0 == box1);
	box1 = AxisAlignedBox::zero;
	box1.merge(Vector3(-1.f, -2.f, -3.f));
	box1.merge(Vector3(1.f, 2.f, 3.f));
	TestAssert(box0 == box1);

	TestAssert(AxisAlignedBox(0.f, 0.f, 0.f, 0.f, 0.f, 0.f).isZero());
	TestAssert(AxisAlignedBox(-0.5f, -0.5f, -0.5f, 0.5f, 0.5f, 0.5f).isUnit());
}
//------------------------------------------------------------------------------
// 変換テスト
void AxisAlignedBoxTest::testTransform(){
	AxisAlignedBox box0(-1.f, -2.f, -3.f, 1.f, 2.f, 3.f);
	AxisAlignedBox box1(AxisAlignedBox::zero);

	Matrix33 mtx33;
	mtx33.setScale(Vector3(1.f, 2.f, 1.f));
	mtx33.addRotationXYZ(Vector3(Math::halfPI, Math::halfPI, Math::halfPI));
	box1 = box0.transform(mtx33);
	TestAssert(box1.epsilonEquals(
		AxisAlignedBox(-3.f, -4.f, -1.f, 3.f, 4.f, 1.f), Math::epsilon));

	Matrix34 mtx43;
	mtx43.setScale(Vector3(1.f, 2.f, 1.f));
	mtx43.addRotationXYZ(Vector3(Math::halfPI, Math::halfPI, Math::halfPI));
	mtx43.addTranslation(1.f, 1.f, 1.f);
	box1 = box0.transform(mtx43);
	TestAssert(box1.epsilonEquals(
		AxisAlignedBox(-2.f, -3.f, 0.f, 4.f, 5.f, 2.f), Math::epsilon));

	Matrix44 mtx44;
	mtx44.setScale(Vector3(1.f, 2.f, 1.f));
	mtx44.addRotationXYZ(Vector3(Math::halfPI, Math::halfPI, Math::halfPI));
	mtx44.addTranslation(1.f, -1.f, 1.f);
	box1 = box0.transform(mtx44);
	TestAssert(box1.epsilonEquals(
		AxisAlignedBox(-2.f, -5.f, 0.f, 4.f, 3.f, 2.f), Math::epsilon));
}
//------------------------------------------------------------------------------
// 論理演算テスト
void AxisAlignedBoxTest::testLogicalOperation(){
	AxisAlignedBox box0(0.f, 0.f, 0.f, 1.f, 1.f, 1.f),
		box1(1.f, 1.f, 1.f, 2.f, 2.f, 2.f),
		box2(0.f, 0.f, 0.f, 1.f, 1.f, 1.f);
	TestAssert(!(box0 == box1));
	TestAssert(box0 == box2);
	TestAssert(box0 != box1);
	TestAssert(!(box0 != box2));
	TestAssert(box0.epsilonEquals(box1, 1.f));
	TestAssert(box0 != box1);
	TestAssert(box0.notEpsilonEquals(box1, 0.5f));
	TestAssert(!box0.notEpsilonEquals(box1, 1.f));
	TestAssert(!box0.notEpsilonEquals(box2, 0.f));
}
//------------------------------------------------------------------------------
// 文字列テスト
void AxisAlignedBoxTest::testToString(){
	AxisAlignedBox box0(12345678.f, 1234.5678f, 0.12345678f,
		12345678.f, 1234.5678f, 0.12345678f);
	TestEquals("{ ( 12345678.00000000, 1234.56774902, 0.12345678 ) "
		"( 12345678.00000000, 1234.56774902, 0.12345678 ) }",
		box0.toString());
}
//------------------------------------------------------------------------------
