diff options
Diffstat (limited to 'indra/llmath/tests')
| -rw-r--r-- | indra/llmath/tests/llbbox_test.cpp | 373 | ||||
| -rw-r--r-- | indra/llmath/tests/llbboxlocal_test.cpp | 238 | ||||
| -rw-r--r-- | indra/llmath/tests/llmodularmath_test.cpp | 82 | ||||
| -rw-r--r-- | indra/llmath/tests/llquaternion_test.cpp | 666 | ||||
| -rw-r--r-- | indra/llmath/tests/llrect_test.cpp | 532 | ||||
| -rw-r--r-- | indra/llmath/tests/m3math_test.cpp | 327 | ||||
| -rw-r--r-- | indra/llmath/tests/mathmisc_test.cpp | 727 | ||||
| -rw-r--r-- | indra/llmath/tests/v2math_test.cpp | 454 | ||||
| -rw-r--r-- | indra/llmath/tests/v3color_test.cpp | 315 | ||||
| -rw-r--r-- | indra/llmath/tests/v3dmath_test.cpp | 532 | ||||
| -rw-r--r-- | indra/llmath/tests/v3math_test.cpp | 573 | ||||
| -rw-r--r-- | indra/llmath/tests/v4color_test.cpp | 365 | ||||
| -rw-r--r-- | indra/llmath/tests/v4coloru_test.cpp | 342 | ||||
| -rw-r--r-- | indra/llmath/tests/v4math_test.cpp | 388 | ||||
| -rw-r--r-- | indra/llmath/tests/xform_test.cpp | 251 | 
15 files changed, 6165 insertions, 0 deletions
| diff --git a/indra/llmath/tests/llbbox_test.cpp b/indra/llmath/tests/llbbox_test.cpp new file mode 100644 index 0000000000..bc439e4618 --- /dev/null +++ b/indra/llmath/tests/llbbox_test.cpp @@ -0,0 +1,373 @@ +/** + * @file   llbbox_tut.cpp + * @author Martin Reddy + * @date   2009-06-25 + * @brief  Test for llbbox.cpp. + *  + * $LicenseInfo:firstyear=2009&license=viewergpl$ + * + * Copyright (c) 2009-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab.  Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "linden_common.h" + +#include "../test/lltut.h" + +#include "../llbbox.h" + + +#define ANGLE                (3.14159265f / 2.0f) +#define APPROX_EQUAL(a, b)   dist_vec((a),(b)) < 1e-5 + +namespace tut +{ +	struct LLBBoxData +	{ +	}; + +	typedef test_group<LLBBoxData> factory; +	typedef factory::object object; +} + +namespace +{ +	tut::factory llbbox_test_factory("LLBBox"); +} + +namespace tut +{ +	template<> template<> +	void object::test<1>() +	{	 +		// +		// test the default constructor +		// +		 +		LLBBox bbox1; +		 +		ensure_equals("Default bbox min", bbox1.getMinLocal(), LLVector3(0.0f, 0.0f, 0.0f)); +		ensure_equals("Default bbox max", bbox1.getMaxLocal(), LLVector3(0.0f, 0.0f, 0.0f)); +		ensure_equals("Default bbox pos agent", bbox1.getPositionAgent(), LLVector3(0.0f, 0.0f, 0.0f)); +		ensure_equals("Default bbox rotation", bbox1.getRotation(), LLQuaternion(0.0f, 0.0f, 0.0f, 1.0f)); +	} +	 +	template<> template<> +	void object::test<2>() +	{	 +		// +		// test the non-default constructor +		// +		 +		LLBBox bbox2(LLVector3(1.0f, 2.0f, 3.0f), LLQuaternion(), +					 LLVector3(2.0f, 3.0f, 4.0f), LLVector3(4.0f, 5.0f, 6.0f)); +		 +		ensure_equals("Custom bbox min", bbox2.getMinLocal(), LLVector3(2.0f, 3.0f, 4.0f)); +		ensure_equals("Custom bbox max", bbox2.getMaxLocal(), LLVector3(4.0f, 5.0f, 6.0f)); +		ensure_equals("Custom bbox pos agent", bbox2.getPositionAgent(), LLVector3(1.0f, 2.0f, 3.0f)); +		ensure_equals("Custom bbox rotation", bbox2.getRotation(), LLQuaternion(0.0f, 0.0f, 0.0f, 1.0f));		 +	} +		 +	template<> template<> +	void object::test<3>() +	{	 +		// +		// test the setMinLocal() method +		// +		LLBBox bbox2; +		bbox2.setMinLocal(LLVector3(3.0f, 3.0f, 3.0f)); +		ensure_equals("Custom bbox min (2)", bbox2.getMinLocal(), LLVector3(3.0f, 3.0f, 3.0f)); +	} + +	template<> template<> +	void object::test<4>() +	{	 +		// +		// test the setMaxLocal() method +		// +		LLBBox bbox2; +		bbox2.setMaxLocal(LLVector3(5.0f, 5.0f, 5.0f)); +		ensure_equals("Custom bbox max (2)", bbox2.getMaxLocal(), LLVector3(5.0f, 5.0f, 5.0f)); +	} + +	template<> template<> +	void object::test<5>() +	{	 +		// +		// test the getCenterLocal() method +		// +		 +		ensure_equals("Default bbox local center", LLBBox().getCenterLocal(), LLVector3(0.0f, 0.0f, 0.0f)); +		 +		LLBBox bbox1(LLVector3(1.0f, 2.0f, 3.0f), LLQuaternion(), +					 LLVector3(2.0f, 4.0f, 6.0f), LLVector3(4.0f, 6.0f, 8.0f)); + +		ensure_equals("Custom bbox center local", bbox1.getCenterLocal(), LLVector3(3.0f, 5.0f, 7.0f)); + +		LLBBox bbox2(LLVector3(1.0f, 1.0f, 1.0f), LLQuaternion(ANGLE, LLVector3(0.0f, 0.0f, 1.0f)), +					 LLVector3(2.0f, 2.0f, 2.0f), LLVector3(4.0f, 4.0f, 4.0f)); + +		ensure_equals("Custom bbox center local with rot", bbox2.getCenterLocal(), LLVector3(3.0f, 3.0f, 3.0f)); +	} + +	template<> template<> +	void object::test<6>() +	{	 +		// +		// test the getCenterAgent() +		// +		 +		ensure_equals("Default bbox agent center", LLBBox().getCenterAgent(), LLVector3(0.0f, 0.0f, 0.0f)); +		 +		LLBBox bbox1(LLVector3(1.0f, 2.0f, 3.0f), LLQuaternion(), +					 LLVector3(2.0f, 4.0f, 6.0f), LLVector3(4.0f, 6.0f, 8.0f)); +		 +		ensure_equals("Custom bbox center agent", bbox1.getCenterAgent(), LLVector3(4.0f, 7.0f, 10.0f)); +		 +		LLBBox bbox2(LLVector3(1.0f, 1.0f, 1.0f), LLQuaternion(ANGLE, LLVector3(0.0f, 0.0f, 1.0f)), +					 LLVector3(2.0f, 2.0f, 2.0f), LLVector3(4.0f, 4.0f, 4.0f)); +		 +		ensure("Custom bbox center agent with rot", APPROX_EQUAL(bbox2.getCenterAgent(), LLVector3(-2.0f, 4.0f, 4.0f))); +	} +	 +	template<> template<> +	void object::test<7>() +	{	 +		// +		// test the getExtentLocal() method +		// +		 +		ensure_equals("Default bbox local extent", LLBBox().getExtentLocal(), LLVector3(0.0f, 0.0f, 0.0f)); +		 +		LLBBox bbox1(LLVector3(1.0f, 2.0f, 3.0f), LLQuaternion(), +					 LLVector3(2.0f, 4.0f, 6.0f), LLVector3(4.0f, 6.0f, 8.0f)); +		 +		ensure_equals("Custom bbox extent local", bbox1.getExtentLocal(), LLVector3(2.0f, 2.0f, 2.0f)); +		 +		LLBBox bbox2(LLVector3(1.0f, 1.0f, 1.0f), LLQuaternion(ANGLE, LLVector3(0.0f, 0.0f, 1.0f)), +					 LLVector3(2.0f, 2.0f, 2.0f), LLVector3(4.0f, 4.0f, 4.0f)); +		 +		ensure_equals("Custom bbox extent local with rot", bbox1.getExtentLocal(), LLVector3(2.0f, 2.0f, 2.0f));		 +	} +	 +	template<> template<> +	void object::test<8>() +	{ +		// +		// test the addPointLocal() method +		// +		 +		LLBBox bbox1; +		bbox1.addPointLocal(LLVector3(1.0f, 1.0f, 1.0f)); +		bbox1.addPointLocal(LLVector3(3.0f, 3.0f, 3.0f)); +		 +		ensure_equals("addPointLocal center local (1)", bbox1.getCenterLocal(), LLVector3(2.0f, 2.0f, 2.0f)); +		ensure_equals("addPointLocal center agent (1)", bbox1.getCenterAgent(), LLVector3(2.0f, 2.0f, 2.0f)); +		ensure_equals("addPointLocal min (1)", bbox1.getMinLocal(), LLVector3(1.0f, 1.0f, 1.0f)); +		ensure_equals("addPointLocal max (1)", bbox1.getMaxLocal(), LLVector3(3.0f, 3.0f, 3.0f)); +		 +		bbox1.addPointLocal(LLVector3(0.0f, 0.0f, 0.0f)); +		bbox1.addPointLocal(LLVector3(1.0f, 1.0f, 1.0f)); +		bbox1.addPointLocal(LLVector3(2.0f, 2.0f, 2.0f)); +		 +		ensure_equals("addPointLocal center local (2)", bbox1.getCenterLocal(), LLVector3(1.5f, 1.5f, 1.5f)); +		ensure_equals("addPointLocal min (2)", bbox1.getMinLocal(), LLVector3(0.0f, 0.0f, 0.0f)); +		ensure_equals("addPointLocal max (2)", bbox1.getMaxLocal(), LLVector3(3.0f, 3.0f, 3.0f));		 +	} + +	template<> template<> +	void object::test<9>() +	{ +		// +		// test the addBBoxLocal() method +		// +		 +		LLBBox bbox1; +		bbox1.addBBoxLocal(LLBBox(LLVector3(), LLQuaternion(), +								  LLVector3(0.0f, 0.0f, 0.0f), LLVector3(3.0f, 3.0f, 3.0f))); +		 +		ensure_equals("addPointLocal center local (3)", bbox1.getCenterLocal(), LLVector3(1.5f, 1.5f, 1.5f)); +		ensure_equals("addPointLocal min (3)", bbox1.getMinLocal(), LLVector3(0.0f, 0.0f, 0.0f)); +		ensure_equals("addPointLocal max (3)", bbox1.getMaxLocal(), LLVector3(3.0f, 3.0f, 3.0f)); +		 +		bbox1.addBBoxLocal(LLBBox(LLVector3(1.0f, 1.0f, 1.0f), LLQuaternion(), +								  LLVector3(5.0f, 5.0f, 5.0f), LLVector3(10.0f, 10.0f, 10.0f))); +		 +		ensure_equals("addPointLocal center local (4)", bbox1.getCenterLocal(), LLVector3(5.0f, 5.0f, 5.0f)); +		ensure_equals("addPointLocal center agent (4)", bbox1.getCenterAgent(), LLVector3(5.0f, 5.0f, 5.0f)); +		ensure_equals("addPointLocal min (4)", bbox1.getMinLocal(), LLVector3(0.0f, 0.0f, 0.0f)); +		ensure_equals("addPointLocal max (4)", bbox1.getMaxLocal(), LLVector3(10.0f, 10.0f, 10.0f));		 +	} +	 +	template<> template<> +	void object::test<10>() +	{ +		// +		// test the addPointAgent() method +		// +		 +		LLBBox bbox1(LLVector3(1.0f, 1.0f, 1.0f), LLQuaternion(1.0, 0.0, 0.0, 1.0), +					 LLVector3(2.0f, 2.0f, 2.0f), LLVector3(4.0f, 4.0f, 4.0f)); + +		bbox1.addPointAgent(LLVector3(1.0f, 1.0f, 1.0f)); +		bbox1.addPointAgent(LLVector3(3.0f, 3.0f, 3.0f)); +		 +		ensure_equals("addPointAgent center local (1)", bbox1.getCenterLocal(), LLVector3(2.0f, 2.0f, -2.0f)); +		ensure_equals("addPointAgent center agent (1)", bbox1.getCenterAgent(), LLVector3(3.0f, 3.0f, 7.0f)); +		ensure_equals("addPointAgent min (1)", bbox1.getMinLocal(), LLVector3(0.0f, 0.0f, -4.0f)); +		ensure_equals("addPointAgent max (1)", bbox1.getMaxLocal(), LLVector3(4.0f, 4.0f, 0.0f)); +	} + +	template<> template<> +	void object::test<11>() +	{ +		// +		// test the addBBoxAgent() method +		// +		 +		LLBBox bbox1(LLVector3(1.0f, 1.0f, 1.0f), LLQuaternion(1.0, 0.0, 0.0, 1.0), +					 LLVector3(2.0f, 2.0f, 2.0f), LLVector3(4.0f, 4.0f, 4.0f)); +		 +		bbox1.addPointAgent(LLVector3(1.0f, 1.0f, 1.0f)); +		bbox1.addPointAgent(LLVector3(3.0f, 3.0f, 3.0f)); +		 +		bbox1.addBBoxLocal(LLBBox(LLVector3(1.0f, 1.0f, 1.0f), LLQuaternion(), +								  LLVector3(5.0f, 5.0f, 5.0f), LLVector3(10.0f, 10.0f, 10.0f))); +		 +		ensure_equals("addPointAgent center local (2)", bbox1.getCenterLocal(), LLVector3(5.0f, 5.0f, 3.0f)); +		ensure_equals("addPointAgent center agent (2)", bbox1.getCenterAgent(), LLVector3(6.0f, -10.0f, 8.0f)); +		ensure_equals("addPointAgent min (2)", bbox1.getMinLocal(), LLVector3(0.0f, 0.0f, -4.0f)); +		ensure_equals("addPointAgent max (2)", bbox1.getMaxLocal(), LLVector3(10.0f, 10.0f, 10.0f));		 +	} +	 +	template<> template<> +	void object::test<12>() +	{ +		// +		// test the expand() method +		// +		 +		LLBBox bbox1; +		bbox1.expand(0.0); + +		ensure_equals("Zero-expanded Default BBox center", bbox1.getCenterLocal(), LLVector3(0.0f, 0.0f, 0.0f)); + +		LLBBox bbox2(LLVector3(1.0f, 1.0f, 1.0f), LLQuaternion(), +					 LLVector3(1.0f, 1.0f, 1.0f), LLVector3(3.0f, 3.0f, 3.0f)); +		bbox2.expand(0.0); +		 +		ensure_equals("Zero-expanded center local", bbox2.getCenterLocal(), LLVector3(2.0f, 2.0f, 2.0f)); +		ensure_equals("Zero-expanded center agent", bbox2.getCenterAgent(), LLVector3(3.0f, 3.0f, 3.0f)); +		ensure_equals("Zero-expanded min", bbox2.getMinLocal(), LLVector3(1.0f, 1.0f, 1.0f)); +		ensure_equals("Zero-expanded max", bbox2.getMaxLocal(), LLVector3(3.0f, 3.0f, 3.0f)); + +		bbox2.expand(0.5); + +		ensure_equals("Positive-expanded center", bbox2.getCenterLocal(), LLVector3(2.0f, 2.0f, 2.0f)); +		ensure_equals("Positive-expanded min", bbox2.getMinLocal(), LLVector3(0.5f, 0.5f, 0.5f)); +		ensure_equals("Positive-expanded max", bbox2.getMaxLocal(), LLVector3(3.5f, 3.5f, 3.5f)); + +		bbox2.expand(-1.0); +		 +		ensure_equals("Negative-expanded center", bbox2.getCenterLocal(), LLVector3(2.0f, 2.0f, 2.0f)); +		ensure_equals("Negative-expanded min", bbox2.getMinLocal(), LLVector3(1.5f, 1.5f, 1.5f)); +		ensure_equals("Negative-expanded max", bbox2.getMaxLocal(), LLVector3(2.5f, 2.5f, 2.5f));		 +	} +	 +	template<> template<> +	void object::test<13>() +	{ +		// +		// test the localToAgent() method +		// +		 +		LLBBox bbox1(LLVector3(1.0f, 1.0f, 1.0f), LLQuaternion(), +					 LLVector3(1.0f, 1.0f, 1.0f), LLVector3(3.0f, 3.0f, 3.0f)); +		 +		ensure_equals("localToAgent(1,2,3)", bbox1.localToAgent(LLVector3(1.0f, 2.0f, 3.0f)), LLVector3(2.0f, 3.0f, 4.0f)); +		 +		LLBBox bbox2(LLVector3(1.0f, 1.0f, 1.0f), LLQuaternion(ANGLE, LLVector3(1.0f, 0.0f, 0.0f)), +					 LLVector3(1.0f, 1.0f, 1.0f), LLVector3(3.0f, 3.0f, 3.0f)); +		 +		ensure("localToAgent(1,2,3) rot", APPROX_EQUAL(bbox2.localToAgent(LLVector3(1.0f, 2.0f, 3.0f)), LLVector3(2.0f, -2.0f, 3.0f))); +	} +	 +	template<> template<> +	void object::test<14>() +	{ +		// +		// test the agentToLocal() method +		// +		 +		LLBBox bbox1(LLVector3(1.0f, 1.0f, 1.0f), LLQuaternion(), +					 LLVector3(1.0f, 1.0f, 1.0f), LLVector3(3.0f, 3.0f, 3.0f)); +		 +		ensure_equals("agentToLocal(1,2,3)", bbox1.agentToLocal(LLVector3(1.0f, 2.0f, 3.0f)), LLVector3(0.0f, 1.0f, 2.0f)); +		ensure_equals("agentToLocal(localToAgent)", bbox1.agentToLocal(bbox1.localToAgent(LLVector3(1.0f, 2.0f, 3.0f))), +					  LLVector3(1.0f, 2.0f, 3.0f)); +		 +		LLBBox bbox2(LLVector3(1.0f, 1.0f, 1.0f), LLQuaternion(ANGLE, LLVector3(1.0f, 0.0f, 0.0f)), +					 LLVector3(1.0f, 1.0f, 1.0f), LLVector3(3.0f, 3.0f, 3.0f)); +		 +		ensure("agentToLocal(1,2,3) rot", APPROX_EQUAL(bbox2.agentToLocal(LLVector3(1.0f, 2.0f, 3.0f)), LLVector3(0.0f, 2.0f, -1.0f))); +		ensure("agentToLocal(localToAgent) rot", APPROX_EQUAL(bbox2.agentToLocal(bbox2.localToAgent(LLVector3(1.0f, 2.0f, 3.0f))), +															  LLVector3(1.0f, 2.0f, 3.0f))); +	} +	 +	template<> template<> +	void object::test<15>() +	{ +		// +		// test the containsPointLocal() method +		// +		 +		LLBBox bbox1(LLVector3(1.0f, 1.0f, 1.0f), LLQuaternion(), +					 LLVector3(1.0f, 2.0f, 3.0f), LLVector3(3.0f, 4.0f, 5.0f)); + +		ensure("containsPointLocal(0,0,0)", bbox1.containsPointLocal(LLVector3(0.0f, 0.0f, 0.0f)) == FALSE); +		ensure("containsPointLocal(1,2,3)", bbox1.containsPointLocal(LLVector3(1.0f, 2.0f, 3.0f)) == TRUE); +		ensure("containsPointLocal(0.999,2,3)", bbox1.containsPointLocal(LLVector3(0.999f, 2.0f, 3.0f)) == FALSE); +		ensure("containsPointLocal(3,4,5)", bbox1.containsPointLocal(LLVector3(3.0f, 4.0f, 5.0f)) == TRUE); +		ensure("containsPointLocal(3,4,5.001)", bbox1.containsPointLocal(LLVector3(3.0f, 4.0f, 5.001f)) == FALSE); +	} + +	template<> template<> +	void object::test<16>() +	{ +		// +		// test the containsPointAgent() method +		// +		 +		LLBBox bbox1(LLVector3(1.0f, 1.0f, 1.0f), LLQuaternion(), +					 LLVector3(1.0f, 2.0f, 3.0f), LLVector3(3.0f, 4.0f, 5.0f)); +		 +		ensure("containsPointAgent(0,0,0)", bbox1.containsPointAgent(LLVector3(0.0f, 0.0f, 0.0f)) == FALSE); +		ensure("containsPointAgent(2,3,4)", bbox1.containsPointAgent(LLVector3(2.0f, 3.0f, 4.0f)) == TRUE); +		ensure("containsPointAgent(2,2.999,4)", bbox1.containsPointAgent(LLVector3(2.0f, 2.999f, 4.0f)) == FALSE); +		ensure("containsPointAgent(4,5,6)", bbox1.containsPointAgent(LLVector3(4.0f, 5.0f, 6.0f)) == TRUE); +		ensure("containsPointAgent(4,5.001,6)", bbox1.containsPointAgent(LLVector3(4.0f, 5.001f, 6.0f)) == FALSE); +	}				 +} + diff --git a/indra/llmath/tests/llbboxlocal_test.cpp b/indra/llmath/tests/llbboxlocal_test.cpp new file mode 100644 index 0000000000..91a303201b --- /dev/null +++ b/indra/llmath/tests/llbboxlocal_test.cpp @@ -0,0 +1,238 @@ +/** + * @file   llbboxlocal_tut.cpp + * @author Martin Reddy + * @date   2009-06-25 + * @brief  Test for llbboxlocal.cpp. + *  + * $LicenseInfo:firstyear=2009&license=viewergpl$ + * + * Copyright (c) 2009-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab.  Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "linden_common.h" +#include "../test/lltut.h" +#include "../llbboxlocal.h" + +namespace tut +{ +	struct LLBBoxLocalData +	{ +	}; + +	typedef test_group<LLBBoxLocalData> factory; +	typedef factory::object object; +} + +namespace +{ +	tut::factory llbboxlocal_test_factory("LLBBoxLocal"); +} + +namespace tut +{ +	template<> template<> +	void object::test<1>() +	{	 +		// +		// test the default constructor +		// +		 +		LLBBoxLocal bbox1; +		 +		ensure_equals("Default bbox min", bbox1.getMin(), LLVector3(0.0f, 0.0f, 0.0f)); +		ensure_equals("Default bbox max", bbox1.getMax(), LLVector3(0.0f, 0.0f, 0.0f)); +	} + +	template<> template<> +	void object::test<2>() +	{	 +		// +		// test the non-default constructor +		// +		 +		LLBBoxLocal bbox2(LLVector3(-1.0f, -2.0f, 0.0f), LLVector3(1.0f, 2.0f, 3.0f)); +		 +		ensure_equals("Custom bbox min", bbox2.getMin(), LLVector3(-1.0f, -2.0f, 0.0f)); +		ensure_equals("Custom bbox max", bbox2.getMax(), LLVector3(1.0f, 2.0f, 3.0f));		 +	} +	 +	template<> template<> +	void object::test<3>() +	{	 +		// +		// test the setMin() +		// +		// N.B. no validation is currently performed to ensure that the min +		// and max vectors are actually the min/max values. +		// +		 +		LLBBoxLocal bbox2; +		bbox2.setMin(LLVector3(1.0f, 2.0f, 3.0f)); +		 +		ensure_equals("Custom bbox min (2)", bbox2.getMin(), LLVector3(1.0f, 2.0f, 3.0f)); +	} +	 +	template<> template<> +	void object::test<4>() +	{	 +		// +		// test the setMax() +		// +		// N.B. no validation is currently performed to ensure that the min +		// and max vectors are actually the min/max values. +		// +		 +		LLBBoxLocal bbox2; +		bbox2.setMax(LLVector3(10.0f, 20.0f, 30.0f)); +		 +		ensure_equals("Custom bbox max (2)", bbox2.getMax(), LLVector3(10.0f, 20.0f, 30.0f)); +	} +	 +	template<> template<> +	void object::test<5>() +	{	 +		// +		// test the getCenter() method +		// +		 +		ensure_equals("Default bbox center", LLBBoxLocal().getCenter(), LLVector3(0.0f, 0.0f, 0.0f)); +		 +		LLBBoxLocal bbox1(LLVector3(-1.0f, -1.0f, -1.0f), LLVector3(0.0f, 0.0f, 0.0f)); +		 +		ensure_equals("Custom bbox center", bbox1.getCenter(), LLVector3(-0.5f, -0.5f, -0.5f)); +		 +		LLBBoxLocal bbox2(LLVector3(0.0f, 0.0f, 0.0f), LLVector3(-1.0f, -1.0f, -1.0f)); +		 +		ensure_equals("Invalid bbox center", bbox2.getCenter(), LLVector3(-0.5f, -0.5f, -0.5f)); +	} + +	template<> template<> +	void object::test<6>() +	{	 +		// +		// test the getExtent() method +		// +		 +		LLBBoxLocal bbox2(LLVector3(0.0f, 0.0f, 0.0f), LLVector3(-1.0f, -1.0f, -1.0f)); +		 +		ensure_equals("Default bbox extent", LLBBoxLocal().getExtent(), LLVector3(0.0f, 0.0f, 0.0f)); +		 +		LLBBoxLocal bbox3(LLVector3(-1.0f, -1.0f, -1.0f), LLVector3(1.0f, 2.0f, 0.0f)); +		 +		ensure_equals("Custom bbox extent", bbox3.getExtent(), LLVector3(2.0f, 3.0f, 1.0f)); +	} +	 +	template<> template<> +	void object::test<7>() +	{ +		// +		// test the addPoint() method +		// +		// N.B. if you create an empty bbox and then add points, +		// the vector (0, 0, 0) will always be part of the bbox. +		// (Fixing this would require adding a bool to the class size). +		// +		 +		LLBBoxLocal bbox1; +		bbox1.addPoint(LLVector3(-1.0f, -2.0f, -3.0f)); +		bbox1.addPoint(LLVector3(3.0f, 4.0f, 5.0f)); +		 +		ensure_equals("Custom BBox center (1)", bbox1.getCenter(), LLVector3(1.0f, 1.0f, 1.0f)); +		ensure_equals("Custom BBox min (1)", bbox1.getMin(), LLVector3(-1.0f, -2.0f, -3.0f)); +		ensure_equals("Custom BBox max (1)", bbox1.getMax(), LLVector3(3.0f, 4.0f, 5.0f)); +		 +		bbox1.addPoint(LLVector3(0.0f, 0.0f, 0.0f)); +		bbox1.addPoint(LLVector3(1.0f, 2.0f, 3.0f)); +		bbox1.addPoint(LLVector3(2.0f, 2.0f, 2.0f)); +		 +		ensure_equals("Custom BBox center (2)", bbox1.getCenter(), LLVector3(1.0f, 1.0f, 1.0f)); +		ensure_equals("Custom BBox min (2)", bbox1.getMin(), LLVector3(-1.0f, -2.0f, -3.0f)); +		ensure_equals("Custom BBox max (2)", bbox1.getMax(), LLVector3(3.0f, 4.0f, 5.0f)); +		 +		bbox1.addPoint(LLVector3(5.0f, 5.0f, 5.0f)); +		 +		ensure_equals("Custom BBox center (3)", bbox1.getCenter(), LLVector3(2.0f, 1.5f, 1.0f)); +		ensure_equals("Custom BBox min (3)", bbox1.getMin(), LLVector3(-1.0f, -2.0f, -3.0f)); +		ensure_equals("Custom BBox max (3)", bbox1.getMax(), LLVector3(5.0f, 5.0f, 5.0f)); +	} +		 +	template<> template<> +	void object::test<8>() +	{ +		// +		// test the addBBox() methods +		// +		// N.B. if you create an empty bbox and then add points, +		// the vector (0, 0, 0) will always be part of the bbox. +		// (Fixing this would require adding a bool to the class size). +		// +		 +		LLBBoxLocal bbox2(LLVector3(1.0f, 1.0f, 1.0f), LLVector3(2.0f, 2.0f, 2.0f)); +		bbox2.addBBox(LLBBoxLocal(LLVector3(1.5f, 1.5f, 1.5f), LLVector3(3.0f, 3.0f, 3.0f))); +		 +		ensure_equals("Custom BBox center (4)", bbox2.getCenter(), LLVector3(2.0f, 2.0f, 2.0f)); +		ensure_equals("Custom BBox min (4)", bbox2.getMin(), LLVector3(1.0f, 1.0f, 1.0f)); +		ensure_equals("Custom BBox max (4)", bbox2.getMax(), LLVector3(3.0f, 3.0f, 3.0f)); +		 +		bbox2.addBBox(LLBBoxLocal(LLVector3(-1.0f, -1.0f, -1.0f), LLVector3(0.0f, 0.0f, 0.0f))); +		 +		ensure_equals("Custom BBox center (5)", bbox2.getCenter(), LLVector3(1.0f, 1.0f, 1.0f)); +		ensure_equals("Custom BBox min (5)", bbox2.getMin(), LLVector3(-1.0f, -1.0f, -1.0f)); +		ensure_equals("Custom BBox max (5)", bbox2.getMax(), LLVector3(3.0f, 3.0f, 3.0f)); +	} +	 +	template<> template<> +	void object::test<9>() +	{ +		// +		// test the expand() method +		// +		 +		LLBBoxLocal bbox1; +		bbox1.expand(0.0f); + +		ensure_equals("Zero-expanded Default BBox center", bbox1.getCenter(), LLVector3(0.0f, 0.0f, 0.0f)); + +		LLBBoxLocal bbox2(LLVector3(1.0f, 2.0f, 3.0f), LLVector3(3.0f, 4.0f, 5.0f)); +		bbox2.expand(0.0f); +		 +		ensure_equals("Zero-expanded BBox center", bbox2.getCenter(), LLVector3(2.0f, 3.0f, 4.0f)); +		ensure_equals("Zero-expanded BBox min", bbox2.getMin(), LLVector3(1.0f, 2.0f, 3.0f)); +		ensure_equals("Zero-expanded BBox max", bbox2.getMax(), LLVector3(3.0f, 4.0f, 5.0f)); + +		bbox2.expand(0.5f); + +		ensure_equals("Positive-expanded BBox center", bbox2.getCenter(), LLVector3(2.0f, 3.0f, 4.0f)); +		ensure_equals("Positive-expanded BBox min", bbox2.getMin(), LLVector3(0.5f, 1.5f, 2.5f)); +		ensure_equals("Positive-expanded BBox max", bbox2.getMax(), LLVector3(3.5f, 4.5f, 5.5f)); + +		bbox2.expand(-1.0f); +		 +		ensure_equals("Negative-expanded BBox center", bbox2.getCenter(), LLVector3(2.0f, 3.0f, 4.0f)); +		ensure_equals("Negative-expanded BBox min", bbox2.getMin(), LLVector3(1.5f, 2.5f, 3.5f)); +		ensure_equals("Negative-expanded BBox max", bbox2.getMax(), LLVector3(2.5f, 3.5f, 4.5f));		 +	} +} diff --git a/indra/llmath/tests/llmodularmath_test.cpp b/indra/llmath/tests/llmodularmath_test.cpp new file mode 100644 index 0000000000..a998a95618 --- /dev/null +++ b/indra/llmath/tests/llmodularmath_test.cpp @@ -0,0 +1,82 @@ +/** + * @file modularmath_tut.cpp + * @author babbage + * @date 2008-09 + * @brief llmodularmath tests + * + * $LicenseInfo:firstyear=2007&license=viewergpl$ + *  + * Copyright (c) 2007-2009, Linden Research, Inc. + *  + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab.  Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + *  + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + *  + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + *  + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ +  +#include "linden_common.h" + +#include "../llmodularmath.h" + +#include "../test/lltut.h" + +namespace tut +{ +	struct modularmath_data +	{ +	}; +	typedef test_group<modularmath_data> modularmath_test; +	typedef modularmath_test::object modularmath_object; +	tut::modularmath_test modularmath_testcase("modularmath"); + +	template<> template<> +	void modularmath_object::test<1>() +	{ +		// lhs < rhs +		const U32 lhs = 0x000001; +		const U32 rhs = 0xFFFFFF; +		const U32 width = 24; +		U32 result = LLModularMath::subtract<width>(lhs, rhs);  +		ensure_equals("diff(0x000001, 0xFFFFFF, 24)", result, 2); +	} + +	template<> template<> +	void modularmath_object::test<2>() +	{ +		// lhs > rhs +		const U32 lhs = 0x000002; +		const U32 rhs = 0x000001; +		const U32 width = 24; +		U32 result = LLModularMath::subtract<width>(lhs, rhs);  +		ensure_equals("diff(0x000002, 0x000001, 24)", result, 1); +	} + +	template<> template<> +	void modularmath_object::test<3>() +	{ +		// lhs == rhs +		const U32 lhs = 0xABCDEF; +		const U32 rhs = 0xABCDEF; +		const U32 width = 24; +		U32 result = LLModularMath::subtract<width>(lhs, rhs);  +		ensure_equals("diff(0xABCDEF, 0xABCDEF, 24)", result, 0); +	}	 +} diff --git a/indra/llmath/tests/llquaternion_test.cpp b/indra/llmath/tests/llquaternion_test.cpp new file mode 100644 index 0000000000..bfa475d91b --- /dev/null +++ b/indra/llmath/tests/llquaternion_test.cpp @@ -0,0 +1,666 @@ +/**  + * @file llquaternion_tut.cpp + * @author Adroit + * @date 2007-03 + * @brief Test cases of llquaternion.h + * + * $LicenseInfo:firstyear=2007&license=viewergpl$ + *  + * Copyright (c) 2007-2009, Linden Research, Inc. + *  + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab.  Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + *  + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + *  + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + *  + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "linden_common.h" +#include "../test/lltut.h" + +#include "../llquaternion.h" +#include "../v4math.h" +#include "../v3math.h" +#include "../v3dmath.h" +#include "../m4math.h" +#include "../m3math.h" + +namespace tut +{ +	struct llquat_test +	{ +	}; +	typedef test_group<llquat_test> llquat_test_t; +	typedef llquat_test_t::object llquat_test_object_t; +	tut::llquat_test_t tut_llquat_test("llquat"); + +	//test case for LLQuaternion::LLQuaternion(void) fn. +	template<> template<> +	void llquat_test_object_t::test<1>() +	{ +		LLQuaternion llquat; +		ensure("LLQuaternion::LLQuaternion() failed", 0.f == llquat.mQ[0] && +		 									0.f == llquat.mQ[1] && +		 									0.f == llquat.mQ[2] && +											1.f == llquat.mQ[3]); +	} + +	//test case for explicit LLQuaternion(const LLMatrix4 &mat) fn. +	template<> template<> +	void llquat_test_object_t::test<2>() +	{ +		LLMatrix4 llmat; +		LLVector4 vector1(2.0f, 1.0f, 3.0f, 6.0f); +		LLVector4 vector2(5.0f, 6.0f, 0.0f, 1.0f); +		LLVector4 vector3(2.0f, 1.0f, 2.0f, 9.0f); +		LLVector4 vector4(3.0f, 8.0f, 1.0f, 5.0f); + +		llmat.initRows(vector1, vector2, vector3, vector4); +		ensure("explicit LLQuaternion(const LLMatrix4 &mat) failed", 2.0f == llmat.mMatrix[0][0] && +										 	1.0f == llmat.mMatrix[0][1] && +											3.0f == llmat.mMatrix[0][2] && +											6.0f == llmat.mMatrix[0][3] && +											5.0f == llmat.mMatrix[1][0] && +											6.0f == llmat.mMatrix[1][1] && +											0.0f == llmat.mMatrix[1][2] && +											1.0f == llmat.mMatrix[1][3] && +											2.0f == llmat.mMatrix[2][0] && +											1.0f == llmat.mMatrix[2][1] && +											2.0f == llmat.mMatrix[2][2] && +											9.0f == llmat.mMatrix[2][3] && +											3.0f == llmat.mMatrix[3][0] && +											8.0f == llmat.mMatrix[3][1] && +											1.0f == llmat.mMatrix[3][2] && +											5.0f == llmat.mMatrix[3][3]); +	} +	 +	template<> template<> +	void llquat_test_object_t::test<3>() +	{ +		LLMatrix3 llmat; + +		LLVector3 vect1(3.4028234660000000f , 234.56f, 4234.442234f); +		LLVector3 vect2(741.434f, 23.00034f, 6567.223423f); +		LLVector3 vect3(566.003034f, 12.98705f, 234.764423f); +		llmat.setRows(vect1, vect2, vect3); + +		ensure("LLMatrix3::setRows fn failed.", 3.4028234660000000f == llmat.mMatrix[0][0] && +										234.56f == llmat.mMatrix[0][1] && +										4234.442234f == llmat.mMatrix[0][2] && +										741.434f == llmat.mMatrix[1][0] && +										23.00034f == llmat.mMatrix[1][1] && +										6567.223423f == llmat.mMatrix[1][2] && +										566.003034f == llmat.mMatrix[2][0] && +										12.98705f == llmat.mMatrix[2][1] && +										234.764423f == llmat.mMatrix[2][2]);		 +	} + +	//test case for LLQuaternion(F32 x, F32 y, F32 z, F32 w), setQuatInit() and normQuat() fns. +	template<> template<> +	void llquat_test_object_t::test<4>() +	{ +		F32 x_val = 3.0f; +		F32 y_val = 2.0f; +		F32 z_val = 6.0f; +		F32 w_val = 1.0f; +		 +		LLQuaternion res_quat; +		res_quat.setQuatInit(x_val, y_val, z_val, w_val); +		res_quat.normQuat(); +				 +		ensure("LLQuaternion::normQuat() fn failed",  +							is_approx_equal(0.42426407f, res_quat.mQ[0]) && +							is_approx_equal(0.28284273f, res_quat.mQ[1]) && +							is_approx_equal(0.84852815f, res_quat.mQ[2]) && +							is_approx_equal(0.14142136f, res_quat.mQ[3])); +		 +		x_val = 0.0f; +		y_val = 0.0f; +		z_val = 0.0f; +		w_val = 0.0f; + +		res_quat.setQuatInit(x_val, y_val, z_val, w_val); +		res_quat.normQuat(); + +		ensure("LLQuaternion::normQuat() fn. failed.",  +							is_approx_equal(0.0f, res_quat.mQ[0]) && +							is_approx_equal(0.0f, res_quat.mQ[1]) && +							is_approx_equal(0.0f, res_quat.mQ[2]) && +							is_approx_equal(1.0f, res_quat.mQ[3])); + + +		ensure("LLQuaternion::normQuat() fn. failed.",  +							is_approx_equal(0.0f, res_quat.mQ[0]) && +							is_approx_equal(0.0f, res_quat.mQ[1]) && +							is_approx_equal(0.0f, res_quat.mQ[2]) && +							is_approx_equal(1.0f, res_quat.mQ[3])); +	} + +	//test case for conjQuat() and transQuat() fns. +	template<> template<> +	void llquat_test_object_t::test<5>() +	{ +		F32 x_val = 3.0f; +		F32 y_val = 2.0f; +		F32 z_val = 6.0f; +		F32 w_val = 1.0f; +		 +		LLQuaternion res_quat; +		LLQuaternion result, result1; +		result1 = result = res_quat.setQuatInit(x_val, y_val, z_val, w_val); +				 +		result.conjQuat(); +		result1.transQuat(); + +		ensure("LLQuaternion::conjQuat and LLQuaternion::transQuat failed ",  +								is_approx_equal(result1.mQ[0], result.mQ[0]) && +								is_approx_equal(result1.mQ[1], result.mQ[1]) && +								is_approx_equal(result1.mQ[2], result.mQ[2]));		 + +	} + +	//test case for dot(const LLQuaternion &a, const LLQuaternion &b) fn. +	template<> template<> +	void llquat_test_object_t::test<6>() +	{ +		LLQuaternion quat1(3.0f, 2.0f, 6.0f, 0.0f), quat2(1.0f, 1.0f, 1.0f, 1.0f); +		ensure("1. The two values are different", llround(12.000000f, 2) == llround(dot(quat1, quat2), 2)); + +		LLQuaternion quat0(3.0f, 9.334f, 34.5f, 23.0f), quat(34.5f, 23.23f, 2.0f, 45.5f); +		ensure("2. The two values are different", llround(1435.828807f, 2) == llround(dot(quat0, quat), 2)); +	} + +	//test case for LLQuaternion &LLQuaternion::constrain(F32 radians) fn. +	template<> template<> +	void llquat_test_object_t::test<7>() +	{ +		F32 radian = 60.0f; +		LLQuaternion quat(3.0f, 2.0f, 6.0f, 0.0f); +		LLQuaternion quat1; +		quat1 = quat.constrain(radian); +		ensure("1. LLQuaternion::constrain(F32 radians) failed",  +									is_approx_equal_fraction(-0.423442f, quat1.mQ[0], 8) && +									is_approx_equal_fraction(-0.282295f, quat1.mQ[1], 8) && +									is_approx_equal_fraction(-0.846884f, quat1.mQ[2], 8) &&				 +									is_approx_equal_fraction(0.154251f, quat1.mQ[3], 8));				 +											 + +		radian = 30.0f; +		LLQuaternion quat0(37.50f, 12.0f, 86.023f, 40.32f); +		quat1 = quat0.constrain(radian); +	 +		ensure("2. LLQuaternion::constrain(F32 radians) failed",  +									is_approx_equal_fraction(37.500000f, quat1.mQ[0], 8) && +									is_approx_equal_fraction(12.0000f, quat1.mQ[1], 8) && +									is_approx_equal_fraction(86.0230f, quat1.mQ[2], 8) &&				 +									is_approx_equal_fraction(40.320000f, quat1.mQ[3], 8));				 +	} + +	template<> template<> +	void llquat_test_object_t::test<8>() +	{ +		F32 value1 = 15.0f; +		LLQuaternion quat1(1.0f, 2.0f, 4.0f, 1.0f); +		LLQuaternion quat2(4.0f, 3.0f, 6.5f, 9.7f); +		LLQuaternion res_lerp, res_slerp, res_nlerp; +		 +		//test case for lerp(F32 t, const LLQuaternion &q) fn.  +		res_lerp = lerp(value1, quat1); +		ensure("1. LLQuaternion lerp(F32 t, const LLQuaternion &q) failed",  +										is_approx_equal_fraction(0.181355f, res_lerp.mQ[0], 16) && +										is_approx_equal_fraction(0.362711f, res_lerp.mQ[1], 16) && +										is_approx_equal_fraction(0.725423f, res_lerp.mQ[2], 16) &&				 +										is_approx_equal_fraction(0.556158f, res_lerp.mQ[3], 16));				 + +		//test case for lerp(F32 t, const LLQuaternion &p, const LLQuaternion &q) fn. +		res_lerp = lerp(value1, quat1, quat2); +		ensure("2. LLQuaternion lerp(F32 t, const LLQuaternion &p, const LLQuaternion &q) failed", +										is_approx_equal_fraction(0.314306f, res_lerp.mQ[0], 16) && +										is_approx_equal_fraction(0.116156f, res_lerp.mQ[1], 16) && +										is_approx_equal_fraction(0.283559f, res_lerp.mQ[2], 16) &&				 +										is_approx_equal_fraction(0.898506f, res_lerp.mQ[3], 16));				 + +		//test case for slerp( F32 u, const LLQuaternion &a, const LLQuaternion &b ) fn. +		res_slerp = slerp(value1, quat1, quat2); +		ensure("3. LLQuaternion slerp( F32 u, const LLQuaternion &a, const LLQuaternion &b) failed",  +										is_approx_equal_fraction(46.000f, res_slerp.mQ[0], 16) && +										is_approx_equal_fraction(17.00f, res_slerp.mQ[1], 16) && +										is_approx_equal_fraction(41.5f, res_slerp.mQ[2], 16) &&				 +										is_approx_equal_fraction(131.5f, res_slerp.mQ[3], 16));				 + +		//test case for nlerp(F32 t, const LLQuaternion &a, const LLQuaternion &b) fn. +		res_nlerp = nlerp(value1, quat1, quat2); +		ensure("4. LLQuaternion nlerp(F32 t, const LLQuaternion &a, const LLQuaternion &b) failed",   +										is_approx_equal_fraction(0.314306f, res_nlerp.mQ[0], 16) && +										is_approx_equal_fraction(0.116157f, res_nlerp.mQ[1], 16) && +										is_approx_equal_fraction(0.283559f, res_nlerp.mQ[2], 16) &&				 +										is_approx_equal_fraction(0.898506f, res_nlerp.mQ[3], 16));				 + +		//test case for nlerp(F32 t, const LLQuaternion &q) fn. +		res_slerp = slerp(value1, quat1); +		ensure("5. LLQuaternion slerp(F32 t, const LLQuaternion &q) failed",  +										is_approx_equal_fraction(1.0f, res_slerp.mQ[0], 16) && +										is_approx_equal_fraction(2.0f, res_slerp.mQ[1], 16) && +										is_approx_equal_fraction(4.0000f, res_slerp.mQ[2], 16) &&				 +										is_approx_equal_fraction(1.000f, res_slerp.mQ[3], 16));				 +										 +		LLQuaternion quat3(2.0f, 1.0f, 5.5f, 10.5f); +		LLQuaternion res_nlerp1; +		value1 = 100.0f; +		res_nlerp1 = nlerp(value1, quat3); +		ensure("6. LLQuaternion nlerp(F32 t, const LLQuaternion &q)  failed",  +										is_approx_equal_fraction(0.268245f, res_nlerp1.mQ[0], 16) &&										is_approx_equal_fraction(0.134122f, res_nlerp1.mQ[1], 2) && +										is_approx_equal_fraction(0.737673f, res_nlerp1.mQ[2], 16) &&				 +										is_approx_equal_fraction(0.604892f, res_nlerp1.mQ[3], 16));				 + +		//test case for lerp(F32 t, const LLQuaternion &q) fn.  +		res_lerp = lerp(value1, quat2); +		ensure("7. LLQuaternion lerp(F32 t, const LLQuaternion &q) failed",  +										is_approx_equal_fraction(0.404867f, res_lerp.mQ[0], 16) && +										is_approx_equal_fraction(0.303650f, res_lerp.mQ[1], 16) && +										is_approx_equal_fraction(0.657909f, res_lerp.mQ[2], 16) &&				 +										is_approx_equal_fraction(0.557704f, res_lerp.mQ[3], 16));				 +		 +	} + +	template<> template<> +	void llquat_test_object_t::test<9>() +	{ +		//test case for LLQuaternion operator*(const LLQuaternion &a, const LLQuaternion &b) fn +		LLQuaternion quat1(1.0f, 2.5f, 3.5f, 5.5f); +		LLQuaternion quat2(4.0f, 3.0f, 5.0f, 1.0f); +		LLQuaternion result = quat1 *  quat2; +		ensure("1. LLQuaternion Operator* failed", (21.0f == result.mQ[0]) && +											(10.0f == result.mQ[1]) && +											(38.0f == result.mQ[2]) &&  +											(-23.5f == result.mQ[3])); + +		LLQuaternion quat3(2341.340f, 2352.345f, 233.25f, 7645.5f); +		LLQuaternion quat4(674.067f, 893.0897f, 578.0f, 231.0f); +		result = quat3 * quat4; +		ensure("2. LLQuaternion Operator* failed", (4543086.5f == result.mQ[0]) && +											(8567578.0f == result.mQ[1]) && +											(3967591.25f == result.mQ[2]) && +											is_approx_equal(-2047783.25f, result.mQ[3])); + +		//inline LLQuaternion operator+(const LLQuaternion &a, const LLQuaternion &b)fn.		 +		result = quat1 + quat2; +		ensure("3. LLQuaternion operator+ failed", (5.0f == result.mQ[0]) && +											(5.5f == result.mQ[1]) && +											(8.5f == result.mQ[2]) && +											(6.5f == result.mQ[3])); + +		result = quat3 + quat4; +		ensure( +			"4. LLQuaternion operator+ failed", +			is_approx_equal(3015.407227f, result.mQ[0]) && +			is_approx_equal(3245.434570f, result.mQ[1]) && +			(811.25f == result.mQ[2]) && +			(7876.5f == result.mQ[3])); + +		//inline LLQuaternion operator-(const LLQuaternion &a, const LLQuaternion &b) fn +		result = quat1 - quat2; +		ensure( +			"5. LLQuaternion operator-(const LLQuaternion &a, const LLQuaternion &b) failed",  +			(-3.0f == result.mQ[0]) && +			(-0.5f == result.mQ[1]) && +			(-1.5f == result.mQ[2]) && +			(4.5f == result.mQ[3])); + +		result = quat3 - quat4; +		ensure( +			"6. LLQuaternion operator-(const LLQuaternion &a, const LLQuaternion &b) failed",  +			is_approx_equal(1667.273071f, result.mQ[0]) && +			is_approx_equal(1459.255249f, result.mQ[1]) && +			(-344.75f == result.mQ[2]) && +			(7414.50f == result.mQ[3])); +	} + +	//test case for LLVector4 operator*(const LLVector4 &a, const LLQuaternion &rot) fn. +	template<> template<> +	void llquat_test_object_t::test<10>() +	{ +		LLVector4 vect(12.0f, 5.0f, 60.0f, 75.1f); +		LLQuaternion quat(2323.034f, 23.5f, 673.23f, 57667.5f); +		LLVector4 result = vect * quat; +		ensure( +			"1. LLVector4 operator*(const LLVector4 &a, const LLQuaternion &rot) failed",  +			is_approx_equal(39928406016.0f, result.mV[0]) && +			// gcc on x86 actually gives us more precision than we were expecting, verified with -ffloat-store - we forgive this +			(1457802240.0f >= result.mV[1]) && // gcc+x86+linux +			(1457800960.0f <= result.mV[1]) && // elsewhere +			is_approx_equal(200580612096.0f, result.mV[2]) && +			(75.099998f == result.mV[3])); + +		LLVector4 vect1(22.0f, 45.0f, 40.0f, 78.1f); +		LLQuaternion quat1(2.034f, 45.5f, 37.23f, 7.5f); +		result = vect1 * quat1; +		ensure( +			"2. LLVector4 operator*(const LLVector4 &a, const LLQuaternion &rot) failed",  +			is_approx_equal(-58153.5390f, result.mV[0]) && +			(183787.8125f == result.mV[1]) && +			(116864.164063f == result.mV[2]) && +			(78.099998f == result.mV[3])); +	} + +	//test case for LLVector3 operator*(const LLVector3 &a, const LLQuaternion &rot) fn. +	template<> template<> +	void llquat_test_object_t::test<11>() +	{ +		LLVector3 vect(12.0f, 5.0f, 60.0f); +		LLQuaternion quat(23.5f, 6.5f, 3.23f, 56.5f); +		LLVector3 result = vect * quat; +		ensure( +			"1. LLVector3 operator*(const LLVector3 &a, const LLQuaternion &rot) failed",  +			is_approx_equal(97182.953125f,result.mV[0]) && +			is_approx_equal(-135405.640625f, result.mV[1]) && +			is_approx_equal(162986.140f, result.mV[2])); + +		LLVector3 vect1(5.0f, 40.0f, 78.1f); +		LLQuaternion quat1(2.034f, 45.5f, 37.23f, 7.5f); +		result = vect1 * quat1; +		ensure( +			"2. LLVector3 operator*(const LLVector3 &a, const LLQuaternion &rot) failed",  +			is_approx_equal(33217.703f, result.mV[0]) && +			is_approx_equal(295383.8125f, result.mV[1]) && +			is_approx_equal(84718.140f, result.mV[2])); +	} + +	//test case for LLVector3d operator*(const LLVector3d &a, const LLQuaternion &rot) fn. +	template<> template<> +	void llquat_test_object_t::test<12>() +	{ +		LLVector3d vect(-2.0f, 5.0f, -6.0f); +		LLQuaternion quat(-3.5f, 4.5f, 3.5f, 6.5f); +		LLVector3d result = vect * quat; +		ensure( +			"1. LLVector3d operator*(const LLVector3d &a, const LLQuaternion &rot) failed ",  +			(-633.0f == result.mdV[0]) && +			(-300.0f == result.mdV[1]) && +			(-36.0f == result.mdV[2])); + +		LLVector3d vect1(5.0f, -4.5f, 8.21f); +		LLQuaternion quat1(2.0f, 4.5f, -7.2f, 9.5f); +		result = vect1 * quat1; +		ensure( +			"2. LLVector3d operator*(const LLVector3d &a, const LLQuaternion &rot) failed",  +			is_approx_equal_fraction(-120.29f, (F32) result.mdV[0], 8) && +			is_approx_equal_fraction(-1683.958f, (F32) result.mdV[1], 8) && +			is_approx_equal_fraction(516.56f, (F32) result.mdV[2], 8)); + +		LLVector3d vect2(2.0f, 3.5f, 1.1f); +		LLQuaternion quat2(1.0f, 4.0f, 2.0f, 5.0f); +		result = vect2 * quat2; +		ensure( +			"3. LLVector3d operator*(const LLVector3d &a, const LLQuaternion &rot) failed",  +			is_approx_equal_fraction(18.400001f, (F32) result.mdV[0], 8) && +			is_approx_equal_fraction(188.6f, (F32) result.mdV[1], 8) && +			is_approx_equal_fraction(32.20f, (F32) result.mdV[2], 8)); +	} + +	//test case for inline LLQuaternion operator-(const LLQuaternion &a) fn. +	template<> template<> +	void llquat_test_object_t::test<13>() +	{ +		LLQuaternion quat(23.5f, 34.5f, 16723.4f, 324.7f); +		LLQuaternion result = -quat; +		ensure( +			"1. LLQuaternion operator-(const LLQuaternion &a) failed",  +			(-23.5f == result.mQ[0]) && +			(-34.5f == result.mQ[1]) && +			(-16723.4f == result.mQ[2]) && +			(-324.7f == result.mQ[3])); + +		LLQuaternion quat1(-3.5f, -34.5f, -16.4f, -154.7f); +		result = -quat1; +		ensure( +			"2. LLQuaternion operator-(const LLQuaternion &a) failed.",  +			(3.5f == result.mQ[0]) && +			(34.5f == result.mQ[1]) && +			(16.4f == result.mQ[2]) && +			(154.7f == result.mQ[3])); +	} + +	//test case for inline LLQuaternion operator*(F32 a, const LLQuaternion &q) and +	//inline LLQuaternion operator*(F32 a, const LLQuaternion &q) fns. +	template<> template<> +	void llquat_test_object_t::test<14>() +	{ +		LLQuaternion quat_value(9.0f, 8.0f, 7.0f, 6.0f); +		F32 a =3.5f; +		LLQuaternion result = a * quat_value; +		LLQuaternion result1 = quat_value * a; + +		ensure( +			"1. LLQuaternion operator* failed", +			(result.mQ[0] == result1.mQ[0]) && +			(result.mQ[1] == result1.mQ[1]) && +			(result.mQ[2] == result1.mQ[2]) && +			(result.mQ[3] == result1.mQ[3])); + + +		LLQuaternion quat_val(9454.0f, 43568.3450f, 456343247.0343f, 2346.03434f); +		a =-3324.3445f; +		result = a * quat_val; +		result1 = quat_val * a; + +		ensure( +			"2. LLQuaternion operator* failed", +			(result.mQ[0] == result1.mQ[0]) && +			(result.mQ[1] == result1.mQ[1]) && +			(result.mQ[2] == result1.mQ[2]) && +			(result.mQ[3] == result1.mQ[3])); +	} +	 +	template<> template<> +	void llquat_test_object_t::test<15>() +	{ +		// test cases for inline LLQuaternion operator~(const LLQuaternion &a) +		LLQuaternion quat_val(2323.634f, -43535.4f, 3455.88f, -32232.45f); +		LLQuaternion result = ~quat_val; +		ensure( +			"1. LLQuaternion operator~(const LLQuaternion &a) failed ",  +			(-2323.634f == result.mQ[0]) && +			(43535.4f == result.mQ[1]) && +			(-3455.88f == result.mQ[2]) && +			(-32232.45f == result.mQ[3])); + +		//test case for inline bool LLQuaternion::operator==(const LLQuaternion &b) const +		LLQuaternion quat_val1(2323.634f, -43535.4f, 3455.88f, -32232.45f); +		LLQuaternion quat_val2(2323.634f, -43535.4f, 3455.88f, -32232.45f); +		ensure( +			"2. LLQuaternion::operator==(const LLQuaternion &b) failed", +			quat_val1 == quat_val2); +	} +	 +	template<> template<> +	void llquat_test_object_t::test<16>() +	{ +		//test case for inline bool LLQuaternion::operator!=(const LLQuaternion &b) const +		LLQuaternion quat_val1(2323.634f, -43535.4f, 3455.88f, -32232.45f); +		LLQuaternion quat_val2(0, -43535.4f, 3455.88f, -32232.45f); +		ensure("LLQuaternion::operator!=(const LLQuaternion &b) failed", quat_val1 != quat_val2); +	} + +	template<> template<> +	void llquat_test_object_t::test<17>() +	{ +		//test case for LLQuaternion mayaQ(F32 xRot, F32 yRot, F32 zRot, LLQuaternion::Order order) +		F32 x = 2.0f; +		F32 y = 1.0f; +		F32 z = 3.0f; +		 +		LLQuaternion result = mayaQ(x, y, z, LLQuaternion::XYZ); +		ensure( +			"1. LLQuaternion mayaQ(F32 xRot, F32 yRot, F32 zRot, LLQuaternion::Order order) failed for XYZ", +			is_approx_equal_fraction(0.0172174f, result.mQ[0], 16) && +			is_approx_equal_fraction(0.009179f, result.mQ[1], 16) && +			is_approx_equal_fraction(0.026020f, result.mQ[2], 16) && +			is_approx_equal_fraction(0.999471f, result.mQ[3], 16)); + +		LLQuaternion result1 = mayaQ(x, y, z, LLQuaternion::YZX); +		ensure( +			"2. LLQuaternion mayaQ(F32 xRot, F32 yRot, F32 zRot, LLQuaternion::Order order) failed for XYZ", +			is_approx_equal_fraction(0.017217f, result1.mQ[0], 16) && +			is_approx_equal_fraction(0.008265f, result1.mQ[1], 16) && +			is_approx_equal_fraction(0.026324f, result1.mQ[2], 16) && +			is_approx_equal_fraction(0.999471f, result1.mQ[3], 16)); +		 +		LLQuaternion result2 = mayaQ(x, y, z, LLQuaternion::ZXY); +		ensure( +			"3. LLQuaternion mayaQ(F32 xRot, F32 yRot, F32 zRot, LLQuaternion::Order order) failed for ZXY",  +			is_approx_equal_fraction(0.017674f, result2.mQ[0], 16) && +			is_approx_equal_fraction(0.008265f, result2.mQ[1], 16) && +			is_approx_equal_fraction(0.026020f, result2.mQ[2], 16) && +			is_approx_equal_fraction(0.999471f, result2.mQ[3], 16)); +											 +		LLQuaternion result3 = mayaQ(x, y, z, LLQuaternion::XZY); +		ensure( +			"4. TLLQuaternion mayaQ(F32 xRot, F32 yRot, F32 zRot, LLQuaternion::Order order) failed for XZY",  +			is_approx_equal_fraction(0.017674f, result3.mQ[0], 16) && +			is_approx_equal_fraction(0.009179f, result3.mQ[1], 16) && +			is_approx_equal_fraction(0.026020f, result3.mQ[2], 16) && +			is_approx_equal_fraction(0.999463f, result3.mQ[3], 16)); +											 +		LLQuaternion result4 = mayaQ(x, y, z, LLQuaternion::YXZ); +		ensure( +			"5. LLQuaternion mayaQ(F32 xRot, F32 yRot, F32 zRot, LLQuaternion::Order order) failed for YXZ",  +			is_approx_equal_fraction(0.017217f, result4.mQ[0], 16) && +			is_approx_equal_fraction(0.009179f, result4.mQ[1], 16) && +			is_approx_equal_fraction(0.026324f, result4.mQ[2], 16) && +			is_approx_equal_fraction(0.999463f, result4.mQ[3], 16)); +											 +		LLQuaternion result5 = mayaQ(x, y, z, LLQuaternion::ZYX); +		ensure( +			"6. LLQuaternion mayaQ(F32 xRot, F32 yRot, F32 zRot, LLQuaternion::Order order) failed for ZYX",  +			is_approx_equal_fraction(0.017674f, result5.mQ[0], 16) && +			is_approx_equal_fraction(0.008265f, result5.mQ[1], 16) && +			is_approx_equal_fraction(0.026324f, result5.mQ[2], 16) && +			is_approx_equal_fraction(0.999463f, result5.mQ[3], 16)); +	} + +	template<> template<> +	void llquat_test_object_t::test<18>() +	{ +		// test case for friend std::ostream& operator<<(std::ostream &s, const LLQuaternion &a) fn +		LLQuaternion a(1.0f, 1.0f, 1.0f, 1.0f);  +		std::ostringstream result_value; +		result_value << a; +		ensure_equals("1. Operator << failed", result_value.str(), "{ 1, 1, 1, 1 }"); + +		LLQuaternion b(-31.034f, 231.2340f, 3451.344320f, -341.0f);  +		std::ostringstream result_value1; +		result_value1 << b; +		ensure_equals("2. Operator << failed", result_value1.str(), "{ -31.034, 231.234, 3451.34, -341 }"); + +		LLQuaternion c(1.0f, 2.2f, 3.3f, 4.4f);  +		result_value << c; +		ensure_equals("3. Operator << failed", result_value.str(), "{ 1, 1, 1, 1 }{ 1, 2.2, 3.3, 4.4 }"); + +	} +	 +	template<> template<> +	void llquat_test_object_t::test<19>() +	{ +		//test case for const char *OrderToString( const LLQuaternion::Order order ) fn +		const char* result = OrderToString(LLQuaternion::XYZ); +		ensure("1. OrderToString failed for XYZ",  (0 == strcmp("XYZ", result))); +		 +		result = OrderToString(LLQuaternion::YZX); +		ensure("2. OrderToString failed for YZX",  (0 == strcmp("YZX", result))); +		 +		result = OrderToString(LLQuaternion::ZXY); +		ensure( +			"3. OrderToString failed for ZXY", +			(0 == strcmp("ZXY", result)) && +			(0 != strcmp("XYZ", result)) && +			(0 != strcmp("YXZ", result)) && +			(0 != strcmp("ZYX", result)) && +			(0 != strcmp("XYZ", result))); + +		result = OrderToString(LLQuaternion::XZY); +		ensure("4. OrderToString failed for XZY",  (0 == strcmp("XZY", result))); + +		result = OrderToString(LLQuaternion::ZYX); +		ensure("5. OrderToString failed for ZYX",  (0 == strcmp("ZYX", result))); + +		result = OrderToString(LLQuaternion::YXZ); +		ensure("6.OrderToString failed for YXZ",  (0 == strcmp("YXZ", result))); +	} + +	template<> template<> +	void llquat_test_object_t::test<20>() +	{ +		//test case for LLQuaternion::Order StringToOrder( const char *str ) fn +		int result = StringToOrder("XYZ"); +		ensure("1. LLQuaternion::Order StringToOrder(const char *str ) failed for XYZ", 0 == result); + +		result = StringToOrder("YZX"); +		ensure("2. LLQuaternion::Order StringToOrder(const char *str) failed for YZX", 1 == result); + +		result = StringToOrder("ZXY"); +		ensure("3. LLQuaternion::Order StringToOrder(const char *str) failed for ZXY", 2 == result); +		 +		result = StringToOrder("XZY"); +		ensure("4. LLQuaternion::Order StringToOrder(const char *str) failed for XZY", 3 == result); + +		result = StringToOrder("YXZ"); +		ensure("5. LLQuaternion::Order StringToOrder(const char *str) failed for YXZ", 4 == result); +	 +		result = StringToOrder("ZYX"); +		ensure("6. LLQuaternion::Order StringToOrder(const char *str) failed for  ZYX", 5 == result);	 + +	} + +	template<> template<> +	void llquat_test_object_t::test<21>() +	{ +		//void LLQuaternion::getAngleAxis(F32* angle, LLVector3 &vec) const fn +		F32 angle_value = 90.0f; +		LLVector3 vect(12.0f, 4.0f, 1.0f); +		LLQuaternion llquat(angle_value, vect); +		llquat.getAngleAxis(&angle_value, vect);  +		ensure( +			"LLQuaternion::getAngleAxis(F32* angle, LLVector3 &vec) failed",  +			is_approx_equal_fraction(2.035406f, angle_value, 16) && +			is_approx_equal_fraction(0.315244f, vect.mV[1], 16) && +			is_approx_equal_fraction(0.078811f, vect.mV[2], 16) && +			is_approx_equal_fraction(0.945733f, vect.mV[0], 16)); +	} + +	template<> template<> +	void llquat_test_object_t::test<22>() +	{ +		//test case for void LLQuaternion::getEulerAngles(F32 *roll, F32 *pitch, F32 *yaw) const fn +		F32 roll = -12.0f; +		F32 pitch = -22.43f; +		F32 yaw = 11.0f; + +		LLQuaternion llquat; +		llquat.getEulerAngles(&roll, &pitch, &yaw); +		ensure( +			"LLQuaternion::getEulerAngles(F32 *roll, F32 *pitch, F32 *yaw) failed", +			is_approx_equal(0.000f, llquat.mQ[0]) && +			is_approx_equal(0.000f, llquat.mQ[1]) && +			is_approx_equal(0.000f, llquat.mQ[2]) && +			is_approx_equal(1.000f, llquat.mQ[3])); +	} + +} diff --git a/indra/llmath/tests/llrect_test.cpp b/indra/llmath/tests/llrect_test.cpp new file mode 100644 index 0000000000..26a1163b5f --- /dev/null +++ b/indra/llmath/tests/llrect_test.cpp @@ -0,0 +1,532 @@ +/** + * @file   llrect_tut.cpp + * @author Martin Reddy + * @date   2009-06-25 + * @brief  Test for llrect.cpp. + *  + * $LicenseInfo:firstyear=2009&license=viewergpl$ + * + * Copyright (c) 2009-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab.  Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "linden_common.h" +#include "../test/lltut.h" +#include "../llrect.h" + +namespace tut +{ +	struct LLRectData +	{ +	}; + +	typedef test_group<LLRectData> factory; +	typedef factory::object object; +} + +namespace +{ +	tut::factory llrect_test_factory("LLRect"); +} + +namespace tut +{ +	template<> template<> +	void object::test<1>() +	{	 +		// +		// test the LLRect default constructor +		// +		 +		LLSD zero; +		zero.append(0);	zero.append(0); zero.append(0); zero.append(0); +		 +		// default constructor +		LLRect rect1; +		ensure_equals("Empty rect", rect1.getValue(), zero); +		ensure_equals("Empty rect left", rect1.mLeft, 0); +		ensure_equals("Empty rect top", rect1.mTop, 0); +		ensure_equals("Empty rect right", rect1.mRight, 0); +		ensure_equals("Empty rect bottom", rect1.mBottom, 0); +		ensure_equals("Empty rect width", rect1.getWidth(), 0); +		ensure_equals("Empty rect height", rect1.getHeight(), 0); +		ensure_equals("Empty rect centerx", rect1.getCenterX(), 0); +		ensure_equals("Empty rect centery", rect1.getCenterY(), 0); +	} +	 +	template<> template<> +	void object::test<2>() +	{	 +		// +		// test the LLRectf default constructor +		// +		 +		LLSD zerof; +		zerof.append(0.0f); zerof.append(0.0f); zerof.append(0.0f); zerof.append(0.0f); + +		LLRectf rect2; +		ensure_equals("Empty rectf", rect2.getValue(), zerof); +		ensure_equals("Empty rectf left", rect2.mLeft, 0.0f); +		ensure_equals("Empty rectf top", rect2.mTop, 0.0f); +		ensure_equals("Empty rectf right", rect2.mRight, 0.0f); +		ensure_equals("Empty rectf bottom", rect2.mBottom, 0.0f); +		ensure_equals("Empty rectf width", rect2.getWidth(), 0.0f); +		ensure_equals("Empty rectf height", rect2.getHeight(), 0.0f); +		ensure_equals("Empty rectf centerx", rect2.getCenterX(), 0.0f); +		ensure_equals("Empty rectf centery", rect2.getCenterY(), 0.0f); +	} + +	template<> template<> +	void object::test<3>() +	{	 +		// +		// test the LLRect constructor from another LLRect +		//	 +		 +		LLRect rect3(LLRect(1, 6, 7, 2)); +		ensure_equals("Default rect left", rect3.mLeft, 1); +		ensure_equals("Default rect top", rect3.mTop, 6); +		ensure_equals("Default rect right", rect3.mRight, 7); +		ensure_equals("Default rect bottom", rect3.mBottom, 2); +		ensure_equals("Default rect width", rect3.getWidth(), 6); +		ensure_equals("Default rect height", rect3.getHeight(), 4); +		ensure_equals("Default rect centerx", rect3.getCenterX(), 4); +		ensure_equals("Default rect centery", rect3.getCenterY(), 4); +	} + +	template<> template<> +	void object::test<4>() +	{	 +		// +		// test the LLRectf four-float constructor +		//	 +		 +		LLRectf rect4(1.0f, 5.0f, 6.0f, 2.0f); +		ensure_equals("Default rectf left", rect4.mLeft, 1.0f); +		ensure_equals("Default rectf top", rect4.mTop, 5.0f); +		ensure_equals("Default rectf right", rect4.mRight, 6.0f); +		ensure_equals("Default rectf bottom", rect4.mBottom, 2.0f); +		ensure_equals("Default rectf width", rect4.getWidth(), 5.0f); +		ensure_equals("Default rectf height", rect4.getHeight(), 3.0f); +		ensure_equals("Default rectf centerx", rect4.getCenterX(), 3.5f); +		ensure_equals("Default rectf centery", rect4.getCenterY(), 3.5f); +	} + +	template<> template<> +	void object::test<5>() +	{	 +		// +		// test the LLRectf LLSD constructor +		// + +		LLSD array; +		array.append(-1.0f); array.append(0.0f); array.append(0.0f); array.append(-1.0f); +		LLRectf rect5(array); +		ensure_equals("LLSD rectf left", rect5.mLeft, -1.0f); +		ensure_equals("LLSD rectf top", rect5.mTop, 0.0f); +		ensure_equals("LLSD rectf right", rect5.mRight, 0.0f); +		ensure_equals("LLSD rectf bottom", rect5.mBottom, -1.0f); +		ensure_equals("LLSD rectf width", rect5.getWidth(), 1.0f); +		ensure_equals("LLSD rectf height", rect5.getHeight(), 1.0f); +		ensure_equals("LLSD rectf centerx", rect5.getCenterX(), -0.5f); +		ensure_equals("LLSD rectf centery", rect5.getCenterY(), -0.5f);		 +	} +	 +	template<> template<> +	void object::test<6>() +	{	 +		// +		// test directly setting the member variables for dimensions +		// +		 +		LLRectf rectf; + +		rectf.mLeft = -1.0f; +		rectf.mTop = 1.0f; +		rectf.mRight = 1.0f; +		rectf.mBottom = -1.0f; +		ensure_equals("Member-set rectf left", rectf.mLeft, -1.0f); +		ensure_equals("Member-set rectf top", rectf.mTop, 1.0f); +		ensure_equals("Member-set rectf right", rectf.mRight, 1.0f); +		ensure_equals("Member-set rectf bottom", rectf.mBottom, -1.0f); +		ensure_equals("Member-set rectf width", rectf.getWidth(), 2.0f); +		ensure_equals("Member-set rectf height", rectf.getHeight(), 2.0f); +		ensure_equals("Member-set rectf centerx", rectf.getCenterX(), 0.0f); +		ensure_equals("Member-set rectf centery", rectf.getCenterY(), 0.0f); +	} +		 +	template<> template<> +	void object::test<7>() +	{	 +		// +		// test the setValue() method +		// +			 +		LLRectf rectf; +		 +		LLSD array; +		array.append(-1.0f); array.append(0.0f); array.append(0.0f); array.append(-1.0f); +		rectf.setValue(array); +		ensure_equals("setValue() rectf left", rectf.mLeft, -1.0f); +		ensure_equals("setValue() rectf top", rectf.mTop, 0.0f); +		ensure_equals("setValue() rectf right", rectf.mRight, 0.0f); +		ensure_equals("setValue() rectf bottom", rectf.mBottom, -1.0f); +		ensure_equals("setValue() rectf width", rectf.getWidth(), 1.0f); +		ensure_equals("setValue() rectf height", rectf.getHeight(), 1.0f); +		ensure_equals("setValue() rectf centerx", rectf.getCenterX(), -0.5f); +		ensure_equals("setValue() rectf centery", rectf.getCenterY(), -0.5f); +	} +		 +	template<> template<> +	void object::test<8>() +	{	 +		// +		// test the set() method +		// +		 +		LLRect rect; +		 +		rect.set(10, 90, 70, 10); +		ensure_equals("set() rectf left", rect.mLeft, 10); +		ensure_equals("set() rectf top", rect.mTop, 90); +		ensure_equals("set() rectf right", rect.mRight, 70); +		ensure_equals("set() rectf bottom", rect.mBottom, 10); +		ensure_equals("set() rectf width", rect.getWidth(), 60); +		ensure_equals("set() rectf height", rect.getHeight(), 80); +		ensure_equals("set() rectf centerx", rect.getCenterX(), 40); +		ensure_equals("set() rectf centery", rect.getCenterY(), 50); +	} + +	template<> template<> +	void object::test<9>() +	{	 +		// +		// test the setOriginAndSize() method +		// +		 +		LLRectf rectf; +		 +		rectf.setOriginAndSize(0.0f, 0.0f, 2.0f, 1.0f); +		ensure_equals("setOriginAndSize() rectf left", rectf.mLeft, 0.0f); +		ensure_equals("setOriginAndSize() rectf top", rectf.mTop, 1.0f); +		ensure_equals("setOriginAndSize() rectf right", rectf.mRight, 2.0f); +		ensure_equals("setOriginAndSize() rectf bottom", rectf.mBottom, 0.0f); +		ensure_equals("setOriginAndSize() rectf width", rectf.getWidth(), 2.0f); +		ensure_equals("setOriginAndSize() rectf height", rectf.getHeight(), 1.0f); +		ensure_equals("setOriginAndSize() rectf centerx", rectf.getCenterX(), 1.0f); +		ensure_equals("setOriginAndSize() rectf centery", rectf.getCenterY(), 0.5f);	 +	} +	 +	template<> template<> +	void object::test<10>() +	{	 +		// +		// test the setLeftTopAndSize() method +		// +		 +		LLRectf rectf; + +		rectf.setLeftTopAndSize(0.0f, 0.0f, 2.0f, 1.0f); +		ensure_equals("setLeftTopAndSize() rectf left", rectf.mLeft, 0.0f); +		ensure_equals("setLeftTopAndSize() rectf top", rectf.mTop, 0.0f); +		ensure_equals("setLeftTopAndSize() rectf right", rectf.mRight, 2.0f); +		ensure_equals("setLeftTopAndSize() rectf bottom", rectf.mBottom, -1.0f); +		ensure_equals("setLeftTopAndSize() rectf width", rectf.getWidth(), 2.0f); +		ensure_equals("setLeftTopAndSize() rectf height", rectf.getHeight(), 1.0f); +		ensure_equals("setLeftTopAndSize() rectf centerx", rectf.getCenterX(), 1.0f); +		ensure_equals("setLeftTopAndSize() rectf centery", rectf.getCenterY(), -0.5f); +	} + +	template<> template<> +	void object::test<11>() +	{	 +		// +		// test the setCenterAndSize() method +		// +		 +		LLRectf rectf; +		 +		rectf.setCenterAndSize(0.0f, 0.0f, 2.0f, 1.0f); +		ensure_equals("setCenterAndSize() rectf left", rectf.mLeft, -1.0f); +		ensure_equals("setCenterAndSize() rectf top", rectf.mTop, 0.5f); +		ensure_equals("setCenterAndSize() rectf right", rectf.mRight, 1.0f); +		ensure_equals("setCenterAndSize() rectf bottom", rectf.mBottom, -0.5f); +		ensure_equals("setCenterAndSize() rectf width", rectf.getWidth(), 2.0f); +		ensure_equals("setCenterAndSize() rectf height", rectf.getHeight(), 1.0f); +		ensure_equals("setCenterAndSize() rectf centerx", rectf.getCenterX(), 0.0f); +		ensure_equals("setCenterAndSize() rectf centery", rectf.getCenterY(), 0.0f); +	} + +	template<> template<> +	void object::test<12>() +	{	 +		// +		// test the validity checking method +		// +		 +		LLRectf rectf; + +		rectf.set(-1.0f, 1.0f, 1.0f, -1.0f); +		ensure("BBox is valid", rectf.isValid()); + +		rectf.mLeft = 2.0f; +		ensure("BBox is not valid", ! rectf.isValid()); + +		rectf.makeValid(); +		ensure("BBox forced valid", rectf.isValid()); + +		rectf.set(-1.0f, -1.0f, -1.0f, -1.0f); +		ensure("BBox(0,0,0,0) is valid", rectf.isValid()); +	} + +	template<> template<> +	void object::test<13>() +	{	 +		// +		// test the null checking methods +		// +		 +		LLRectf rectf; +		 +		rectf.set(-1.0f, 1.0f, 1.0f, -1.0f); +		ensure("BBox is not Null", ! rectf.isEmpty()); +		ensure("BBox notNull", rectf.notEmpty()); +		 +		rectf.mLeft = 2.0f; +		rectf.makeValid(); +		ensure("BBox is now Null", rectf.isEmpty()); +		 +		rectf.set(-1.0f, -1.0f, -1.0f, -1.0f); +		ensure("BBox(0,0,0,0) is Null", rectf.isEmpty()); +	} +		 +	template<> template<> +	void object::test<14>() +	{	 +		// +		// test the (in)equality operators +		// +		 +		LLRectf rect1, rect2; + +		rect1.set(-1.0f, 1.0f, 1.0f, -1.0f); +		rect2.set(-1.0f, 0.9f, 1.0f, -1.0f); + +		ensure("rect1 == rect2 (false)", ! (rect1 == rect2)); +		ensure("rect1 != rect2 (true)", rect1 != rect2); + +		ensure("rect1 == rect1 (true)", rect1 == rect1); +		ensure("rect1 != rect1 (false)", ! (rect1 != rect1)); +	} +	 +	template<> template<> +	void object::test<15>() +	{	 +		// +		// test the copy constructor +		// +		 +		LLRectf rect1, rect2(rect1); + +		ensure("rect1 == rect2 (true)", rect1 == rect2); +		ensure("rect1 != rect2 (false)", ! (rect1 != rect2)); +	} + +	template<> template<> +	void object::test<16>() +	{	 +		// +		// test the translate() method +		// +		 +		LLRectf rect1(-1.0f, 1.0f, 1.0f, -1.0f); +		LLRectf rect2(rect1); + +		rect1.translate(0.0f, 0.0f); + +		ensure("translate(0, 0)", rect1 == rect2); + +		rect1.translate(100.0f, 100.0f); +		rect1.translate(-100.0f, -100.0f); + +		ensure("translate(100, 100) + translate(-100, -100)", rect1 == rect2); + +		rect1.translate(10.0f, 0.0f); +		rect2.set(9.0f, 1.0f, 11.0f, -1.0f); +		ensure("translate(10, 0)", rect1 == rect2); + +		rect1.translate(0.0f, 10.0f); +		rect2.set(9.0f, 11.0f, 11.0f, 9.0f); +		ensure("translate(0, 10)", rect1 == rect2); + +		rect1.translate(-10.0f, -10.0f); +		rect2.set(-1.0f, 1.0f, 1.0f, -1.0f); +		ensure("translate(-10, -10)", rect1 == rect2); +	} + +	template<> template<> +	void object::test<17>() +	{	 +		// +		// test the stretch() method +		// +		 +		LLRectf rect1(-1.0f, 1.0f, 1.0f, -1.0f); +		LLRectf rect2(rect1); +		 +		rect1.stretch(0.0f); +		ensure("stretch(0)", rect1 == rect2); +		 +		rect1.stretch(0.0f, 0.0f); +		ensure("stretch(0, 0)", rect1 == rect2); +		 +		rect1.stretch(10.0f); +		rect1.stretch(-10.0f); +		ensure("stretch(10) + stretch(-10)", rect1 == rect2); +		 +		rect1.stretch(2.0f, 1.0f); +		rect2.set(-3.0f, 2.0f, 3.0f, -2.0f); +		ensure("stretch(2, 1)", rect1 == rect2); +	} +	 +	 +	template<> template<> +	void object::test<18>() +	{	 +		// +		// test the unionWith() method +		// +		 +		LLRectf rect1, rect2, rect3; + +		rect1.set(-1.0f, 1.0f, 1.0f, -1.0f); +		rect2.set(-1.0f, 1.0f, 1.0f, -1.0f); +		rect3 = rect1; +		rect3.unionWith(rect2); +		ensure_equals("union with self", rect3, rect1); + +		rect1.set(-1.0f, 1.0f, 1.0f, -1.0f); +		rect2.set(-2.0f, 2.0f, 0.0f, 0.0f); +		rect3 = rect1; +		rect3.unionWith(rect2); +		ensure_equals("union - overlap", rect3, LLRectf(-2.0f, 2.0f, 1.0f, -1.0f)); +		 +		rect1.set(-1.0f, 1.0f, 1.0f, -1.0f); +		rect2.set(5.0f, 10.0f, 10.0f, 5.0f); +		rect3 = rect1; +		rect3.unionWith(rect2); +		ensure_equals("union - no overlap", rect3, LLRectf(-1.0f, 10.0f, 10.0f, -1.0f)); +	} + +	template<> template<> +	void object::test<19>() +	{	 +		// +		// test the intersectWith() methods +		// +		 +		LLRectf rect1, rect2, rect3; +		 +		rect1.set(-1.0f, 1.0f, 1.0f, -1.0f); +		rect2.set(-1.0f, 1.0f, 1.0f, -1.0f); +		rect3 = rect1; +		rect3.intersectWith(rect2); +		ensure_equals("intersect with self", rect3, rect1); +		 +		rect1.set(-1.0f, 1.0f, 1.0f, -1.0f); +		rect2.set(-2.0f, 2.0f, 0.0f, 0.0f); +		rect3 = rect1; +		rect3.intersectWith(rect2); +		ensure_equals("intersect - overlap", rect3, LLRectf(-1.0f, 1.0f, 0.0f, 0.0f)); +		 +		rect1.set(-1.0f, 1.0f, 1.0f, -1.0f); +		rect2.set(5.0f, 10.0f, 10.0f, 5.0f); +		rect3 = rect1; +		rect3.intersectWith(rect2); +		ensure("intersect - no overlap", rect3.isEmpty()); +	} +		 +	template<> template<> +	void object::test<20>() +	{ +		// +		// test the pointInRect() method +		// +		 +		LLRectf rect(1.0f, 3.0f, 3.0f, 1.0f); + +		ensure("(0,0) not in rect", rect.pointInRect(0.0f, 0.0f) == FALSE); +		ensure("(2,2) in rect", rect.pointInRect(2.0f, 2.0f) == TRUE); +		ensure("(1,1) in rect", rect.pointInRect(1.0f, 1.0f) == TRUE); +		ensure("(3,3) not in rect", rect.pointInRect(3.0f, 3.0f) == FALSE); +		ensure("(2.999,2.999) in rect", rect.pointInRect(2.999f, 2.999f) == TRUE); +		ensure("(2.999,3.0) not in rect", rect.pointInRect(2.999f, 3.0f) == FALSE); +		ensure("(3.0,2.999) not in rect", rect.pointInRect(3.0f, 2.999f) == FALSE); +	} + +	template<> template<> +	void object::test<21>() +	{ +		// +		// test the localPointInRect() method +		// +		 +		LLRectf rect(1.0f, 3.0f, 3.0f, 1.0f); +		 +		ensure("(0,0) in local rect", rect.localPointInRect(0.0f, 0.0f) == TRUE); +		ensure("(-0.0001,-0.0001) not in local rect", rect.localPointInRect(-0.0001f, -0.001f) == FALSE); +		ensure("(1,1) in local rect", rect.localPointInRect(1.0f, 1.0f) == TRUE); +		ensure("(2,2) not in local rect", rect.localPointInRect(2.0f, 2.0f) == FALSE); +		ensure("(1.999,1.999) in local rect", rect.localPointInRect(1.999f, 1.999f) == TRUE); +		ensure("(1.999,2.0) not in local rect", rect.localPointInRect(1.999f, 2.0f) == FALSE); +		ensure("(2.0,1.999) not in local rect", rect.localPointInRect(2.0f, 1.999f) == FALSE); +	} +	 +	template<> template<> +	void object::test<22>() +	{ +		// +		// test the clampPointToRect() method +		// + +		LLRectf rect(1.0f, 3.0f, 3.0f, 1.0f); +		F32 x, y; + +		x = 2.0f; y = 2.0f; +		rect.clampPointToRect(x, y); +		ensure_equals("clamp x-coord within rect", x, 2.0f); +		ensure_equals("clamp y-coord within rect", y, 2.0f); + +		x = -100.0f; y = 100.0f; +		rect.clampPointToRect(x, y); +		ensure_equals("clamp x-coord outside rect", x, 1.0f); +		ensure_equals("clamp y-coord outside rect", y, 3.0f); + +		x = 3.0f; y = 1.0f; +		rect.clampPointToRect(x, y); +		ensure_equals("clamp x-coord edge rect", x, 3.0f); +		ensure_equals("clamp y-coord edge rect", y, 1.0f); +	} +} diff --git a/indra/llmath/tests/m3math_test.cpp b/indra/llmath/tests/m3math_test.cpp new file mode 100644 index 0000000000..83ca5768df --- /dev/null +++ b/indra/llmath/tests/m3math_test.cpp @@ -0,0 +1,327 @@ +/**  + * @file m3math_test.cpp + * @author Adroit + * @date 2007-03 + * @brief Test cases of m3math.h + * + * $LicenseInfo:firstyear=2007&license=viewergpl$ + *  + * Copyright (c) 2007-2009, Linden Research, Inc. + *  + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab.  Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + *  + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + *  + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + *  + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "linden_common.h" + +#include "../m3math.h" +#include "../v3math.h" +#include "../v4math.h" +#include "../m4math.h" +#include "../llquaternion.h" +#include "../v3dmath.h" + +#include "../test/lltut.h" + +namespace tut +{ +	struct m3math_test +	{ +	}; +	typedef test_group<m3math_test> m3math_test_t; +	typedef m3math_test_t::object m3math_test_object_t; +	tut::m3math_test_t tut_m3math_test("m3math_test"); + +	//test case for setIdentity() fn. +	template<> template<> +	void m3math_test_object_t::test<1>() +	{ +		LLMatrix3 llmat3_obj; +		llmat3_obj.setIdentity(); +		ensure("LLMatrix3::setIdentity failed", 1.f == llmat3_obj.mMatrix[0][0] && +					0.f == llmat3_obj.mMatrix[0][1] && +					0.f == llmat3_obj.mMatrix[0][2] && +					0.f == llmat3_obj.mMatrix[1][0] && +					1.f == llmat3_obj.mMatrix[1][1] && +					0.f == llmat3_obj.mMatrix[1][2] && +					0.f == llmat3_obj.mMatrix[2][0] && +					0.f == llmat3_obj.mMatrix[2][1] && +					1.f == llmat3_obj.mMatrix[2][2]); +	} + +	//test case for LLMatrix3& setZero() fn. +	template<> template<> +	void m3math_test_object_t::test<2>() +	{ +		LLMatrix3 llmat3_obj(30, 1, 2, 3); +		llmat3_obj.setZero(); + +		ensure("LLMatrix3::setZero failed", 0.f == llmat3_obj.setZero().mMatrix[0][0] && +					0.f == llmat3_obj.setZero().mMatrix[0][1] && +					0.f == llmat3_obj.setZero().mMatrix[0][2] && +					0.f == llmat3_obj.setZero().mMatrix[1][0] && +					0.f == llmat3_obj.setZero().mMatrix[1][1] && +					0.f == llmat3_obj.setZero().mMatrix[1][2] && +					0.f == llmat3_obj.setZero().mMatrix[2][0] && +					0.f == llmat3_obj.setZero().mMatrix[2][1] && +					0.f == llmat3_obj.setZero().mMatrix[2][2]); +	} + +	//test case for setRows(const LLVector3 &x_axis, const LLVector3 &y_axis, const LLVector3 &z_axis) fns. +	template<> template<> +	void m3math_test_object_t::test<3>() +	{ +		LLMatrix3 llmat3_obj; +		LLVector3 vect1(2, 1, 4); +		LLVector3 vect2(3, 5, 7); +		LLVector3 vect3(6, 9, 7); +		llmat3_obj.setRows(vect1, vect2, vect3); +		ensure("LLVector3::setRows failed ", 2 == llmat3_obj.mMatrix[0][0] && +						1 == llmat3_obj.mMatrix[0][1] && +						4 == llmat3_obj.mMatrix[0][2] && +						3 == llmat3_obj.mMatrix[1][0] && +						5 == llmat3_obj.mMatrix[1][1] && +						7 == llmat3_obj.mMatrix[1][2] && +						6 == llmat3_obj.mMatrix[2][0] && +						9 == llmat3_obj.mMatrix[2][1] && +						7 == llmat3_obj.mMatrix[2][2]); +	} + +	//test case for getFwdRow(), getLeftRow(), getUpRow() fns. +	template<> template<> +	void m3math_test_object_t::test<4>() +	{ +		LLMatrix3 llmat3_obj; +		LLVector3 vect1(2, 1, 4); +		LLVector3 vect2(3, 5, 7); +		LLVector3 vect3(6, 9, 7); +		llmat3_obj.setRows(vect1, vect2, vect3); +		 +		ensure("LLVector3::getFwdRow failed ", vect1 == llmat3_obj.getFwdRow()); +		ensure("LLVector3::getLeftRow failed ", vect2 == llmat3_obj.getLeftRow()); +		ensure("LLVector3::getUpRow failed ", vect3 == llmat3_obj.getUpRow()); +	} + +	//test case for operator*(const LLMatrix3 &a, const LLMatrix3 &b) +	template<> template<> +	void m3math_test_object_t::test<5>() +	{ +		LLMatrix3 llmat_obj1; +		LLMatrix3 llmat_obj2;		 +		LLMatrix3 llmat_obj3; +		 +		LLVector3 llvec1(1, 3, 5); +		LLVector3 llvec2(3, 6, 1); +		LLVector3 llvec3(4, 6, 9); + +		LLVector3 llvec4(1, 1, 5); +		LLVector3 llvec5(3, 6, 8); +		LLVector3 llvec6(8, 6, 2); + +		LLVector3 llvec7(0, 0, 0); +		LLVector3 llvec8(0, 0, 0); +		LLVector3 llvec9(0, 0, 0); +		 +		llmat_obj1.setRows(llvec1, llvec2, llvec3); +		llmat_obj2.setRows(llvec4, llvec5, llvec6); +		llmat_obj3.setRows(llvec7, llvec8, llvec9); +		llmat_obj3 = llmat_obj1 * llmat_obj2; +		ensure("LLMatrix3::operator*(const LLMatrix3 &a, const LLMatrix3 &b) failed",  +						50 == llmat_obj3.mMatrix[0][0] && +						49 == llmat_obj3.mMatrix[0][1] && +						39 == llmat_obj3.mMatrix[0][2] && +						29 == llmat_obj3.mMatrix[1][0] && +						45 == llmat_obj3.mMatrix[1][1] && +						65 == llmat_obj3.mMatrix[1][2] && +						94 == llmat_obj3.mMatrix[2][0] && +						94 == llmat_obj3.mMatrix[2][1] && +						86 == llmat_obj3.mMatrix[2][2]); +	} + + +	//test case for operator*(const LLVector3 &a, const LLMatrix3 &b) +	template<> template<> +	void m3math_test_object_t::test<6>() +	{ +				 +		LLMatrix3 llmat_obj1; +		 +		LLVector3 llvec(1, 3, 5); +		LLVector3 res_vec(0, 0, 0); +		LLVector3 llvec1(1, 3, 5); +		LLVector3 llvec2(3, 6, 1); +		LLVector3 llvec3(4, 6, 9); +		 +		llmat_obj1.setRows(llvec1, llvec2, llvec3); +		res_vec = llvec * llmat_obj1; + +		LLVector3 expected_result(30, 51, 53); + +		ensure("LLMatrix3::operator*(const LLVector3 &a, const LLMatrix3 &b) failed", res_vec == expected_result); +	} + +	//test case for operator*(const LLVector3d &a, const LLMatrix3 &b)  +	template<> template<> +	void m3math_test_object_t::test<7>() +	{ +		LLMatrix3 llmat_obj1; +		LLVector3d llvec3d1;		 +		LLVector3d llvec3d2(0, 3, 4); + +		LLVector3 llvec1(1, 3, 5); +		LLVector3 llvec2(3, 2, 1); +		LLVector3 llvec3(4, 6, 0); +		 +		llmat_obj1.setRows(llvec1, llvec2, llvec3); +		llvec3d1 = llvec3d2 * llmat_obj1; + +		LLVector3d expected_result(25, 30, 3); +		 +		ensure("LLMatrix3::operator*(const LLVector3 &a, const LLMatrix3 &b) failed", llvec3d1 == expected_result); +	} + +	// test case for operator==(const LLMatrix3 &a, const LLMatrix3 &b) +	template<> template<> +	void m3math_test_object_t::test<8>() +	{ +		LLMatrix3 llmat_obj1; +		LLMatrix3 llmat_obj2;		 +		 +		LLVector3 llvec1(1, 3, 5); +		LLVector3 llvec2(3, 6, 1); +		LLVector3 llvec3(4, 6, 9); + +		llmat_obj1.setRows(llvec1, llvec2, llvec3); +		llmat_obj2.setRows(llvec1, llvec2, llvec3); +		ensure("LLMatrix3::operator==(const LLMatrix3 &a, const LLMatrix3 &b) failed", llmat_obj1 == llmat_obj2); + +		llmat_obj2.setRows(llvec2, llvec2, llvec3); +		ensure("LLMatrix3::operator!=(const LLMatrix3 &a, const LLMatrix3 &b) failed", llmat_obj1 != llmat_obj2); +	} + +	//test case for quaternion() fn. +	template<> template<> +	void m3math_test_object_t::test<9>() +	{ +		LLMatrix3 llmat_obj1; +		LLQuaternion llmat_quat;		 +		 +		LLVector3 llmat1(2.0f, 1.0f, 6.0f); +		LLVector3 llmat2(1.0f, 1.0f, 3.0f); +		LLVector3 llmat3(1.0f, 7.0f, 5.0f); + +		llmat_obj1.setRows(llmat1, llmat2, llmat3); +		llmat_quat = llmat_obj1.quaternion(); +		ensure("LLMatrix3::quaternion failed ", is_approx_equal(-0.66666669f, llmat_quat.mQ[0]) && +						is_approx_equal(-0.83333337f, llmat_quat.mQ[1]) && +						is_approx_equal(0.0f, llmat_quat.mQ[2]) && +						is_approx_equal(1.5f, llmat_quat.mQ[3])); +	} + +	//test case for transpose() fn. +	template<> template<> +	void m3math_test_object_t::test<10>() +	{ +		LLMatrix3 llmat_obj; +	 +		LLVector3 llvec1(1, 2, 3); +		LLVector3 llvec2(3, 2, 1); +		LLVector3 llvec3(2, 2, 2); + +		llmat_obj.setRows(llvec1, llvec2, llvec3); +		llmat_obj.transpose(); + +		LLVector3 resllvec1(1, 3, 2); +		LLVector3 resllvec2(2, 2, 2); +		LLVector3 resllvec3(3, 1, 2); +		LLMatrix3 expectedllmat_obj; +		expectedllmat_obj.setRows(resllvec1, resllvec2, resllvec3); + +		ensure("LLMatrix3::transpose failed ", llmat_obj == expectedllmat_obj); +	} +	 +	//test case for determinant() fn. +	template<> template<> +	void m3math_test_object_t::test<11>() +	{ +		LLMatrix3 llmat_obj1; +		 +		LLVector3 llvec1(1, 2, 3); +		LLVector3 llvec2(3, 2, 1); +		LLVector3 llvec3(2, 2, 2); +		llmat_obj1.setRows(llvec1, llvec2, llvec3); +		ensure("LLMatrix3::determinant failed ",  0.0f == llmat_obj1.determinant()); +	} + +	//test case for orthogonalize() fn. +	template<> template<> +	void m3math_test_object_t::test<12>() +	{ +		LLMatrix3 llmat_obj; + +		LLVector3 llvec1(1, 4, 3); +		LLVector3 llvec2(1, 2, 0); +		LLVector3 llvec3(2, 4, 2); + +		llmat_obj.setRows(llvec1, llvec2, llvec3); +		llmat_obj.orthogonalize(); + +		skip("Grr, LLMatrix3::orthogonalize test is failing.  Has it ever worked?"); +		ensure("LLMatrix3::orthogonalize failed ", +		       is_approx_equal(0.19611613f, llmat_obj.mMatrix[0][0]) && +		       is_approx_equal(0.78446454f, llmat_obj.mMatrix[0][1]) && +		       is_approx_equal(0.58834839f, llmat_obj.mMatrix[0][2]) && +		       is_approx_equal(0.47628206f, llmat_obj.mMatrix[1][0]) && +		       is_approx_equal(0.44826555f, llmat_obj.mMatrix[1][1]) && +		       is_approx_equal(-0.75644791f, llmat_obj.mMatrix[1][2]) && +		       is_approx_equal(-0.85714287f, llmat_obj.mMatrix[2][0]) && +		       is_approx_equal(0.42857143f, llmat_obj.mMatrix[2][1]) && +		       is_approx_equal(-0.28571427f, llmat_obj.mMatrix[2][2])); +	} + +	//test case for adjointTranspose() fn. +	template<> template<> +	void m3math_test_object_t::test<13>() +	{ +		LLMatrix3 llmat_obj; + +		LLVector3 llvec1(3, 2, 1); +		LLVector3 llvec2(6, 2, 1); +		LLVector3 llvec3(3, 6, 8); + +		llmat_obj.setRows(llvec1, llvec2, llvec3); +		llmat_obj.adjointTranspose(); +		 +		ensure("LLMatrix3::adjointTranspose failed ", 10 == llmat_obj.mMatrix[0][0] && +						-45 == llmat_obj.mMatrix[1][0] && +						30 == llmat_obj.mMatrix[2][0] && +						-10 == llmat_obj.mMatrix[0][1] && +						21 == llmat_obj.mMatrix[1][1] && +						-12 == llmat_obj.mMatrix[2][1] && +						0  == llmat_obj.mMatrix[0][2] && +						3 == llmat_obj.mMatrix[1][2] && +						-6 == llmat_obj.mMatrix[2][2]); +	} + +	/* TBD: Need to add test cases for getEulerAngles() and setRot() functions */ +} diff --git a/indra/llmath/tests/mathmisc_test.cpp b/indra/llmath/tests/mathmisc_test.cpp new file mode 100644 index 0000000000..ea42f6e001 --- /dev/null +++ b/indra/llmath/tests/mathmisc_test.cpp @@ -0,0 +1,727 @@ +/**  + * @file math.cpp + * @author Phoenix + * @date 2005-09-26 + * @brief Tests for the llmath library. + * + * $LicenseInfo:firstyear=2005&license=viewergpl$ + *  + * Copyright (c) 2005-2009, Linden Research, Inc. + *  + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab.  Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + *  + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + *  + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + *  + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "linden_common.h" +#include "../test/lltut.h" + +#include "llcrc.h" +#include "llrand.h" +#include "lluuid.h" + +#include "../llline.h" +#include "../llmath.h" +#include "../llsphere.h" +#include "../v3math.h" + +namespace tut +{ +	struct math_data +	{ +	}; +	typedef test_group<math_data> math_test; +	typedef math_test::object math_object; +	tut::math_test tm("basic_linden_math"); + +	template<> template<> +	void math_object::test<1>() +	{ +		S32 val = 89543; +		val = llabs(val); +		ensure("integer absolute value 1", (89543 == val)); +		val = -500; +		val = llabs(val); +		ensure("integer absolute value 2", (500 == val)); +	} + +	template<> template<> +	void math_object::test<2>() +	{ +		F32 val = -2583.4f; +		val = llabs(val); +		ensure("float absolute value 1", (2583.4f == val)); +		val = 430903.f; +		val = llabs(val); +		ensure("float absolute value 2", (430903.f == val)); +	} + +	template<> template<> +	void math_object::test<3>() +	{ +		F64 val = 387439393.987329839; +		val = llabs(val); +		ensure("double absolute value 1", (387439393.987329839 == val)); +		val = -8937843.9394878; +		val = llabs(val); +		ensure("double absolute value 2", (8937843.9394878 == val)); +	} + +	template<> template<> +	void math_object::test<4>() +	{ +		F32 val = 430903.9f; +		S32 val1 = lltrunc(val); +		ensure("float truncate value 1", (430903 == val1)); +		val = -2303.9f; +		val1 = lltrunc(val); +		ensure("float truncate value 2", (-2303  == val1)); +	} + +	template<> template<> +	void math_object::test<5>() +	{ +		F64 val = 387439393.987329839 ; +		S32 val1 = lltrunc(val); +		ensure("float truncate value 1", (387439393 == val1)); +		val = -387439393.987329839; +		val1 = lltrunc(val); +		ensure("float truncate value 2", (-387439393  == val1)); +	} + +	template<> template<> +	void math_object::test<6>() +	{ +		F32 val = 430903.2f; +		S32 val1 = llfloor(val); +		ensure("float llfloor value 1", (430903 == val1)); +		val = -430903.9f; +		val1 = llfloor(val); +		ensure("float llfloor value 2", (-430904 == val1)); +	} + +	template<> template<> +	void math_object::test<7>() +	{ +		F32 val = 430903.2f; +		S32 val1 = llceil(val); +		ensure("float llceil value 1", (430904 == val1)); +		val = -430903.9f; +		val1 = llceil(val); +		ensure("float llceil value 2", (-430903 == val1)); +	} + +	template<> template<> +	void math_object::test<8>() +	{ +		F32 val = 430903.2f; +		S32 val1 = llround(val); +		ensure("float llround value 1", (430903 == val1)); +		val = -430903.9f; +		val1 = llround(val); +		ensure("float llround value 2", (-430904 == val1)); +	} + +	template<> template<> +	void math_object::test<9>() +	{ +		F32 val = 430905.2654f, nearest = 100.f; +		val = llround(val, nearest); +		ensure("float llround value 1", (430900 == val)); +		val = -430905.2654f, nearest = 10.f; +		val = llround(val, nearest); +		ensure("float llround value 1", (-430910 == val)); +	} + +	template<> template<> +	void math_object::test<10>() +	{ +		F64 val = 430905.2654, nearest = 100.0; +		val = llround(val, nearest); +		ensure("double llround value 1", (430900 == val)); +		val = -430905.2654, nearest = 10.0; +		val = llround(val, nearest); +		ensure("double llround value 1", (-430910.00000 == val)); +	} + +	template<> template<> +	void math_object::test<11>() +	{ +		const F32	F_PI		= 3.1415926535897932384626433832795f; +		F32 angle = 3506.f; +		angle =  llsimple_angle(angle); +		ensure("llsimple_angle  value 1", (angle <=F_PI && angle >= -F_PI)); +		angle = -431.f; +		angle =  llsimple_angle(angle); +		ensure("llsimple_angle  value 1", (angle <=F_PI && angle >= -F_PI)); +	} +} + +namespace tut +{ +	struct uuid_data +	{ +		LLUUID id; +	}; +	typedef test_group<uuid_data> uuid_test; +	typedef uuid_test::object uuid_object; +	tut::uuid_test tu("uuid"); + +	template<> template<> +	void uuid_object::test<1>() +	{ +		ensure("uuid null", id.isNull()); +		id.generate(); +		ensure("generate not null", id.notNull()); +		id.setNull(); +		ensure("set null", id.isNull()); +	} + +	template<> template<> +	void uuid_object::test<2>() +	{ +		id.generate(); +		LLUUID a(id); +		ensure_equals("copy equal", id, a); +		a.generate(); +		ensure_not_equals("generate not equal", id, a); +		a = id; +		ensure_equals("assignment equal", id, a); +	} + +	template<> template<> +	void uuid_object::test<3>() +	{ +		id.generate(); +		LLUUID copy(id); +		LLUUID mask; +		mask.generate(); +		copy ^= mask; +		ensure_not_equals("mask not equal", id, copy); +		copy ^= mask; +		ensure_equals("mask back", id, copy); +	} + +	template<> template<> +	void uuid_object::test<4>() +	{ +		id.generate(); +		std::string id_str = id.asString(); +		LLUUID copy(id_str.c_str()); +		ensure_equals("string serialization", id, copy); +	} +	 +} + +namespace tut +{ +	struct crc_data +	{ +	}; +	typedef test_group<crc_data> crc_test; +	typedef crc_test::object crc_object; +	tut::crc_test tc("crc"); + +	template<> template<> +	void crc_object::test<1>() +	{ +		/* Test buffer update and individual char update */ +		const char TEST_BUFFER[] = "hello &#$)$&Nd0"; +		LLCRC c1, c2; +		c1.update((U8*)TEST_BUFFER, sizeof(TEST_BUFFER) - 1); +		char* rh = (char*)TEST_BUFFER; +		while(*rh != '\0') +		{ +			c2.update(*rh); +			++rh; +		} +		ensure_equals("crc update 1", c1.getCRC(), c2.getCRC()); +	} + +	template<> template<> +	void crc_object::test<2>() +	{ +		/* Test mixing of buffer and individual char update */ +		const char TEST_BUFFER1[] = "Split Buffer one $^%$%#@$"; +		const char TEST_BUFFER2[] = "Split Buffer two )(8723#5dsds"; +		LLCRC c1, c2; +		c1.update((U8*)TEST_BUFFER1, sizeof(TEST_BUFFER1) - 1); +		char* rh = (char*)TEST_BUFFER2; +		while(*rh != '\0') +		{ +			c1.update(*rh); +			++rh; +		} + +		rh = (char*)TEST_BUFFER1; +		while(*rh != '\0') +		{ +			c2.update(*rh); +			++rh; +		} +		c2.update((U8*)TEST_BUFFER2, sizeof(TEST_BUFFER2) - 1); + +		ensure_equals("crc update 2", c1.getCRC(), c2.getCRC()); +	} +} + +namespace tut +{ +	struct sphere_data +	{ +	}; +	typedef test_group<sphere_data> sphere_test; +	typedef sphere_test::object sphere_object; +	tut::sphere_test tsphere("LLSphere"); + +	template<> template<> +	void sphere_object::test<1>() +	{ +		// test LLSphere::contains() and ::overlaps() +		S32 number_of_tests = 10; +		for (S32 test = 0; test < number_of_tests; ++test) +		{ +			LLVector3 first_center(1.f, 1.f, 1.f); +			F32 first_radius = 3.f; +			LLSphere first_sphere( first_center, first_radius ); +	 +			F32 half_millimeter = 0.0005f; +			LLVector3 direction( ll_frand(2.f) - 1.f, ll_frand(2.f) - 1.f, ll_frand(2.f) - 1.f); +			direction.normalize(); +	 +			F32 distance = ll_frand(first_radius - 2.f * half_millimeter); +			LLVector3 second_center = first_center + distance * direction; +			F32 second_radius = first_radius - distance - half_millimeter; +			LLSphere second_sphere( second_center, second_radius ); +			ensure("first sphere should contain the second", first_sphere.contains(second_sphere)); +			ensure("first sphere should overlap the second", first_sphere.overlaps(second_sphere)); +	 +			distance = first_radius + ll_frand(first_radius); +			second_center = first_center + distance * direction; +			second_radius = distance - first_radius + half_millimeter; +			second_sphere.set( second_center, second_radius ); +			ensure("first sphere should NOT contain the second", !first_sphere.contains(second_sphere)); +			ensure("first sphere should overlap the second", first_sphere.overlaps(second_sphere)); +	 +			distance = first_radius + ll_frand(first_radius) + half_millimeter; +			second_center = first_center + distance * direction; +			second_radius = distance - first_radius - half_millimeter; +			second_sphere.set( second_center, second_radius ); +			ensure("first sphere should NOT contain the second", !first_sphere.contains(second_sphere)); +			ensure("first sphere should NOT overlap the second", !first_sphere.overlaps(second_sphere)); +		} +	} + +	template<> template<> +	void sphere_object::test<2>() +	{ +		// test LLSphere::getBoundingSphere() +		S32 number_of_tests = 100; +		S32 number_of_spheres = 10; +		F32 sphere_center_range = 32.f; +		F32 sphere_radius_range = 5.f; + +		for (S32 test = 0; test < number_of_tests; ++test) +		{ +			// gegnerate a bunch of random sphere +			std::vector< LLSphere > sphere_list; +			for (S32 sphere_count=0; sphere_count < number_of_spheres; ++sphere_count) +			{ +				LLVector3 direction( ll_frand(2.f) - 1.f, ll_frand(2.f) - 1.f, ll_frand(2.f) - 1.f); +				direction.normalize(); +				F32 distance = ll_frand(sphere_center_range); +				LLVector3 center = distance * direction; +				F32 radius = ll_frand(sphere_radius_range); +				LLSphere sphere( center, radius ); +				sphere_list.push_back(sphere); +			} + +			// compute the bounding sphere +			LLSphere bounding_sphere = LLSphere::getBoundingSphere(sphere_list); + +			// make sure all spheres are inside the bounding sphere +			{ +				std::vector< LLSphere >::const_iterator sphere_itr; +				for (sphere_itr = sphere_list.begin(); sphere_itr != sphere_list.end(); ++sphere_itr) +				{ +					ensure("sphere should be contained by the bounding sphere", bounding_sphere.contains(*sphere_itr)); +				} +			} + +			// TODO -- improve LLSphere::getBoundingSphere() to the point where +			// we can reduce the 'expansion' in the two tests below to about  +			// 2 mm or less + +			F32 expansion = 0.005f; +			// move all spheres out a little bit  +			// and count how many are NOT contained +			{ +				std::vector< LLVector3 > uncontained_directions; +				std::vector< LLSphere >::iterator sphere_itr; +				for (sphere_itr = sphere_list.begin(); sphere_itr != sphere_list.end(); ++sphere_itr) +				{ +					LLVector3 direction = sphere_itr->getCenter() - bounding_sphere.getCenter(); +					direction.normalize(); +	 +					sphere_itr->setCenter( sphere_itr->getCenter() + expansion * direction ); +					if (! bounding_sphere.contains( *sphere_itr ) ) +					{ +						uncontained_directions.push_back(direction); +					} +				} +				ensure("when moving spheres out there should be at least two uncontained spheres",  +						uncontained_directions.size() > 1); + +				/* TODO -- when the bounding sphere algorithm is improved we can open up this test +				 * at the moment it occasionally fails when the sphere collection is tight and small +				 * (2 meters or less) +				if (2 == uncontained_directions.size() ) +				{ +					// if there were only two uncontained spheres then +					// the two directions should be nearly opposite +					F32 dir_dot = uncontained_directions[0] * uncontained_directions[1]; +					ensure("two uncontained spheres should lie opposite the bounding center", dir_dot < -0.95f); +				} +				*/ +			} + +			// compute the new bounding sphere +			bounding_sphere = LLSphere::getBoundingSphere(sphere_list); + +			// increase the size of all spheres a little bit +			// and count how many are NOT contained +			{ +				std::vector< LLVector3 > uncontained_directions; +				std::vector< LLSphere >::iterator sphere_itr; +				for (sphere_itr = sphere_list.begin(); sphere_itr != sphere_list.end(); ++sphere_itr) +				{ +					LLVector3 direction = sphere_itr->getCenter() - bounding_sphere.getCenter(); +					direction.normalize(); +	 +					sphere_itr->setRadius( sphere_itr->getRadius() + expansion ); +					if (! bounding_sphere.contains( *sphere_itr ) ) +					{ +						uncontained_directions.push_back(direction); +					} +				} +				ensure("when boosting sphere radii there should be at least two uncontained spheres",  +						uncontained_directions.size() > 1); + +				/* TODO -- when the bounding sphere algorithm is improved we can open up this test +				 * at the moment it occasionally fails when the sphere collection is tight and small +				 * (2 meters or less) +				if (2 == uncontained_directions.size() ) +				{ +					// if there were only two uncontained spheres then +					// the two directions should be nearly opposite +					F32 dir_dot = uncontained_directions[0] * uncontained_directions[1]; +					ensure("two uncontained spheres should lie opposite the bounding center", dir_dot < -0.95f); +				} +				*/ +			} +		} +	} +} + +namespace tut +{ +	F32 SMALL_RADIUS = 1.0f; +	F32 MEDIUM_RADIUS = 5.0f; +	F32 LARGE_RADIUS = 10.0f; + +	struct line_data +	{ +	}; +	typedef test_group<line_data> line_test; +	typedef line_test::object line_object; +	tut::line_test tline("LLLine"); + +	template<> template<> +	void line_object::test<1>() +	{ +		// this is a test for LLLine::intersects(point) which returns TRUE  +		// if the line passes within some tolerance of point + +		// these tests will have some floating point error,  +		// so we need to specify how much error is ok +		F32 allowable_relative_error = 0.00001f; +		S32 number_of_tests = 100; +		for (S32 test = 0; test < number_of_tests; ++test) +		{ +			// generate some random point to be on the line +			LLVector3 point_on_line( ll_frand(2.f) - 1.f,  +			   						 ll_frand(2.f) - 1.f,  +			   						 ll_frand(2.f) - 1.f); +			point_on_line.normalize(); +			point_on_line *= ll_frand(LARGE_RADIUS); + +			// generate some random point to "intersect" +			LLVector3 random_direction ( ll_frand(2.f) - 1.f,  +			   							 ll_frand(2.f) - 1.f,  +			   							 ll_frand(2.f) - 1.f); +			random_direction.normalize(); + +			LLVector3 random_offset( ll_frand(2.f) - 1.f,  +			   						 ll_frand(2.f) - 1.f,  +			   						 ll_frand(2.f) - 1.f); +			random_offset.normalize(); +			random_offset *= ll_frand(SMALL_RADIUS); + +			LLVector3 point = point_on_line + MEDIUM_RADIUS * random_direction +				+ random_offset; +	 +			// compute the axis of approach (a unit vector between the points) +			LLVector3 axis_of_approach = point - point_on_line; +			axis_of_approach.normalize(); +	 +			// compute the direction of the the first line (perp to axis_of_approach) +			LLVector3 first_dir( ll_frand(2.f) - 1.f,  +			   					 ll_frand(2.f) - 1.f,  +			   					 ll_frand(2.f) - 1.f); +			first_dir.normalize(); +			F32 dot = first_dir * axis_of_approach;		 +			first_dir -= dot * axis_of_approach;	// subtract component parallel to axis +			first_dir.normalize(); +	 +			// construct the line +			LLVector3 another_point_on_line = point_on_line + ll_frand(LARGE_RADIUS) * first_dir; +			LLLine line(another_point_on_line, point_on_line); +	 +			// test that the intersection point is within MEDIUM_RADIUS + SMALL_RADIUS +			F32 test_radius = MEDIUM_RADIUS + SMALL_RADIUS; +			test_radius += (LARGE_RADIUS * allowable_relative_error); +			ensure("line should pass near intersection point", line.intersects(point, test_radius)); + +			test_radius = allowable_relative_error * (point - point_on_line).length(); +			ensure("line should intersect point used to define it", line.intersects(point_on_line, test_radius)); +		} +	} + +	template<> template<> +	void line_object::test<2>() +	{ +          /* +            These tests fail intermittently on all platforms - see DEV-16600 +            Commenting this out until dev has time to investigate. +             +		// this is a test for LLLine::nearestApproach(LLLIne) method +		// which computes the point on a line nearest another line + +		// these tests will have some floating point error,  +		// so we need to specify how much error is ok +		// TODO -- make nearestApproach() algorithm more accurate so +		// we can tighten the allowable_error.  Most tests are tighter +		// than one milimeter, however when doing randomized testing +		// you can walk into inaccurate cases. +		F32 allowable_relative_error = 0.001f; +		S32 number_of_tests = 100; +		for (S32 test = 0; test < number_of_tests; ++test) +		{ +			// generate two points to be our known nearest approaches +			LLVector3 some_point( ll_frand(2.f) - 1.f,  +			   					  ll_frand(2.f) - 1.f,  +			   					  ll_frand(2.f) - 1.f); +			some_point.normalize(); +			some_point *= ll_frand(LARGE_RADIUS); + +			LLVector3 another_point( ll_frand(2.f) - 1.f,  +			   						 ll_frand(2.f) - 1.f,  +			   						 ll_frand(2.f) - 1.f); +			another_point.normalize(); +			another_point *= ll_frand(LARGE_RADIUS); + +			// compute the axis of approach (a unit vector between the points) +			LLVector3 axis_of_approach = another_point - some_point; +			axis_of_approach.normalize(); +	 +			// compute the direction of the the first line (perp to axis_of_approach) +			LLVector3 first_dir( ll_frand(2.f) - 1.f,  +			   					 ll_frand(2.f) - 1.f,  +			   					 ll_frand(2.f) - 1.f); +			F32 dot = first_dir * axis_of_approach;		 +			first_dir -= dot * axis_of_approach;		// subtract component parallel to axis +			first_dir.normalize();						// normalize +	 +			// compute the direction of the the second line +			LLVector3 second_dir( ll_frand(2.f) - 1.f,  +			   					  ll_frand(2.f) - 1.f,  +			   					  ll_frand(2.f) - 1.f); +			dot = second_dir * axis_of_approach;		 +			second_dir -= dot * axis_of_approach; +			second_dir.normalize(); + +			// make sure the lines aren't too parallel,  +			dot = fabsf(first_dir * second_dir); +			if (dot > 0.99f) +			{ +				// skip this test, we're not interested in testing  +				// the intractible cases +				continue; +			} +	 +			// construct the lines +			LLVector3 first_point = some_point + ll_frand(LARGE_RADIUS) * first_dir; +			LLLine first_line(first_point, some_point); +	 +			LLVector3 second_point = another_point + ll_frand(LARGE_RADIUS) * second_dir; +			LLLine second_line(second_point, another_point); +	 +			// compute the points of nearest approach +			LLVector3 some_computed_point = first_line.nearestApproach(second_line); +			LLVector3 another_computed_point = second_line.nearestApproach(first_line); +	 +			// compute the error +			F32 first_error = (some_point - some_computed_point).length(); +			F32 scale = llmax((some_point - another_point).length(), some_point.length()); +			scale = llmax(scale, another_point.length()); +			scale = llmax(scale, 1.f); +			F32 first_relative_error = first_error / scale; + +			F32 second_error = (another_point - another_computed_point).length(); +			F32 second_relative_error = second_error / scale; + +			//if (first_relative_error > allowable_relative_error) +			//{ +			//	std::cout << "first_error = " << first_error  +			//		<< "  first_relative_error = " << first_relative_error  +			//		<< "  scale = " << scale  +			//		<< "  dir_dot = " << (first_dir * second_dir) +			//		<< std::endl; +			//} +			//if (second_relative_error > allowable_relative_error) +			//{ +			//	std::cout << "second_error = " << second_error  +			//		<< "  second_relative_error = " << second_relative_error  +			//		<< "  scale = " << scale  +			//		<< "  dist = " << (some_point - another_point).length() +			//		<< "  dir_dot = " << (first_dir * second_dir) +			//		<< std::endl; +			//} + +			// test that the errors are small + +			ensure("first line should accurately compute its closest approach",  +					first_relative_error <= allowable_relative_error); +			ensure("second line should accurately compute its closest approach",  +					second_relative_error <= allowable_relative_error); +		} +          */ +	} + +	F32 ALMOST_PARALLEL = 0.99f; +	template<> template<> +	void line_object::test<3>() +	{ +		// this is a test for LLLine::getIntersectionBetweenTwoPlanes() method + +		// first some known tests +		LLLine xy_plane(LLVector3(0.f, 0.f, 2.f), LLVector3(0.f, 0.f, 3.f)); +		LLLine yz_plane(LLVector3(2.f, 0.f, 0.f), LLVector3(3.f, 0.f, 0.f)); +		LLLine zx_plane(LLVector3(0.f, 2.f, 0.f), LLVector3(0.f, 3.f, 0.f)); + +		LLLine x_line; +		LLLine y_line; +		LLLine z_line; + +		bool x_success = LLLine::getIntersectionBetweenTwoPlanes(x_line, xy_plane, zx_plane); +		bool y_success = LLLine::getIntersectionBetweenTwoPlanes(y_line, yz_plane, xy_plane); +		bool z_success = LLLine::getIntersectionBetweenTwoPlanes(z_line, zx_plane, yz_plane); + +		ensure("xy and zx planes should intersect", x_success); +		ensure("yz and xy planes should intersect", y_success); +		ensure("zx and yz planes should intersect", z_success); + +		LLVector3 direction = x_line.getDirection(); +		ensure("x_line should be parallel to x_axis", fabs(direction.mV[VX]) == 1.f +				                                      && 0.f == direction.mV[VY] +				                                      && 0.f == direction.mV[VZ] ); +		direction = y_line.getDirection(); +		ensure("y_line should be parallel to y_axis", 0.f == direction.mV[VX] +													  && fabs(direction.mV[VY]) == 1.f +				                                      && 0.f == direction.mV[VZ] ); +		direction = z_line.getDirection(); +		ensure("z_line should be parallel to z_axis", 0.f == direction.mV[VX] +				                                      && 0.f == direction.mV[VY] +													  && fabs(direction.mV[VZ]) == 1.f ); + +		// next some random tests +		F32 allowable_relative_error = 0.0001f; +		S32 number_of_tests = 20; +		for (S32 test = 0; test < number_of_tests; ++test) +		{ +			// generate the known line +			LLVector3 some_point( ll_frand(2.f) - 1.f,  +			   					  ll_frand(2.f) - 1.f,  +			   					  ll_frand(2.f) - 1.f); +			some_point.normalize(); +			some_point *= ll_frand(LARGE_RADIUS); +			LLVector3 another_point( ll_frand(2.f) - 1.f,  +			   						 ll_frand(2.f) - 1.f,  +			   						 ll_frand(2.f) - 1.f); +			another_point.normalize(); +			another_point *= ll_frand(LARGE_RADIUS); +			LLLine known_intersection(some_point, another_point); + +			// compute a plane that intersect the line +			LLVector3 point_on_plane( ll_frand(2.f) - 1.f,  +			   						  ll_frand(2.f) - 1.f,  +			   						  ll_frand(2.f) - 1.f); +			point_on_plane.normalize(); +			point_on_plane *= ll_frand(LARGE_RADIUS); +			LLVector3 plane_normal = (point_on_plane - some_point) % known_intersection.getDirection(); +			plane_normal.normalize(); +			LLLine first_plane(point_on_plane, point_on_plane + plane_normal); + +			// compute a different plane that intersect the line +			LLVector3 point_on_different_plane( ll_frand(2.f) - 1.f,  +			   									ll_frand(2.f) - 1.f,  +			   									ll_frand(2.f) - 1.f); +			point_on_different_plane.normalize(); +			point_on_different_plane *= ll_frand(LARGE_RADIUS); +			LLVector3 different_plane_normal = (point_on_different_plane - another_point) % known_intersection.getDirection(); +			different_plane_normal.normalize(); +			LLLine second_plane(point_on_different_plane, point_on_different_plane + different_plane_normal); + +			if (fabs(plane_normal * different_plane_normal) > ALMOST_PARALLEL) +			{ +				// the two planes are approximately parallel, so we won't test this case +				continue; +			} + +			LLLine measured_intersection; +			bool success = LLLine::getIntersectionBetweenTwoPlanes( +					measured_intersection, +					first_plane, +					second_plane); + +			ensure("plane intersection should succeed", success); + +			F32 dot = fabs(known_intersection.getDirection() * measured_intersection.getDirection()); +			ensure("measured intersection should be parallel to known intersection", +					dot > ALMOST_PARALLEL); + +			ensure("measured intersection should pass near known point", +					measured_intersection.intersects(some_point, LARGE_RADIUS * allowable_relative_error)); +		} +	} +} + diff --git a/indra/llmath/tests/v2math_test.cpp b/indra/llmath/tests/v2math_test.cpp new file mode 100644 index 0000000000..456faf7c0c --- /dev/null +++ b/indra/llmath/tests/v2math_test.cpp @@ -0,0 +1,454 @@ +/** + * @file v2math_tut.cpp + * @author Adroit + * @date 2007-02 + * @brief v2math test cases. + * + * $LicenseInfo:firstyear=2007&license=viewergpl$ + *  + * Copyright (c) 2007-2009, Linden Research, Inc. + *  + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab.  Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + *  + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + *  + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + *  + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "linden_common.h" +#include "../test/lltut.h"  + +#include "../v2math.h" + + +namespace tut +{ +	struct v2math_data +	{ +	}; +	typedef test_group<v2math_data> v2math_test; +	typedef v2math_test::object v2math_object; +	tut::v2math_test v2math_testcase("v2math"); + +	template<> template<> +	void v2math_object::test<1>() +	{ +		LLVector2 vec2; +		ensure("LLVector2:Fail to initialize ", (0.f == vec2.mV[VX] && 0.f == vec2.mV[VY])); + +		F32 x =2.0f, y = 3.2f ; +		LLVector2 vec3(x,y); +		ensure("LLVector2(F32 x, F32 y):Fail to initialize ", (x == vec3.mV[VX]) && (y == vec3.mV[VY])); + +		const F32 vec[2] = {3.2f, 4.5f}; +		LLVector2 vec4(vec); +		ensure("LLVector2(const F32 *vec):Fail to initialize ", (vec[0] == vec4.mV[VX]) && (vec[1] == vec4.mV[VY])); + +		vec4.clearVec(); +		ensure("clearVec():Fail to clean the values ", (0.f == vec4.mV[VX] && 0.f == vec4.mV[VY])); + +		vec3.zeroVec(); +		ensure("zeroVec():Fail to fill the zero ", (0.f == vec3.mV[VX] && 0.f == vec3.mV[VY])); +	} + +	template<> template<> +	void v2math_object::test<2>() +	{ +		F32 x = 123.356f, y = 2387.453f; +		LLVector2 vec2,vec3; +		vec2.setVec(x, y); +		ensure("1:setVec: Fail  ", (x == vec2.mV[VX]) && (y == vec2.mV[VY])); + +		vec3.setVec(vec2); +		ensure("2:setVec: Fail   " ,(vec2 == vec3)); + +		vec3.zeroVec(); +		const F32 vec[2] = {3.24653f, 457653.4f}; +		vec3.setVec(vec); +		ensure("3:setVec: Fail  ", (vec[0] == vec3.mV[VX]) && (vec[1] == vec3.mV[VY])); +	} + +	template<> template<> +	void v2math_object::test<3>() +	{ +		F32 x = 2.2345f, y = 3.5678f ; +		LLVector2 vec2(x,y); +		ensure("magVecSquared:Fail ", is_approx_equal(vec2.magVecSquared(), (x*x + y*y))); +		ensure("magVec:Fail ", is_approx_equal(vec2.magVec(), fsqrtf(x*x + y*y))); +	} + +	template<> template<> +	void v2math_object::test<4>() +	{ +		F32 x =-2.0f, y = -3.0f ; +		LLVector2 vec2(x,y); +		ensure_equals("abs():Fail", vec2.abs(), TRUE); +		ensure("abs() x", is_approx_equal(vec2.mV[VX], 2.f)); +		ensure("abs() y", is_approx_equal(vec2.mV[VY], 3.f)); + +		ensure("isNull():Fail ", FALSE == vec2.isNull());	//Returns TRUE if vector has a _very_small_ length + +		x =.00000001f, y = .000001001f; +		vec2.setVec(x, y); +		ensure("isNull(): Fail ", TRUE == vec2.isNull());	 +	} + +	template<> template<> +	void v2math_object::test<5>() +	{ +		F32 x =1.f, y = 2.f; +		LLVector2 vec2(x, y), vec3; +		vec3 = vec3.scaleVec(vec2); +		ensure("scaleVec: Fail ", vec3.mV[VX] == 0. && vec3.mV[VY] == 0.); +		ensure("isExactlyZero(): Fail", TRUE == vec3.isExactlyZero()); + +		vec3.setVec(2.f, 1.f); +		vec3 = vec3.scaleVec(vec2); +		ensure("scaleVec: Fail ", (2.f == vec3.mV[VX]) && (2.f == vec3.mV[VY])); +		ensure("isExactlyZero():Fail", FALSE == vec3.isExactlyZero()); +	} + +	template<> template<> +	void v2math_object::test<6>() +	{ +		F32 x1 =1.f, y1 = 2.f, x2 = -2.3f, y2 = 1.11f; +		F32 val1, val2; +		LLVector2 vec2(x1, y1), vec3(x2, y2), vec4; +		vec4 = vec2 + vec3 ; +		val1 = x1+x2; +		val2 = y1+y2; +		ensure("1:operator+ failed",(val1 == vec4.mV[VX]) && ((val2 == vec4.mV[VY])));  + +		vec2.clearVec(); +		vec3.clearVec(); +		x1 = -.235f, y1 = -24.32f,  x2 = -2.3f, y2 = 1.f; +		vec2.setVec(x1, y1); +		vec3.setVec(x2, y2); +		vec4 = vec2 + vec3; +		val1 = x1+x2; +		val2 = y1+y2; +		ensure("2:operator+ failed",(val1 == vec4.mV[VX]) && ((val2 == vec4.mV[VY])));  +	} + +	template<> template<> +	void v2math_object::test<7>() +	{ +		F32 x1 =1.f, y1 = 2.f,  x2 = -2.3f, y2 = 1.11f; +		F32 val1, val2; +		LLVector2 vec2(x1, y1), vec3(x2, y2), vec4; +		vec4 = vec2 - vec3 ; +		val1 = x1-x2; +		val2 = y1-y2; +		ensure("1:operator- failed",(val1 == vec4.mV[VX]) && ((val2 == vec4.mV[VY])));  + +		vec2.clearVec(); +		vec3.clearVec(); +		vec4.clearVec(); +		x1 = -.235f, y1 = -24.32f,  x2 = -2.3f, y2 = 1.f; +		vec2.setVec(x1, y1); +		vec3.setVec(x2, y2); +		vec4 = vec2 - vec3; +		val1 = x1-x2; +		val2 = y1-y2; +		ensure("2:operator- failed",(val1 == vec4.mV[VX]) && ((val2 == vec4.mV[VY])));  +	} + +	template<> template<> +	void v2math_object::test<8>() +	{ +		F32 x1 =1.f, y1 = 2.f,  x2 = -2.3f, y2 = 1.11f; +		F32 val1, val2; +		LLVector2 vec2(x1, y1), vec3(x2, y2); +		val1 = vec2 * vec3; +		val2 = x1*x2 + y1*y2; +		ensure("1:operator* failed",(val1 == val2)); + +		vec3.clearVec(); +		F32 mulVal = 4.332f; +		vec3 = vec2 * mulVal; +		val1 = x1*mulVal; +		val2 = y1*mulVal; +		ensure("2:operator* failed",(val1 == vec3.mV[VX]) && (val2 == vec3.mV[VY])); + +		vec3.clearVec(); +		vec3 = mulVal * vec2; +		ensure("3:operator* failed",(val1 == vec3.mV[VX]) && (val2 == vec3.mV[VY]));		 +	} + +	template<> template<> +	void v2math_object::test<9>() +	{ +		F32 x1 =1.f, y1 = 2.f, div = 3.2f; +		F32 val1, val2; +		LLVector2 vec2(x1, y1), vec3; +		vec3 = vec2 / div; +		val1 = x1 / div; +		val2 = y1 / div; +		ensure("1:operator/ failed", is_approx_equal(val1, vec3.mV[VX]) && is_approx_equal(val2, vec3.mV[VY]));		 + +		vec3.clearVec(); +		x1 = -.235f, y1 = -24.32f, div = -2.2f; +		vec2.setVec(x1, y1); +		vec3 = vec2 / div; +		val1 = x1 / div; +		val2 = y1 / div; +		ensure("2:operator/ failed", is_approx_equal(val1, vec3.mV[VX]) && is_approx_equal(val2, vec3.mV[VY]));		 +	} + +	template<> template<> +	void v2math_object::test<10>() +	{ +		F32 x1 =1.f, y1 = 2.f,  x2 = -2.3f, y2 = 1.11f; +		F32 val1, val2; +		LLVector2 vec2(x1, y1), vec3(x2, y2), vec4; +		vec4 = vec2 % vec3; +		val1 = x1*y2 - x2*y1; +		val2 = y1*x2 - y2*x1; +		ensure("1:operator% failed",(val1 == vec4.mV[VX]) && (val2 == vec4.mV[VY]));	 + +		vec2.clearVec(); +		vec3.clearVec(); +		vec4.clearVec(); +		x1 = -.235f, y1 = -24.32f,  x2 = -2.3f, y2 = 1.f; +		vec2.setVec(x1, y1); +		vec3.setVec(x2, y2); +		vec4 = vec2 % vec3; +		val1 = x1*y2 - x2*y1; +		val2 = y1*x2 - y2*x1; +		ensure("2:operator% failed",(val1 == vec4.mV[VX]) && (val2 == vec4.mV[VY]));	 +	} +	template<> template<> +	void v2math_object::test<11>() +	{ +		F32 x1 =1.f, y1 = 2.f; +		LLVector2 vec2(x1, y1), vec3(x1, y1); +		ensure("1:operator== failed",(vec2 == vec3)); +		 +		vec2.clearVec(); +		vec3.clearVec(); +		x1 = -.235f, y1 = -24.32f; +		vec2.setVec(x1, y1); +		vec3.setVec(vec2); +		ensure("2:operator== failed",(vec2 == vec3)); +	} + +	template<> template<> +	void v2math_object::test<12>() +	{ +		F32 x1 = 1.f, y1 = 2.f,x2 = 2.332f, y2 = -1.23f; +		LLVector2 vec2(x1, y1), vec3(x2, y2); +		ensure("1:operator!= failed",(vec2 != vec3)); +		 +		vec2.clearVec(); +		vec3.clearVec(); +		vec2.setVec(x1, y1); +		vec3.setVec(vec2); +		ensure("2:operator!= failed", (FALSE == (vec2 != vec3))); +	} +	template<> template<> +	void v2math_object::test<13>() +	{ +		F32 x1 = 1.f, y1 = 2.f,x2 = 2.332f, y2 = -1.23f; +		F32 val1, val2; +		LLVector2 vec2(x1, y1), vec3(x2, y2); +		vec2 +=vec3; +		val1 = x1+x2; +		val2 = y1+y2; +		ensure("1:operator+= failed",(val1 == vec2.mV[VX]) && (val2 == vec2.mV[VY])); +		 +		vec2.setVec(x1, y1); +		vec2 -=vec3; +		val1 = x1-x2; +		val2 = y1-y2; +		ensure("2:operator-= failed",(val1 == vec2.mV[VX]) && (val2 == vec2.mV[VY])); +		 +		vec2.clearVec(); +		vec3.clearVec(); +		x1 = -21.000466f, y1 = 2.98382f,x2 = 0.332f, y2 = -01.23f; +		vec2.setVec(x1, y1); +		vec3.setVec(x2, y2); +		vec2 +=vec3; +		val1 = x1+x2; +		val2 = y1+y2; +		ensure("3:operator+= failed",(val1 == vec2.mV[VX]) && (val2 == vec2.mV[VY])); + +		vec2.setVec(x1, y1); +		vec2 -=vec3; +		val1 = x1-x2; +		val2 = y1-y2; +		ensure("4:operator-= failed", is_approx_equal(val1, vec2.mV[VX]) && is_approx_equal(val2, vec2.mV[VY])); +	} + +	template<> template<> +	void v2math_object::test<14>() +	{ +		F32 x1 =1.f, y1 = 2.f; +		F32 val1, val2, mulVal = 4.332f; +		LLVector2 vec2(x1, y1); +		vec2 /=mulVal; +		val1 = x1 / mulVal; +		val2 = y1 / mulVal; +		ensure("1:operator/= failed", is_approx_equal(val1, vec2.mV[VX]) && is_approx_equal(val2, vec2.mV[VY])); +		 +		vec2.clearVec(); +		x1 = .213f, y1 = -2.34f, mulVal = -.23f; +		vec2.setVec(x1, y1); +		vec2 /=mulVal; +		val1 = x1 / mulVal; +		val2 = y1 / mulVal; +		ensure("2:operator/= failed", is_approx_equal(val1, vec2.mV[VX]) && is_approx_equal(val2, vec2.mV[VY])); +	} + +	template<> template<> +	void v2math_object::test<15>() +	{ +		F32 x1 =1.f, y1 = 2.f; +		F32 val1, val2, mulVal = 4.332f; +		LLVector2 vec2(x1, y1); +		vec2 *=mulVal; +		val1 = x1*mulVal; +		val2 = y1*mulVal; +		ensure("1:operator*= failed",(val1 == vec2.mV[VX]) && (val2 == vec2.mV[VY])); +		 +		vec2.clearVec(); +		x1 = .213f, y1 = -2.34f, mulVal = -.23f; +		vec2.setVec(x1, y1); +		vec2 *=mulVal; +		val1 = x1*mulVal; +		val2 = y1*mulVal; +		ensure("2:operator*= failed",(val1 == vec2.mV[VX]) && (val2 == vec2.mV[VY])); +	} +	 +	template<> template<> +	void v2math_object::test<16>() +	{ +		F32 x1 =1.f, y1 = 2.f,  x2 = -2.3f, y2 = 1.11f; +		F32 val1, val2; +		LLVector2 vec2(x1, y1), vec3(x2, y2); +		vec2 %= vec3; +		val1 = x1*y2 - x2*y1; +		val2 = y1*x2 - y2*x1; +		ensure("1:operator%= failed",(val1 == vec2.mV[VX]) && (val2 == vec2.mV[VY]));	 +	} + +	template<> template<> +	void v2math_object::test<17>() +	{ +		F32 x1 =1.f, y1 = 2.f; +		LLVector2 vec2(x1, y1),vec3; +		vec3 = -vec2; +		ensure("1:operator- failed",(-vec3 == vec2));	 +	} + +	template<> template<> +	void v2math_object::test<18>() +	{ +		F32 x1 =1.f, y1 = 2.f; +		std::ostringstream stream1, stream2; +		LLVector2 vec2(x1, y1),vec3; +		stream1 << vec2; +		vec3.setVec(x1, y1); +		stream2 << vec3; +		ensure("1:operator << failed",(stream1.str() == stream2.str()));	 +	} + +	template<> template<> +	void v2math_object::test<19>() +	{ +		F32 x1 =1.0f, y1 = 2.0f, x2 = -.32f, y2 = .2234f; +		LLVector2 vec2(x1, y1),vec3(x2, y2); +		ensure("1:operator < failed",(vec3 < vec2));	 + +		x1 = 1.0f, y1 = 2.0f, x2 = 1.0f, y2 = 3.2234f; +		vec2.setVec(x1, y1); +		vec3.setVec(x2, y2); +		ensure("2:operator < failed", (FALSE == (vec3 < vec2)));	 +	} + +	template<> template<> +	void v2math_object::test<20>() +	{ +		F32 x1 =1.0f, y1 = 2.0f; +		LLVector2 vec2(x1, y1); +		ensure("1:operator [] failed",( x1 ==  vec2[0]));	 +		ensure("2:operator [] failed",( y1 ==  vec2[1])); + +		vec2.clearVec(); +		x1 = 23.0f, y1 = -.2361f; +		vec2.setVec(x1, y1); +		F32 ref1 = vec2[0]; +		ensure("3:operator [] failed", ( ref1 ==  x1)); +		F32 ref2 = vec2[1]; +		ensure("4:operator [] failed", ( ref2 ==  y1)); +	} + +	template<> template<> +	void v2math_object::test<21>() +	{ +		F32 x1 =1.f, y1 = 2.f, x2 = -.32f, y2 = .2234f; +		F32 val1, val2; +		LLVector2 vec2(x1, y1),vec3(x2, y2);		 +		val1 = dist_vec_squared2D(vec2, vec3); +		val2 = (x1 - x2)*(x1 - x2) + (y1 - y2)* (y1 - y2); +		ensure_equals("dist_vec_squared2D values are not equal",val2, val1); + +		val1 = dist_vec_squared(vec2, vec3); +		ensure_equals("dist_vec_squared values are not equal",val2, val1); + +		val1 = 	dist_vec(vec2, vec3); +		val2 = fsqrtf((x1 - x2)*(x1 - x2) + (y1 - y2)* (y1 - y2)); +		ensure_equals("dist_vec values are not equal",val2, val1); +	} + +	template<> template<> +	void v2math_object::test<22>() +	{ +		F32 x1 =1.f, y1 = 2.f, x2 = -.32f, y2 = .2234f,fVal = .0121f; +		F32 val1, val2; +		LLVector2 vec2(x1, y1),vec3(x2, y2); +		LLVector2 vec4 = lerp(vec2, vec3, fVal); +		val1 = x1 + (x2 - x1) * fVal; +		val2 = y1 + (y2 - y1) * fVal; +		ensure("lerp values are not equal", ((val1 == vec4.mV[VX]) && (val2 == vec4.mV[VY]))); +	} + +	template<> template<> +	void v2math_object::test<23>() +	{ +		F32 x1 =1.f, y1 = 2.f; +		F32 val1, val2; +		LLVector2 vec2(x1, y1); + +		F32 vecMag = vec2.normVec(); +		F32 mag = fsqrtf(x1*x1 + y1*y1); + +		F32 oomag = 1.f / mag; +		val1 = x1 * oomag; +		val2 = y1 * oomag; + +		ensure("normVec failed", is_approx_equal(val1, vec2.mV[VX]) && is_approx_equal(val2, vec2.mV[VY]) && is_approx_equal(vecMag, mag)); + +		x1 =.00000001f, y1 = 0.f; + +		vec2.setVec(x1, y1); +		vecMag = vec2.normVec(); +		ensure("normVec failed should be 0.", 0. == vec2.mV[VX] && 0. == vec2.mV[VY] && vecMag == 0.); +	} +} diff --git a/indra/llmath/tests/v3color_test.cpp b/indra/llmath/tests/v3color_test.cpp new file mode 100644 index 0000000000..bb6e234fd6 --- /dev/null +++ b/indra/llmath/tests/v3color_test.cpp @@ -0,0 +1,315 @@ +/** + * @file v3color_tut.cpp + * @author Adroit + * @date 2007-03 + * @brief v3color test cases. + * + * $LicenseInfo:firstyear=2007&license=viewergpl$ + *  + * Copyright (c) 2007-2009, Linden Research, Inc. + *  + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab.  Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + *  + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + *  + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + *  + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "linden_common.h" +#include "../test/lltut.h" + +#include "../v3color.h" + + +namespace tut +{ +	struct v3color_data +	{ +	}; +	typedef test_group<v3color_data> v3color_test; +	typedef v3color_test::object v3color_object; +	tut::v3color_test v3color_testcase("v3color"); + +	template<> template<> +	void v3color_object::test<1>() +	{ +		LLColor3 llcolor3; +		ensure("1:LLColor3:Fail to default-initialize ", (0.0f == llcolor3.mV[0]) && (0.0f == llcolor3.mV[1]) && (0.0f == llcolor3.mV[2])); +		F32 r = 2.0f, g = 3.2f, b = 1.f; +		F32 v1,v2,v3; +		LLColor3 llcolor3a(r,g,b); +		ensure("2:LLColor3:Fail to initialize " ,(2.0f == llcolor3a.mV[0]) && (3.2f == llcolor3a.mV[1]) && (1.f == llcolor3a.mV[2])); +		 +		const F32 vec[3] = {2.0f, 3.2f,1.f}; +		LLColor3 llcolor3b(vec); +		ensure("3:LLColor3:Fail to initialize " ,(2.0f == llcolor3b.mV[0]) && (3.2f == llcolor3b.mV[1]) && (1.f == llcolor3b.mV[2])); +		const char* str = "561122"; +		LLColor3 llcolor3c(str); +		v1 = (F32)86.0f/255.0f; // 0x56 = 86 +		v2 = (F32)17.0f/255.0f; // 0x11 = 17 +		v3 = (F32)34.0f/255.f;  // 0x22 = 34 +		ensure("4:LLColor3:Fail to initialize " , is_approx_equal(v1, llcolor3c.mV[0]) && is_approx_equal(v2, llcolor3c.mV[1]) && is_approx_equal(v3, llcolor3c.mV[2])); +	} + +	template<> template<> +	void v3color_object::test<2>() +	{ +		LLColor3 llcolor3; +		llcolor3.setToBlack(); +		ensure("setToBlack:Fail to set black ", ((llcolor3.mV[0] == 0.f) && (llcolor3.mV[1] == 0.f) && (llcolor3.mV[2] == 0.f))); +		llcolor3.setToWhite(); +		ensure("setToWhite:Fail to set white  ", ((llcolor3.mV[0] == 1.f) && (llcolor3.mV[1] == 1.f) && (llcolor3.mV[2] == 1.f))); +	} + +	template<> template<> +	void v3color_object::test<3>() +	{ +		F32 r = 2.3436212f, g = 1231.f, b = 4.7849321232f; +		LLColor3 llcolor3, llcolor3a; +		llcolor3.setVec(r,g,b); +		ensure("1:setVec(r,g,b) Fail ",((r == llcolor3.mV[0]) && (g == llcolor3.mV[1]) && (b == llcolor3.mV[2]))); +		llcolor3a.setVec(llcolor3); +		ensure_equals("2:setVec(LLColor3) Fail ", llcolor3,llcolor3a); +		F32 vec[3] = {1.2324f, 2.45634f, .234563f}; +		llcolor3.setToBlack(); +		llcolor3.setVec(vec); +		ensure("3:setVec(F32*) Fail ",((vec[0] == llcolor3.mV[0]) && (vec[1] == llcolor3.mV[1]) && (vec[2] == llcolor3.mV[2]))); +	} + +	template<> template<> +	void v3color_object::test<4>() +	{ +		F32 r = 2.3436212f, g = 1231.f, b = 4.7849321232f; +		LLColor3 llcolor3(r,g,b); +		ensure("magVecSquared:Fail ", is_approx_equal(llcolor3.magVecSquared(), (r*r + g*g + b*b))); +		ensure("magVec:Fail ", is_approx_equal(llcolor3.magVec(), fsqrtf(r*r + g*g + b*b))); +	} + +	template<> template<> +	void v3color_object::test<5>() +	{ +		F32 r = 2.3436212f, g = 1231.f, b = 4.7849321232f; +		F32 val1, val2,val3; +		LLColor3 llcolor3(r,g,b); +		F32 vecMag = llcolor3.normVec(); +		F32 mag = fsqrtf(r*r + g*g + b*b); +		F32 oomag = 1.f / mag; +		val1 = r * oomag; +		val2 = g * oomag; +		val3 = b * oomag; +		ensure("1:normVec failed ", (is_approx_equal(val1, llcolor3.mV[0]) && is_approx_equal(val2, llcolor3.mV[1]) && is_approx_equal(val3, llcolor3.mV[2]) && is_approx_equal(vecMag, mag))); +		r = .000000000f, g = 0.f, b = 0.0f; +		llcolor3.setVec(r,g,b); +		vecMag = llcolor3.normVec(); +		ensure("2:normVec failed should be 0. ", (0. == llcolor3.mV[0] && 0. == llcolor3.mV[1] && 0. == llcolor3.mV[2] && vecMag == 0.)); +	} + +	template<> template<> +	void v3color_object::test<6>() +	{ +		F32 r = 2.3436212f, g = -1231.f, b = .7849321232f; +		std::ostringstream stream1, stream2; +		LLColor3 llcolor3(r,g,b),llcolor3a; +		stream1 << llcolor3; +		llcolor3a.setVec(r,g,b); +		stream2 << llcolor3a; +		ensure("operator << failed ", (stream1.str() == stream2.str()));	 +	} +		 +	template<> template<> +	void v3color_object::test<7>() +	{ +		F32 r = 2.3436212f, g = -1231.f, b = .7849321232f; +		LLColor3 llcolor3(r,g,b),llcolor3a; +		llcolor3a = llcolor3; +		ensure("operator == failed ", (llcolor3a == llcolor3));	 +	} + +	template<> template<> +	void v3color_object::test<8>() +	{ +		F32 r1 =1.f, g1 = 2.f,b1 = 1.2f, r2 = -2.3f, g2 = 1.11f, b2 = 1234.234f; +		LLColor3 llcolor3(r1,g1,b1),llcolor3a(r2,g2,b2),llcolor3b; +		llcolor3b = llcolor3 + llcolor3a ; +		ensure("1:operator+ failed",is_approx_equal(r1+r2 ,llcolor3b.mV[0]) && is_approx_equal(g1+g2,llcolor3b.mV[1])&& is_approx_equal(b1+b2,llcolor3b.mV[2])); +		r1 = -.235f, g1 = -24.32f, b1 = 2.13f,  r2 = -2.3f, g2 = 1.f, b2 = 34.21f; +		llcolor3.setVec(r1,g1,b1); +		llcolor3a.setVec(r2,g2,b2); +		llcolor3b = llcolor3 + llcolor3a; +		ensure("2:operator+ failed",is_approx_equal(r1+r2 ,llcolor3b.mV[0]) && is_approx_equal(g1+g2,llcolor3b.mV[1])&& is_approx_equal(b1+b2,llcolor3b.mV[2])); +	} + +	template<> template<> +	void v3color_object::test<9>() +	{ +		F32 r1 =1.f, g1 = 2.f,b1 = 1.2f, r2 = -2.3f, g2 = 1.11f, b2 = 1234.234f; +		LLColor3 llcolor3(r1,g1,b1),llcolor3a(r2,g2,b2),llcolor3b; +		llcolor3b = llcolor3 - llcolor3a ; +		ensure("1:operator- failed",is_approx_equal(r1-r2 ,llcolor3b.mV[0]) && is_approx_equal(g1-g2,llcolor3b.mV[1])&& is_approx_equal(b1-b2,llcolor3b.mV[2])); +		r1 = -.235f, g1 = -24.32f, b1 = 2.13f,  r2 = -2.3f, g2 = 1.f, b2 = 34.21f; +		llcolor3.setVec(r1,g1,b1); +		llcolor3a.setVec(r2,g2,b2); +		llcolor3b = llcolor3 - llcolor3a; +		ensure("2:operator- failed",is_approx_equal(r1-r2 ,llcolor3b.mV[0]) && is_approx_equal(g1-g2,llcolor3b.mV[1])&& is_approx_equal(b1-b2,llcolor3b.mV[2])); +	} + +	template<> template<> +	void v3color_object::test<10>() +	{ +		F32 r1 =1.f, g1 = 2.f,b1 = 1.2f, r2 = -2.3f, g2 = 1.11f, b2 = 1234.234f; +		LLColor3 llcolor3(r1,g1,b1),llcolor3a(r2,g2,b2),llcolor3b; +		llcolor3b = llcolor3 * llcolor3a; +		ensure("1:operator* failed",is_approx_equal(r1*r2 ,llcolor3b.mV[0]) && is_approx_equal(g1*g2,llcolor3b.mV[1])&& is_approx_equal(b1*b2,llcolor3b.mV[2])); +		llcolor3a.setToBlack(); +		F32 mulVal = 4.332f; +		llcolor3a = llcolor3 * mulVal; +		ensure("2:operator* failed",is_approx_equal(r1*mulVal ,llcolor3a.mV[0]) && is_approx_equal(g1*mulVal,llcolor3a.mV[1])&& is_approx_equal(b1*mulVal,llcolor3a.mV[2])); +		llcolor3a.setToBlack(); +		llcolor3a = mulVal * llcolor3; +		ensure("3:operator* failed",is_approx_equal(r1*mulVal ,llcolor3a.mV[0]) && is_approx_equal(g1*mulVal,llcolor3a.mV[1])&& is_approx_equal(b1*mulVal,llcolor3a.mV[2])); +	} + +	template<> template<> +	void v3color_object::test<11>() +	{ +		F32 r = 2.3436212f, g = 1231.f, b = 4.7849321232f; +		LLColor3 llcolor3(r,g,b),llcolor3a; +		llcolor3a = -llcolor3; +		ensure("operator- failed ", (-llcolor3a == llcolor3));	 +	} + +	template<> template<> +	void v3color_object::test<12>() +	{ +		F32 r = 2.3436212f, g = 1231.f, b = 4.7849321232f; +		LLColor3 llcolor3(r,g,b),llcolor3a(r,g,b); +		ensure_equals("1:operator== failed",llcolor3a,llcolor3); +		r = 13.3436212f, g = -11.f, b = .7849321232f; +		llcolor3.setVec(r,g,b); +		llcolor3a.setVec(r,g,b); +		ensure_equals("2:operator== failed",llcolor3a,llcolor3); +	} + +	template<> template<> +	void v3color_object::test<13>() +	{ +		F32 r1 =1.f, g1 = 2.f,b1 = 1.2f, r2 = -2.3f, g2 = 1.11f, b2 = 1234.234f; +		LLColor3 llcolor3(r1,g1,b1),llcolor3a(r2,g2,b2); +		ensure("1:operator!= failed",(llcolor3 != llcolor3a)); +		llcolor3.setToBlack(); +		llcolor3a.setVec(llcolor3); +		ensure("2:operator!= failed", ( FALSE == (llcolor3a != llcolor3))); +	} + +	template<> template<> +	void v3color_object::test<14>() +	{ +		F32 r1 =1.f, g1 = 2.f,b1 = 1.2f, r2 = -2.3f, g2 = 1.11f, b2 = 1234.234f; +		LLColor3 llcolor3(r1,g1,b1),llcolor3a(r2,g2,b2); +		llcolor3a += llcolor3; +		ensure("1:operator+= failed",is_approx_equal(r1+r2 ,llcolor3a.mV[0]) && is_approx_equal(g1+g2,llcolor3a.mV[1])&& is_approx_equal(b1+b2,llcolor3a.mV[2])); +		llcolor3.setVec(r1,g1,b1); +		llcolor3a.setVec(r2,g2,b2); +		llcolor3a += llcolor3; +		ensure("2:operator+= failed",is_approx_equal(r1+r2 ,llcolor3a.mV[0]) && is_approx_equal(g1+g2,llcolor3a.mV[1])&& is_approx_equal(b1+b2,llcolor3a.mV[2])); +	} + +	template<> template<> +	void v3color_object::test<15>() +	{ +		F32 r1 =1.f, g1 = 2.f,b1 = 1.2f, r2 = -2.3f, g2 = 1.11f, b2 = 1234.234f; +		LLColor3 llcolor3(r1,g1,b1),llcolor3a(r2,g2,b2); +		llcolor3a -= llcolor3; +		ensure("1:operator-= failed", is_approx_equal(r2-r1, llcolor3a.mV[0])); +		ensure("2:operator-= failed", is_approx_equal(g2-g1, llcolor3a.mV[1])); +		ensure("3:operator-= failed", is_approx_equal(b2-b1, llcolor3a.mV[2])); +		llcolor3.setVec(r1,g1,b1); +		llcolor3a.setVec(r2,g2,b2); +		llcolor3a -= llcolor3; +		ensure("4:operator-= failed", is_approx_equal(r2-r1, llcolor3a.mV[0])); +		ensure("5:operator-= failed", is_approx_equal(g2-g1, llcolor3a.mV[1])); +		ensure("6:operator-= failed", is_approx_equal(b2-b1, llcolor3a.mV[2])); +	} +	 +	template<> template<> +	void v3color_object::test<16>() +	{ +		F32 r1 =1.f, g1 = 2.f,b1 = 1.2f, r2 = -2.3f, g2 = 1.11f, b2 = 1234.234f; +		LLColor3 llcolor3(r1,g1,b1),llcolor3a(r2,g2,b2); +		llcolor3a *= llcolor3; +		ensure("1:operator*= failed",is_approx_equal(r1*r2 ,llcolor3a.mV[0]) && is_approx_equal(g1*g2,llcolor3a.mV[1])&& is_approx_equal(b1*b2,llcolor3a.mV[2])); +		F32 mulVal = 4.332f; +		llcolor3 *=mulVal; +		ensure("2:operator*= failed",is_approx_equal(r1*mulVal ,llcolor3.mV[0]) && is_approx_equal(g1*mulVal,llcolor3.mV[1])&& is_approx_equal(b1*mulVal,llcolor3.mV[2])); +	} + +	template<> template<> +	void v3color_object::test<17>() +	{ +		F32 r = 2.3436212f, g = -1231.f, b = .7849321232f; +		LLColor3 llcolor3(r,g,b); +		llcolor3.clamp(); +		ensure("1:clamp:Fail to clamp " ,(1.0f == llcolor3.mV[0]) && (0.f == llcolor3.mV[1]) && (b == llcolor3.mV[2])); +		r = -2.3436212f, g = -1231.f, b = 67.7849321232f; +		llcolor3.setVec(r,g,b); +		llcolor3.clamp(); +		ensure("2:clamp:Fail to clamp " ,(0.f == llcolor3.mV[0]) && (0.f == llcolor3.mV[1]) && (1.f == llcolor3.mV[2])); +	} + +	template<> template<> +	void v3color_object::test<18>() +	{ +		F32 r1 =1.f, g1 = 2.f,b1 = 1.2f, r2 = -2.3f, g2 = 1.11f, b2 = 1234.234f; +		F32 val = 2.3f,val1,val2,val3; +		LLColor3 llcolor3(r1,g1,b1),llcolor3a(r2,g2,b2); +		val1 = r1 + (r2 - r1)* val; +		val2 = g1 + (g2 - g1)* val; +		val3 = b1 + (b2 - b1)* val; +		LLColor3 llcolor3b = lerp(llcolor3,llcolor3a,val); +		ensure("lerp failed ", ((val1 ==llcolor3b.mV[0])&& (val2 ==llcolor3b.mV[1]) && (val3 ==llcolor3b.mV[2])));		 +	} + +	template<> template<> +	void v3color_object::test<19>() +	{ +		F32 r1 =1.f, g1 = 2.f,b1 = 1.2f, r2 = -2.3f, g2 = 1.11f, b2 = 1234.234f; +		LLColor3 llcolor3(r1,g1,b1),llcolor3a(r2,g2,b2); +		F32 val = distVec(llcolor3,llcolor3a); +		ensure("distVec failed ", is_approx_equal(fsqrtf((r1-r2)*(r1-r2) + (g1-g2)*(g1-g2) + (b1-b2)*(b1-b2)) ,val)); +		 +		F32 val1 = distVec_squared(llcolor3,llcolor3a); +		ensure("distVec_squared failed ", is_approx_equal(((r1-r2)*(r1-r2) + (g1-g2)*(g1-g2) + (b1-b2)*(b1-b2)) ,val1)); +	} + +	template<> template<> +	void v3color_object::test<20>() +	{ +		F32 r1 = 1.02223f, g1 = 22222.212f, b1 = 122222.00002f; +		LLColor3 llcolor31(r1,g1,b1); + +		LLSD sd = llcolor31.getValue(); +		LLColor3 llcolor32; +		llcolor32.setValue(sd); +		ensure_equals("LLColor3::setValue/getValue failed", llcolor31, llcolor32); + +		LLColor3 llcolor33(sd); +		ensure_equals("LLColor3(LLSD) failed", llcolor31, llcolor33); +	} +} diff --git a/indra/llmath/tests/v3dmath_test.cpp b/indra/llmath/tests/v3dmath_test.cpp new file mode 100644 index 0000000000..780495e53d --- /dev/null +++ b/indra/llmath/tests/v3dmath_test.cpp @@ -0,0 +1,532 @@ +/** + * @file v3dmath_tut.cpp + * @author Adroit + * @date 2007-03 + * @brief v3dmath test cases. + * + * $LicenseInfo:firstyear=2007&license=viewergpl$ + *  + * Copyright (c) 2007-2009, Linden Research, Inc. + *  + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab.  Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + *  + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + *  + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + *  + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ +  +#include "linden_common.h" +#include "llsd.h" +#include "../test/lltut.h" + +#include "../llquaternion.h" +#include "../m3math.h" +#include "../v4math.h" +#include "../v3dmath.h" +#include "../v3dmath.h" + +namespace tut +{ +	struct v3dmath_data +	{ +	}; +	typedef test_group<v3dmath_data> v3dmath_test; +	typedef v3dmath_test::object v3dmath_object; +	tut::v3dmath_test v3dmath_testcase("v3dmath"); + +	template<> template<> +	void v3dmath_object::test<1>() +	{ +		LLVector3d vec3D; +		ensure("1:LLVector3d:Fail to initialize ", ((0 == vec3D.mdV[VX]) && (0 == vec3D.mdV[VY]) && (0 == vec3D.mdV[VZ]))); +		F64 x = 2.32f, y = 1.212f, z = -.12f; +		LLVector3d vec3Da(x,y,z); +		ensure("2:LLVector3d:Fail to initialize ", ((2.32f == vec3Da.mdV[VX]) && (1.212f == vec3Da.mdV[VY]) && (-.12f == vec3Da.mdV[VZ]))); +		const F64 vec[3] = {1.2f ,3.2f, -4.2f}; +		LLVector3d vec3Db(vec); +		ensure("3:LLVector3d:Fail to initialize ", ((1.2f == vec3Db.mdV[VX]) && (3.2f == vec3Db.mdV[VY]) && (-4.2f == vec3Db.mdV[VZ]))); +		LLVector3 vec3((F32)x,(F32)y,(F32)z); +		LLVector3d vec3Dc(vec3); +		ensure_equals("4:LLVector3d Fail to initialize",vec3Da,vec3Dc); +	} + +	template<> template<> +	void v3dmath_object::test<2>() +	{ +		S32 a = -235; +		LLSD llsd(a); +		LLVector3d vec3d(llsd); +		LLSD sd = vec3d.getValue(); +		LLVector3d vec3da(sd); +		ensure("1:getValue:Fail ", (vec3d == vec3da)); +	} + +	template<> template<> +	void v3dmath_object::test<3>() +	{ +		F64 a = 232345521.411132; +		LLSD llsd(a); +		LLVector3d vec3d; +		vec3d.setValue(llsd); +		LLSD sd = vec3d.getValue(); +		LLVector3d vec3da(sd); +		ensure("1:setValue:Fail to initialize ", (vec3d == vec3da)); +	} + +	template<> template<> +	void v3dmath_object::test<4>() +	{ +		F64 a[3] = {222231.43222, 12345.2343, -434343.33222}; +		LLSD llsd; +		llsd[0] = a[0]; +		llsd[1] = a[1]; +		llsd[2] = a[2]; +		LLVector3d vec3D; +		vec3D = (LLVector3d)llsd; +		ensure("1:operator=:Fail to initialize ", ((llsd[0].asReal()== vec3D.mdV[VX]) && (llsd[1].asReal() == vec3D.mdV[VY]) && (llsd[2].asReal() == vec3D.mdV[VZ]))); +	} +	 +	template<> template<> +	void v3dmath_object::test<5>() +	{ +		F64 x = 2.32f, y = 1.212f, z = -.12f; +		LLVector3d vec3D(x,y,z); +		vec3D.clearVec(); +		ensure("1:clearVec:Fail to initialize ", ((0 == vec3D.mdV[VX]) && (0 == vec3D.mdV[VY]) && (0 == vec3D.mdV[VZ]))); +		vec3D.setVec(x,y,z); +		ensure("2:setVec:Fail to initialize ", ((x == vec3D.mdV[VX]) && (y == vec3D.mdV[VY]) && (z == vec3D.mdV[VZ]))); +		vec3D.zeroVec(); +		ensure("3:zeroVec:Fail to initialize ", ((0 == vec3D.mdV[VX]) && (0 == vec3D.mdV[VY]) && (0 == vec3D.mdV[VZ]))); +		vec3D.clearVec(); +		LLVector3 vec3((F32)x,(F32)y,(F32)z); +		vec3D.setVec(vec3); +		ensure("4:setVec:Fail to initialize ", ((x == vec3D.mdV[VX]) && (y == vec3D.mdV[VY]) && (z == vec3D.mdV[VZ]))); +		vec3D.clearVec(); +		const F64 vec[3] = {x,y,z}; +		vec3D.setVec(vec); +		ensure("5:setVec:Fail to initialize ", ((x == vec3D.mdV[VX]) && (y == vec3D.mdV[VY]) && (z == vec3D.mdV[VZ]))); +		LLVector3d vec3Da; +		vec3Da.setVec(vec3D); +		ensure_equals("6:setVec: Fail to initialize", vec3D, vec3Da); +	} +	 +	template<> template<> +	void v3dmath_object::test<6>() +	{ +		F64 x = -2.32, y = 1.212, z = -.12; +		LLVector3d vec3D(x,y,z); +		vec3D.abs(); +		ensure("1:abs:Fail  ", ((-x == vec3D.mdV[VX]) && (y == vec3D.mdV[VY]) && (-z == vec3D.mdV[VZ]))); +		ensure("2:isNull():Fail ", (FALSE == vec3D.isNull()));	 +		vec3D.clearVec(); +		x =.00000001, y = .000001001, z = .000001001; +		vec3D.setVec(x,y,z); +		ensure("3:isNull():Fail ", (TRUE == vec3D.isNull()));	 +		ensure("4:isExactlyZero():Fail ", (FALSE == vec3D.isExactlyZero()));	 +		x =.0000000, y = .00000000, z = .00000000; +		vec3D.setVec(x,y,z); +		ensure("5:isExactlyZero():Fail ", (TRUE == vec3D.isExactlyZero()));	 +	} + +	template<> template<> +	void v3dmath_object::test<7>() +	{ +		F64 x = -2.32, y = 1.212, z = -.12; +		LLVector3d vec3D(x,y,z); +		 +		ensure("1:operator [] failed",( x ==  vec3D[0]));	 +		ensure("2:operator [] failed",( y ==  vec3D[1])); +		ensure("3:operator [] failed",( z ==  vec3D[2])); +		vec3D.clearVec(); +		x = 23.23, y = -.2361, z = 3.25; +		vec3D.setVec(x,y,z); +		F64 &ref1 = vec3D[0]; +		ensure("4:operator [] failed",( ref1 ==  vec3D[0])); +		F64 &ref2 = vec3D[1]; +		ensure("5:operator [] failed",( ref2 ==  vec3D[1])); +		F64 &ref3 = vec3D[2]; +		ensure("6:operator [] failed",( ref3 ==  vec3D[2])); +	} + +	template<> template<> +	void v3dmath_object::test<8>() +	{ +		F32 x = 1.f, y = 2.f, z = -1.f; +		LLVector4 vec4(x,y,z);		 +		LLVector3d vec3D; +		vec3D = vec4; +		ensure("1:operator=:Fail to initialize ", ((vec4.mV[VX] == vec3D.mdV[VX]) && (vec4.mV[VY] == vec3D.mdV[VY]) && (vec4.mV[VZ] == vec3D.mdV[VZ]))); +	} + +	template<> template<> +	void v3dmath_object::test<9>() +	{ +		F64 x1 = 1.78787878, y1 = 232322.2121, z1 = -12121.121212; +		F64 x2 = 1.2, y2 = 2.5, z2 = 1.; +		LLVector3d vec3D(x1,y1,z1),vec3Da(x2,y2,z2),vec3Db; +		vec3Db = vec3Da+ vec3D; +		ensure("1:operator+:Fail to initialize ", ((x1+x2 == vec3Db.mdV[VX]) && (y1+y2 == vec3Db.mdV[VY]) && (z1+z2 == vec3Db.mdV[VZ]))); +		x1 = -2.45, y1 = 2.1, z1 = 3.0; +		vec3D.clearVec(); +		vec3Da.clearVec(); +		vec3D.setVec(x1,y1,z1); +		vec3Da += vec3D; +		ensure_equals("2:operator+=: Fail to initialize", vec3Da,vec3D); +		vec3Da += vec3D; +		ensure("3:operator+=:Fail to initialize ", ((2*x1 == vec3Da.mdV[VX]) && (2*y1 == vec3Da.mdV[VY]) && (2*z1 == vec3Da.mdV[VZ]))); +	} + +	template<> template<> +	void v3dmath_object::test<10>() +	{ +		F64 x1 = 1., y1 = 2., z1 = -1.1; +		F64 x2 = 1.2, y2 = 2.5, z2 = 1.; +		LLVector3d vec3D(x1,y1,z1),vec3Da(x2,y2,z2),vec3Db; +		vec3Db = vec3Da - vec3D; +		ensure("1:operator-:Fail to initialize ", ((x2-x1 == vec3Db.mdV[VX]) && (y2-y1 == vec3Db.mdV[VY]) && (z2-z1 == vec3Db.mdV[VZ]))); +		x1 = -2.45, y1 = 2.1, z1 = 3.0; +		vec3D.clearVec(); +		vec3Da.clearVec(); +		vec3D.setVec(x1,y1,z1); +		vec3Da -=vec3D; +		ensure("2:operator-=:Fail to initialize ", ((2.45 == vec3Da.mdV[VX]) && (-2.1 == vec3Da.mdV[VY]) && (-3.0 == vec3Da.mdV[VZ]))); +		vec3Da -= vec3D; +		ensure("3:operator-=:Fail to initialize ", ((-2*x1 == vec3Da.mdV[VX]) && (-2*y1 == vec3Da.mdV[VY]) && (-2*z1 == vec3Da.mdV[VZ]))); +	} +	template<> template<> +	void v3dmath_object::test<11>() +	{ +		F64 x1 = 1., y1 = 2., z1 = -1.1; +		F64 x2 = 1.2, y2 = 2.5, z2 = 1.; +		LLVector3d vec3D(x1,y1,z1),vec3Da(x2,y2,z2); +		F64 res = vec3D * vec3Da; +		ensure_approximately_equals( +			"1:operator* failed", +			res, +			(x1*x2 + y1*y2 + z1*z2), +			8); +		vec3Da.clearVec(); +		F64 mulVal = 4.2; +		vec3Da = vec3D * mulVal; +		ensure_approximately_equals( +			"2a:operator* failed", +			vec3Da.mdV[VX], +			x1*mulVal, +			8); +		ensure_approximately_equals( +			"2b:operator* failed", +			vec3Da.mdV[VY], +			y1*mulVal, +			8); +		ensure_approximately_equals( +			"2c:operator* failed", +			vec3Da.mdV[VZ], +			z1*mulVal, +			8); +		vec3Da.clearVec(); +		vec3Da = mulVal * vec3D; +		ensure_approximately_equals( +			"3a:operator* failed", +			vec3Da.mdV[VX], +			x1*mulVal, +			8); +		ensure_approximately_equals( +			"3b:operator* failed", +			vec3Da.mdV[VY], +			y1*mulVal, +			8); +		ensure_approximately_equals( +			"3c:operator* failed", +			vec3Da.mdV[VZ], +			z1*mulVal, +			8); +		vec3D *= mulVal; +		ensure_approximately_equals( +			"4a:operator*= failed", +			vec3D.mdV[VX], +			x1*mulVal, +			8); +		ensure_approximately_equals( +			"4b:operator*= failed", +			vec3D.mdV[VY], +			y1*mulVal, +			8); +		ensure_approximately_equals( +			"4c:operator*= failed", +			vec3D.mdV[VZ], +			z1*mulVal, +			8); +	} + +	template<> template<> +	void v3dmath_object::test<12>() +	{ +		F64 x1 = 1., y1 = 2., z1 = -1.1; +		F64 x2 = 1.2, y2 = 2.5, z2 = 1.; +		F64 val1, val2, val3; +		LLVector3d vec3D(x1,y1,z1),vec3Da(x2,y2,z2), vec3Db; +		vec3Db = vec3D % vec3Da; +		val1 = y1*z2 - y2*z1; +		val2 = z1*x2 -z2*x1; +		val3 = x1*y2-x2*y1; +		ensure("1:operator% failed",(val1 == vec3Db.mdV[VX]) && (val2 == vec3Db.mdV[VY]) && (val3 == vec3Db.mdV[VZ]));  +		vec3D %= vec3Da; +		ensure("2:operator%= failed", +		       is_approx_equal(vec3D.mdV[VX],vec3Db.mdV[VX]) && +		       is_approx_equal(vec3D.mdV[VY],vec3Db.mdV[VY]) && +		       is_approx_equal(vec3D.mdV[VZ],vec3Db.mdV[VZ]) );  +	} + +	template<> template<> +	void v3dmath_object::test<13>() +	{ +		F64 x1 = 1., y1 = 2., z1 = -1.1,div = 4.2; +		F64 t = 1.f / div; +		LLVector3d vec3D(x1,y1,z1), vec3Da; +		vec3Da = vec3D/div; +		ensure_approximately_equals( +			"1a:operator/ failed", +			vec3Da.mdV[VX], +			x1*t, +			8); +		ensure_approximately_equals( +			"1b:operator/ failed", +			vec3Da.mdV[VY], +			y1*t, +			8); +		ensure_approximately_equals( +			"1c:operator/ failed", +			vec3Da.mdV[VZ], +			z1*t, +			8); +		x1 = 1.23, y1 = 4., z1 = -2.32; +		vec3D.clearVec(); +		vec3Da.clearVec(); +		vec3D.setVec(x1,y1,z1); +		vec3Da = vec3D/div; +		ensure_approximately_equals( +			"2a:operator/ failed", +			vec3Da.mdV[VX], +			x1*t, +			8); +		ensure_approximately_equals( +			"2b:operator/ failed", +			vec3Da.mdV[VY], +			y1*t, +			8); +		ensure_approximately_equals( +			"2c:operator/ failed", +			vec3Da.mdV[VZ], +			z1*t, +			8); +		vec3D /= div; +		ensure_approximately_equals( +			"3a:operator/= failed", +			vec3D.mdV[VX], +			x1*t, +			8); +		ensure_approximately_equals( +			"3b:operator/= failed", +			vec3D.mdV[VY], +			y1*t, +			8); +		ensure_approximately_equals( +			"3c:operator/= failed", +			vec3D.mdV[VZ], +			z1*t, +			8); +	} + +	template<> template<> +	void v3dmath_object::test<14>() +	{ +		F64 x1 = 1., y1 = 2., z1 = -1.1; +		LLVector3d vec3D(x1,y1,z1), vec3Da; +		ensure("1:operator!= failed",(TRUE == (vec3D !=vec3Da))); +		vec3Da = vec3D; +		ensure("2:operator== failed",(vec3D ==vec3Da));  +		vec3D.clearVec(); +		vec3Da.clearVec(); +		x1 = .211, y1 = 21.111, z1 = 23.22; +		vec3D.setVec(x1,y1,z1); +		vec3Da.setVec(x1,y1,z1); +		ensure("3:operator== failed",(vec3D ==vec3Da));  +		ensure("4:operator!= failed",(FALSE == (vec3D !=vec3Da))); +	} +		 +	template<> template<> +	void v3dmath_object::test<15>() +	{ +		F64 x1 = 1., y1 = 2., z1 = -1.1; +		LLVector3d vec3D(x1,y1,z1), vec3Da; +		std::ostringstream stream1, stream2; +		stream1 << vec3D; +		vec3Da.setVec(x1,y1,z1); +		stream2 << vec3Da; +		ensure("1:operator << failed",(stream1.str() == stream2.str()));	 +	} + +	template<> template<> +	void v3dmath_object::test<16>() +	{ +		F64 x1 = 1.23, y1 = 2.0, z1 = 4.; +		std::string buf("1.23 2. 4"); +		LLVector3d vec3D, vec3Da(x1,y1,z1); +		LLVector3d::parseVector3d(buf, &vec3D); +		ensure_equals("1:parseVector3d: failed " , vec3D, vec3Da);	 +	} + +	template<> template<> +	void v3dmath_object::test<17>() +	{ +		F64 x1 = 1., y1 = 2., z1 = -1.1; +		LLVector3d vec3D(x1,y1,z1), vec3Da; +		vec3Da = -vec3D; +		ensure("1:operator- failed", (vec3D == - vec3Da));	 +	} + +	template<> template<> +	void v3dmath_object::test<18>() +	{ +		F64 x = 1., y = 2., z = -1.1; +		LLVector3d vec3D(x,y,z); +		F64 res = (x*x + y*y + z*z) - vec3D.magVecSquared(); +		ensure("1:magVecSquared:Fail ", ((-F_APPROXIMATELY_ZERO <= res)&& (res <=F_APPROXIMATELY_ZERO))); +		res = fsqrtf(x*x + y*y + z*z) - vec3D.magVec(); +		ensure("2:magVec: Fail ", ((-F_APPROXIMATELY_ZERO <= res)&& (res <=F_APPROXIMATELY_ZERO)));	 +	} + +	template<> template<> +	void v3dmath_object::test<19>() +	{ +		F64 x = 1., y = 2., z = -1.1; +		LLVector3d vec3D(x,y,z); +		F64 mag = vec3D.normVec(); +		mag = 1.f/ mag; +		ensure_approximately_equals( +			"1a:normVec: Fail ", +			vec3D.mdV[VX], +			x * mag, +			8); +		ensure_approximately_equals( +			"1b:normVec: Fail ", +			vec3D.mdV[VY], +			y * mag, +			8); +		ensure_approximately_equals( +			"1c:normVec: Fail ", +			vec3D.mdV[VZ], +			z * mag, +			8); +		x = 0.000000001, y = 0.000000001, z = 0.000000001; +		vec3D.clearVec(); +		vec3D.setVec(x,y,z); +		mag = vec3D.normVec(); +		ensure_approximately_equals( +			"2a:normVec: Fail ", +			vec3D.mdV[VX], +			x * mag, +			8); +		ensure_approximately_equals( +			"2b:normVec: Fail ", +			vec3D.mdV[VY], +			y * mag, +			8); +		ensure_approximately_equals( +			"2c:normVec: Fail ", +			vec3D.mdV[VZ], +			z * mag, +			8); +	} + +	template<> template<> +	void v3dmath_object::test<20>() +	{ +		F64 x1 = 1111.232222; +		F64 y1 = 2222222222.22; +		F64 z1 = 422222222222.0; +		std::string buf("1111.232222 2222222222.22 422222222222"); +		LLVector3d vec3Da, vec3Db(x1,y1,z1); +		LLVector3d::parseVector3d(buf, &vec3Da); +		ensure_equals("1:parseVector3 failed", vec3Da, vec3Db);	 +	} + +	template<> template<> +	void v3dmath_object::test<21>() +	{ +		F64 x1 = 1., y1 = 2., z1 = -1.1; +		F64 x2 = 1.2, y2 = 2.5, z2 = 1.; +		F64 val = 2.3f,val1,val2,val3; +		val1 = x1 + (x2 - x1)* val; +		val2 = y1 + (y2 - y1)* val; +		val3 = z1 + (z2 - z1)* val; +		LLVector3d vec3Da(x1,y1,z1),vec3Db(x2,y2,z2); +		LLVector3d vec3d = lerp(vec3Da,vec3Db,val); +		ensure("1:lerp failed", ((val1 ==vec3d.mdV[VX])&& (val2 ==vec3d.mdV[VY]) && (val3 ==vec3d.mdV[VZ])));		 +	} + +	template<> template<> +	void v3dmath_object::test<22>() +	{ +		F64 x = 2.32, y = 1.212, z = -.12; +		F64 min = 0.0001, max = 3.0; +		LLVector3d vec3d(x,y,z);		 +		ensure("1:clamp:Fail ", (TRUE == (vec3d.clamp(min, max)))); +		x = 0.000001f, z = 5.3f; +		vec3d.setVec(x,y,z); +		ensure("2:clamp:Fail ", (TRUE == (vec3d.clamp(min, max)))); +	} + +	template<> template<> +	void v3dmath_object::test<23>() +	{ +		F64 x = 10., y = 20., z = -15.; +		F64 epsilon = .23425; +		LLVector3d vec3Da(x,y,z), vec3Db(x,y,z); +		ensure("1:are_parallel: Fail ", (TRUE == are_parallel(vec3Da,vec3Db,epsilon))); +		F64 x1 = -12., y1 = -20., z1 = -100.; +		vec3Db.clearVec(); +		vec3Db.setVec(x1,y1,z1); +		ensure("2:are_parallel: Fail ", (FALSE == are_parallel(vec3Da,vec3Db,epsilon))); +	} + +	template<> template<> +	void v3dmath_object::test<24>() +	{ +#if LL_WINDOWS && _MSC_VER < 1400 +		skip("This fails on VS2003!"); +#else +		F64 x = 10., y = 20., z = -15.; +		F64 angle1, angle2; +		LLVector3d vec3Da(x,y,z), vec3Db(x,y,z); +		angle1 = angle_between(vec3Da, vec3Db); +		ensure("1:angle_between: Fail ", (0 == angle1)); +		F64 x1 = -1., y1 = -20., z1 = -1.; +		vec3Da.clearVec(); +		vec3Da.setVec(x1,y1,z1); +		angle2 = angle_between(vec3Da, vec3Db); +		vec3Db.normVec(); +		vec3Da.normVec(); +		F64 angle = vec3Db*vec3Da; +		angle = acos(angle); +		ensure("2:angle_between: Fail ", (angle == angle2)); +#endif +	} +} diff --git a/indra/llmath/tests/v3math_test.cpp b/indra/llmath/tests/v3math_test.cpp new file mode 100644 index 0000000000..14159974a3 --- /dev/null +++ b/indra/llmath/tests/v3math_test.cpp @@ -0,0 +1,573 @@ +/** + * @file v3math_tut.cpp + * @author Adroit + * @date 2007-02 + * @brief v3math test cases. + * + * $LicenseInfo:firstyear=2007&license=viewergpl$ + *  + * Copyright (c) 2007-2009, Linden Research, Inc. + *  + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab.  Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + *  + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + *  + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + *  + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ +  +#include "linden_common.h" +#include "../test/lltut.h" +#include "llsd.h" + +#include "../llquaternion.h" +#include "../llquantize.h" +#include "../v3dmath.h" +#include "../m3math.h" +#include "../v4math.h" +#include "../v3math.h" + + +namespace tut +{ +	struct v3math_data +	{ +	}; +	typedef test_group<v3math_data> v3math_test; +	typedef v3math_test::object v3math_object; +	tut::v3math_test v3math_testcase("v3math"); + +	template<> template<> +	void v3math_object::test<1>() +	{ +		LLVector3 vec3; +		ensure("1:LLVector3:Fail to initialize ", ((0.f == vec3.mV[VX]) && (0.f == vec3.mV[VY]) && (0.f == vec3.mV[VZ]))); +		F32 x = 2.32f, y = 1.212f, z = -.12f; +		LLVector3 vec3a(x,y,z); +		ensure("2:LLVector3:Fail to initialize ", ((2.32f == vec3a.mV[VX]) && (1.212f == vec3a.mV[VY]) && (-.12f == vec3a.mV[VZ]))); +		const F32 vec[3] = {1.2f ,3.2f, -4.2f}; +		LLVector3 vec3b(vec); +		ensure("3:LLVector3:Fail to initialize ", ((1.2f == vec3b.mV[VX]) && (3.2f == vec3b.mV[VY]) && (-4.2f == vec3b.mV[VZ]))); +	} + +	template<> template<> +	void v3math_object::test<2>() +	{ +		F32 x = 2.32f, y = 1.212f, z = -.12f; +		LLVector3 vec3(x,y,z); +		LLVector3d vector3d(vec3); +		LLVector3 vec3a(vector3d); +		ensure("1:LLVector3:Fail to initialize ", vec3 == vec3a); +		LLVector4 vector4(vec3); +		LLVector3 vec3b(vector4); +		ensure("2:LLVector3:Fail to initialize ", vec3 == vec3b); +	} + +	template<> template<> +	void v3math_object::test<3>() +	{ +		S32 a = 231; +		LLSD llsd(a); +		LLVector3 vec3(llsd); +		LLSD sd = vec3.getValue(); +		LLVector3 vec3a(sd); +		ensure("1:LLVector3:Fail to initialize ", (vec3 == vec3a)); +	} + +	template<> template<> +	void v3math_object::test<4>() +	{ +		S32 a = 231; +		LLSD llsd(a); +		LLVector3 vec3(llsd),vec3a; +		vec3a = vec3; +		ensure("1:Operator= Fail to initialize " ,(vec3 == vec3a)); +	} +	 +	template<> template<> +	void v3math_object::test<5>() +	{ +		F32 x = 2.32f, y = 1.212f, z = -.12f; +		LLVector3 vec3(x,y,z); +		ensure("1:isFinite= Fail to initialize ", (TRUE == vec3.isFinite()));//need more test cases: +		vec3.clearVec(); +		ensure("2:clearVec:Fail to set values ", ((0.f == vec3.mV[VX]) && (0.f == vec3.mV[VY]) && (0.f == vec3.mV[VZ]))); +		vec3.setVec(x,y,z); +		ensure("3:setVec:Fail to set values ", ((2.32f == vec3.mV[VX]) && (1.212f == vec3.mV[VY]) && (-.12f == vec3.mV[VZ]))); +		vec3.zeroVec(); +		ensure("4:zeroVec:Fail to set values ", ((0.f == vec3.mV[VX]) && (0.f == vec3.mV[VY]) && (0.f == vec3.mV[VZ]))); +	} +	 +	template<> template<> +	void v3math_object::test<6>() +	{ +		F32 x = 2.32f, y = 1.212f, z = -.12f; +		LLVector3 vec3(x,y,z),vec3a; +		vec3.abs(); +		ensure("1:abs:Fail ", ((x == vec3.mV[VX]) && (y == vec3.mV[VY]) && (-z == vec3.mV[VZ]))); +		vec3a.setVec(vec3); +		ensure("2:setVec:Fail to initialize ", (vec3a == vec3));	 +		const F32 vec[3] = {1.2f ,3.2f, -4.2f}; +		vec3.clearVec(); +		vec3.setVec(vec); +		ensure("3:setVec:Fail to initialize ", ((1.2f == vec3.mV[VX]) && (3.2f == vec3.mV[VY]) && (-4.2f == vec3.mV[VZ]))); +		vec3a.clearVec(); +		LLVector3d vector3d(vec3); +		vec3a.setVec(vector3d); +		ensure("4:setVec:Fail to initialize ", (vec3 == vec3a)); +		LLVector4 vector4(vec3); +		vec3a.clearVec(); +		vec3a.setVec(vector4); +		ensure("5:setVec:Fail to initialize ", (vec3 == vec3a)); +	} + +	template<> template<> +	void v3math_object::test<7>() +	{ +		F32 x = 2.32f, y = 3.212f, z = -.12f; +		F32 min = 0.0001f, max = 3.0f; +		LLVector3 vec3(x,y,z);		 +		ensure("1:clamp:Fail  ", TRUE == vec3.clamp(min, max) && x == vec3.mV[VX] && max == vec3.mV[VY] && min == vec3.mV[VZ]); +		x = 1.f, y = 2.2f, z = 2.8f; +		vec3.setVec(x,y,z); +		ensure("2:clamp:Fail  ", FALSE == vec3.clamp(min, max)); +	} + +	template<> template<> +	void v3math_object::test<8>() +	{ +		F32 x = 2.32f, y = 1.212f, z = -.12f; +		LLVector3 vec3(x,y,z);		 +		ensure("1:magVecSquared:Fail ", is_approx_equal(vec3.magVecSquared(), (x*x + y*y + z*z))); +		ensure("2:magVec:Fail ", is_approx_equal(vec3.magVec(), fsqrtf(x*x + y*y + z*z))); +	} + +	template<> template<> +	void v3math_object::test<9>() +	{ +		F32 x =-2.0f, y = -3.0f, z = 1.23f ; +		LLVector3 vec3(x,y,z); +		ensure("1:abs():Fail ", (TRUE == vec3.abs()));	 +		ensure("2:isNull():Fail", (FALSE == vec3.isNull()));	//Returns TRUE if vector has a _very_small_ length +		x =.00000001f, y = .000001001f, z = .000001001f; +		vec3.setVec(x,y,z); +		ensure("3:isNull(): Fail ", (TRUE == vec3.isNull()));	 +	} + +	template<> template<> +	void v3math_object::test<10>() +	{ +		F32 x =-2.0f, y = -3.0f, z = 1.f ; +		LLVector3 vec3(x,y,z),vec3a; +		ensure("1:isExactlyZero():Fail ", (TRUE == vec3a.isExactlyZero())); +		vec3a = vec3a.scaleVec(vec3); +		ensure("2:scaleVec: Fail ", vec3a.mV[VX] == 0.f && vec3a.mV[VY] == 0.f && vec3a.mV[VZ] == 0.f); +		vec3a.setVec(x,y,z); +		vec3a = vec3a.scaleVec(vec3); +		ensure("3:scaleVec: Fail ", ((4 == vec3a.mV[VX]) && (9 == vec3a.mV[VY]) &&(1 == vec3a.mV[VZ]))); +		ensure("4:isExactlyZero():Fail ", (FALSE == vec3.isExactlyZero())); +	} + +	template<> template<> +	void v3math_object::test<11>() +	{ +		F32 x =20.0f, y = 30.0f, z = 15.f ; +		F32 angle = 100.f; +		LLVector3 vec3(x,y,z),vec3a(1.f,2.f,3.f); +		vec3a = vec3a.rotVec(angle, vec3); +		LLVector3 vec3b(1.f,2.f,3.f); +		vec3b = vec3b.rotVec(angle, vec3); +		ensure_equals("rotVec():Fail" ,vec3b,vec3a); +	} + +	template<> template<> +	void v3math_object::test<12>() +	{ +		F32 x =-2.0f, y = -3.0f, z = 1.f ; +		LLVector3 vec3(x,y,z); +		ensure("1:operator [] failed",( x ==  vec3[0]));	 +		ensure("2:operator [] failed",( y ==  vec3[1])); +		ensure("3:operator [] failed",( z ==  vec3[2])); + +		vec3.clearVec(); +		x = 23.f, y = -.2361f, z = 3.25; +		vec3.setVec(x,y,z); +		F32 &ref1 = vec3[0]; +		ensure("4:operator [] failed",( ref1 ==  vec3[0])); +		F32 &ref2 = vec3[1]; +		ensure("5:operator [] failed",( ref2 ==  vec3[1])); +		F32 &ref3 = vec3[2]; +		ensure("6:operator [] failed",( ref3 ==  vec3[2])); +	} + +	template<> template<> +	void v3math_object::test<13>() +	{ +		F32 x1 =1.f, y1 = 2.f,z1 = 1.2f, x2 = -2.3f, y2 = 1.11f, z2 = 1234.234f; +		F32 val1, val2, val3; +		LLVector3 vec3(x1,y1,z1), vec3a(x2,y2,z2), vec3b; +		vec3b = vec3 + vec3a ; +		val1 = x1+x2; +		val2 = y1+y2; +		val3 = z1+z2; +		ensure("1:operator+ failed",(val1 == vec3b.mV[VX]) && (val2 == vec3b.mV[VY]) && (val3 == vec3b.mV[VZ]));  + +		vec3.clearVec(); +		vec3a.clearVec(); +		vec3b.clearVec(); +		x1 = -.235f, y1 = -24.32f,z1 = 2.13f,  x2 = -2.3f, y2 = 1.f, z2 = 34.21f; +		vec3.setVec(x1,y1,z1); +		vec3a.setVec(x2,y2,z2); +		vec3b = vec3 + vec3a; +		val1 = x1+x2; +		val2 = y1+y2; +		val3 = z1+z2; +		ensure("2:operator+ failed",(val1 == vec3b.mV[VX]) && (val2 == vec3b.mV[VY]) && (val3 == vec3b.mV[VZ]));  +	} + +	template<> template<> +	void v3math_object::test<14>() +	{ +		F32 x1 =1.f, y1 = 2.f,z1 = 1.2f, x2 = -2.3f, y2 = 1.11f, z2 = 1234.234f; +		F32 val1, val2, val3; +		LLVector3 vec3(x1,y1,z1), vec3a(x2,y2,z2), vec3b; +		vec3b = vec3 - vec3a ; +		val1 = x1-x2; +		val2 = y1-y2; +		val3 = z1-z2; +		ensure("1:operator- failed",(val1 == vec3b.mV[VX]) && (val2 == vec3b.mV[VY]) && (val3 == vec3b.mV[VZ]));  + +		vec3.clearVec(); +		vec3a.clearVec(); +		vec3b.clearVec(); +		x1 = -.235f, y1 = -24.32f,z1 = 2.13f,  x2 = -2.3f, y2 = 1.f, z2 = 34.21f; +		vec3.setVec(x1,y1,z1); +		vec3a.setVec(x2,y2,z2); +		vec3b = vec3 - vec3a; +		val1 = x1-x2; +		val2 = y1-y2; +		val3 = z1-z2; +		ensure("2:operator- failed",(val1 == vec3b.mV[VX]) && (val2 == vec3b.mV[VY]) && (val3 == vec3b.mV[VZ]));  +	} + +	template<> template<> +	void v3math_object::test<15>() +	{ +		F32 x1 =1.f, y1 = 2.f,z1 = 1.2f, x2 = -2.3f, y2 = 1.11f, z2 = 1234.234f; +		F32 val1, val2, val3; +		LLVector3 vec3(x1,y1,z1), vec3a(x2,y2,z2); +		val1 = vec3 * vec3a; +		val2 = x1*x2 + y1*y2 + z1*z2; +		ensure_equals("1:operator* failed",val1,val2); + +		vec3a.clearVec(); +		F32 mulVal = 4.332f; +		vec3a = vec3 * mulVal; +		val1 = x1*mulVal; +		val2 = y1*mulVal; +		val3 = z1*mulVal; +		ensure("2:operator* failed",(val1 == vec3a.mV[VX]) && (val2 == vec3a.mV[VY])&& (val3 == vec3a.mV[VZ])); +		vec3a.clearVec(); +		vec3a = mulVal * vec3; +		ensure("3:operator* failed ", (val1 == vec3a.mV[VX]) && (val2 == vec3a.mV[VY])&& (val3 == vec3a.mV[VZ])); +	} + +	template<> template<> +	void v3math_object::test<16>() +	{ +		F32 x1 =1.f, y1 = 2.f,z1 = 1.2f, x2 = -2.3f, y2 = 1.11f, z2 = 1234.234f; +		F32 val1, val2, val3; +		LLVector3 vec3(x1,y1,z1), vec3a(x2,y2,z2), vec3b; +		vec3b = vec3 % vec3a ; +		val1 = y1*z2 - y2*z1; +		val2 = z1*x2 -z2*x1; +		val3 = x1*y2-x2*y1; +		ensure("1:operator% failed",(val1 == vec3b.mV[VX]) && (val2 == vec3b.mV[VY]) && (val3 == vec3b.mV[VZ]));  + +		vec3.clearVec(); +		vec3a.clearVec(); +		vec3b.clearVec(); +		x1 =112.f, y1 = 22.3f,z1 = 1.2f, x2 = -2.3f, y2 = 341.11f, z2 = 1234.234f; +		vec3.setVec(x1,y1,z1); +		vec3a.setVec(x2,y2,z2); +		vec3b = vec3 % vec3a ; +		val1 = y1*z2 - y2*z1; +		val2 = z1*x2 -z2*x1; +		val3 = x1*y2-x2*y1; +		ensure("2:operator% failed ", (val1 == vec3b.mV[VX]) && (val2 == vec3b.mV[VY]) && (val3 == vec3b.mV[VZ]));  +	} + +	template<> template<> +	void v3math_object::test<17>() +	{ +		F32 x1 =1.f, y1 = 2.f,z1 = 1.2f, div = 3.2f; +		F32 t = 1.f / div, val1, val2, val3; +		LLVector3 vec3(x1,y1,z1), vec3a; +		vec3a = vec3 / div; +		val1 = x1 * t; +		val2 = y1 * t; +		val3 = z1 *t; +		ensure("1:operator/ failed",(val1 == vec3a.mV[VX]) && (val2 == vec3a.mV[VY]) && (val3 == vec3a.mV[VZ]));		 + +		vec3a.clearVec(); +		x1 = -.235f, y1 = -24.32f, z1 = .342f, div = -2.2f; +		t = 1.f / div; +		vec3.setVec(x1,y1,z1); +		vec3a = vec3 / div; +		val1 = x1 * t; +		val2 = y1 * t; +		val3 = z1 *t; +		ensure("2:operator/ failed",(val1 == vec3a.mV[VX]) && (val2 == vec3a.mV[VY]) && (val3 == vec3a.mV[VZ]));		 +	} + +	template<> template<> +	void v3math_object::test<18>() +	{ +		F32 x1 =1.f, y1 = 2.f,z1 = 1.2f; +		LLVector3 vec3(x1,y1,z1), vec3a(x1,y1,z1); +		ensure("1:operator== failed",(vec3 == vec3a));		 + +		vec3a.clearVec(); +		x1 = -.235f, y1 = -24.32f, z1 = .342f; +		vec3.clearVec(); +		vec3a.clearVec(); +		vec3.setVec(x1,y1,z1); +		vec3a.setVec(x1,y1,z1); +		ensure("2:operator== failed ", (vec3 == vec3a));		 +	} + +	template<> template<> +	void v3math_object::test<19>() +	{ +		F32 x1 =1.f, y1 = 2.f,z1 = 1.2f, x2 =112.f, y2 = 2.234f,z2 = 11.2f;; +		LLVector3 vec3(x1,y1,z1), vec3a(x2,y2,z2); +		ensure("1:operator!= failed",(vec3a != vec3)); + +		vec3.clearVec(); +		vec3.clearVec(); +		vec3a.setVec(vec3); +		ensure("2:operator!= failed", ( FALSE == (vec3a != vec3))); +	} + +	template<> template<> +	void v3math_object::test<20>() +	{ +		F32 x1 =1.f, y1 = 2.f,z1 = 1.2f, x2 =112.f, y2 = 2.2f,z2 = 11.2f;; +		LLVector3 vec3(x1,y1,z1), vec3a(x2,y2,z2); +		vec3a += vec3; +		F32 val1, val2, val3; +		val1 = x1+x2; +		val2 = y1+y2; +		val3 = z1+z2; +		ensure("1:operator+= failed",(val1 == vec3a.mV[VX]) && (val2 == vec3a.mV[VY])&& (val3 == vec3a.mV[VZ])); +	} +	 +	template<> template<> +	void v3math_object::test<21>() +	{ +		F32 x1 =1.f, y1 = 2.f,z1 = 1.2f, x2 =112.f, y2 = 2.2f,z2 = 11.2f;; +		LLVector3 vec3(x1,y1,z1), vec3a(x2,y2,z2); +		vec3a -= vec3; +		F32 val1, val2, val3; +		val1 = x2-x1; +		val2 = y2-y1; +		val3 = z2-z1; +		ensure("1:operator-= failed",(val1 == vec3a.mV[VX]) && (val2 == vec3a.mV[VY])&& (val3 == vec3a.mV[VZ])); +	} + +	template<> template<> +	void v3math_object::test<22>() +	{ +		F32 x1 =1.f, y1 = 2.f,z1 = 1.2f, x2 = -2.3f, y2 = 1.11f, z2 = 1234.234f; +		F32 val1,val2,val3; +		LLVector3 vec3(x1,y1,z1), vec3a(x2,y2,z2); +		vec3a *= vec3; +		val1 = x1*x2; +		val2 = y1*y2; +		val3 = z1*z2; +		ensure("1:operator*= failed",(val1 == vec3a.mV[VX]) && (val2 == vec3a.mV[VY])&& (val3 == vec3a.mV[VZ])); + +		F32 mulVal = 4.332f; +		vec3 *=mulVal; +		val1 = x1*mulVal; +		val2 = y1*mulVal; +		val3 = z1*mulVal; +		ensure("2:operator*= failed ", is_approx_equal(val1, vec3.mV[VX]) && is_approx_equal(val2, vec3.mV[VY]) && is_approx_equal(val3, vec3.mV[VZ])); +	} + +	template<> template<> +	void v3math_object::test<23>() +	{ +		F32 x1 =1.f, y1 = 2.f,z1 = 1.2f, x2 = -2.3f, y2 = 1.11f, z2 = 1234.234f; +		LLVector3 vec3(x1,y1,z1), vec3a(x2,y2,z2),vec3b; +		vec3b = vec3a % vec3; +		vec3a %= vec3; +		ensure_equals("1:operator%= failed",vec3a,vec3b);  +	} + +	template<> template<> +	void v3math_object::test<24>() +	{ +		F32 x1 =1.f, y1 = 2.f,z1 = 1.2f, div = 3.2f; +		F32 t = 1.f / div, val1, val2, val3; +		LLVector3 vec3a(x1,y1,z1); +		vec3a /= div; +		val1 = x1 * t; +		val2 = y1 * t; +		val3 = z1 *t; +		ensure("1:operator/= failed",(val1 == vec3a.mV[VX]) && (val2 == vec3a.mV[VY]) && (val3 == vec3a.mV[VZ]));		 +	} + +	template<> template<> +	void v3math_object::test<25>() +	{ +		F32 x1 =1.f, y1 = 2.f,z1 = 1.2f; +		LLVector3 vec3(x1,y1,z1), vec3a; +		vec3a = -vec3; +		ensure("1:operator- failed",(-vec3a == vec3));	 +	} + +	template<> template<> +	void v3math_object::test<26>() +	{ +		F32 x1 =1.f, y1 = 2.f,z1 = 1.2f; +		std::ostringstream stream1, stream2; +		LLVector3 vec3(x1,y1,z1), vec3a; +		stream1 << vec3; +		vec3a.setVec(x1,y1,z1); +		stream2 << vec3a; +		ensure("1:operator << failed",(stream1.str() == stream2.str()));	 +	} + +	template<> template<> +	void v3math_object::test<27>() +	{ +		F32 x1 =-2.3f, y1 = 2.f,z1 = 1.2f, x2 = 1.3f, y2 = 1.11f, z2 = 1234.234f; +		LLVector3 vec3(x1,y1,z1), vec3a(x2,y2,z2); +		ensure("1:operator< failed", (TRUE == (vec3 < vec3a))); +		x1 =-2.3f, y1 = 2.f,z1 = 1.2f, x2 = 1.3f, y2 = 2.f, z2 = 1234.234f; +		vec3.setVec(x1,y1,z1); +		vec3a.setVec(x2,y2,z2); +		ensure("2:operator< failed ", (TRUE == (vec3 < vec3a))); +		x1 =2.3f, y1 = 2.f,z1 = 1.2f, x2 = 1.3f, +		vec3.setVec(x1,y1,z1); +		vec3a.setVec(x2,y2,z2); +		ensure("3:operator< failed ", (FALSE == (vec3 < vec3a))); +	} + +	template<> template<> +	void v3math_object::test<28>() +	{ +		F32 x1 =1.23f, y1 = 2.f,z1 = 4.f; +		std::string buf("1.23 2. 4"); +		LLVector3 vec3, vec3a(x1,y1,z1); +		LLVector3::parseVector3(buf, &vec3); +		ensure_equals("1:parseVector3 failed", vec3, vec3a);	 +	} + +	template<> template<> +	void v3math_object::test<29>() +	{ +		F32 x1 =1.f, y1 = 2.f,z1 = 4.f; +		LLVector3 vec3(x1,y1,z1),vec3a,vec3b; +		vec3a.setVec(1,1,1); +		vec3a.scaleVec(vec3); +		ensure_equals("1:scaleVec failed", vec3, vec3a);	 +		vec3a.clearVec(); +		vec3a.setVec(x1,y1,z1); +		vec3a.scaleVec(vec3); +		ensure("2:scaleVec failed", ((1.f ==vec3a.mV[VX])&& (4.f ==vec3a.mV[VY]) && (16.f ==vec3a.mV[VZ])));		 +	} +	 +	template<> template<> +	void v3math_object::test<30>() +	{ +		F32 x1 =-2.3f, y1 = 2.f,z1 = 1.2f, x2 = 1.3f, y2 = 1.11f, z2 = 1234.234f; +		F32 val = 2.3f,val1,val2,val3; +		val1 = x1 + (x2 - x1)* val; +		val2 = y1 + (y2 - y1)* val; +		val3 = z1 + (z2 - z1)* val; +		LLVector3 vec3(x1,y1,z1),vec3a(x2,y2,z2); +		LLVector3 vec3b = lerp(vec3,vec3a,val); +		ensure("1:lerp failed", ((val1 ==vec3b.mV[VX])&& (val2 ==vec3b.mV[VY]) && (val3 ==vec3b.mV[VZ])));		 +	} + +	template<> template<> +	void v3math_object::test<31>() +	{ +		F32 x1 =-2.3f, y1 = 2.f,z1 = 1.2f, x2 = 1.3f, y2 = 1.f, z2 = 1.f; +		F32 val1,val2; +		LLVector3 vec3(x1,y1,z1),vec3a(x2,y2,z2); +		val1 = dist_vec(vec3,vec3a); +		val2 = fsqrtf((x1 - x2)*(x1 - x2) + (y1 - y2)* (y1 - y2) + (z1 - z2)* (z1 -z2)); +		ensure_equals("1:dist_vec: Fail ",val2, val1); +		val1 = dist_vec_squared(vec3,vec3a); +		val2 =((x1 - x2)*(x1 - x2) + (y1 - y2)* (y1 - y2) + (z1 - z2)* (z1 -z2)); +		ensure_equals("2:dist_vec_squared: Fail ",val2, val1); +		val1 = dist_vec_squared2D(vec3, vec3a); +		val2 =(x1 - x2)*(x1 - x2) + (y1 - y2)* (y1 - y2); +		ensure_equals("3:dist_vec_squared2D: Fail ",val2, val1); +	} + +	template<> template<> +	void v3math_object::test<32>() +	{ +		F32 x =12.3524f, y = -342.f,z = 4.126341f; +		LLVector3 vec3(x,y,z); +		F32 mag = vec3.normVec(); +		mag = 1.f/ mag; +		F32 val1 = x* mag, val2 = y* mag, val3 = z* mag; +		ensure("1:normVec: Fail ", is_approx_equal(val1, vec3.mV[VX]) && is_approx_equal(val2, vec3.mV[VY]) && is_approx_equal(val3, vec3.mV[VZ])); +		x = 0.000000001f, y = 0.f, z = 0.f; +		vec3.clearVec(); +		vec3.setVec(x,y,z); +		mag = vec3.normVec(); +		val1 = x* mag, val2 = y* mag, val3 = z* mag; +		ensure("2:normVec: Fail ", (mag == 0.) && (0. == vec3.mV[VX]) && (0. == vec3.mV[VY])&& (0. == vec3.mV[VZ])); +	} + +	template<> template<> +	void v3math_object::test<33>() +	{ +		F32 x = -202.23412f, y = 123.2312f, z = -89.f; +		LLVector3 vec(x,y,z); +		vec.snap(2); +		ensure("1:snap: Fail ", is_approx_equal(-202.23f, vec.mV[VX]) && is_approx_equal(123.23f, vec.mV[VY]) && is_approx_equal(-89.f, vec.mV[VZ])); +	} +		 +	template<> template<> +	void v3math_object::test<34>() +	{ +		F32 x = 10.f, y = 20.f, z = -15.f; +		F32 x1, y1, z1; +		F32 lowerxy = 0.f, upperxy = 1.0f, lowerz = -1.0f, upperz = 1.f; +		LLVector3 vec3(x,y,z); +		vec3.quantize16(lowerxy,upperxy,lowerz,upperz); +		x1 = U16_to_F32(F32_to_U16(x, lowerxy, upperxy), lowerxy, upperxy); +		y1 = U16_to_F32(F32_to_U16(y, lowerxy, upperxy), lowerxy, upperxy); +		z1 = U16_to_F32(F32_to_U16(z, lowerz,  upperz),  lowerz,  upperz); +		ensure("1:quantize16: Fail ", is_approx_equal(x1, vec3.mV[VX]) && is_approx_equal(y1, vec3.mV[VY]) && is_approx_equal(z1, vec3.mV[VZ])); +		LLVector3 vec3a(x,y,z); +		vec3a.quantize8(lowerxy,upperxy,lowerz,upperz); +		x1 = U8_to_F32(F32_to_U8(x, lowerxy, upperxy), lowerxy, upperxy); +		y1 = U8_to_F32(F32_to_U8(y, lowerxy, upperxy), lowerxy, upperxy); +		z1 = U8_to_F32(F32_to_U8(z, lowerz, upperz), lowerz, upperz); +		ensure("2:quantize8: Fail ", is_approx_equal(x1, vec3a.mV[VX]) && is_approx_equal(y1, vec3a.mV[VY]) && is_approx_equal(z1, vec3a.mV[VZ])); +	} +} diff --git a/indra/llmath/tests/v4color_test.cpp b/indra/llmath/tests/v4color_test.cpp new file mode 100644 index 0000000000..cebb026ce6 --- /dev/null +++ b/indra/llmath/tests/v4color_test.cpp @@ -0,0 +1,365 @@ +/** + * @file v4color_tut.cpp + * @author Adroit + * @date 2007-03 + * @brief v4color test cases. + * + * $LicenseInfo:firstyear=2007&license=viewergpl$ + *  + * Copyright (c) 2007-2009, Linden Research, Inc. + *  + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab.  Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + *  + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + *  + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + *  + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + + +#include "linden_common.h" +#include "../test/lltut.h" + +#include "../v4coloru.h" +#include "llsd.h" +#include "../v3color.h" +#include "../v4color.h" + + +namespace tut +{ +	struct v4color_data +	{ +	}; +	typedef test_group<v4color_data> v4color_test; +	typedef v4color_test::object v4color_object; +	tut::v4color_test v4color_testcase("v4color"); + +	template<> template<> +	void v4color_object::test<1>() +	{ +		LLColor4 llcolor4; +		ensure("1:LLColor4:Fail to initialize ", ((0 == llcolor4.mV[VX]) && (0 == llcolor4.mV[VY]) && (0 == llcolor4.mV[VZ])&& (1.0f == llcolor4.mV[VW]))); + +		F32 r = 0x20, g = 0xFFFF, b = 0xFF, a = 0xAF; +		LLColor4 llcolor4a(r,g,b); +		ensure("2:LLColor4:Fail to initialize ", ((r == llcolor4a.mV[VX]) && (g == llcolor4a.mV[VY]) && (b == llcolor4a.mV[VZ])&& (1.0f == llcolor4a.mV[VW]))); +		 +		LLColor4 llcolor4b(r,g,b,a); +		ensure("3:LLColor4:Fail to initialize ", ((r == llcolor4b.mV[VX]) && (g == llcolor4b.mV[VY]) && (b == llcolor4b.mV[VZ])&& (a == llcolor4b.mV[VW]))); +		 +		const F32 vec[4] = {.112f ,23.2f, -4.2f, -.0001f}; +		LLColor4 llcolor4c(vec); +		ensure("4:LLColor4:Fail to initialize ", ((vec[0] == llcolor4c.mV[VX]) && (vec[1] == llcolor4c.mV[VY]) && (vec[2] == llcolor4c.mV[VZ])&& (vec[3] == llcolor4c.mV[VW])));		 +		 +		LLColor3 llcolor3(-2.23f,1.01f,42.3f); +		F32 val = -.1f; +		LLColor4 llcolor4d(llcolor3,val); +		ensure("5:LLColor4:Fail to initialize ", ((llcolor3.mV[VX] == llcolor4d.mV[VX]) && (llcolor3.mV[VY] == llcolor4d.mV[VY]) && (llcolor3.mV[VZ] == llcolor4d.mV[VZ])&& (val == llcolor4d.mV[VW]))); + +		LLSD sd = llcolor4d.getValue(); +		LLColor4 llcolor4e(sd); +		ensure_equals("6:LLColor4:(LLSD) failed ", llcolor4d, llcolor4e); +		 +		U8 r1 = 0xF2, g1 = 0xFA, b1 = 0xBF; +		LLColor4U color4u(r1,g1,b1); +		LLColor4 llcolor4g(color4u); +		const F32 SCALE = 1.f/255.f; +		F32 r2 = r1*SCALE, g2 = g1* SCALE, b2 = b1* SCALE; +		ensure("7:LLColor4:Fail to initialize ", ((r2 == llcolor4g.mV[VX]) && (g2 == llcolor4g.mV[VY]) && (b2 == llcolor4g.mV[VZ]))); +	} + +	template<> template<> +	void v4color_object::test<2>() +	{ +		LLColor4 llcolor(1.0, 2.0, 3.0, 4.0); +		LLSD llsd = llcolor.getValue(); +		LLColor4 llcolor4(llsd), llcolor4a; +		llcolor4a.setValue(llsd); +		ensure("setValue: failed", (llcolor4 == llcolor4a)); +		LLSD sd = llcolor4a.getValue(); +		LLColor4 llcolor4b(sd); +		ensure("getValue: Failed ", (llcolor4b == llcolor4a)); +	} + +	template<> template<> +	void v4color_object::test<3>() +	{ +		F32 r = 0x20, g = 0xFFFF, b = 0xFF,a = 0xAF; +		LLColor4 llcolor4(r,g,b,a); +		llcolor4.setToBlack(); +		ensure("setToBlack:Fail to set the black ", ((0 == llcolor4.mV[VX]) && (0 == llcolor4.mV[VY]) && (0 == llcolor4.mV[VZ])&& (1.0f == llcolor4.mV[VW]))); + +		llcolor4.setToWhite(); +		ensure("setToWhite:Fail to set the white ", ((1.f == llcolor4.mV[VX]) && (1.f == llcolor4.mV[VY]) && (1.f == llcolor4.mV[VZ])&& (1.0f == llcolor4.mV[VW]))); +	} + +	template<> template<> +	void v4color_object::test<4>() +	{ +		F32 r = 0x20, g = 0xFFFF, b = 0xFF, a = 0xAF; +		LLColor4 llcolor4; +		llcolor4.setVec(r,g,b); +		ensure("1:setVec:Fail to set the values ", ((r == llcolor4.mV[VX]) && (g == llcolor4.mV[VY]) && (b == llcolor4.mV[VZ])&& (1.f == llcolor4.mV[VW]))); + +		llcolor4.setVec(r,g,b,a); +		ensure("2:setVec:Fail to set the values ", ((r == llcolor4.mV[VX]) && (g == llcolor4.mV[VY]) && (b == llcolor4.mV[VZ])&& (a == llcolor4.mV[VW]))); + +		LLColor4 llcolor4a;  +		llcolor4a.setVec(llcolor4); +		ensure_equals("3:setVec:Fail to set the values ", llcolor4a,llcolor4); + +		LLColor3 llcolor3(-2.23f,1.01f,42.3f); +		llcolor4a.setVec(llcolor3); +		ensure("4:setVec:Fail to set the values ", ((llcolor3.mV[VX] == llcolor4a.mV[VX]) && (llcolor3.mV[VY] == llcolor4a.mV[VY]) && (llcolor3.mV[VZ] == llcolor4a.mV[VZ]))); + +		F32 val = -.33f; +		llcolor4a.setVec(llcolor3,val); +		ensure("4:setVec:Fail to set the values ", ((llcolor3.mV[VX] == llcolor4a.mV[VX]) && (llcolor3.mV[VY] == llcolor4a.mV[VY]) && (llcolor3.mV[VZ] == llcolor4a.mV[VZ]) && (val == llcolor4a.mV[VW]))); + +		const F32 vec[4] = {.112f ,23.2f, -4.2f, -.0001f}; +		LLColor4 llcolor4c; +		llcolor4c.setVec(vec); +		ensure("5:setVec:Fail to initialize ", ((vec[0] == llcolor4c.mV[VX]) && (vec[1] == llcolor4c.mV[VY]) && (vec[2] == llcolor4c.mV[VZ])&& (vec[3] == llcolor4c.mV[VW])));		 + +		U8 r1 = 0xF2, g1 = 0xFA, b1= 0xBF; +		LLColor4U color4u(r1,g1,b1); +		llcolor4.setVec(color4u); +		const F32 SCALE = 1.f/255.f; +		F32 r2 = r1*SCALE, g2 = g1* SCALE, b2 = b1* SCALE; +		ensure("6:setVec:Fail to initialize ", ((r2 == llcolor4.mV[VX]) && (g2 == llcolor4.mV[VY]) && (b2 == llcolor4.mV[VZ]))); +	} + +	template<> template<> +	void v4color_object::test<5>() +	{ +		F32 alpha = 0xAF; +		LLColor4 llcolor4; +		llcolor4.setAlpha(alpha); +		ensure("setAlpha:Fail to initialize ", (alpha == llcolor4.mV[VW])); +	} + +	template<> template<> +	void v4color_object::test<6>() +	{ +		F32 r = 0x20, g = 0xFFFF, b = 0xFF; +		LLColor4 llcolor4(r,g,b); +		ensure("magVecSquared:Fail ", is_approx_equal(llcolor4.magVecSquared(), (r*r + g*g + b*b))); +		ensure("magVec:Fail ", is_approx_equal(llcolor4.magVec(), fsqrtf(r*r + g*g + b*b))); +	} + +	template<> template<> +	void v4color_object::test<7>() +	{ +		F32 r = 0x20, g = 0xFFFF, b = 0xFF; +		LLColor4 llcolor4(r,g,b); +		F32 vecMag = llcolor4.normVec(); +		F32 mag = fsqrtf(r*r + g*g + b*b); +		F32 oomag = 1.f / mag; +		F32 val1 = r * oomag, val2 = g * oomag,	val3 = b * oomag; +		ensure("1:normVec failed ", (is_approx_equal(val1, llcolor4.mV[0]) && is_approx_equal(val2, llcolor4.mV[1]) && is_approx_equal(val3, llcolor4.mV[2]) && is_approx_equal(vecMag, mag))); +	} + +	template<> template<> +	void v4color_object::test<8>() +	{ +		LLColor4 llcolor4; +		ensure("1:isOpaque failed ",(1 == llcolor4.isOpaque())); +		F32 r = 0x20, g = 0xFFFF, b = 0xFF,a = 1.f; +		llcolor4.setVec(r,g,b,a); +		ensure("2:isOpaque failed ",(1 == llcolor4.isOpaque())); +		a = 2.f; +		llcolor4.setVec(r,g,b,a); +		ensure("3:isOpaque failed ",(0 == llcolor4.isOpaque())); +	} + +	template<> template<> +	void v4color_object::test<9>() +	{ +		F32 r = 0x20, g = 0xFFFF, b = 0xFF; +		LLColor4 llcolor4(r,g,b); +		ensure("1:operator [] failed",( r ==  llcolor4[0]));	 +		ensure("2:operator [] failed",( g ==  llcolor4[1])); +		ensure("3:operator [] failed",( b ==  llcolor4[2])); + +		r = 0xA20, g = 0xFBFF, b = 0xFFF; +		llcolor4.setVec(r,g,b); +		F32 &ref1 = llcolor4[0]; +		ensure("4:operator [] failed",( ref1 ==  llcolor4[0])); +		F32 &ref2 = llcolor4[1]; +		ensure("5:operator [] failed",( ref2 ==  llcolor4[1])); +		F32 &ref3 = llcolor4[2]; +		ensure("6:operator [] failed",( ref3 ==  llcolor4[2])); +	} + +	template<> template<> +	void v4color_object::test<10>() +	{ +		F32 r = 0x20, g = 0xFFFF, b = 0xFF; +		LLColor3 llcolor3(r,g,b); +		LLColor4 llcolor4a,llcolor4b; +		llcolor4a = llcolor3; +		ensure("Operator=:Fail to initialize ", ((llcolor3.mV[0] == llcolor4a.mV[VX]) && (llcolor3.mV[1] == llcolor4a.mV[VY]) && (llcolor3.mV[2] == llcolor4a.mV[VZ]))); +		LLSD sd = llcolor4a.getValue(); +		llcolor4b = LLColor4(sd); +		ensure_equals("Operator= LLSD:Fail ", llcolor4a, llcolor4b); +	} + +	template<> template<> +	void v4color_object::test<11>() +	{ +		F32 r = 0x20, g = 0xFFFF, b = 0xFF; +		std::ostringstream stream1, stream2; +		LLColor4 llcolor4a(r,g,b),llcolor4b; +		stream1 << llcolor4a; +		llcolor4b.setVec(r,g,b); +		stream2 << llcolor4b; +		ensure("operator << failed ", (stream1.str() == stream2.str()));	 +	} + +	template<> template<> +	void v4color_object::test<12>() +	{ +		F32 r1 = 0x20, g1 = 0xFFFF, b1 = 0xFF; +		F32 r2 = 0xABF, g2 = 0xFB, b2 = 0xFFF; +		LLColor4 llcolor4a(r1,g1,b1),llcolor4b(r2,g2,b2),llcolor4c; +		llcolor4c = llcolor4b + llcolor4a; +		ensure("operator+:Fail to Add the values ",  (is_approx_equal(r1+r2,llcolor4c.mV[VX]) && is_approx_equal(g1+g2,llcolor4c.mV[VY]) && is_approx_equal(b1+b2,llcolor4c.mV[VZ]))); + +		llcolor4b += llcolor4a; +		ensure("operator+=:Fail to Add the values ",  (is_approx_equal(r1+r2,llcolor4b.mV[VX]) && is_approx_equal(g1+g2,llcolor4b.mV[VY]) && is_approx_equal(b1+b2,llcolor4b.mV[VZ]))); +	} + +	template<> template<> +	void v4color_object::test<13>() +	{ +		F32 r1 = 0x20, g1 = 0xFFFF, b1 = 0xFF; +		F32 r2 = 0xABF, g2 = 0xFB, b2 = 0xFFF; +		LLColor4 llcolor4a(r1,g1,b1),llcolor4b(r2,g2,b2),llcolor4c; +		llcolor4c = llcolor4a - llcolor4b; +		ensure("operator-:Fail to subtract the values ",  (is_approx_equal(r1-r2,llcolor4c.mV[VX]) && is_approx_equal(g1-g2,llcolor4c.mV[VY]) && is_approx_equal(b1-b2,llcolor4c.mV[VZ]))); + +		llcolor4a -= llcolor4b; +		ensure("operator-=:Fail to subtract the values ",  (is_approx_equal(r1-r2,llcolor4a.mV[VX]) && is_approx_equal(g1-g2,llcolor4a.mV[VY]) && is_approx_equal(b1-b2,llcolor4a.mV[VZ]))); +	} + +	template<> template<> +	void v4color_object::test<14>() +	{ +		F32 r1 = 0x20, g1 = 0xFFFF, b1 = 0xFF; +		F32 r2 = 0xABF, g2 = 0xFB, b2 = 0xFFF; +		LLColor4 llcolor4a(r1,g1,b1),llcolor4b(r2,g2,b2),llcolor4c; +		llcolor4c = llcolor4a * llcolor4b; +		ensure("1:operator*:Fail to multiply the values",  (is_approx_equal(r1*r2,llcolor4c.mV[VX]) && is_approx_equal(g1*g2,llcolor4c.mV[VY]) && is_approx_equal(b1*b2,llcolor4c.mV[VZ]))); +		 +		F32 mulVal = 3.33f; +		llcolor4c = llcolor4a * mulVal; +		ensure("2:operator*:Fail ",  (is_approx_equal(r1*mulVal,llcolor4c.mV[VX]) && is_approx_equal(g1*mulVal,llcolor4c.mV[VY]) && is_approx_equal(b1*mulVal,llcolor4c.mV[VZ]))); +		llcolor4c = mulVal * llcolor4a; +		ensure("3:operator*:Fail to multiply the values",  (is_approx_equal(r1*mulVal,llcolor4c.mV[VX]) && is_approx_equal(g1*mulVal,llcolor4c.mV[VY]) && is_approx_equal(b1*mulVal,llcolor4c.mV[VZ]))); + +		llcolor4a *= mulVal; +		ensure("4:operator*=:Fail to multiply the values ",  (is_approx_equal(r1*mulVal,llcolor4a.mV[VX]) && is_approx_equal(g1*mulVal,llcolor4a.mV[VY]) && is_approx_equal(b1*mulVal,llcolor4a.mV[VZ]))); + +		LLColor4 llcolor4d(r1,g1,b1),llcolor4e(r2,g2,b2); +		llcolor4e *= llcolor4d; +		ensure("5:operator*=:Fail to multiply the values ",  (is_approx_equal(r1*r2,llcolor4e.mV[VX]) && is_approx_equal(g1*g2,llcolor4e.mV[VY]) && is_approx_equal(b1*b2,llcolor4e.mV[VZ]))); +	} + +	template<> template<> +	void v4color_object::test<15>() +	{ +		F32 r = 0x20, g = 0xFFFF, b = 0xFF,a = 0x30; +		F32 div = 12.345f; +		LLColor4 llcolor4a(r,g,b,a),llcolor4b; +		llcolor4b = llcolor4a % div;//chnage only alpha value nor r,g,b; +		ensure("1operator%:Fail ",  (is_approx_equal(r,llcolor4b.mV[VX]) && is_approx_equal(g,llcolor4b.mV[VY]) && is_approx_equal(b,llcolor4b.mV[VZ])&& is_approx_equal(div*a,llcolor4b.mV[VW]))); +		 +		llcolor4b = div % llcolor4a; +		ensure("2operator%:Fail ",  (is_approx_equal(r,llcolor4b.mV[VX]) && is_approx_equal(g,llcolor4b.mV[VY]) && is_approx_equal(b,llcolor4b.mV[VZ])&& is_approx_equal(div*a,llcolor4b.mV[VW]))); + +		llcolor4a %= div; +		ensure("operator%=:Fail ",  (is_approx_equal(a*div,llcolor4a.mV[VW]))); +	} + +	template<> template<> +	void v4color_object::test<16>() +	{ +		F32 r = 0x20, g = 0xFFFF, b = 0xFF,a = 0x30; +		LLColor4 llcolor4a(r,g,b,a),llcolor4b; +		llcolor4b = llcolor4a; +		ensure("1:operator== failed to ensure the equality ", (llcolor4b == llcolor4a));	 +		F32 r1 = 0x2, g1 = 0xFF, b1 = 0xFA; +		LLColor3 llcolor3(r1,g1,b1); +		llcolor4b = llcolor3; +		ensure("2:operator== failed to ensure the equality ", (llcolor4b == llcolor3));	 +		ensure("2:operator!= failed to ensure the equality ", (llcolor4a != llcolor3)); +	} + +	template<> template<> +	void v4color_object::test<17>() +	{ +		F32 r = 0x20, g = 0xFFFF, b = 0xFF; +		LLColor4 llcolor4a(r,g,b),llcolor4b; +		LLColor3 llcolor3 = vec4to3(llcolor4a); +		ensure("vec4to3:Fail to convert vec4 to vec3 ",  (is_approx_equal(llcolor3.mV[VX],llcolor4a.mV[VX]) && is_approx_equal(llcolor3.mV[VY],llcolor4a.mV[VY]) && is_approx_equal(llcolor3.mV[VZ],llcolor4a.mV[VZ]))); +		llcolor4b = vec3to4(llcolor3); +		ensure_equals("vec3to4:Fail to convert vec3 to vec4 ",  llcolor4b, llcolor4a); +	} + +	template<> template<> +	void v4color_object::test<18>() +	{ +		F32 r1 = 0x20, g1 = 0xFFFF, b1 = 0xFF, val = 0x20; +		F32 r2 = 0xABF, g2 = 0xFB, b2 = 0xFFF; +		LLColor4 llcolor4a(r1,g1,b1),llcolor4b(r2,g2,b2),llcolor4c; +		llcolor4c = lerp(llcolor4a,llcolor4b,val); +		ensure("lerp:Fail ",  (is_approx_equal(r1 + (r2 - r1)* val,llcolor4c.mV[VX]) && is_approx_equal(g1 + (g2 - g1)* val,llcolor4c.mV[VY]) && is_approx_equal(b1 + (b2 - b1)* val,llcolor4c.mV[VZ]))); +	} + +	template<> template<> +	void v4color_object::test<19>() +	{ +		F32 r = 12.0f, g = -2.3f, b = 1.32f, a = 5.0f; +		LLColor4 llcolor4a(r,g,b,a),llcolor4b; +		std::string color("red"); +		LLColor4::parseColor(color, &llcolor4b); +		ensure_equals("1:parseColor() failed to parse the color value ", llcolor4b, LLColor4::red); + +		color = "12.0, -2.3, 1.32, 5.0"; +		LLColor4::parseColor(color, &llcolor4b); +		llcolor4a = llcolor4a * (1.f / 255.f); +		ensure_equals("2:parseColor() failed to parse the color value ",  llcolor4a,llcolor4b); + +		color = "yellow5"; +		llcolor4a.setVec(r,g,b); +		LLColor4::parseColor(color, &llcolor4a); +		ensure_equals("3:parseColor() failed to parse the color value ", llcolor4a, LLColor4::yellow5); +	} + +	template<> template<> +	void v4color_object::test<20>() +	{ +		F32 r = 12.0f, g = -2.3f, b = 1.32f, a = 5.0f; +		LLColor4 llcolor4a(r,g,b,a),llcolor4b; +		std::string color("12.0, -2.3, 1.32, 5.0"); +		LLColor4::parseColor4(color, &llcolor4b); +		ensure_equals("parseColor4() failed to parse the color value ",  llcolor4a, llcolor4b); +	} +} diff --git a/indra/llmath/tests/v4coloru_test.cpp b/indra/llmath/tests/v4coloru_test.cpp new file mode 100644 index 0000000000..00515893da --- /dev/null +++ b/indra/llmath/tests/v4coloru_test.cpp @@ -0,0 +1,342 @@ +/** + * @file v4coloru_tut.cpp + * @author Adroit + * @date 2007-03 + * @brief v4coloru test cases. + * + * $LicenseInfo:firstyear=2007&license=viewergpl$ + *  + * Copyright (c) 2007-2009, Linden Research, Inc. + *  + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab.  Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + *  + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + *  + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + *  + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + + +#include "linden_common.h" +#include "../test/lltut.h" + +#include "llsd.h" + +#include "../v4coloru.h" + + +namespace tut +{ +	struct v4coloru_data +	{ +	}; +	typedef test_group<v4coloru_data> v4coloru_test; +	typedef v4coloru_test::object v4coloru_object; +	tut::v4coloru_test v4coloru_testcase("v4coloru"); + +	template<> template<> +	void v4coloru_object::test<1>() +	{ +		LLColor4U llcolor4u; +		ensure("1:LLColor4u:Fail to initialize ", ((0 == llcolor4u.mV[VX]) && (0 == llcolor4u.mV[VY]) && (0 == llcolor4u.mV[VZ])&& (255 == llcolor4u.mV[VW]))); + +		U8 r = 0x12, g = 0xFF, b = 0xAF, a = 0x23; +		LLColor4U llcolor4u1(r,g,b); +		ensure("2:LLColor4u:Fail to initialize ", ((r == llcolor4u1.mV[VX]) && (g == llcolor4u1.mV[VY]) && (b == llcolor4u1.mV[VZ])&& (255 == llcolor4u1.mV[VW]))); +		 +		LLColor4U llcolor4u2(r,g,b,a); +		ensure("3:LLColor4u:Fail to initialize ", ((r == llcolor4u2.mV[VX]) && (g == llcolor4u2.mV[VY]) && (b == llcolor4u2.mV[VZ])&& (a == llcolor4u2.mV[VW]))); + +		const U8 vec[4] = {0x12,0xFF,0xAF,0x23}; +		LLColor4U llcolor4u3(vec); +		ensure("4:LLColor4u:Fail to initialize ", ((vec[0] == llcolor4u3.mV[VX]) && (vec[1] == llcolor4u3.mV[VY]) && (vec[2] == llcolor4u3.mV[VZ])&& (vec[3] == llcolor4u3.mV[VW])));		 + +		LLSD sd = llcolor4u3.getValue(); +		LLColor4U llcolor4u4(sd); +		ensure_equals("5:LLColor4u (LLSD) Failed ", llcolor4u4, llcolor4u3); +	} +	 +	template<> template<> +	void v4coloru_object::test<2>() +	{ +		LLColor4U llcolor4ua(1, 2, 3, 4); +		LLSD sd = llcolor4ua.getValue(); +		LLColor4U llcolor4u; +		llcolor4u.setValue(sd); +		ensure_equals("setValue(LLSD)/getValue Failed ", llcolor4u, llcolor4ua); +	} + +	template<> template<> +	void v4coloru_object::test<3>() +	{ +		U8 r = 0x12, g = 0xFF, b = 0xAF, a = 0x23; +		LLColor4U llcolor4u(r,g,b,a); +		llcolor4u.setToBlack(); +		ensure("setToBlack:Fail to set black ", ((0 == llcolor4u.mV[VX]) && (0 == llcolor4u.mV[VY]) && (0 == llcolor4u.mV[VZ])&& (255 == llcolor4u.mV[VW]))); + +		llcolor4u.setToWhite(); +		ensure("setToWhite:Fail to white ", ((255 == llcolor4u.mV[VX]) && (255 == llcolor4u.mV[VY]) && (255 == llcolor4u.mV[VZ])&& (255 == llcolor4u.mV[VW]))); +	} +	 +	template<> template<> +	void v4coloru_object::test<4>() +	{ +		U8 r = 0x12, g = 0xFF, b = 0xAF, a = 0x23; +		LLColor4U llcolor4ua(r,g,b,a); +		LLSD sd = llcolor4ua.getValue(); +		LLColor4U llcolor4u = (LLColor4U)sd; +		ensure_equals("Operator=(LLSD) Failed ",  llcolor4u, llcolor4ua); +	} + +	template<> template<> +	void v4coloru_object::test<5>() +	{ +		U8 r = 0x12, g = 0xFF, b = 0xAF, a = 0x23; +		LLColor4U llcolor4u; +		llcolor4u.setVec(r,g,b,a); +		ensure("1:setVec:Fail to set the values ", ((r == llcolor4u.mV[VX]) && (g == llcolor4u.mV[VY]) && (b == llcolor4u.mV[VZ])&& (a == llcolor4u.mV[VW]))); + +		llcolor4u.setToBlack(); +		llcolor4u.setVec(r,g,b); +		ensure("2:setVec:Fail to set the values ", ((r == llcolor4u.mV[VX]) && (g == llcolor4u.mV[VY]) && (b == llcolor4u.mV[VZ])&& (255 == llcolor4u.mV[VW]))); + +		LLColor4U llcolor4u1; +		llcolor4u1.setVec(llcolor4u); +		ensure_equals("3:setVec:Fail to set the values ", llcolor4u1,llcolor4u); +		 +		const U8 vec[4] = {0x12,0xFF,0xAF,0x23}; +		LLColor4U llcolor4u2; +		llcolor4u2.setVec(vec); +		ensure("4:setVec:Fail to set the values ", ((vec[0] == llcolor4u2.mV[VX]) && (vec[1] == llcolor4u2.mV[VY]) && (vec[2] == llcolor4u2.mV[VZ])&& (vec[3] == llcolor4u2.mV[VW])));		 +	} +	 +	template<> template<> +	void v4coloru_object::test<6>() +	{ +		U8 alpha = 0x12; +		LLColor4U llcolor4u; +		llcolor4u.setAlpha(alpha); +		ensure("setAlpha:Fail to set alpha value ", (alpha == llcolor4u.mV[VW])); +	} +	 +	template<> template<> +	void v4coloru_object::test<7>() +	{ +		U8 r = 0x12, g = 0xFF, b = 0xAF; +		LLColor4U llcolor4u(r,g,b); +		ensure("magVecSquared:Fail ", is_approx_equal(llcolor4u.magVecSquared(), (F32)(r*r + g*g + b*b))); +		ensure("magVec:Fail ", is_approx_equal(llcolor4u.magVec(), fsqrtf(r*r + g*g + b*b))); +	} + +	template<> template<> +	void v4coloru_object::test<8>() +	{ +		U8 r = 0x12, g = 0xFF, b = 0xAF; +		std::ostringstream stream1, stream2; +		LLColor4U llcolor4u1(r,g,b),llcolor4u2; +		stream1 << llcolor4u1; +		llcolor4u2.setVec(r,g,b); +		stream2 << llcolor4u2; +		ensure("operator << failed ", (stream1.str() == stream2.str()));	 +	} + +	template<> template<> +	void v4coloru_object::test<9>() +	{ +		U8 r1 = 0x12, g1 = 0xFF, b1 = 0xAF; +		U8 r2 = 0x1C, g2 = 0x9A, b2 = 0x1B; +		LLColor4U llcolor4u1(r1,g1,b1), llcolor4u2(r2,g2,b2),llcolor4u3; +		llcolor4u3 = llcolor4u1 + llcolor4u2; +		ensure_equals( +			"1a.operator+:Fail to Add the values ", +			llcolor4u3.mV[VX], +			(U8)(r1+r2)); +		ensure_equals( +			"1b.operator+:Fail to Add the values ", +			llcolor4u3.mV[VY], +			(U8)(g1+g2)); +		ensure_equals( +			"1c.operator+:Fail to Add the values ", +			llcolor4u3.mV[VZ], +			(U8)(b1+b2)); + +		llcolor4u2 += llcolor4u1; +		ensure_equals( +			"2a.operator+=:Fail to Add the values ", +			llcolor4u2.mV[VX], +			(U8)(r1+r2)); +		ensure_equals( +			"2b.operator+=:Fail to Add the values ", +			llcolor4u2.mV[VY], +			(U8)(g1+g2)); +		ensure_equals( +			"2c.operator+=:Fail to Add the values ", +			llcolor4u2.mV[VZ], +			(U8)(b1+b2)); +	} + +	template<> template<> +	void v4coloru_object::test<10>() +	{ +		U8 r1 = 0x12, g1 = 0xFF, b1 = 0xAF; +		U8 r2 = 0x1C, g2 = 0x9A, b2 = 0x1B; +		LLColor4U llcolor4u1(r1,g1,b1), llcolor4u2(r2,g2,b2),llcolor4u3; +		llcolor4u3 = llcolor4u1 - llcolor4u2; +		ensure_equals( +			"1a. operator-:Fail to Add the values ", +			llcolor4u3.mV[VX], +			(U8)(r1-r2)); +		ensure_equals( +			"1b. operator-:Fail to Add the values ", +			llcolor4u3.mV[VY], +			(U8)(g1-g2)); +		ensure_equals( +			"1c. operator-:Fail to Add the values ", +			llcolor4u3.mV[VZ], +			(U8)(b1-b2)); + +		llcolor4u1 -= llcolor4u2; +		ensure_equals( +			"2a. operator-=:Fail to Add the values ", +			llcolor4u1.mV[VX], +			(U8)(r1-r2)); +		ensure_equals( +			"2b. operator-=:Fail to Add the values ", +			llcolor4u1.mV[VY], +			(U8)(g1-g2)); +		ensure_equals( +			"2c. operator-=:Fail to Add the values ", +			llcolor4u1.mV[VZ], +			(U8)(b1-b2)); +	} + +	template<> template<> +	void v4coloru_object::test<11>() +	{ +		U8 r1 = 0x12, g1 = 0xFF, b1 = 0xAF; +		U8 r2 = 0x1C, g2 = 0x9A, b2 = 0x1B; +		LLColor4U llcolor4u1(r1,g1,b1), llcolor4u2(r2,g2,b2),llcolor4u3; +		llcolor4u3 = llcolor4u1 * llcolor4u2; +		ensure_equals( +			"1a. operator*:Fail to multiply the values", +			llcolor4u3.mV[VX], +			(U8)(r1*r2)); +		ensure_equals( +			"1b. operator*:Fail to multiply the values", +			llcolor4u3.mV[VY], +			(U8)(g1*g2)); +		ensure_equals( +			"1c. operator*:Fail to multiply the values", +			llcolor4u3.mV[VZ], +			(U8)(b1*b2)); +		 +		U8 mulVal = 123; +		llcolor4u1 *= mulVal; +		ensure_equals( +			"2a. operator*=:Fail to multiply the values", +			llcolor4u1.mV[VX], +			(U8)(r1*mulVal)); +		ensure_equals( +			"2b. operator*=:Fail to multiply the values", +			llcolor4u1.mV[VY], +			(U8)(g1*mulVal)); +		ensure_equals( +			"2c. operator*=:Fail to multiply the values", +			llcolor4u1.mV[VZ], +			(U8)(b1*mulVal)); +	} + +	template<> template<> +	void v4coloru_object::test<12>() +	{ +		U8 r = 0x12, g = 0xFF, b = 0xAF; +		LLColor4U llcolor4u(r,g,b),llcolor4u1; +		llcolor4u1 = llcolor4u; +		ensure("operator== failed to ensure the equality ", (llcolor4u1 == llcolor4u));	 +		llcolor4u1.setToBlack(); +		ensure("operator!= failed to ensure the equality ", (llcolor4u1 != llcolor4u));	 +	} + +	template<> template<> +	void v4coloru_object::test<13>() +	{ +		U8 r = 0x12, g = 0xFF, b = 0xAF, a = 12; +		LLColor4U llcolor4u(r,g,b,a); +		U8 modVal = 45; +		llcolor4u %= modVal; +		ensure_equals("operator%=:Fail ", llcolor4u.mV[VW], (U8)(a * modVal)); +	} + +	template<> template<> +	void v4coloru_object::test<14>() +	{ +		U8 r = 0x12, g = 0xFF, b = 0xAF, a = 12; +		LLColor4U llcolor4u1(r,g,b,a); +		std::string color("12, 23, 132, 50"); +		LLColor4U::parseColor4U(color, &llcolor4u1); +		ensure("parseColor4U() failed to parse the color value ", ((12 == llcolor4u1.mV[VX]) && (23 == llcolor4u1.mV[VY]) && (132 == llcolor4u1.mV[VZ])&& (50 == llcolor4u1.mV[VW]))); + +		color = "12, 23, 132"; +		ensure("2:parseColor4U() failed to parse the color value ",  (FALSE == LLColor4U::parseColor4U(color, &llcolor4u1))); + +		color = "12"; +		ensure("2:parseColor4U() failed to parse the color value ",  (FALSE == LLColor4U::parseColor4U(color, &llcolor4u1))); +	} + +	template<> template<> +	void v4coloru_object::test<15>() +	{ +		U8 r = 12, g = 123, b = 3, a = 2; +		LLColor4U llcolor4u(r,g,b,a),llcolor4u1; +		const F32 fVal = 3.f; +		llcolor4u1 = llcolor4u.multAll(fVal); +		ensure("multAll:Fail to multiply ", (((U8)llround(r * fVal) == llcolor4u1.mV[VX]) && (U8)llround(g * fVal) == llcolor4u1.mV[VY] +											&& ((U8)llround(b * fVal) == llcolor4u1.mV[VZ])&& ((U8)llround(a * fVal) == llcolor4u1.mV[VW])));		 +	} + +	template<> template<> +	void v4coloru_object::test<16>() +	{ +		U8 r1 = 12, g1 = 123, b1 = 3, a1 = 2; +		U8 r2 = 23, g2 = 230, b2 = 124, a2 = 255; +		LLColor4U llcolor4u(r1,g1,b1,a1),llcolor4u1(r2,g2,b2,a2); +		llcolor4u1 = llcolor4u1.addClampMax(llcolor4u); +		ensure("1:addClampMax():Fail to add the value ",  ((r1+r2 == llcolor4u1.mV[VX]) && (255 == llcolor4u1.mV[VY]) && (b1+b2 == llcolor4u1.mV[VZ])&& (255 == llcolor4u1.mV[VW]))); + +		r1 = 132, g1 = 3, b1 = 3, a1 = 2; +		r2 = 123, g2 = 230, b2 = 154, a2 = 25; +		LLColor4U llcolor4u2(r1,g1,b1,a1),llcolor4u3(r2,g2,b2,a2); +		llcolor4u3 = llcolor4u3.addClampMax(llcolor4u2); +		ensure("2:addClampMax():Fail to add the value ",  ((255 == llcolor4u3.mV[VX]) && (g1+g2 == llcolor4u3.mV[VY]) && (b1+b2 == llcolor4u3.mV[VZ])&& (a1+a2 == llcolor4u3.mV[VW]))); +	} + +	template<> template<> +	void v4coloru_object::test<17>() +	{ +		F32 r = 23.f, g = 12.32f, b = -12.3f; +		LLColor3 color3(r,g,b); +		LLColor4U llcolor4u; +		llcolor4u.setVecScaleClamp(color3); +		const S32 MAX_COLOR = 255; +		F32 color_scale_factor = MAX_COLOR/r; +		S32 r2 = llround(r * color_scale_factor); +		S32 g2 = llround(g * color_scale_factor); +		ensure("setVecScaleClamp():Fail to add the value ",  ((r2 == llcolor4u.mV[VX]) && (g2 == llcolor4u.mV[VY]) && (0 == llcolor4u.mV[VZ])&& (255 == llcolor4u.mV[VW]))); +	} +} diff --git a/indra/llmath/tests/v4math_test.cpp b/indra/llmath/tests/v4math_test.cpp new file mode 100644 index 0000000000..e020038ae5 --- /dev/null +++ b/indra/llmath/tests/v4math_test.cpp @@ -0,0 +1,388 @@ +/** + * @file v4math_tut.cpp + * @author Adroit + * @date 2007-03 + * @brief v4math test cases. + * + * $LicenseInfo:firstyear=2007&license=viewergpl$ + *  + * Copyright (c) 2007-2009, Linden Research, Inc. + *  + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab.  Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + *  + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + *  + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + *  + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ +  +#include "linden_common.h" +#include "../test/lltut.h" +#include "llsd.h" + +#include "../llquaternion.h" +#include "../m4math.h" +#include "../v4math.h" + +namespace tut +{ +	struct v4math_data +	{ +	}; +	typedef test_group<v4math_data> v4math_test; +	typedef v4math_test::object v4math_object; +	tut::v4math_test v4math_testcase("v4math"); + +	template<> template<> +	void v4math_object::test<1>() +	{ +		LLVector4 vec4; +		ensure("1:LLVector4:Fail to initialize " ,((0 == vec4.mV[VX]) && (0 == vec4.mV[VY]) && (0 == vec4.mV[VZ])&& (1.0f == vec4.mV[VW]))); +		F32 x = 10.f, y = -2.3f, z = -.023f, w = -2.0f; +		LLVector4 vec4a(x,y,z); +		ensure("2:LLVector4:Fail to initialize " ,((x == vec4a.mV[VX]) && (y == vec4a.mV[VY]) && (z == vec4a.mV[VZ])&& (1.0f == vec4a.mV[VW]))); +		LLVector4 vec4b(x,y,z,w); +		ensure("3:LLVector4:Fail to initialize " ,((x == vec4b.mV[VX]) && (y == vec4b.mV[VY]) && (z == vec4b.mV[VZ])&& (w == vec4b.mV[VW]))); +		const F32 vec[4] = {.112f ,23.2f, -4.2f, -.0001f}; +		LLVector4 vec4c(vec); +		ensure("4:LLVector4:Fail to initialize " ,((vec[0] == vec4c.mV[VX]) && (vec[1] == vec4c.mV[VY]) && (vec[2] == vec4c.mV[VZ])&& (vec[3] == vec4c.mV[VW]))); +		LLVector3 vec3(-2.23f,1.01f,42.3f); +		LLVector4 vec4d(vec3); +		ensure("5:LLVector4:Fail to initialize " ,((vec3.mV[VX] == vec4d.mV[VX]) && (vec3.mV[VY] == vec4d.mV[VY]) && (vec3.mV[VZ] == vec4d.mV[VZ])&& (1.f == vec4d.mV[VW]))); +		F32 w1 = -.234f; +		LLVector4 vec4e(vec3,w1); +		ensure("6:LLVector4:Fail to initialize " ,((vec3.mV[VX] == vec4e.mV[VX]) && (vec3.mV[VY] == vec4e.mV[VY]) && (vec3.mV[VZ] == vec4e.mV[VZ])&& (w1 == vec4e.mV[VW]))); +	} + +	template<> template<> +	void v4math_object::test<2>() +	{ +		F32 x = 10.f, y = -2.3f, z = -.023f, w = -2.0f; +		LLVector4 vec4; +		vec4.setVec(x,y,z); +		ensure("1:setVec:Fail to initialize " ,((x == vec4.mV[VX]) && (y == vec4.mV[VY]) && (z == vec4.mV[VZ])&& (1.0f == vec4.mV[VW]))); +		vec4.clearVec(); +		ensure("2:clearVec:Fail " ,((0 == vec4.mV[VX]) && (0 == vec4.mV[VY]) && (0 == vec4.mV[VZ])&& (1.0f == vec4.mV[VW]))); +		vec4.setVec(x,y,z,w); +		ensure("3:setVec:Fail to initialize " ,((x == vec4.mV[VX]) && (y == vec4.mV[VY]) && (z == vec4.mV[VZ])&& (w == vec4.mV[VW]))); +		vec4.zeroVec(); +		ensure("4:zeroVec:Fail " ,((0 == vec4.mV[VX]) && (0 == vec4.mV[VY]) && (0 == vec4.mV[VZ])&& (0 == vec4.mV[VW]))); +		LLVector3 vec3(-2.23f,1.01f,42.3f); +		vec4.clearVec(); +		vec4.setVec(vec3); +		ensure("5:setVec:Fail to initialize " ,((vec3.mV[VX] == vec4.mV[VX]) && (vec3.mV[VY] == vec4.mV[VY]) && (vec3.mV[VZ] == vec4.mV[VZ])&& (1.f == vec4.mV[VW]))); +		F32 w1 = -.234f; +		vec4.zeroVec(); +		vec4.setVec(vec3,w1); +		ensure("6:setVec:Fail to initialize " ,((vec3.mV[VX] == vec4.mV[VX]) && (vec3.mV[VY] == vec4.mV[VY]) && (vec3.mV[VZ] == vec4.mV[VZ])&& (w1 == vec4.mV[VW]))); +		const F32 vec[4] = {.112f ,23.2f, -4.2f, -.0001f}; +		LLVector4 vec4a; +		vec4a.setVec(vec); +		ensure("7:setVec:Fail to initialize " ,((vec[0] == vec4a.mV[VX]) && (vec[1] == vec4a.mV[VY]) && (vec[2] == vec4a.mV[VZ])&& (vec[3] == vec4a.mV[VW]))); +	} + +	template<> template<> +	void v4math_object::test<3>() +	{ +		F32 x = 10.f, y = -2.3f, z = -.023f; +		LLVector4 vec4(x,y,z); +		ensure("magVec:Fail ", is_approx_equal(vec4.magVec(), fsqrtf(x*x + y*y + z*z))); +		ensure("magVecSquared:Fail ", is_approx_equal(vec4.magVecSquared(), (x*x + y*y + z*z))); +	} + +	template<> template<> +	void v4math_object::test<4>() +	{ +		F32 x = 10.f, y = -2.3f, z = -.023f; +		LLVector4 vec4(x,y,z); +		F32 mag = vec4.normVec(); +		mag = 1.f/ mag; +		ensure("1:normVec: Fail " ,is_approx_equal(mag*x,vec4.mV[VX]) && is_approx_equal(mag*y, vec4.mV[VY])&& is_approx_equal(mag*z, vec4.mV[VZ])); +		x = 0.000000001f, y = 0.000000001f, z = 0.000000001f; +		vec4.clearVec(); +		vec4.setVec(x,y,z); +		mag = vec4.normVec(); +		ensure("2:normVec: Fail " ,is_approx_equal(mag*x,vec4.mV[VX]) && is_approx_equal(mag*y, vec4.mV[VY])&& is_approx_equal(mag*z, vec4.mV[VZ])); +	} + +	template<> template<> +	void v4math_object::test<5>() +	{ +		F32 x = 10.f, y = -2.3f, z = -.023f, w = -2.0f; +		LLVector4 vec4(x,y,z,w); +		vec4.abs(); +		ensure("abs:Fail " ,((x == vec4.mV[VX]) && (-y == vec4.mV[VY]) && (-z == vec4.mV[VZ])&& (-w == vec4.mV[VW]))); +		vec4.clearVec(); +		ensure("isExactlyClear:Fail " ,(TRUE == vec4.isExactlyClear())); +		vec4.zeroVec(); +		ensure("isExactlyZero:Fail " ,(TRUE == vec4.isExactlyZero())); +	} + +	template<> template<> +	void v4math_object::test<6>() +	{ +		F32 x = 10.f, y = -2.3f, z = -.023f, w = -2.0f; +		LLVector4 vec4(x,y,z,w),vec4a; +		vec4a = vec4.scaleVec(vec4); +		ensure("scaleVec:Fail " ,(is_approx_equal(x*x, vec4a.mV[VX]) && is_approx_equal(y*y, vec4a.mV[VY]) && is_approx_equal(z*z, vec4a.mV[VZ])&& is_approx_equal(w*w, vec4a.mV[VW]))); +	} + +	template<> template<> +	void v4math_object::test<7>() +	{ +		F32 x = 10.f, y = -2.3f, z = -.023f, w = -2.0f; +		LLVector4 vec4(x,y,z,w); +		ensure("1:operator [] failed " ,( x ==  vec4[0]));	 +		ensure("2:operator [] failed " ,( y ==  vec4[1])); +		ensure("3:operator [] failed " ,( z ==  vec4[2])); +		ensure("4:operator [] failed " ,( w ==  vec4[3])); +		x = 23.f, y = -.2361f, z = 3.25; +		vec4.setVec(x,y,z); +		F32 &ref1 = vec4[0]; +		ensure("5:operator [] failed " ,( ref1 ==  vec4[0])); +		F32 &ref2 = vec4[1]; +		ensure("6:operator [] failed " ,( ref2 ==  vec4[1])); +		F32 &ref3 = vec4[2]; +		ensure("7:operator [] failed " ,( ref3 ==  vec4[2]));	 +		F32 &ref4 = vec4[3]; +		ensure("8:operator [] failed " ,( ref4 ==  vec4[3])); +	} + +	template<> template<> +	void v4math_object::test<8>() +	{ +		F32 x = 10.f, y = -2.3f, z = -.023f, w = -2.0f; +		const  F32 val[16] = { +            1.f,  2.f,   3.f,    0.f, +            .34f, .1f,   -.5f,   0.f, +            2.f,  1.23f, 1.234f, 0.f, +            .89f, 0.f,   0.f,    0.f +        }; +		LLMatrix4 mat(val); +		LLVector4 vec4(x,y,z,w),vec4a; +		vec4.rotVec(mat); +		vec4a.setVec(x,y,z,w); +		vec4a.rotVec(mat); +		ensure_equals("1:rotVec: Fail " ,vec4a, vec4); +		F32 a = 2.32f, b = -23.2f, c = -34.1112f, d = 1.010112f; +		LLQuaternion q(a,b,c,d); +		LLVector4 vec4b(a,b,c,d),vec4c; +		vec4b.rotVec(q); +		vec4c.setVec(a, b, c, d); +		vec4c.rotVec(q); +		ensure_equals("2:rotVec: Fail " ,vec4b, vec4c); +	} +	 +	template<> template<> +	void v4math_object::test<9>() +	{ +		F32 x = 10.f, y = -2.3f, z = -.023f, w = -2.0f; +		LLVector4 vec4(x,y,z,w),vec4a;; +		std::ostringstream stream1, stream2; +		stream1 << vec4; +		vec4a.setVec(x,y,z,w); +		stream2 << vec4a; +		ensure("operator << failed",(stream1.str() == stream2.str()));	 +	} +	 +	template<> template<> +	void v4math_object::test<10>() +	{ +		F32 x1 = 1.f, y1 = 2.f, z1 = -1.1f, w1 = .23f; +		F32 x2 = 1.2f, y2 = 2.5f, z2 = 1.f, w2 = 1.3f; +		LLVector4 vec4(x1,y1,z1,w1),vec4a(x2,y2,z2,w2),vec4b; +		vec4b = vec4a + vec4; +		ensure("1:operator+:Fail to initialize " ,(is_approx_equal(x1+x2,vec4b.mV[VX]) && is_approx_equal(y1+y2,vec4b.mV[VY]) && is_approx_equal(z1+z2,vec4b.mV[VZ]))); +		x1 = -2.45f, y1 = 2.1f, z1 = 3.0f; +		vec4.clearVec(); +		vec4a.clearVec(); +		vec4.setVec(x1,y1,z1); +		vec4a +=vec4; +		ensure_equals("2:operator+=: Fail to initialize", vec4a,vec4); +		vec4a += vec4; +		ensure("3:operator+=:Fail to initialize " ,(is_approx_equal(2*x1,vec4a.mV[VX]) && is_approx_equal(2*y1,vec4a.mV[VY]) && is_approx_equal(2*z1,vec4a.mV[VZ]))); +	} +	template<> template<> +	void v4math_object::test<11>() +	{ +		F32 x1 = 1.f, y1 = 2.f, z1 = -1.1f, w1 = .23f; +		F32 x2 = 1.2f, y2 = 2.5f, z2 = 1.f, w2 = 1.3f; +		LLVector4 vec4(x1,y1,z1,w1),vec4a(x2,y2,z2,w2),vec4b; +		vec4b = vec4a - vec4; +		ensure("1:operator-:Fail to initialize " ,(is_approx_equal(x2-x1,vec4b.mV[VX]) && is_approx_equal(y2-y1,vec4b.mV[VY]) && is_approx_equal(z2-z1,vec4b.mV[VZ]))); +		x1 = -2.45f, y1 = 2.1f, z1 = 3.0f; +		vec4.clearVec(); +		vec4a.clearVec(); +		vec4.setVec(x1,y1,z1); +		vec4a -=vec4; +		ensure_equals("2:operator-=: Fail to initialize" , vec4a,-vec4); +		vec4a -=vec4; +		ensure("3:operator-=:Fail to initialize " ,(is_approx_equal(-2*x1,vec4a.mV[VX]) && is_approx_equal(-2*y1,vec4a.mV[VY]) && is_approx_equal(-2*z1,vec4a.mV[VZ]))); +	} + +	template<> template<> +	void v4math_object::test<12>() +	{ +		F32 x1 = 1.f, y1 = 2.f, z1 = -1.1f; +		F32 x2 = 1.2f, y2 = 2.5f, z2 = 1.f; +		LLVector4 vec4(x1,y1,z1),vec4a(x2,y2,z2); +		F32 res = vec4 * vec4a; +		ensure("1:operator* failed " ,is_approx_equal(res, x1*x2 + y1*y2 + z1*z2)); +		vec4a.clearVec(); +		F32 mulVal = 4.2f; +		vec4a = vec4 * mulVal; +		ensure("2:operator* failed " ,is_approx_equal(x1*mulVal,vec4a.mV[VX]) && is_approx_equal(y1*mulVal, vec4a.mV[VY])&& is_approx_equal(z1*mulVal, vec4a.mV[VZ])); +		vec4a.clearVec(); +		vec4a = mulVal *  vec4 ; +		ensure("3:operator* failed " ,is_approx_equal(x1*mulVal, vec4a.mV[VX]) && is_approx_equal(y1*mulVal, vec4a.mV[VY])&& is_approx_equal(z1*mulVal, vec4a.mV[VZ])); +		vec4 *= mulVal; +		ensure("4:operator*= failed " ,is_approx_equal(x1*mulVal, vec4.mV[VX]) && is_approx_equal(y1*mulVal, vec4.mV[VY])&& is_approx_equal(z1*mulVal, vec4.mV[VZ])); +	} + +	template<> template<> +	void v4math_object::test<13>() +	{ +		F32 x1 = 1.f, y1 = 2.f, z1 = -1.1f; +		F32 x2 = 1.2f, y2 = 2.5f, z2 = 1.f; +		LLVector4 vec4(x1,y1,z1),vec4a(x2,y2,z2),vec4b; +		vec4b = vec4 % vec4a; +		ensure("1:operator% failed " ,is_approx_equal(y1*z2 - y2*z1, vec4b.mV[VX]) && is_approx_equal(z1*x2 -z2*x1, vec4b.mV[VY]) && is_approx_equal(x1*y2-x2*y1, vec4b.mV[VZ]));  +		vec4 %= vec4a; +		ensure_equals("operator%= failed " ,vec4,vec4b);  +	} + +	template<> template<> +	void v4math_object::test<14>() +	{ +		F32 x = 1.f, y = 2.f, z = -1.1f,div = 4.2f; +		F32 t = 1.f / div; +		LLVector4 vec4(x,y,z), vec4a; +		vec4a = vec4/div; +		ensure("1:operator/ failed " ,is_approx_equal(x*t, vec4a.mV[VX]) && is_approx_equal(y*t, vec4a.mV[VY])&& is_approx_equal(z*t, vec4a.mV[VZ])); +		x = 1.23f, y = 4.f, z = -2.32f; +		vec4.clearVec(); +		vec4a.clearVec(); +		vec4.setVec(x,y,z); +		vec4a = vec4/div; +		ensure("2:operator/ failed " ,is_approx_equal(x*t, vec4a.mV[VX]) && is_approx_equal(y*t, vec4a.mV[VY])&& is_approx_equal(z*t, vec4a.mV[VZ])); +		vec4 /= div; +		ensure("3:operator/ failed " ,is_approx_equal(x*t, vec4.mV[VX]) && is_approx_equal(y*t, vec4.mV[VY])&& is_approx_equal(z*t, vec4.mV[VZ])); +	} + +	template<> template<> +	void v4math_object::test<15>() +	{ +		F32 x = 1.f, y = 2.f, z = -1.1f; +		LLVector4 vec4(x,y,z), vec4a; +		ensure("operator!= failed " ,(vec4 != vec4a)); +		vec4a = vec4; +		ensure("operator== failed " ,(vec4 ==vec4a));  +	} + +	template<> template<> +	void v4math_object::test<16>() +	{ +		F32 x = 1.f, y = 2.f, z = -1.1f; +		LLVector4 vec4(x,y,z), vec4a; +		vec4a = - vec4; +		ensure("operator- failed " , (vec4 == - vec4a));	 +	} + +	template<> template<> +	void v4math_object::test<17>() +	{ +		F32 x = 1.f, y = 2.f, z = -1.1f,epsilon = .23425f; +		LLVector4 vec4(x,y,z), vec4a(x,y,z); +		ensure("1:are_parallel: Fail " ,(TRUE == are_parallel(vec4a,vec4,epsilon))); +		x = 21.f, y = 12.f, z = -123.1f; +		vec4a.clearVec(); +		vec4a.setVec(x,y,z); +		ensure("2:are_parallel: Fail " ,(FALSE == are_parallel(vec4a,vec4,epsilon))); +	} + +	template<> template<> +	void v4math_object::test<18>() +	{ +		F32 x = 1.f, y = 2.f, z = -1.1f; +		F32 angle1, angle2; +		LLVector4 vec4(x,y,z), vec4a(x,y,z); +		angle1 = angle_between(vec4, vec4a); +		vec4.normVec(); +		vec4a.normVec(); +		angle2 = acos(vec4 * vec4a); +		ensure_approximately_equals("1:angle_between: Fail " ,angle1,angle2,8); +		F32 x1 = 21.f, y1 = 2.23f, z1 = -1.1f; +		LLVector4 vec4b(x,y,z), vec4c(x1,y1,z1); +		angle1 = angle_between(vec4b, vec4c); +		vec4b.normVec(); +		vec4c.normVec(); +		angle2 = acos(vec4b * vec4c); +		ensure_approximately_equals("2:angle_between: Fail " ,angle1,angle2,8); +	} + +	template<> template<> +	void v4math_object::test<19>() +	{ +		F32 x1 =-2.3f, y1 = 2.f,z1 = 1.2f, x2 = 1.3f, y2 = 1.f, z2 = 1.f; +		F32 val1,val2; +		LLVector4 vec4(x1,y1,z1),vec4a(x2,y2,z2); +		val1 = dist_vec(vec4,vec4a); +		val2 = fsqrtf((x1 - x2)*(x1 - x2) + (y1 - y2)* (y1 - y2) + (z1 - z2)* (z1 -z2)); +		ensure_equals("dist_vec: Fail ",val2, val1); +		val1 = dist_vec_squared(vec4,vec4a); +		val2 =((x1 - x2)*(x1 - x2) + (y1 - y2)* (y1 - y2) + (z1 - z2)* (z1 -z2)); +		ensure_equals("dist_vec_squared: Fail ",val2, val1); +	} + +	template<> template<> +	void v4math_object::test<20>() +	{ +		F32 x1 =-2.3f, y1 = 2.f,z1 = 1.2f, w1 = -.23f, x2 = 1.3f, y2 = 1.f, z2 = 1.f,w2 = .12f; +		F32 val = 2.3f,val1,val2,val3,val4; +		LLVector4 vec4(x1,y1,z1,w1),vec4a(x2,y2,z2,w2); +		val1 = x1 + (x2 - x1)* val; +		val2 = y1 + (y2 - y1)* val; +		val3 = z1 + (z2 - z1)* val; +		val4 = w1 + (w2 - w1)* val; +		LLVector4 vec4b = lerp(vec4,vec4a,val); +		ensure("lerp failed", ((val1 ==vec4b.mV[VX])&& (val2 ==vec4b.mV[VY]) && (val3 ==vec4b.mV[VZ])&& (val4 ==vec4b.mV[VW])));	 +	} + +	template<> template<> +	void v4math_object::test<21>() +	{ +		F32 x = 1.f, y = 2.f, z = -1.1f; +		LLVector4 vec4(x,y,z); +		LLVector3 vec3 = vec4to3(vec4); +		ensure("vec4to3 failed", ((x == vec3.mV[VX])&& (y == vec3.mV[VY]) && (z == vec3.mV[VZ])));	 +		LLVector4 vec4a = vec3to4(vec3); +		ensure_equals("vec3to4 failed",vec4a,vec4);	 +	} + +	template<> template<> +	void v4math_object::test<22>() +	{ +		F32 x = 1.f, y = 2.f, z = -1.1f; +		LLVector4 vec4(x,y,z); +		LLSD llsd = vec4.getValue(); +		LLVector3 vec3(llsd); +		LLVector4 vec4a = vec3to4(vec3); +		ensure_equals("getValue failed",vec4a,vec4);	 +	}		 +} diff --git a/indra/llmath/tests/xform_test.cpp b/indra/llmath/tests/xform_test.cpp new file mode 100644 index 0000000000..81116a58f0 --- /dev/null +++ b/indra/llmath/tests/xform_test.cpp @@ -0,0 +1,251 @@ +/**  + * @file xform_tut.cpp + * @author Adroit + * @date March 2007  + * @brief Test cases for LLXform + * + * $LicenseInfo:firstyear=2007&license=viewergpl$ + *  + * Copyright (c) 2007-2009, Linden Research, Inc. + *  + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab.  Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + *  + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + *  + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + *  + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "linden_common.h" +#include "../test/lltut.h" + +#include "../xform.h" + +namespace tut +{ +	struct xform_test +	{ +	}; +	typedef test_group<xform_test> xform_test_t; +	typedef xform_test_t::object xform_test_object_t; +	tut::xform_test_t tut_xform_test("xform_test"); + +	//test case for init(), getParent(), getRotation(), getPositionW(), getWorldRotation() fns. +	template<> template<> +	void xform_test_object_t::test<1>() +	{ +		LLXform xform_obj; +		LLVector3 emptyVec(0.f,0.f,0.f); +		LLVector3 initialScaleVec(1.f,1.f,1.f); + +		ensure("LLXform empty constructor failed: ", !xform_obj.getParent() && !xform_obj.isChanged() && +			xform_obj.getPosition() == emptyVec &&  +			(xform_obj.getRotation()).isIdentity() && +			xform_obj.getScale() == initialScaleVec &&  +			xform_obj.getPositionW() == emptyVec &&  +			(xform_obj.getWorldRotation()).isIdentity() && +			!xform_obj.getScaleChildOffset()); +	} + +	// test cases for  +	// setScale(const LLVector3& scale)  +	// setScale(const F32 x, const F32 y, const F32 z) +	// setRotation(const F32 x, const F32 y, const F32 z)  +	// setPosition(const F32 x, const F32 y, const F32 z)  +	// getLocalMat4(LLMatrix4 &mat) +	template<> template<> +	void xform_test_object_t::test<2>()	 +	{ +		LLMatrix4 llmat4; +		LLXform xform_obj; + +		F32 x = 3.6f; +		F32 y = 5.5f; +		F32 z = 4.2f; +		F32 w = 0.f; +		F32 posz = z + 2.122f; +		LLVector3 vec(x, y, z); +		xform_obj.setScale(x, y, z); +		xform_obj.setPosition(x, y, posz); +		ensure("setScale failed: ", xform_obj.getScale() == vec); + +		vec.setVec(x, y, posz); +		ensure("getPosition failed: ", xform_obj.getPosition() == vec); + +		x = x * 2.f; +		y = y + 2.3f; +		z = posz * 4.f;  +		vec.setVec(x, y, z); +		xform_obj.setPositionX(x); +		xform_obj.setPositionY(y); +		xform_obj.setPositionZ(z); +		ensure("setPositionX/Y/Z failed: ", xform_obj.getPosition() == vec); + +		xform_obj.setScaleChildOffset(TRUE); +		ensure("setScaleChildOffset failed: ", xform_obj.getScaleChildOffset()); + +		vec.setVec(x, y, z); + +		xform_obj.addPosition(vec); +		vec += vec; +		ensure("addPosition failed: ", xform_obj.getPosition() == vec); + +		xform_obj.setScale(vec); +		ensure("setScale vector failed: ", xform_obj.getScale() == vec); + +		LLQuaternion quat(x, y, z, w); +		xform_obj.setRotation(quat); +		ensure("setRotation quat failed: ", xform_obj.getRotation() == quat); + +		xform_obj.setRotation(x, y, z, w); +		ensure("getRotation 2 failed: ", xform_obj.getRotation() == quat); + +		xform_obj.setRotation(x, y, z); +		quat.setQuat(x,y,z);  +		ensure("setRotation xyz failed: ", xform_obj.getRotation() == quat); + +		// LLXform::setRotation(const F32 x, const F32 y, const F32 z)  +		//		Does normalization +		// LLXform::setRotation(const F32 x, const F32 y, const F32 z, const F32 s)  +		//		Simply copies the individual values - does not do any normalization.  +		// Is that the expected behavior? +	} + +	// test cases for inline BOOL setParent(LLXform *parent) and getParent() fn. +	template<> template<> +	void xform_test_object_t::test<3>()	 +	{		 +		LLXform xform_obj; +		LLXform par; +		LLXform grandpar; +		xform_obj.setParent(&par);  +		par.setParent(&grandpar);  +		ensure("setParent/getParent failed: ", &par == xform_obj.getParent()); +		ensure("getRoot failed: ", &grandpar == xform_obj.getRoot()); +		ensure("isRoot failed: ", grandpar.isRoot() && !par.isRoot() && !xform_obj.isRoot()); +		ensure("isRootEdit failed: ", grandpar.isRootEdit() && !par.isRootEdit() && !xform_obj.isRootEdit()); +	} + +	template<> template<> +	void xform_test_object_t::test<4>()	 +	{ +		LLXform xform_obj; +		xform_obj.setChanged(LLXform::TRANSLATED | LLXform::ROTATED | LLXform::SCALED); +		ensure("setChanged/isChanged failed: ", xform_obj.isChanged()); + +		xform_obj.clearChanged(LLXform::TRANSLATED | LLXform::ROTATED | LLXform::SCALED); +		ensure("clearChanged failed: ", !xform_obj.isChanged()); +		 +		LLVector3 llvect3(12.4f, -5.6f, 0.34f); +		xform_obj.setScale(llvect3); +		ensure("setScale did not set SCALED flag: ", xform_obj.isChanged(LLXform::SCALED)); +		xform_obj.setPosition(1.2f, 2.3f, 3.4f); +		ensure("setScale did not set TRANSLATED flag: ", xform_obj.isChanged(LLXform::TRANSLATED)); +		ensure("TRANSLATED reset SCALED flag: ", xform_obj.isChanged(LLXform::TRANSLATED | LLXform::SCALED)); +		xform_obj.clearChanged(LLXform::SCALED); +		ensure("reset SCALED failed: ", !xform_obj.isChanged(LLXform::SCALED)); +		xform_obj.setRotation(1, 2, 3, 4); +		ensure("ROTATION flag not set ", xform_obj.isChanged(LLXform::TRANSLATED | LLXform::ROTATED)); +		xform_obj.setScale(llvect3); +		ensure("ROTATION flag not set ", xform_obj.isChanged(LLXform::MOVED)); +	} + +	//to test init() and getWorldMatrix() fns. +	template<> template<> +	void xform_test_object_t::test<5>()	 +	{ +		LLXformMatrix formMatrix_obj; +		formMatrix_obj.init(); +		LLMatrix4 mat4_obj; +		 +		ensure("1. The value is not NULL", 1.f == formMatrix_obj.getWorldMatrix().mMatrix[0][0]); +		ensure("2. The value is not NULL", 0.f == formMatrix_obj.getWorldMatrix().mMatrix[0][1]); +		ensure("3. The value is not NULL", 0.f == formMatrix_obj.getWorldMatrix().mMatrix[0][2]); +		ensure("4. The value is not NULL", 0.f == formMatrix_obj.getWorldMatrix().mMatrix[0][3]); +		ensure("5. The value is not NULL", 0.f == formMatrix_obj.getWorldMatrix().mMatrix[1][0]); +		ensure("6. The value is not NULL", 1.f == formMatrix_obj.getWorldMatrix().mMatrix[1][1]); +		ensure("7. The value is not NULL", 0.f == formMatrix_obj.getWorldMatrix().mMatrix[1][2]); +		ensure("8. The value is not NULL", 0.f == formMatrix_obj.getWorldMatrix().mMatrix[1][3]); +		ensure("9. The value is not NULL", 0.f == formMatrix_obj.getWorldMatrix().mMatrix[2][0]); +		ensure("10. The value is not NULL", 0.f == formMatrix_obj.getWorldMatrix().mMatrix[2][1]); +		ensure("11. The value is not NULL", 1.f == formMatrix_obj.getWorldMatrix().mMatrix[2][2]); +		ensure("12. The value is not NULL", 0.f == formMatrix_obj.getWorldMatrix().mMatrix[2][3]); +		ensure("13. The value is not NULL", 0.f == formMatrix_obj.getWorldMatrix().mMatrix[3][0]); +		ensure("14. The value is not NULL", 0.f == formMatrix_obj.getWorldMatrix().mMatrix[3][1]); +		ensure("15. The value is not NULL", 0.f == formMatrix_obj.getWorldMatrix().mMatrix[3][2]); +		ensure("16. The value is not NULL", 1.f == formMatrix_obj.getWorldMatrix().mMatrix[3][3]); +	} + +	//to test mMin.clearVec() and mMax.clearVec() fns +	template<> template<> +	void xform_test_object_t::test<6>()	 +	{ +		LLXformMatrix formMatrix_obj; +		formMatrix_obj.init(); +		LLVector3 llmin_vec3; +		LLVector3 llmax_vec3; +		formMatrix_obj.getMinMax(llmin_vec3, llmax_vec3); +		ensure("1. The value is not NULL", 0.f == llmin_vec3.mV[0]); +		ensure("2. The value is not NULL", 0.f == llmin_vec3.mV[1]); +		ensure("3. The value is not NULL", 0.f == llmin_vec3.mV[2]); +		ensure("4. The value is not NULL", 0.f == llmin_vec3.mV[0]); +		ensure("5. The value is not NULL", 0.f == llmin_vec3.mV[1]); +		ensure("6. The value is not NULL", 0.f == llmin_vec3.mV[2]); +	} + +	//test case of update() fn. +	template<> template<> +	void xform_test_object_t::test<7>()	 +	{ +		LLXformMatrix formMatrix_obj; + +		LLXformMatrix parent; +		LLVector3 llvecpos(1.0, 2.0, 3.0); +		LLVector3 llvecpospar(10.0, 20.0, 30.0); +		formMatrix_obj.setPosition(llvecpos); +		parent.setPosition(llvecpospar); + +		LLVector3 llvecparentscale(1.0, 2.0, 0); +		parent.setScaleChildOffset(TRUE); +		parent.setScale(llvecparentscale); + +		LLQuaternion quat(1, 2, 3, 4); +		LLQuaternion quatparent(5, 6, 7, 8); +		formMatrix_obj.setRotation(quat); +		parent.setRotation(quatparent); +		formMatrix_obj.setParent(&parent); + +		parent.update(); +		formMatrix_obj.update(); + +		LLVector3 worldPos = llvecpos; +		worldPos.scaleVec(llvecparentscale); +		worldPos *= quatparent; +		worldPos += llvecpospar; + +		LLQuaternion worldRot = quat * quatparent;  + +		ensure("getWorldPosition failed: ", formMatrix_obj.getWorldPosition() == worldPos); +		ensure("getWorldRotation failed: ", formMatrix_obj.getWorldRotation() == worldRot); + +		ensure("getWorldPosition for parent failed: ", parent.getWorldPosition() == llvecpospar); +		ensure("getWorldRotation for parent failed: ", parent.getWorldRotation() == quatparent); +	} +}	 + | 
