diff options
author | Jacek Antonelli | 2008-08-15 23:45:42 -0500 |
---|---|---|
committer | Jacek Antonelli | 2008-08-15 23:45:42 -0500 |
commit | ce28e056c20bf2723f565bbf464b87781ec248a2 (patch) | |
tree | ef7b0501c4de4b631a916305cbc2a5fdc125e52d /linden/indra/test | |
parent | Second Life viewer sources 1.19.1.4b (diff) | |
download | meta-impy-ce28e056c20bf2723f565bbf464b87781ec248a2.zip meta-impy-ce28e056c20bf2723f565bbf464b87781ec248a2.tar.gz meta-impy-ce28e056c20bf2723f565bbf464b87781ec248a2.tar.bz2 meta-impy-ce28e056c20bf2723f565bbf464b87781ec248a2.tar.xz |
Second Life viewer sources 1.20.2
Diffstat (limited to 'linden/indra/test')
-rw-r--r-- | linden/indra/test/files.lst | 2 | ||||
-rw-r--r-- | linden/indra/test/inventory.cpp | 4 | ||||
-rw-r--r-- | linden/indra/test/io.cpp | 2 | ||||
-rw-r--r-- | linden/indra/test/llcontrol_tut.cpp | 147 | ||||
-rw-r--r-- | linden/indra/test/llmessageconfig_tut.cpp | 24 | ||||
-rw-r--r-- | linden/indra/test/llmessagetemplateparser_tut.cpp | 2 | ||||
-rw-r--r-- | linden/indra/test/llnamevalue_tut.cpp | 550 | ||||
-rwxr-xr-x | linden/indra/test/llsdmessagereader_tut.cpp | 2 | ||||
-rw-r--r-- | linden/indra/test/llstreamtools_tut.cpp | 42 | ||||
-rw-r--r-- | linden/indra/test/lltemplatemessagebuilder_tut.cpp | 2 | ||||
-rw-r--r-- | linden/indra/test/lltut.h | 10 | ||||
-rw-r--r-- | linden/indra/test/mass_properties_tut.cpp | 1008 | ||||
-rw-r--r-- | linden/indra/test/math.cpp | 442 | ||||
-rw-r--r-- | linden/indra/test/message_tut.cpp | 2 | ||||
-rw-r--r-- | linden/indra/test/prim_linkability_tut.cpp | 490 | ||||
-rw-r--r-- | linden/indra/test/test.vcproj | 19 | ||||
-rw-r--r-- | linden/indra/test/test_vc8.vcproj | 6 | ||||
-rw-r--r-- | linden/indra/test/test_vc9.vcproj | 2 |
18 files changed, 2198 insertions, 558 deletions
diff --git a/linden/indra/test/files.lst b/linden/indra/test/files.lst index d923d8f..b335dbf 100644 --- a/linden/indra/test/files.lst +++ b/linden/indra/test/files.lst | |||
@@ -5,6 +5,7 @@ test/llapp_tut.cpp | |||
5 | test/llbase64_tut.cpp | 5 | test/llbase64_tut.cpp |
6 | test/llblowfish_tut.cpp | 6 | test/llblowfish_tut.cpp |
7 | test/llbuffer_tut.cpp | 7 | test/llbuffer_tut.cpp |
8 | test/llcontrol_tut.cpp | ||
8 | test/lldate_tut.cpp | 9 | test/lldate_tut.cpp |
9 | test/llerror_tut.cpp | 10 | test/llerror_tut.cpp |
10 | test/llhost_tut.cpp | 11 | test/llhost_tut.cpp |
@@ -38,6 +39,7 @@ test/lluuidhashmap_tut.cpp | |||
38 | test/llxfer_tut.cpp | 39 | test/llxfer_tut.cpp |
39 | test/math.cpp | 40 | test/math.cpp |
40 | test/message_tut.cpp | 41 | test/message_tut.cpp |
42 | test/prim_linkability_tut.cpp | ||
41 | test/reflection_tut.cpp | 43 | test/reflection_tut.cpp |
42 | test/test.cpp | 44 | test/test.cpp |
43 | test/v2math_tut.cpp | 45 | test/v2math_tut.cpp |
diff --git a/linden/indra/test/inventory.cpp b/linden/indra/test/inventory.cpp index 7c81dbe..3899dfc 100644 --- a/linden/indra/test/inventory.cpp +++ b/linden/indra/test/inventory.cpp | |||
@@ -453,9 +453,7 @@ namespace tut | |||
453 | ensure_equals("9.sale price::getSalePrice() failed price", src1->getSaleInfo().getSalePrice(), src2->getSaleInfo().getSalePrice()); | 453 | ensure_equals("9.sale price::getSalePrice() failed price", src1->getSaleInfo().getSalePrice(), src2->getSaleInfo().getSalePrice()); |
454 | ensure_equals("10.name::getName() failed", src1->getName(), src2->getName()); | 454 | ensure_equals("10.name::getName() failed", src1->getName(), src2->getName()); |
455 | ensure_equals("11.description::getDescription() failed", src1->getDescription(), src2->getDescription()); | 455 | ensure_equals("11.description::getDescription() failed", src1->getDescription(), src2->getDescription()); |
456 | 456 | //skip_fail("12.creation::getCreationDate()"); | |
457 | |||
458 | skip_fail("12.creation::getCreationDate()"); | ||
459 | ensure_equals("12.creation::getCreationDate() failed", src1->getCreationDate(), src2->getCreationDate()); | 457 | ensure_equals("12.creation::getCreationDate() failed", src1->getCreationDate(), src2->getCreationDate()); |
460 | } | 458 | } |
461 | 459 | ||
diff --git a/linden/indra/test/io.cpp b/linden/indra/test/io.cpp index fe8c19d..408b7c8 100644 --- a/linden/indra/test/io.cpp +++ b/linden/indra/test/io.cpp | |||
@@ -1151,7 +1151,7 @@ namespace tut | |||
1151 | chain.push_back(LLIOPipe::ptr_t(new LLPipeStringInjector("hi"))); | 1151 | chain.push_back(LLIOPipe::ptr_t(new LLPipeStringInjector("hi"))); |
1152 | chain.push_back(LLIOPipe::ptr_t(new LLIOSocketWriter(client))); | 1152 | chain.push_back(LLIOPipe::ptr_t(new LLIOSocketWriter(client))); |
1153 | chain.push_back(LLIOPipe::ptr_t(new LLIONull)); | 1153 | chain.push_back(LLIOPipe::ptr_t(new LLIONull)); |
1154 | mPump->addChain(chain, 0.2); | 1154 | mPump->addChain(chain, 0.2f); |
1155 | chain.clear(); | 1155 | chain.clear(); |
1156 | 1156 | ||
1157 | // pump for a bit and make sure all 3 chains are running | 1157 | // pump for a bit and make sure all 3 chains are running |
diff --git a/linden/indra/test/llcontrol_tut.cpp b/linden/indra/test/llcontrol_tut.cpp new file mode 100644 index 0000000..aabe205 --- /dev/null +++ b/linden/indra/test/llcontrol_tut.cpp | |||
@@ -0,0 +1,147 @@ | |||
1 | /** | ||
2 | * @file llcontrol_tut.cpp | ||
3 | * @date February 2008 | ||
4 | * @brief control group unit tests | ||
5 | * | ||
6 | * $LicenseInfo:firstyear=2008&license=viewergpl$ | ||
7 | * | ||
8 | * Copyright (c) 2008, Linden Research, Inc. | ||
9 | * | ||
10 | * Second Life Viewer Source Code | ||
11 | * The source code in this file ("Source Code") is provided by Linden Lab | ||
12 | * to you under the terms of the GNU General Public License, version 2.0 | ||
13 | * ("GPL"), unless you have obtained a separate licensing agreement | ||
14 | * ("Other License"), formally executed by you and Linden Lab. Terms of | ||
15 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | ||
16 | * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 | ||
17 | * | ||
18 | * There are special exceptions to the terms and conditions of the GPL as | ||
19 | * it is applied to this Source Code. View the full text of the exception | ||
20 | * in the file doc/FLOSS-exception.txt in this software distribution, or | ||
21 | * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception | ||
22 | * | ||
23 | * By copying, modifying or distributing this software, you acknowledge | ||
24 | * that you have read and understood your obligations described above, | ||
25 | * and agree to abide by those obligations. | ||
26 | * | ||
27 | * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO | ||
28 | * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, | ||
29 | * COMPLETENESS OR PERFORMANCE. | ||
30 | * $/LicenseInfo$ | ||
31 | */ | ||
32 | |||
33 | #include "linden_common.h" | ||
34 | |||
35 | #include <tut/tut.h> | ||
36 | #include "lltut.h" | ||
37 | |||
38 | #include "llcontrol.h" | ||
39 | #include "llsdserialize.h" | ||
40 | |||
41 | namespace tut | ||
42 | { | ||
43 | |||
44 | struct control_group | ||
45 | { | ||
46 | LLControlGroup* mCG; | ||
47 | LLString mTestConfigDir; | ||
48 | LLString mTestConfigFile; | ||
49 | static bool mListenerFired; | ||
50 | control_group() | ||
51 | { | ||
52 | mCG = new LLControlGroup; | ||
53 | LLUUID random; | ||
54 | random.generate(); | ||
55 | // generate temp dir | ||
56 | std::ostringstream oStr; | ||
57 | oStr << "/tmp/llcontrol-test-" << random << "/"; | ||
58 | mTestConfigDir = oStr.str(); | ||
59 | mTestConfigFile = mTestConfigDir + "settings.xml"; | ||
60 | LLFile::mkdir(mTestConfigDir.c_str()); | ||
61 | LLSD config; | ||
62 | config["TestSetting"]["Comment"] = "Dummy setting used for testing"; | ||
63 | config["TestSetting"]["Persist"] = 1; | ||
64 | config["TestSetting"]["Type"] = "U32"; | ||
65 | config["TestSetting"]["Value"] = 12; | ||
66 | writeSettingsFile(config); | ||
67 | } | ||
68 | ~control_group() | ||
69 | { | ||
70 | //Remove test files | ||
71 | delete mCG; | ||
72 | } | ||
73 | void writeSettingsFile(const LLSD& config) | ||
74 | { | ||
75 | llofstream file(mTestConfigFile.c_str()); | ||
76 | if (file.is_open()) | ||
77 | { | ||
78 | LLSDSerialize::toPrettyXML(config, file); | ||
79 | } | ||
80 | file.close(); | ||
81 | } | ||
82 | static bool handleListenerTest(const LLSD& newvalue) | ||
83 | { | ||
84 | control_group::mListenerFired = true; | ||
85 | return true; | ||
86 | } | ||
87 | }; | ||
88 | |||
89 | bool control_group::mListenerFired = false; | ||
90 | |||
91 | typedef test_group<control_group> control_group_test; | ||
92 | typedef control_group_test::object control_group_t; | ||
93 | control_group_test tut_control_group("control_group"); | ||
94 | |||
95 | //load settings from files - LLSD | ||
96 | template<> template<> | ||
97 | void control_group_t::test<1>() | ||
98 | { | ||
99 | int results = mCG->loadFromFile(mTestConfigFile.c_str()); | ||
100 | ensure("number of settings", (results == 1)); | ||
101 | ensure("value of setting", (mCG->getU32("TestSetting") == 12)); | ||
102 | } | ||
103 | |||
104 | //save settings to files | ||
105 | template<> template<> | ||
106 | void control_group_t::test<2>() | ||
107 | { | ||
108 | int results = mCG->loadFromFile(mTestConfigFile.c_str()); | ||
109 | mCG->setU32("TestSetting", 13); | ||
110 | ensure_equals("value of changed setting", mCG->getU32("TestSetting"), 13); | ||
111 | LLControlGroup test_cg; | ||
112 | LLString temp_test_file = (mTestConfigDir + "setting_llsd_temp.xml"); | ||
113 | mCG->saveToFile(temp_test_file.c_str(), TRUE); | ||
114 | results = test_cg.loadFromFile(temp_test_file.c_str()); | ||
115 | ensure("number of changed settings loaded", (results == 1)); | ||
116 | ensure("value of changed settings loaded", (test_cg.getU32("TestSetting") == 13)); | ||
117 | } | ||
118 | |||
119 | //priorities | ||
120 | template<> template<> | ||
121 | void control_group_t::test<3>() | ||
122 | { | ||
123 | int results = mCG->loadFromFile(mTestConfigFile.c_str()); | ||
124 | LLControlVariable* control = mCG->getControl("TestSetting"); | ||
125 | LLSD new_value = 13; | ||
126 | control->setValue(new_value, FALSE); | ||
127 | ensure_equals("value of changed setting", mCG->getU32("TestSetting"), 13); | ||
128 | LLControlGroup test_cg; | ||
129 | LLString temp_test_file = (mTestConfigDir + "setting_llsd_persist_temp.xml"); | ||
130 | mCG->saveToFile(temp_test_file.c_str(), TRUE); | ||
131 | results = test_cg.loadFromFile(temp_test_file.c_str()); | ||
132 | //If we haven't changed any settings, then we shouldn't have any settings to load | ||
133 | ensure("number of non-persisted changed settings loaded", (results == 0)); | ||
134 | } | ||
135 | |||
136 | //listeners | ||
137 | template<> template<> | ||
138 | void control_group_t::test<4>() | ||
139 | { | ||
140 | int results = mCG->loadFromFile(mTestConfigFile.c_str()); | ||
141 | ensure("number of settings", (results == 1)); | ||
142 | mCG->getControl("TestSetting")->getSignal()->connect(boost::bind(&this->handleListenerTest, _1)); | ||
143 | mCG->setU32("TestSetting", 13); | ||
144 | ensure("listener fired on changed setting", mListenerFired); | ||
145 | } | ||
146 | |||
147 | } | ||
diff --git a/linden/indra/test/llmessageconfig_tut.cpp b/linden/indra/test/llmessageconfig_tut.cpp index b709bfc..e5dd328 100644 --- a/linden/indra/test/llmessageconfig_tut.cpp +++ b/linden/indra/test/llmessageconfig_tut.cpp | |||
@@ -35,7 +35,6 @@ | |||
35 | #include "lltut.h" | 35 | #include "lltut.h" |
36 | #include "llsdserialize.h" | 36 | #include "llsdserialize.h" |
37 | #include "llfile.h" | 37 | #include "llfile.h" |
38 | #include "lldir.h" | ||
39 | #include "lltimer.h" | 38 | #include "lltimer.h" |
40 | #include "llframetimer.h" | 39 | #include "llframetimer.h" |
41 | #include "llsdutil.h" | 40 | #include "llsdutil.h" |
@@ -51,7 +50,11 @@ namespace tut | |||
51 | random.generate(); | 50 | random.generate(); |
52 | // generate temp dir | 51 | // generate temp dir |
53 | std::ostringstream oStr; | 52 | std::ostringstream oStr; |
53 | #if LL_WINDOWS | ||
54 | oStr << "llmessage-config-test-" << random; | ||
55 | #else | ||
54 | oStr << "/tmp/llmessage-config-test-" << random; | 56 | oStr << "/tmp/llmessage-config-test-" << random; |
57 | #endif | ||
55 | mTestConfigDir = oStr.str(); | 58 | mTestConfigDir = oStr.str(); |
56 | LLFile::mkdir(mTestConfigDir.c_str()); | 59 | LLFile::mkdir(mTestConfigDir.c_str()); |
57 | writeConfigFile(LLSD()); | 60 | writeConfigFile(LLSD()); |
@@ -199,4 +202,23 @@ namespace tut | |||
199 | LLMessageConfig::getServerDefaultFlavor(), | 202 | LLMessageConfig::getServerDefaultFlavor(), |
200 | LLMessageConfig::LLSD_FLAVOR); | 203 | LLMessageConfig::LLSD_FLAVOR); |
201 | } | 204 | } |
205 | |||
206 | template<> template<> | ||
207 | void LLMessageConfigTestObject::test<8>() | ||
208 | // tests that config changes are picked up/refreshed periodically | ||
209 | { | ||
210 | LLSD config; | ||
211 | config["serverDefaults"]["simulator"] = "template"; | ||
212 | config["messages"]["msg1"]["flavor"] = "llsd"; | ||
213 | config["messages"]["msg1"]["only-send-latest"] = true; | ||
214 | config["messages"]["msg2"]["flavor"] = "llsd"; | ||
215 | config["messages"]["msg2"]["only-send-latest"] = false; | ||
216 | LLMessageConfig::useConfig(config); | ||
217 | ensure_equals("Ensure msg1 exists, sent latest-only", | ||
218 | LLMessageConfig::onlySendLatest("msg1"), | ||
219 | true); | ||
220 | ensure_equals("Ensure msg2 exists, sent latest-only", | ||
221 | LLMessageConfig::onlySendLatest("msg2"), | ||
222 | false); | ||
223 | } | ||
202 | } | 224 | } |
diff --git a/linden/indra/test/llmessagetemplateparser_tut.cpp b/linden/indra/test/llmessagetemplateparser_tut.cpp index fe8e34c..7634e90 100644 --- a/linden/indra/test/llmessagetemplateparser_tut.cpp +++ b/linden/indra/test/llmessagetemplateparser_tut.cpp | |||
@@ -56,7 +56,7 @@ namespace tut | |||
56 | 56 | ||
57 | char * prehash(const char * name) | 57 | char * prehash(const char * name) |
58 | { | 58 | { |
59 | return gMessageStringTable.getString(name); | 59 | return LLMessageStringTable::getInstance()->getString(name); |
60 | } | 60 | } |
61 | 61 | ||
62 | void ensure_block_attributes(std::string identifier, | 62 | void ensure_block_attributes(std::string identifier, |
diff --git a/linden/indra/test/llnamevalue_tut.cpp b/linden/indra/test/llnamevalue_tut.cpp index d38913a..f604e84 100644 --- a/linden/indra/test/llnamevalue_tut.cpp +++ b/linden/indra/test/llnamevalue_tut.cpp | |||
@@ -42,133 +42,7 @@ namespace tut | |||
42 | { | 42 | { |
43 | namevalue_test() | 43 | namevalue_test() |
44 | { | 44 | { |
45 | mExpectedNameValueReference.string = NULL; | ||
46 | mExpectedNameValueType = NVT_NULL; | ||
47 | mCallbackCount = 0; | ||
48 | } | 45 | } |
49 | |||
50 | ~namevalue_test() | ||
51 | { | ||
52 | reset(); | ||
53 | }; | ||
54 | |||
55 | void reset() | ||
56 | { | ||
57 | switch(mExpectedNameValueType) | ||
58 | { | ||
59 | case NVT_STRING: | ||
60 | case NVT_ASSET: | ||
61 | delete [] mExpectedNameValueReference.string; | ||
62 | mExpectedNameValueReference.string = NULL; | ||
63 | break; | ||
64 | case NVT_F32: | ||
65 | delete mExpectedNameValueReference.f32; | ||
66 | mExpectedNameValueReference.f32 = NULL; | ||
67 | break; | ||
68 | case NVT_S32: | ||
69 | delete mExpectedNameValueReference.s32; | ||
70 | mExpectedNameValueReference.s32 = NULL; | ||
71 | break; | ||
72 | case NVT_U32: | ||
73 | delete mExpectedNameValueReference.u32; | ||
74 | mExpectedNameValueReference.u32 = NULL; | ||
75 | break; | ||
76 | case NVT_VEC3: | ||
77 | delete mExpectedNameValueReference.vec3; | ||
78 | mExpectedNameValueReference.vec3 = NULL; | ||
79 | break; | ||
80 | case NVT_U64: | ||
81 | delete mExpectedNameValueReference.u64; | ||
82 | mExpectedNameValueReference.u64 = NULL; | ||
83 | default: | ||
84 | break; | ||
85 | } | ||
86 | |||
87 | mExpectedNameValueType = NVT_NULL; | ||
88 | mCallbackCount = 0; | ||
89 | } | ||
90 | |||
91 | void setExpectedResult(ENameValueType type, void* value) | ||
92 | { | ||
93 | reset(); | ||
94 | mExpectedNameValueType = type; | ||
95 | switch(type) | ||
96 | { | ||
97 | case NVT_STRING: | ||
98 | case NVT_ASSET: | ||
99 | mExpectedNameValueReference.string = new char[strlen((const char*) value)+1]; | ||
100 | strcpy(mExpectedNameValueReference.string, (const char*) value); | ||
101 | break; | ||
102 | case NVT_F32: | ||
103 | mExpectedNameValueReference.f32 = new F32(*((F32*) value)); | ||
104 | break; | ||
105 | case NVT_S32: | ||
106 | mExpectedNameValueReference.s32 = new S32(*((S32*) value)); | ||
107 | break; | ||
108 | case NVT_U32: | ||
109 | mExpectedNameValueReference.u32 = new U32(*((U32*) value)); | ||
110 | break; | ||
111 | case NVT_VEC3: | ||
112 | mExpectedNameValueReference.vec3 = new LLVector3(*((LLVector3*) value)); | ||
113 | break; | ||
114 | case NVT_U64: | ||
115 | mExpectedNameValueReference.u64 = new U64(*((U64*) value)); | ||
116 | default: | ||
117 | break; | ||
118 | } | ||
119 | } | ||
120 | |||
121 | void verifyChange(LLNameValue* changed) | ||
122 | { | ||
123 | std::string str = ""; | ||
124 | str += "Expected Value of type: "; | ||
125 | str += NameValueTypeStrings[mExpectedNameValueType]; | ||
126 | str += "not equal"; | ||
127 | |||
128 | switch(mExpectedNameValueType) | ||
129 | { | ||
130 | case NVT_STRING: | ||
131 | ensure_memory_matches(str.c_str(), changed->getString(), strlen(changed->getString()), mExpectedNameValueReference.string, strlen(mExpectedNameValueReference.string)); | ||
132 | break; | ||
133 | case NVT_ASSET: | ||
134 | ensure_memory_matches(str.c_str(), changed->getAsset(), strlen(changed->getAsset()), mExpectedNameValueReference.string, strlen(mExpectedNameValueReference.string)); | ||
135 | break; | ||
136 | case NVT_F32: | ||
137 | ensure(str, *(changed->getF32()) == *mExpectedNameValueReference.f32); | ||
138 | break; | ||
139 | case NVT_S32: | ||
140 | ensure(str, *(changed->getS32()) == *mExpectedNameValueReference.s32); | ||
141 | break; | ||
142 | case NVT_U32: | ||
143 | ensure(str, *(changed->getU32()) == *mExpectedNameValueReference.u32); | ||
144 | break; | ||
145 | case NVT_VEC3: | ||
146 | ensure(str, *(changed->getVec3()) == *mExpectedNameValueReference.vec3); | ||
147 | break; | ||
148 | case NVT_U64: | ||
149 | ensure(str, *(changed->getU64()) == *mExpectedNameValueReference.u64); | ||
150 | break; | ||
151 | default: | ||
152 | break; | ||
153 | } | ||
154 | } | ||
155 | |||
156 | void HandleCallback(LLNameValue* changed) | ||
157 | { | ||
158 | mCallbackCount++; | ||
159 | verifyChange(changed); | ||
160 | ensure("Callback called more than once", mCallbackCount == 1); | ||
161 | } | ||
162 | |||
163 | static void NameValueCallbackFunction(LLNameValue* changed, void** data) | ||
164 | { | ||
165 | namevalue_test* pNameValue = (namevalue_test*)data; | ||
166 | pNameValue->HandleCallback(changed); | ||
167 | } | ||
168 | |||
169 | ENameValueType mExpectedNameValueType; | ||
170 | UNameValueReference mExpectedNameValueReference; | ||
171 | int mCallbackCount; | ||
172 | }; | 46 | }; |
173 | typedef test_group<namevalue_test> namevalue_t; | 47 | typedef test_group<namevalue_test> namevalue_t; |
174 | typedef namevalue_t::object namevalue_object_t; | 48 | typedef namevalue_t::object namevalue_object_t; |
@@ -225,33 +99,33 @@ namespace tut | |||
225 | ensure("3. getS32 failed", *nValue3.getS32() == -43456787); | 99 | ensure("3. getS32 failed", *nValue3.getS32() == -43456787); |
226 | ensure("sendToData or sendToViewer failed", nValue3.sendToData() && !nValue3.sendToViewer()); | 100 | ensure("sendToData or sendToViewer failed", nValue3.sendToData() && !nValue3.sendToViewer()); |
227 | 101 | ||
228 | LLNameValue nValue4("SecondLife", "<1.0, 2.0, 3.0>", "VEC3", "CB", "SV"); | 102 | LLNameValue nValue4("SecondLife", "<1.0, 2.0, 3.0>", "VEC3", "RW", "SV"); |
229 | LLVector3 llvec4(1.0, 2.0, 3.0); | 103 | LLVector3 llvec4(1.0, 2.0, 3.0); |
230 | ensure("4. getTypeEnum failed", nValue4.getTypeEnum() == NVT_VEC3); | 104 | ensure("4. getTypeEnum failed", nValue4.getTypeEnum() == NVT_VEC3); |
231 | ensure("4. getClassEnum failed", nValue4.getClassEnum() == NVC_CALLBACK); | 105 | ensure("4. getClassEnum failed", nValue4.getClassEnum() == NVC_READ_WRITE); |
232 | ensure("4. getSendtoEnum failed", nValue4.getSendtoEnum() == NVS_SIM_VIEWER); | 106 | ensure("4. getSendtoEnum failed", nValue4.getSendtoEnum() == NVS_SIM_VIEWER); |
233 | ensure("4. getVec3 failed", *nValue4.getVec3() == llvec4); | 107 | ensure("4. getVec3 failed", *nValue4.getVec3() == llvec4); |
234 | ensure("4. sendToData or sendToViewer failed", !nValue4.sendToData() && nValue4.sendToViewer()); | 108 | ensure("4. sendToData or sendToViewer failed", !nValue4.sendToData() && nValue4.sendToViewer()); |
235 | 109 | ||
236 | LLNameValue nValue5("SecondLife", "-1.0, 2.4, 3", "VEC3", "CALLBACK", "SIM_VIEWER"); | 110 | LLNameValue nValue5("SecondLife", "-1.0, 2.4, 3", "VEC3", "RW", "SIM_VIEWER"); |
237 | LLVector3 llvec5(-1.0f, 2.4f, 3); | 111 | LLVector3 llvec5(-1.0f, 2.4f, 3); |
238 | ensure("5. getTypeEnum failed", nValue5.getTypeEnum() == NVT_VEC3); | 112 | ensure("5. getTypeEnum failed", nValue5.getTypeEnum() == NVT_VEC3); |
239 | ensure("5. getClassEnum failed", nValue5.getClassEnum() == NVC_CALLBACK); | 113 | ensure("5. getClassEnum failed", nValue5.getClassEnum() == NVC_READ_WRITE); |
240 | ensure("5. getSendtoEnum failed", nValue5.getSendtoEnum() == NVS_SIM_VIEWER); | 114 | ensure("5. getSendtoEnum failed", nValue5.getSendtoEnum() == NVS_SIM_VIEWER); |
241 | ensure("5. getVec3 failed", *nValue5.getVec3() == llvec5); | 115 | ensure("5. getVec3 failed", *nValue5.getVec3() == llvec5); |
242 | ensure("5. sendToData or sendToViewer failed", !nValue5.sendToData() && nValue5.sendToViewer()); | 116 | ensure("5. sendToData or sendToViewer failed", !nValue5.sendToData() && nValue5.sendToViewer()); |
243 | 117 | ||
244 | LLNameValue nValue6("SecondLife", "89764323", "U32", "CALLBACK", "DSV"); | 118 | LLNameValue nValue6("SecondLife", "89764323", "U32", "RW", "DSV"); |
245 | ensure("6. getTypeEnum failed", nValue6.getTypeEnum() == NVT_U32); | 119 | ensure("6. getTypeEnum failed", nValue6.getTypeEnum() == NVT_U32); |
246 | ensure("6. getClassEnum failed", nValue6.getClassEnum() == NVC_CALLBACK); | 120 | ensure("6. getClassEnum failed", nValue6.getClassEnum() == NVC_READ_WRITE); |
247 | ensure("6. getSendtoEnum failed", nValue6.getSendtoEnum() == NVS_DATA_SIM_VIEWER); | 121 | ensure("6. getSendtoEnum failed", nValue6.getSendtoEnum() == NVS_DATA_SIM_VIEWER); |
248 | ensure("6. getU32 failed", *nValue6.getU32() == 89764323); | 122 | ensure("6. getU32 failed", *nValue6.getU32() == 89764323); |
249 | ensure("6. sendToData or sendToViewer failed", nValue6.sendToData() && nValue6.sendToViewer()); | 123 | ensure("6. sendToData or sendToViewer failed", nValue6.sendToData() && nValue6.sendToViewer()); |
250 | 124 | ||
251 | LLNameValue nValue7("SecondLife", "89764323323232", "U64", "CALLBACK", "SIM_SPACE_VIEWER"); | 125 | LLNameValue nValue7("SecondLife", "89764323323232", "U64", "RW", "SIM_SPACE_VIEWER"); |
252 | U64 u64_7 = U64L(89764323323232); | 126 | U64 u64_7 = U64L(89764323323232); |
253 | ensure("7. getTypeEnum failed", nValue7.getTypeEnum() == NVT_U64); | 127 | ensure("7. getTypeEnum failed", nValue7.getTypeEnum() == NVT_U64); |
254 | ensure("7. getClassEnum failed", nValue7.getClassEnum() == NVC_CALLBACK); | 128 | ensure("7. getClassEnum failed", nValue7.getClassEnum() == NVC_READ_WRITE); |
255 | ensure("7. getSendtoEnum failed", nValue7.getSendtoEnum() == NVS_DATA_SIM_VIEWER); | 129 | ensure("7. getSendtoEnum failed", nValue7.getSendtoEnum() == NVS_DATA_SIM_VIEWER); |
256 | ensure("7. getU32 failed", *nValue7.getU64() == u64_7); | 130 | ensure("7. getU32 failed", *nValue7.getU64() == u64_7); |
257 | ensure("7. sendToData or sendToViewer failed", nValue7.sendToData() && nValue7.sendToViewer()); | 131 | ensure("7. sendToData or sendToViewer failed", nValue7.sendToData() && nValue7.sendToViewer()); |
@@ -288,30 +162,30 @@ namespace tut | |||
288 | ensure("3. getSendtoEnum failed", nValue3.getSendtoEnum() == NVS_SIM); | 162 | ensure("3. getSendtoEnum failed", nValue3.getSendtoEnum() == NVS_SIM); |
289 | ensure("3. getS32 failed", *nValue3.getS32() == -43456787); | 163 | ensure("3. getS32 failed", *nValue3.getS32() == -43456787); |
290 | 164 | ||
291 | LLNameValue nValue4("SecondLife", "<1.0, 2.0, 3.0>", "VEC3", "CB"); | 165 | LLNameValue nValue4("SecondLife", "<1.0, 2.0, 3.0>", "VEC3", "RW"); |
292 | LLVector3 llvec4(1.0, 2.0, 3.0); | 166 | LLVector3 llvec4(1.0, 2.0, 3.0); |
293 | ensure("4. getTypeEnum failed", nValue4.getTypeEnum() == NVT_VEC3); | 167 | ensure("4. getTypeEnum failed", nValue4.getTypeEnum() == NVT_VEC3); |
294 | ensure("4. getClassEnum failed", nValue4.getClassEnum() == NVC_CALLBACK); | 168 | ensure("4. getClassEnum failed", nValue4.getClassEnum() == NVC_READ_WRITE); |
295 | ensure("4. getSendtoEnum failed", nValue4.getSendtoEnum() == NVS_SIM); | 169 | ensure("4. getSendtoEnum failed", nValue4.getSendtoEnum() == NVS_SIM); |
296 | ensure("4. getVec3 failed", *nValue4.getVec3() == llvec4); | 170 | ensure("4. getVec3 failed", *nValue4.getVec3() == llvec4); |
297 | 171 | ||
298 | LLNameValue nValue5("SecondLife", "-1.0, 2.4, 3", "VEC3", "CALLBACK"); | 172 | LLNameValue nValue5("SecondLife", "-1.0, 2.4, 3", "VEC3", "RW"); |
299 | LLVector3 llvec5(-1.0f, 2.4f, 3); | 173 | LLVector3 llvec5(-1.0f, 2.4f, 3); |
300 | ensure("5. getTypeEnum failed", nValue5.getTypeEnum() == NVT_VEC3); | 174 | ensure("5. getTypeEnum failed", nValue5.getTypeEnum() == NVT_VEC3); |
301 | ensure("5. getClassEnum failed", nValue5.getClassEnum() == NVC_CALLBACK); | 175 | ensure("5. getClassEnum failed", nValue5.getClassEnum() == NVC_READ_WRITE); |
302 | ensure("5. getSendtoEnum failed", nValue5.getSendtoEnum() == NVS_SIM); | 176 | ensure("5. getSendtoEnum failed", nValue5.getSendtoEnum() == NVS_SIM); |
303 | ensure("5. getVec3 failed", *nValue5.getVec3() == llvec5); | 177 | ensure("5. getVec3 failed", *nValue5.getVec3() == llvec5); |
304 | 178 | ||
305 | LLNameValue nValue6("SecondLife", "89764323", "U32", "CALLBACK"); | 179 | LLNameValue nValue6("SecondLife", "89764323", "U32", "RW"); |
306 | ensure("6. getTypeEnum failed", nValue6.getTypeEnum() == NVT_U32); | 180 | ensure("6. getTypeEnum failed", nValue6.getTypeEnum() == NVT_U32); |
307 | ensure("6. getClassEnum failed", nValue6.getClassEnum() == NVC_CALLBACK); | 181 | ensure("6. getClassEnum failed", nValue6.getClassEnum() == NVC_READ_WRITE); |
308 | ensure("6. getSendtoEnum failed", nValue6.getSendtoEnum() == NVS_SIM); | 182 | ensure("6. getSendtoEnum failed", nValue6.getSendtoEnum() == NVS_SIM); |
309 | ensure("6. getU32 failed", *nValue6.getU32() == 89764323); | 183 | ensure("6. getU32 failed", *nValue6.getU32() == 89764323); |
310 | 184 | ||
311 | LLNameValue nValue7("SecondLife", "89764323323232", "U64", "CALLBACK"); | 185 | LLNameValue nValue7("SecondLife", "89764323323232", "U64", "RW"); |
312 | U64 u64_7 = U64L(89764323323232); | 186 | U64 u64_7 = U64L(89764323323232); |
313 | ensure("7. getTypeEnum failed", nValue7.getTypeEnum() == NVT_U64); | 187 | ensure("7. getTypeEnum failed", nValue7.getTypeEnum() == NVT_U64); |
314 | ensure("7. getClassEnum failed", nValue7.getClassEnum() == NVC_CALLBACK); | 188 | ensure("7. getClassEnum failed", nValue7.getClassEnum() == NVC_READ_WRITE); |
315 | ensure("7. getSendtoEnum failed", nValue7.getSendtoEnum() == NVS_SIM); | 189 | ensure("7. getSendtoEnum failed", nValue7.getSendtoEnum() == NVS_SIM); |
316 | ensure("7. getU32 failed", *nValue7.getU64() == u64_7); | 190 | ensure("7. getU32 failed", *nValue7.getU64() == u64_7); |
317 | } | 191 | } |
@@ -343,208 +217,118 @@ namespace tut | |||
343 | ensure("3. getClassEnum failed", nValue3.getClassEnum() == NVC_READ_ONLY); | 217 | ensure("3. getClassEnum failed", nValue3.getClassEnum() == NVC_READ_ONLY); |
344 | ensure("3. getSendtoEnum failed", nValue3.getSendtoEnum() == NVS_SIM); | 218 | ensure("3. getSendtoEnum failed", nValue3.getSendtoEnum() == NVS_SIM); |
345 | 219 | ||
346 | skip_fail("NVC_CALLBACK does not parse."); | 220 | LLNameValue nValue4("SecondLife", "VEC3", "READ_WRITE"); |
347 | |||
348 | LLNameValue nValue4("SecondLife", "VEC3", "CALLBACK"); | ||
349 | ensure("4. getTypeEnum failed", nValue4.getTypeEnum() == NVT_VEC3); | 221 | ensure("4. getTypeEnum failed", nValue4.getTypeEnum() == NVT_VEC3); |
350 | ensure("4. getClassEnum failed", nValue4.getClassEnum() == NVC_CALLBACK); | 222 | ensure("4. getClassEnum failed", nValue4.getClassEnum() == NVC_READ_WRITE); |
351 | ensure("4. getSendtoEnum failed", nValue4.getSendtoEnum() == NVS_SIM); | 223 | ensure("4. getSendtoEnum failed", nValue4.getSendtoEnum() == NVS_SIM); |
352 | 224 | ||
353 | LLNameValue nValue6("SecondLife", "U32", "CALLBACK"); | 225 | LLNameValue nValue6("SecondLife", "U32", "READ_WRITE"); |
354 | ensure("6. getTypeEnum failed", nValue6.getTypeEnum() == NVT_U32); | 226 | ensure("6. getTypeEnum failed", nValue6.getTypeEnum() == NVT_U32); |
355 | ensure("6. getClassEnum failed", nValue6.getClassEnum() == NVC_CALLBACK); | 227 | ensure("6. getClassEnum failed", nValue6.getClassEnum() == NVC_READ_WRITE); |
356 | ensure("6. getSendtoEnum failed", nValue6.getSendtoEnum() == NVS_SIM); | 228 | ensure("6. getSendtoEnum failed", nValue6.getSendtoEnum() == NVS_SIM); |
357 | 229 | ||
358 | LLNameValue nValue7("SecondLife", "U64", "CALLBACK"); | 230 | LLNameValue nValue7("SecondLife", "U64", "READ_WRITE"); |
359 | ensure("7. getTypeEnum failed", nValue7.getTypeEnum() == NVT_U64); | 231 | ensure("7. getTypeEnum failed", nValue7.getTypeEnum() == NVT_U64); |
360 | ensure("7. getClassEnum failed", nValue7.getClassEnum() == NVC_CALLBACK); | 232 | ensure("7. getClassEnum failed", nValue7.getClassEnum() == NVC_READ_WRITE); |
361 | ensure("7. getSendtoEnum failed", nValue7.getSendtoEnum() == NVS_SIM); | 233 | ensure("7. getSendtoEnum failed", nValue7.getSendtoEnum() == NVS_SIM); |
362 | } | 234 | } |
363 | 235 | ||
364 | template<> template<> | 236 | template<> template<> |
365 | void namevalue_object_t::test<5>() | 237 | void namevalue_object_t::test<5>() |
366 | { | 238 | { |
367 | skip_fail("callback will be called more than once."); | 239 | LLNameValue nValue("SecondLife", "This is a test", "STRING", "RW", "SIM"); |
368 | LLNameValue nValue("SecondLife", "This is a test", "STRING", "CB", "SIM", NameValueCallbackFunction, (void**) this); | ||
369 | 240 | ||
370 | ensure("getString failed", (0 == strcmp(nValue.getString(),"This is a test"))); | 241 | ensure("getString failed", (0 == strcmp(nValue.getString(),"This is a test"))); |
371 | reset(); | ||
372 | |||
373 | setExpectedResult(NVT_STRING, (void*)"New Value"); | ||
374 | nValue.setString("New Value"); | ||
375 | ensure("String nonzero failed", nValue.nonzero() == TRUE); | ||
376 | reset(); | ||
377 | setExpectedResult(NVT_STRING, (void*)""); | ||
378 | nValue.setString(""); | ||
379 | ensure("String nonzero failed", nValue.nonzero() == FALSE); | ||
380 | reset(); | ||
381 | } | 242 | } |
382 | 243 | ||
383 | template<> template<> | 244 | template<> template<> |
384 | void namevalue_object_t::test<6>() | 245 | void namevalue_object_t::test<6>() |
385 | { | 246 | { |
386 | skip_fail("callback will be called more than once."); | 247 | LLNameValue nValue("SecondLife", "This is a test", "ASSET", "RW", "S"); |
387 | LLNameValue nValue("SecondLife", "This is a test", "ASSET", "CALLBACK", "S", NameValueCallbackFunction, (void**) this); | ||
388 | ensure("getAsset failed", (0 == strcmp(nValue.getAsset(),"This is a test"))); | 248 | ensure("getAsset failed", (0 == strcmp(nValue.getAsset(),"This is a test"))); |
389 | reset(); | ||
390 | |||
391 | setExpectedResult(NVT_ASSET, (void*)"New Value"); | ||
392 | nValue.setAsset("New Value"); | ||
393 | reset(); | ||
394 | } | 249 | } |
395 | 250 | ||
396 | template<> template<> | 251 | template<> template<> |
397 | void namevalue_object_t::test<7>() | 252 | void namevalue_object_t::test<7>() |
398 | { | 253 | { |
399 | skip_fail("callback will be called more than once."); | 254 | LLNameValue nValue("SecondLife", "555555", "F32", "RW", "SIM"); |
400 | LLNameValue nValue("SecondLife", "555555", "F32", "CB", "SIM", NameValueCallbackFunction, (void**) this); | ||
401 | 255 | ||
402 | ensure("getF32 failed",*nValue.getF32() == 555555.f); | 256 | ensure("getF32 failed",*nValue.getF32() == 555555.f); |
403 | reset(); | ||
404 | |||
405 | F32 fVal = 0.1f; | ||
406 | setExpectedResult(NVT_F32, &fVal); | ||
407 | nValue.setF32(fVal); | ||
408 | |||
409 | fVal = -11111.1f; | ||
410 | setExpectedResult(NVT_F32, &fVal); | ||
411 | nValue.setF32(fVal); | ||
412 | ensure("F32 nonzero failed", nValue.nonzero() == TRUE); | ||
413 | reset(); | ||
414 | |||
415 | fVal = 0.; | ||
416 | setExpectedResult(NVT_F32, &fVal); | ||
417 | nValue.setF32(fVal); | ||
418 | ensure("F32 nonzero failed", nValue.nonzero() == FALSE); | ||
419 | reset(); | ||
420 | } | 257 | } |
421 | 258 | ||
422 | template<> template<> | 259 | template<> template<> |
423 | void namevalue_object_t::test<8>() | 260 | void namevalue_object_t::test<8>() |
424 | { | 261 | { |
425 | skip_fail("callback will be called more than once."); | 262 | LLNameValue nValue("SecondLife", "-5555", "S32", "RW", "SIM"); |
426 | LLNameValue nValue("SecondLife", "-5555", "S32", "CB", "SIM", NameValueCallbackFunction, (void**) this); | ||
427 | 263 | ||
428 | ensure("getS32 failed", *nValue.getS32() == -5555); | 264 | ensure("getS32 failed", *nValue.getS32() == -5555); |
429 | reset(); | ||
430 | 265 | ||
431 | S32 sVal = 0x7FFFFFFF; | 266 | S32 sVal = 0x7FFFFFFF; |
432 | setExpectedResult(NVT_S32, &sVal); | ||
433 | nValue.setS32(sVal); | 267 | nValue.setS32(sVal); |
268 | ensure("getS32 failed", *nValue.getS32() == sVal); | ||
434 | 269 | ||
435 | sVal = -0x7FFFFFFF; | 270 | sVal = -0x7FFFFFFF; |
436 | setExpectedResult(NVT_S32, &sVal); | ||
437 | nValue.setS32(sVal); | 271 | nValue.setS32(sVal); |
438 | ensure("S32 nonzero failed", nValue.nonzero() == TRUE); | 272 | ensure("getS32 failed", *nValue.getS32() == sVal); |
439 | reset(); | ||
440 | 273 | ||
441 | sVal = 0; | 274 | sVal = 0; |
442 | setExpectedResult(NVT_S32, &sVal); | ||
443 | nValue.setS32(sVal); | 275 | nValue.setS32(sVal); |
444 | ensure("S32 nonzero failed", nValue.nonzero() == FALSE); | 276 | ensure("getS32 failed", *nValue.getS32() == sVal); |
445 | reset(); | ||
446 | } | 277 | } |
447 | 278 | ||
448 | template<> template<> | 279 | template<> template<> |
449 | void namevalue_object_t::test<9>() | 280 | void namevalue_object_t::test<9>() |
450 | { | 281 | { |
451 | LLNameValue nValue("SecondLife", "<-3, 2, 1>", "VEC3", "CB", "SIM", NameValueCallbackFunction, (void**) this); | 282 | LLNameValue nValue("SecondLife", "<-3, 2, 1>", "VEC3", "RW", "SIM"); |
452 | LLVector3 vecExpected(-3, 2, 1); | 283 | LLVector3 vecExpected(-3, 2, 1); |
453 | LLVector3 vec; | 284 | LLVector3 vec; |
454 | nValue.getVec3(vec); | 285 | nValue.getVec3(vec); |
455 | ensure("getVec3 failed", vec == vecExpected); | 286 | ensure("getVec3 failed", vec == vecExpected); |
456 | reset(); | ||
457 | |||
458 | vecExpected.setVec(2, -1, 0); | ||
459 | setExpectedResult(NVT_VEC3, &vecExpected); | ||
460 | nValue.setVec3(vecExpected); | ||
461 | ensure("VEC3 nonzero failed", nValue.nonzero() == TRUE); | ||
462 | reset(); | ||
463 | |||
464 | vecExpected.setVec(0, 0, 0); | ||
465 | setExpectedResult(NVT_VEC3, &vecExpected); | ||
466 | nValue.setVec3(vecExpected); | ||
467 | ensure("VEC3 nonzero failed", nValue.nonzero() == FALSE); | ||
468 | reset(); | ||
469 | } | 287 | } |
470 | 288 | ||
471 | template<> template<> | 289 | template<> template<> |
472 | void namevalue_object_t::test<10>() | 290 | void namevalue_object_t::test<10>() |
473 | { | 291 | { |
474 | LLNameValue nValue("SecondLife", "12345678", "U32", "CB", "SIM", NameValueCallbackFunction, (void**) this); | 292 | LLNameValue nValue("SecondLife", "12345678", "U32", "RW", "SIM"); |
475 | 293 | ||
476 | ensure("getU32 failed",*nValue.getU32() == 12345678); | 294 | ensure("getU32 failed",*nValue.getU32() == 12345678); |
477 | 295 | ||
478 | U32 val = 0xFFFFFFFF; | 296 | U32 val = 0xFFFFFFFF; |
479 | setExpectedResult(NVT_U32, &val); | ||
480 | nValue.setU32(val); | 297 | nValue.setU32(val); |
481 | ensure("U32 nonzero failed", nValue.nonzero() == TRUE); | 298 | ensure("U32 max", *nValue.getU32() == val); |
482 | reset(); | ||
483 | 299 | ||
484 | val = 0; | 300 | val = 0; |
485 | setExpectedResult(NVT_U32, &val); | ||
486 | nValue.setU32(val); | 301 | nValue.setU32(val); |
487 | ensure("U32 nonzero failed", nValue.nonzero() == FALSE); | 302 | ensure("U32 min", *nValue.getU32() == val); |
488 | reset(); | ||
489 | } | 303 | } |
490 | 304 | ||
491 | template<> template<> | 305 | template<> template<> |
492 | void namevalue_object_t::test<11>() | 306 | void namevalue_object_t::test<11>() |
493 | { | 307 | { |
494 | skip_fail("incomplete support for U64."); | 308 | //skip_fail("incomplete support for U64."); |
495 | LLNameValue nValue("SecondLife", "44444444444", "U64", "CB", "SIM", NameValueCallbackFunction, (void**) this); | 309 | LLNameValue nValue("SecondLife", "44444444444", "U64", "RW", "SIM"); |
496 | 310 | ||
497 | ensure("getU64 failed",*nValue.getU64() == U64L(44444444444)); | 311 | ensure("getU64 failed",*nValue.getU64() == U64L(44444444444)); |
498 | ensure("U64 nonzero failed", nValue.nonzero() == TRUE); | ||
499 | 312 | ||
500 | // there is no LLNameValue::setU64() | 313 | // there is no LLNameValue::setU64() |
501 | } | 314 | } |
502 | 315 | ||
503 | template<> template<> | ||
504 | void namevalue_object_t::test<12>() | ||
505 | { | ||
506 | LLNameValue nValue("SecondLife F32 RW SIM -333.337600"); | ||
507 | F32 val = nValue.magnitude(); | ||
508 | ensure_equals("F32 magnitude failed", val, 333.337600f); | ||
509 | |||
510 | LLNameValue nValue1("SecondLife STRING RW SIM 3300"); | ||
511 | val = nValue1.magnitude(); | ||
512 | ensure_equals("STRING magnitude failed",val,4.0f); | ||
513 | |||
514 | LLNameValue nValue2("SecondLife S32 RW SIM -3300"); | ||
515 | val = nValue2.magnitude(); | ||
516 | ensure_equals("S32 magnitude failed", val, 3300.); | ||
517 | |||
518 | LLNameValue nValue3("SecondLife U32 RW SIM 3300"); | ||
519 | val = nValue3.magnitude(); | ||
520 | ensure_equals("U32 magnitude failed", val, 3300.); | ||
521 | |||
522 | LLNameValue nValue4("SecondLife VEC3 RW SIM <1,2,3>"); | ||
523 | LLVector3 vec(1,2,3); | ||
524 | val = nValue4.magnitude(); | ||
525 | ensure_equals("VEC3 magnitude failed", val, vec.magVec()); | ||
526 | |||
527 | skip_fail("incomplete support for U64."); | ||
528 | LLNameValue nValue5("SecondLife U64 RW SIM 12345"); | ||
529 | val = nValue5.magnitude(); | ||
530 | ensure_equals("U62 magnitude failed", val, 12345); | ||
531 | } | ||
532 | 316 | ||
533 | template<> template<> | 317 | template<> template<> |
534 | void namevalue_object_t::test<13>() | 318 | void namevalue_object_t::test<12>() |
535 | { | 319 | { |
536 | skip_fail("incomplete support for U64."); | 320 | //skip_fail("incomplete support for U64."); |
537 | LLNameValue nValue("SecondLife U64 RW DSV 44444444444"); | 321 | LLNameValue nValue("SecondLife U64 RW DSV 44444444444"); |
538 | std::string ret_str = nValue.printNameValue(); | 322 | std::string ret_str = nValue.printNameValue(); |
539 | 323 | ||
540 | ensure_equals("1:printNameValue failed",ret_str,"SecondLife U64 RW DSV 44444444444"); | 324 | ensure_equals("1:printNameValue failed",ret_str,"SecondLife U64 RW DSV 44444444444"); |
541 | 325 | ||
542 | LLNameValue nValue1(ret_str.c_str()); | 326 | LLNameValue nValue1(ret_str.c_str()); |
543 | ensure_equals("Serialization of printNameValue failed", nValue, nValue1); | 327 | ensure_equals("Serialization of printNameValue failed", *nValue.getU64(), *nValue1.getU64()); |
544 | } | 328 | } |
545 | 329 | ||
546 | template<> template<> | 330 | template<> template<> |
547 | void namevalue_object_t::test<14>() | 331 | void namevalue_object_t::test<13>() |
548 | { | 332 | { |
549 | LLNameValue nValue("SecondLife STRING RW DSV 44444444444"); | 333 | LLNameValue nValue("SecondLife STRING RW DSV 44444444444"); |
550 | std::string ret_str = nValue.printData(); | 334 | std::string ret_str = nValue.printData(); |
@@ -556,7 +340,7 @@ namespace tut | |||
556 | } | 340 | } |
557 | 341 | ||
558 | template<> template<> | 342 | template<> template<> |
559 | void namevalue_object_t::test<15>() | 343 | void namevalue_object_t::test<14>() |
560 | { | 344 | { |
561 | LLNameValue nValue("SecodLife STRING RW SIM 22222"); | 345 | LLNameValue nValue("SecodLife STRING RW SIM 22222"); |
562 | std::ostringstream stream1,stream2,stream3, stream4, stream5; | 346 | std::ostringstream stream1,stream2,stream3, stream4, stream5; |
@@ -575,271 +359,39 @@ namespace tut | |||
575 | stream4<< nValue3; | 359 | stream4<< nValue3; |
576 | ensure_equals("U32 << failed",stream4.str(),"122222"); | 360 | ensure_equals("U32 << failed",stream4.str(),"122222"); |
577 | 361 | ||
578 | skip_fail("incomplete support for U64."); | 362 | // I don't think we use U64 name value pairs. JC |
579 | LLNameValue nValue4("SecodLife U64 RW SIM 22222"); | 363 | //skip_fail("incomplete support for U64."); |
580 | stream5<< nValue4; | 364 | //LLNameValue nValue4("SecodLife U64 RW SIM 22222"); |
581 | ensure("U64 << failed",0 == strcmp((stream5.str()).c_str(),"22222")); | 365 | //stream5<< nValue4; |
582 | } | 366 | //ensure("U64 << failed",0 == strcmp((stream5.str()).c_str(),"22222")); |
583 | |||
584 | template<> template<> | ||
585 | void namevalue_object_t::test<16>() | ||
586 | { | ||
587 | LLNameValue nValue1("SecondLife STRING RW DSV 44444"); | ||
588 | LLNameValue nValue2("SecondLife STRING RW SIM 33333"); | ||
589 | LLNameValue nValue3("SecondLife"); | ||
590 | nValue3 = nValue1 + nValue2; | ||
591 | ensure("1:operator+ failed",(0==strcmp(nValue3.getString(),"4444433333"))); | ||
592 | |||
593 | LLNameValue nValue4("SecondLife F32 R DSV 44444"); | ||
594 | LLNameValue nValue5("SecondLife F32 RW SIM 33333"); | ||
595 | LLNameValue nValue6("SecondLife"); | ||
596 | nValue6 = nValue4 + nValue5; | ||
597 | ensure_equals("2:operator+ failed",*nValue6.getF32(),77777.0); | ||
598 | |||
599 | LLNameValue nValue7("SecondLife F32 R DSV 44444"); | ||
600 | LLNameValue nValue8("SecondLife S32 RW SIM 33333"); | ||
601 | LLNameValue nValue9("SecondLife F32"); | ||
602 | nValue9 = nValue7 + nValue8; | ||
603 | ensure_equals("3:operator+ failed",*nValue9.getF32(),77777.0); | ||
604 | |||
605 | LLNameValue nValue10("SecondLife VEC3 RW SIM <4, 4, 4>"); | ||
606 | LLNameValue nValue11("SecondLife VEC3 RW SV <3, 3, 3>"); | ||
607 | LLNameValue nValue12("SecondLife VEC3"); | ||
608 | nValue12 = nValue10 + nValue11; | ||
609 | LLVector3 vec(7,7,7); | ||
610 | ensure_equals("4:operator+ failed",*nValue12.getVec3(), vec); | ||
611 | } | ||
612 | |||
613 | template<> template<> | ||
614 | void namevalue_object_t::test<17>() | ||
615 | { | ||
616 | LLNameValue nValue7(" SecondLife S32 RW SIM 22222"); | ||
617 | LLNameValue nValue8(" SecondLife F32 RW SIM 33333"); | ||
618 | LLNameValue nValue9(" SecondLife F32"); | ||
619 | nValue9 = nValue7 - nValue8; | ||
620 | ensure_equals("1:operator- failed",*nValue9.getF32(),-11111.f); | ||
621 | |||
622 | LLNameValue nValue10(" SecondLife VEC3 RW SIM <2, 2, 2>"); | ||
623 | LLNameValue nValue11(" SecondLife VEC3 RW SIM <3, 3, 3>"); | ||
624 | LLNameValue nValue12(" SecondLife VEC3"); | ||
625 | LLVector3 vec(-1,-1,-1); | ||
626 | nValue12 = nValue10 - nValue11; | ||
627 | ensure_equals("2:operator- failed",*nValue12.getVec3(), vec); | ||
628 | } | ||
629 | |||
630 | template<> template<> | ||
631 | void namevalue_object_t::test<18>() | ||
632 | { | ||
633 | |||
634 | LLNameValue nValue1(" SecondLife F32 RW SIM 22222"); | ||
635 | LLNameValue nValue2(" SecondLife F32 RW SIM 33333"); | ||
636 | LLNameValue nValue3(" SecondLife F32"); | ||
637 | nValue3 = nValue1 * nValue2; | ||
638 | ensure_equals("1:operator* failed",*nValue3.getF32(),740725926.f); | ||
639 | |||
640 | LLNameValue nValue4(" SecondLife S32 RW SIM 22222"); | ||
641 | LLNameValue nValue5(" SecondLife F32 RW SIM 33333"); | ||
642 | LLNameValue nValue6(" SecondLife F32"); | ||
643 | nValue6 = nValue4 * nValue5; | ||
644 | ensure_equals("2:operator* failed",*nValue6.getF32(),740725926.f); | ||
645 | |||
646 | LLNameValue nValue10(" SecondLife VEC3 RW SIM <2, 2, 2>"); | ||
647 | LLNameValue nValue11(" SecondLife VEC3 RW SIM <3, 3, 3>"); | ||
648 | LLNameValue nValue12(" SecondLife F32"); | ||
649 | LLVector3 vec1(2,2,2); | ||
650 | LLVector3 vec2(3,3,3); | ||
651 | nValue12 = nValue10 * nValue11; | ||
652 | ensure_equals("2:operator* failed",*nValue12.getF32(), (vec1 * vec2)); | ||
653 | } | 367 | } |
654 | 368 | ||
655 | template<> template<> | 369 | template<> template<> |
656 | void namevalue_object_t::test<19>() | 370 | void namevalue_object_t::test<15>() |
657 | { | ||
658 | LLNameValue nValue1(" SecondLife S32 RW SIM 22222"); | ||
659 | LLNameValue nValue2(" Virtual F32 RW SIM 44444"); | ||
660 | LLNameValue nValue3(" SecondLife F32"); | ||
661 | nValue3 = nValue1 / nValue2; | ||
662 | ensure_equals("1:operator/ failed",*nValue3.getF32(),0.5); | ||
663 | |||
664 | LLNameValue nValue4(" SecondLife F32 RW SIM 33333"); | ||
665 | LLNameValue nValue5(" SecondLife S32 RW SIM 22222"); | ||
666 | LLNameValue nValue6(" SecondLife F32"); | ||
667 | nValue6 = nValue4 / nValue5; | ||
668 | ensure_equals("2:operator/ failed",*nValue6.getF32(),1.5); | ||
669 | } | ||
670 | |||
671 | template<> template<> | ||
672 | void namevalue_object_t::test<20>() | ||
673 | { | ||
674 | LLNameValue nValue1(" SecondLife S32 RW SIM 22222"); | ||
675 | LLNameValue nValue2(" Virtual S32 RW SIM 33333"); | ||
676 | LLNameValue nValue3(" SecondLife S32"); | ||
677 | nValue3 = nValue1 % nValue2; | ||
678 | ensure_equals("1:operator% failed",*nValue3.getS32(),22222); | ||
679 | |||
680 | LLNameValue nValue4(" SecondLife U32 RW SIM 3"); | ||
681 | LLNameValue nValue5(" SecondLife S32 RW SIM 2"); | ||
682 | LLNameValue nValue6(" SecondLife S32"); | ||
683 | nValue6 = nValue4 % nValue5; | ||
684 | ensure_equals("2:operator% failed",*nValue6.getS32(),1); | ||
685 | |||
686 | LLNameValue nValue10(" SecondLife VEC3 RW SIM <4, 5, 6>"); | ||
687 | LLNameValue nValue11(" SecondLife VEC3 RW SIM <1, 2, 3>"); | ||
688 | LLNameValue nValue12(" SecondLife VEC3"); | ||
689 | LLVector3 vec1(4,5,6); | ||
690 | LLVector3 vec2(1,2,3); | ||
691 | LLVector3 vec3(vec1 % vec2); | ||
692 | nValue12 = nValue10 % nValue11; | ||
693 | ensure_equals("5:operator% failed",*nValue12.getVec3(), vec3); | ||
694 | } | ||
695 | |||
696 | template<> template<> | ||
697 | void namevalue_object_t::test<21>() | ||
698 | { | ||
699 | LLNameValue nValue1(" SecondLife STRING RW SIM 22222"); | ||
700 | LLNameValue nValue2(" Virtual STRING RW SIM 22222"); | ||
701 | ensure("1:operator== failed", nValue1 == nValue2); | ||
702 | |||
703 | LLNameValue nValue3(" SecondLife F32 RW SIM 33333"); | ||
704 | LLNameValue nValue4(" Virtual F32 RW SIM 22222"); | ||
705 | ensure("2:operator== failed",!(nValue3 == nValue4)); | ||
706 | |||
707 | LLNameValue nValue5(" SecondLife STRING RW SIM 22222"); | ||
708 | LLNameValue nValue6(" Virtual STRING RW SIM 33333"); | ||
709 | ensure("3:operator== failed",!(nValue5 == nValue6)); | ||
710 | |||
711 | LLNameValue nValue7(" SecondLife VEC3 RW SIM <2, 2, 2>"); | ||
712 | LLNameValue nValue8(" Virtual VEC3 RW SIM <2, 2, 2>"); | ||
713 | ensure("4:operator== failed",(nValue7 == nValue8)); | ||
714 | } | ||
715 | |||
716 | template<> template<> | ||
717 | void namevalue_object_t::test<22>() | ||
718 | { | ||
719 | LLNameValue nValue1(" SecondLife STRING RW SIM 22222"); | ||
720 | LLNameValue nValue2(" Virtual STRING RW SIM 33333"); | ||
721 | bool b_ret = (nValue1 <= nValue2) ? 1 : 0; | ||
722 | ensure("1:operator<= failed",(1==b_ret)); | ||
723 | |||
724 | LLNameValue nValue3(" SecondLife F32 RW SIM 33333"); | ||
725 | LLNameValue nValue4(" Virtual F32 RW SIM 22222"); | ||
726 | b_ret = (nValue3 <= nValue4) ? 1 : 0; | ||
727 | ensure("2:operator<= failed",(0==b_ret)); | ||
728 | } | ||
729 | |||
730 | template<> template<> | ||
731 | void namevalue_object_t::test<23>() | ||
732 | { | ||
733 | LLNameValue nValue1(" SecondLife STRING RW SIM 22222"); | ||
734 | LLNameValue nValue2(" Virtual STRING RW SIM 33333"); | ||
735 | bool b_ret = (nValue1 >= nValue2) ? 1 : 0; | ||
736 | ensure("operator>= failed",!b_ret); | ||
737 | |||
738 | LLNameValue nValue3(" SecondLife F32 RW SIM 33333"); | ||
739 | LLNameValue nValue4(" Virtual F32 RW SIM 22222"); | ||
740 | b_ret = (nValue3 >= nValue4) ? 1 : 0; | ||
741 | ensure("2:operator<= failed",b_ret); | ||
742 | |||
743 | } | ||
744 | |||
745 | template<> template<> | ||
746 | void namevalue_object_t::test<24>() | ||
747 | { | ||
748 | LLNameValue nValue1(" SecondLife STRING RW SIM 33333"); | ||
749 | LLNameValue nValue2(" Virtual STRING RW SIM 33333"); | ||
750 | bool b_ret = (nValue1 < nValue2) ? 1 : 0; | ||
751 | ensure("operator< failed",!b_ret); | ||
752 | |||
753 | LLNameValue nValue3(" SecondLife F32 RW SIM 11111"); | ||
754 | LLNameValue nValue4(" Virtual F32 RW SIM 22222"); | ||
755 | b_ret = (nValue3 < nValue4) ? 1 : 0; | ||
756 | ensure("2:operator< failed",b_ret); | ||
757 | |||
758 | } | ||
759 | |||
760 | template<> template<> | ||
761 | void namevalue_object_t::test<25>() | ||
762 | { | ||
763 | LLNameValue nValue1(" SecondLife STRING RW SIM 33333"); | ||
764 | LLNameValue nValue2(" Virtual STRING RW SIM 33333"); | ||
765 | bool b_ret = (nValue1 > nValue2) ? 1 : 0; | ||
766 | ensure("1:operator> failed",!b_ret); | ||
767 | |||
768 | LLNameValue nValue3(" SecondLife F32 RW SIM 11111"); | ||
769 | LLNameValue nValue4(" Virtual F32 RW SIM 22222"); | ||
770 | b_ret = (nValue3 > nValue4) ? 1 : 0; | ||
771 | ensure("2:operator> failed",!b_ret); | ||
772 | |||
773 | LLNameValue nValue5(" SecondLife S32 RW SIM 22222"); | ||
774 | LLNameValue nValue6(" Virtual F32 RW SIM 11111"); | ||
775 | b_ret = (nValue5 > nValue6) ? 1 : 0; | ||
776 | ensure("3:operator> failed",b_ret); | ||
777 | } | ||
778 | |||
779 | template<> template<> | ||
780 | void namevalue_object_t::test<26>() | ||
781 | { | ||
782 | LLNameValue nValue1(" SecondLife STRING RW SIM 33333"); | ||
783 | LLNameValue nValue2(" Virtual STRING RW SIM 33333"); | ||
784 | bool b_ret = (nValue1 != nValue2) ? 1 : 0; | ||
785 | ensure("1:operator!= failed",!b_ret); | ||
786 | |||
787 | LLNameValue nValue3(" SecondLife F32 RW SIM 11111"); | ||
788 | LLNameValue nValue4(" Virtual F32 RW SIM 22222"); | ||
789 | b_ret = (nValue3 != nValue4) ? 1 : 0; | ||
790 | ensure("2:operator!= failed",b_ret); | ||
791 | |||
792 | } | ||
793 | |||
794 | |||
795 | template<> template<> | ||
796 | void namevalue_object_t::test<27>() | ||
797 | { | ||
798 | LLNameValue nValue1(" SecondLife F32 RW SIM 33333"); | ||
799 | LLNameValue nValue2("Virtual"); | ||
800 | nValue2 = -nValue1; | ||
801 | ensure_equals("1:operator unary- failed",*nValue2.getF32(), -33333.f); | ||
802 | |||
803 | LLNameValue nValue3(" SecondLife U32 RW SIM 11111"); | ||
804 | LLNameValue nValue4("Virtual S32"); | ||
805 | nValue4 = -nValue3; | ||
806 | ensure_equals("2:operator unary- failed",*nValue4.getS32(), -11111); | ||
807 | |||
808 | LLNameValue nValue5(" SecondLife VEC3 RW SIM <1, 1, 1>"); | ||
809 | LLNameValue nValue6("Virtual VEC3"); | ||
810 | LLVector3 vec(-1, -1, -1); | ||
811 | nValue6 = -nValue5; | ||
812 | ensure_equals("3:operator unary- failed",*nValue6.getVec3(), vec); | ||
813 | } | ||
814 | |||
815 | template<> template<> | ||
816 | void namevalue_object_t::test<28>() | ||
817 | { | 371 | { |
818 | LLNameValue nValue("SecondLife", "This is a test", "ASSET", "R", "S", NameValueCallbackFunction, (void**) this); | 372 | LLNameValue nValue("SecondLife", "This is a test", "ASSET", "R", "S"); |
819 | 373 | ||
820 | ensure("getAsset failed", (0 == strcmp(nValue.getAsset(),"This is a test"))); | 374 | ensure("getAsset failed", (0 == strcmp(nValue.getAsset(),"This is a test"))); |
821 | // this should not have updated as it is read only. | 375 | // this should not have updated as it is read only. |
822 | nValue.setAsset("New Value should not be updated"); | 376 | nValue.setAsset("New Value should not be updated"); |
823 | ensure("setAsset on ReadOnly failed", (0 == strcmp(nValue.getAsset(),"This is a test"))); | 377 | ensure("setAsset on ReadOnly failed", (0 == strcmp(nValue.getAsset(),"This is a test"))); |
824 | 378 | ||
825 | LLNameValue nValue1("SecondLife", "1234", "U32", "R", "S", NameValueCallbackFunction, (void**) this); | 379 | LLNameValue nValue1("SecondLife", "1234", "U32", "R", "S"); |
826 | // this should not have updated as it is read only. | 380 | // this should not have updated as it is read only. |
827 | nValue1.setU32(4567); | 381 | nValue1.setU32(4567); |
828 | ensure("setU32 on ReadOnly failed", *nValue1.getU32() == 1234); | 382 | ensure("setU32 on ReadOnly failed", *nValue1.getU32() == 1234); |
829 | 383 | ||
830 | LLNameValue nValue2("SecondLife", "1234", "S32", "R", "S", NameValueCallbackFunction, (void**) this); | 384 | LLNameValue nValue2("SecondLife", "1234", "S32", "R", "S"); |
831 | // this should not have updated as it is read only. | 385 | // this should not have updated as it is read only. |
832 | nValue2.setS32(4567); | 386 | nValue2.setS32(4567); |
833 | ensure("setS32 on ReadOnly failed", *nValue2.getS32() == 1234); | 387 | ensure("setS32 on ReadOnly failed", *nValue2.getS32() == 1234); |
834 | 388 | ||
835 | LLNameValue nValue3("SecondLife", "1234", "F32", "R", "S", NameValueCallbackFunction, (void**) this); | 389 | LLNameValue nValue3("SecondLife", "1234", "F32", "R", "S"); |
836 | // this should not have updated as it is read only. | 390 | // this should not have updated as it is read only. |
837 | nValue3.setF32(4567); | 391 | nValue3.setF32(4567); |
838 | ensure("setF32 on ReadOnly failed", *nValue3.getF32() == 1234); | 392 | ensure("setF32 on ReadOnly failed", *nValue3.getF32() == 1234); |
839 | nValue3 = nValue3 * 2; | ||
840 | ensure("setF32 on ReadOnly failed", *nValue3.getF32() == 1234); | ||
841 | 393 | ||
842 | LLNameValue nValue4("SecondLife", "<1,2,3>", "VEC3", "R", "S", NameValueCallbackFunction, (void**) this); | 394 | LLNameValue nValue4("SecondLife", "<1,2,3>", "VEC3", "R", "S"); |
843 | // this should not have updated as it is read only. | 395 | // this should not have updated as it is read only. |
844 | LLVector3 vec(4,5,6); | 396 | LLVector3 vec(4,5,6); |
845 | nValue3.setVec3(vec); | 397 | nValue3.setVec3(vec); |
diff --git a/linden/indra/test/llsdmessagereader_tut.cpp b/linden/indra/test/llsdmessagereader_tut.cpp index e52809f..04861c4 100755 --- a/linden/indra/test/llsdmessagereader_tut.cpp +++ b/linden/indra/test/llsdmessagereader_tut.cpp | |||
@@ -46,7 +46,7 @@ namespace tut | |||
46 | const std::string& expected_name) | 46 | const std::string& expected_name) |
47 | { | 47 | { |
48 | LLSDMessageReader msg; | 48 | LLSDMessageReader msg; |
49 | msg.setMessage(gMessageStringTable.getString(msg_name.c_str()), msg_data); | 49 | msg.setMessage(LLMessageStringTable::getInstance()->getString(msg_name.c_str()), msg_data); |
50 | ensure_equals("Ensure name", std::string(msg.getMessageName()), | 50 | ensure_equals("Ensure name", std::string(msg.getMessageName()), |
51 | expected_name); | 51 | expected_name); |
52 | } | 52 | } |
diff --git a/linden/indra/test/llstreamtools_tut.cpp b/linden/indra/test/llstreamtools_tut.cpp index 3e89282..c360cc1 100644 --- a/linden/indra/test/llstreamtools_tut.cpp +++ b/linden/indra/test/llstreamtools_tut.cpp | |||
@@ -491,7 +491,7 @@ namespace tut | |||
491 | is.str(str = "First Second \t \r\n Third Fourth-ShouldThisBePartOfFourth IsThisFifth\n"); | 491 | is.str(str = "First Second \t \r\n Third Fourth-ShouldThisBePartOfFourth IsThisFifth\n"); |
492 | actual_result = ""; | 492 | actual_result = ""; |
493 | ret = get_line(actual_result, is); | 493 | ret = get_line(actual_result, is); |
494 | expected_result = "First Second \t \n"; | 494 | expected_result = "First Second \t \r\n"; |
495 | ensure_equals("get_line: 1", actual_result, expected_result); | 495 | ensure_equals("get_line: 1", actual_result, expected_result); |
496 | 496 | ||
497 | actual_result = ""; | 497 | actual_result = ""; |
@@ -545,7 +545,6 @@ namespace tut | |||
545 | template<> template<> | 545 | template<> template<> |
546 | void streamtools_object::test<12>() | 546 | void streamtools_object::test<12>() |
547 | { | 547 | { |
548 | skip_fail("get_line() incorrectly handles lone carriage return."); | ||
549 | std::string str; | 548 | std::string str; |
550 | std::string expected_result; | 549 | std::string expected_result; |
551 | std::string actual_result; | 550 | std::string actual_result; |
@@ -554,10 +553,10 @@ namespace tut | |||
554 | 553 | ||
555 | // need to be check if this test case is wrong or the implementation is wrong. | 554 | // need to be check if this test case is wrong or the implementation is wrong. |
556 | is.clear(); | 555 | is.clear(); |
557 | is.str(str = "Should not skip \r unless they are followed with newline .\r\n"); | 556 | is.str(str = "Should not skip lone \r.\r\n"); |
558 | actual_result = ""; | 557 | actual_result = ""; |
559 | ret = get_line(actual_result, is); | 558 | ret = get_line(actual_result, is); |
560 | expected_result = "Should not skip \r unless they are followed with newline .\n"; | 559 | expected_result = "Should not skip lone \r.\r\n"; |
561 | ensure_equals("get_line: carriage return skipped even though not followed by newline", actual_result, expected_result); | 560 | ensure_equals("get_line: carriage return skipped even though not followed by newline", actual_result, expected_result); |
562 | } | 561 | } |
563 | 562 | ||
@@ -804,37 +803,6 @@ namespace tut | |||
804 | template<> template<> | 803 | template<> template<> |
805 | void streamtools_object::test<21>() | 804 | void streamtools_object::test<21>() |
806 | { | 805 | { |
807 | skip_fail("get_brace_count() has bugs."); | ||
808 | |||
809 | std::string str; | ||
810 | std::string expected_result; | ||
811 | int count; | ||
812 | |||
813 | str = " { "; | ||
814 | count = get_brace_count(str); | ||
815 | ensure("get_brace_count: 1 for {", count == 1); | ||
816 | |||
817 | str = "\t}\t\t \n"; | ||
818 | count = get_brace_count(str); | ||
819 | ensure("get_brace_count: 1 for {", count == -1); | ||
820 | |||
821 | str = "\t\t\t \n"; | ||
822 | count = get_brace_count(str); | ||
823 | ensure("get_brace_count: 0 for no braces", count == 0); | ||
824 | |||
825 | str = "{ Remaining line not empty\n"; | ||
826 | count = get_brace_count(str); | ||
827 | ensure("get_brace_count: 0 for remainign line not empty", count == 0); | ||
828 | |||
829 | /* shouldn't this return 1? */ | ||
830 | str = "{ /*Remaining line in comment*/\n"; | ||
831 | count = get_brace_count(str); | ||
832 | ensure("get_brace_count: 1 for { with remaining line in comment", count == 1); | ||
833 | |||
834 | /* shouldn't this return -1? */ | ||
835 | str = " } //Remaining line in comment \n"; | ||
836 | count = get_brace_count(str); | ||
837 | ensure("get_brace_count: -1 for } with remaining line in comment", count == -1); | ||
838 | } | 806 | } |
839 | 807 | ||
840 | //testcases for get_keyword_and_value() | 808 | //testcases for get_keyword_and_value() |
@@ -860,8 +828,6 @@ namespace tut | |||
860 | template<> template<> | 828 | template<> template<> |
861 | void streamtools_object::test<23>() | 829 | void streamtools_object::test<23>() |
862 | { | 830 | { |
863 | skip_fail("get_keyword_and_value() has bugs."); | ||
864 | |||
865 | std::string s; | 831 | std::string s; |
866 | std::string keyword = "SOME PRIOR KEYWORD"; | 832 | std::string keyword = "SOME PRIOR KEYWORD"; |
867 | std::string value = "SOME PRIOR VALUE"; | 833 | std::string value = "SOME PRIOR VALUE"; |
@@ -875,8 +841,6 @@ namespace tut | |||
875 | template<> template<> | 841 | template<> template<> |
876 | void streamtools_object::test<24>() | 842 | void streamtools_object::test<24>() |
877 | { | 843 | { |
878 | skip_fail("get_keyword_and_value() has bugs."); | ||
879 | |||
880 | std::string s; | 844 | std::string s; |
881 | std::string keyword = "SOME PRIOR KEYWORD"; | 845 | std::string keyword = "SOME PRIOR KEYWORD"; |
882 | std::string value = "SOME PRIOR VALUE"; | 846 | std::string value = "SOME PRIOR VALUE"; |
diff --git a/linden/indra/test/lltemplatemessagebuilder_tut.cpp b/linden/indra/test/lltemplatemessagebuilder_tut.cpp index 1b3d600..86b1fbd 100644 --- a/linden/indra/test/lltemplatemessagebuilder_tut.cpp +++ b/linden/indra/test/lltemplatemessagebuilder_tut.cpp | |||
@@ -65,7 +65,7 @@ namespace tut | |||
65 | LL_VERSION_PATCH, | 65 | LL_VERSION_PATCH, |
66 | FALSE, | 66 | FALSE, |
67 | "notasharedsecret"); | 67 | "notasharedsecret"); |
68 | init_prehash_data(); | 68 | //init_prehash_data(); |
69 | init = true; | 69 | init = true; |
70 | } | 70 | } |
71 | return LLMessageTemplate(_PREHASH_TestMessage, 1, MFT_HIGH); | 71 | return LLMessageTemplate(_PREHASH_TestMessage, 1, MFT_HIGH); |
diff --git a/linden/indra/test/lltut.h b/linden/indra/test/lltut.h index e5c2419..4e4af73 100644 --- a/linden/indra/test/lltut.h +++ b/linden/indra/test/lltut.h | |||
@@ -44,6 +44,16 @@ class LLSD; | |||
44 | 44 | ||
45 | namespace tut | 45 | namespace tut |
46 | { | 46 | { |
47 | inline void ensure_approximately_equals(const char* msg, F64 actual, F64 expected, U32 frac_bits) | ||
48 | { | ||
49 | if(!is_approx_equal_fraction(actual, expected, frac_bits)) | ||
50 | { | ||
51 | std::stringstream ss; | ||
52 | ss << (msg?msg:"") << (msg?": ":"") << "not equal actual: " << actual << " expected: " << expected; | ||
53 | throw tut::failure(ss.str().c_str()); | ||
54 | } | ||
55 | } | ||
56 | |||
47 | inline void ensure_approximately_equals(const char* msg, F32 actual, F32 expected, U32 frac_bits) | 57 | inline void ensure_approximately_equals(const char* msg, F32 actual, F32 expected, U32 frac_bits) |
48 | { | 58 | { |
49 | if(!is_approx_equal_fraction(actual, expected, frac_bits)) | 59 | if(!is_approx_equal_fraction(actual, expected, frac_bits)) |
diff --git a/linden/indra/test/mass_properties_tut.cpp b/linden/indra/test/mass_properties_tut.cpp new file mode 100644 index 0000000..08cfeac --- /dev/null +++ b/linden/indra/test/mass_properties_tut.cpp | |||
@@ -0,0 +1,1008 @@ | |||
1 | /** | ||
2 | * @file mass_properties.cpp | ||
3 | * @author andrew@lindenlab.com | ||
4 | * @date 2007-12-20 | ||
5 | * @brief Tests for the LLPrimMassProperties and LLObjectMassProperties classes | ||
6 | * | ||
7 | * $LicenseInfo:firstyear=2007&license=internal$ | ||
8 | * | ||
9 | * Copyright (c) 2007-2008, Linden Research, Inc. | ||
10 | * | ||
11 | * The following source code is PROPRIETARY AND CONFIDENTIAL. Use of | ||
12 | * this source code is governed by the Linden Lab Source Code Disclosure | ||
13 | * Agreement ("Agreement") previously entered between you and Linden | ||
14 | * Lab. By accessing, using, copying, modifying or distributing this | ||
15 | * software, you acknowledge that you have been informed of your | ||
16 | * obligations under the Agreement and agree to abide by those obligations. | ||
17 | * | ||
18 | * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO | ||
19 | * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, | ||
20 | * COMPLETENESS OR PERFORMANCE. | ||
21 | * $/LicenseInfo$ | ||
22 | */ | ||
23 | |||
24 | #include "linden_common.h" | ||
25 | #include "lltut.h" | ||
26 | #include <llmath/v3math.h> | ||
27 | #include <llmath/llquaternion.h> | ||
28 | #include <llphysics/abstract/utils/llinertiatensorutils.h> | ||
29 | #include <llphysics/abstract/utils/llobjectmassproperties.h> | ||
30 | #include <llphysics/abstract/utils/llprimmassproperties.h> | ||
31 | #include <llphysics/abstract/utils/llphysicsvolumemanager.h> | ||
32 | #include <llprimitive/llmaterialtable.h> | ||
33 | #include <llprimitive/llprimitive.h> | ||
34 | |||
35 | |||
36 | const F32 SMALL_RELATIVE_ERROR = 0.001f; // 0.1% | ||
37 | const F32 SQRT_THREE = 1.732050808f; | ||
38 | const F32 SQRT_SIX = 2.449489743f; | ||
39 | |||
40 | namespace tut | ||
41 | { | ||
42 | struct mass_properties_data | ||
43 | { | ||
44 | LLPrimMassProperties prim_properties; | ||
45 | LLObjectMassProperties object_properties; | ||
46 | }; | ||
47 | |||
48 | typedef test_group<mass_properties_data> mass_properties_group; | ||
49 | typedef mass_properties_group::object mass_properties; | ||
50 | tut::mass_properties_group mp_test_group("mass properties"); | ||
51 | |||
52 | template<> template<> | ||
53 | void mass_properties::test<1>() | ||
54 | { | ||
55 | // test SPHERE mass properties | ||
56 | LLPrimMassProperties prim_sphere; | ||
57 | prim_sphere.setUnitSphere(); | ||
58 | |||
59 | F32 density = 1000.f; | ||
60 | F32 radius = 5.f; | ||
61 | F32 diameter = 2.f * radius; | ||
62 | LLVector3 scale(diameter, diameter, diameter); | ||
63 | LLObjectMassProperties obj_sphere(prim_sphere, scale, density); | ||
64 | |||
65 | F32 computed_mass = obj_sphere.getMass(); | ||
66 | //LLVector3 center_of_mass | ||
67 | //obj_sphere.getCenterOfMass(center_of_mass); | ||
68 | LLMatrix3 inertia; | ||
69 | obj_sphere.getInertiaLocal(inertia); | ||
70 | F32 computed_inertia_eigenvalue = inertia.mMatrix[0][0]; | ||
71 | |||
72 | |||
73 | // volume is normalized for scale = <1,1,1> | ||
74 | // V = 4/3 * PI * r^3 | ||
75 | // inertia_eigenvalue = (2/5) * M * r^2 | ||
76 | F32 volume = ( 4.f / 3.f ) * radius * radius * radius * F_PI; | ||
77 | F32 expected_mass = density * volume; | ||
78 | F32 expected_inertia_eigenvalue = ( 2.f / 5.f ) * expected_mass * radius * radius; | ||
79 | |||
80 | F32 error = fabs(computed_mass - expected_mass) / expected_mass; | ||
81 | ensure("expected sphere mass should match computed", error < SMALL_RELATIVE_ERROR); | ||
82 | |||
83 | error = fabs(computed_inertia_eigenvalue - expected_inertia_eigenvalue) / expected_inertia_eigenvalue; | ||
84 | ensure("expected sphere inertia should match computed", error < SMALL_RELATIVE_ERROR); | ||
85 | } | ||
86 | |||
87 | template<> template<> | ||
88 | void mass_properties::test<2>() | ||
89 | { | ||
90 | // test LLInertiaTensorUtils | ||
91 | |||
92 | // define a known inertia tensor in the center of mass frame | ||
93 | // from the numerical example in this paper: | ||
94 | // http://www.journaldatabase.org/articles/87064/Explicit_Exact_Formulas_f.html | ||
95 | F32 known_mass = 1873.23f; | ||
96 | LLVector3 known_center( 0.f, 0.f, 0.f ); | ||
97 | LLMatrix3 known_inertia; | ||
98 | known_inertia.mMatrix[0][0] = 43520.33257f; | ||
99 | known_inertia.mMatrix[1][1] = 194711.28938f; | ||
100 | known_inertia.mMatrix[2][2] = 191168.76173f; | ||
101 | |||
102 | known_inertia.mMatrix[0][1] = -11996.20119f; | ||
103 | known_inertia.mMatrix[1][0] = -11996.20119f; | ||
104 | |||
105 | known_inertia.mMatrix[0][2] = 46343.16662f; | ||
106 | known_inertia.mMatrix[2][0] = 46343.16662f; | ||
107 | |||
108 | known_inertia.mMatrix[2][1] = -4417.66150f; | ||
109 | known_inertia.mMatrix[1][2] = -4417.66150f; | ||
110 | |||
111 | // the following two shifts should have null effect | ||
112 | { | ||
113 | LLVector3 first_shift(2.f, 3.f, 4.f); | ||
114 | LLVector3 second_shift = - first_shift; | ||
115 | LLMatrix3 inertia = known_inertia; | ||
116 | |||
117 | LLInertiaTensorUtils::shiftCenteredInertiaTensor(inertia, first_shift, known_mass); | ||
118 | LLInertiaTensorUtils::centerInertiaTensor(inertia, second_shift, known_mass); | ||
119 | |||
120 | // we should now have the same inertia with which we started | ||
121 | for (S32 i=0; i<3; ++i) | ||
122 | { | ||
123 | for (S32 j=0; j<3; ++j) | ||
124 | { | ||
125 | F32 error = fabs(1.f - inertia.mMatrix[i][j] / known_inertia.mMatrix[i][j]); | ||
126 | ensure("LLInertiaTensorUtils shift+sclae-shift-scale should be no-op", error < SMALL_RELATIVE_ERROR); | ||
127 | } | ||
128 | } | ||
129 | } | ||
130 | |||
131 | // the following series operations should have null effect | ||
132 | { | ||
133 | LLVector3 first_shift(1.f, 5.f, 10.f); | ||
134 | LLVector3 second_scale(2.f, 3.f, 4.f); | ||
135 | LLVector3 third_shift; | ||
136 | LLVector3 fourth_scale; | ||
137 | for (S32 i = 0; i < 3; ++i) | ||
138 | { | ||
139 | third_shift.mV[i] = -first_shift.mV[i] * second_scale.mV[i]; | ||
140 | fourth_scale.mV[i] = 1.f / second_scale.mV[i]; | ||
141 | } | ||
142 | |||
143 | F32 mass = known_mass; | ||
144 | LLVector3 center = known_center; | ||
145 | LLMatrix3 inertia = known_inertia; | ||
146 | |||
147 | // first | ||
148 | LLInertiaTensorUtils::shiftCenteredInertiaTensor(inertia, first_shift, mass); | ||
149 | center += first_shift; | ||
150 | |||
151 | // second | ||
152 | LLInertiaTensorUtils::scaleInertiaTensor(inertia, second_scale); | ||
153 | mass *= second_scale.mV[VX] * second_scale.mV[VY] * second_scale.mV[VZ]; | ||
154 | for (S32 i = 0; i < 3; ++i) | ||
155 | { | ||
156 | center.mV[i] *= second_scale.mV[i]; | ||
157 | } | ||
158 | |||
159 | // third | ||
160 | LLInertiaTensorUtils::centerInertiaTensor(inertia, third_shift, mass); | ||
161 | center -= third_shift; | ||
162 | |||
163 | // foruth | ||
164 | LLInertiaTensorUtils::scaleInertiaTensor(inertia, fourth_scale); | ||
165 | |||
166 | // we should now have the same inertia with which we started | ||
167 | for (S32 i=0; i<3; ++i) | ||
168 | { | ||
169 | for (S32 j=0; j<3; ++j) | ||
170 | { | ||
171 | F32 error = fabs(1.f - inertia.mMatrix[i][j] / known_inertia.mMatrix[i][j]); | ||
172 | ensure("LLInertiaTensorUtils shift+sclae-shift-scale should be no-op", error < SMALL_RELATIVE_ERROR); | ||
173 | } | ||
174 | } | ||
175 | } | ||
176 | } | ||
177 | |||
178 | template<> template<> | ||
179 | void mass_properties::test<3>() | ||
180 | { | ||
181 | // test tetrahedral decomposition of unit tetrahedron centered on origin | ||
182 | std::vector< LLVector3 > points; | ||
183 | points.push_back( LLVector3( 0.f, 0.f, 0.f ) ); | ||
184 | points.push_back( LLVector3( 1.f, 0.f, 0.f ) ); | ||
185 | points.push_back( LLVector3( 0.5f, 0.5f * SQRT_THREE, 0.f) ); | ||
186 | points.push_back( LLVector3( 0.5f, SQRT_THREE / 6.f, SQRT_SIX / 3.f) ); | ||
187 | |||
188 | // compute the center | ||
189 | LLVector3 center; | ||
190 | for (S32 i = 0; i < (S32)points.size(); ++i) | ||
191 | { | ||
192 | center += points[i]; | ||
193 | } | ||
194 | center *= ( 1.f / F32(points.size()) ); | ||
195 | |||
196 | // shift all points to center of mass frame | ||
197 | for (S32 i = 0; i < (S32)points.size(); ++i) | ||
198 | { | ||
199 | points[i] -= center; | ||
200 | } | ||
201 | |||
202 | LLPrimMassProperties tetrahedron; | ||
203 | tetrahedron.addSignedTetrahedron(1.0, points[0], points[1], points[2], points[3]); | ||
204 | // we must manually center the inertia tensor here | ||
205 | // since addSignedTetrahedron() does not do it automatically | ||
206 | tetrahedron.centerInertiaTensor(); | ||
207 | |||
208 | F32 density = 1.0f; | ||
209 | LLVector3 scale(1.f, 1.f, 1.f); | ||
210 | LLMatrix3 analytic_inertia; | ||
211 | tetrahedron.getScaledInertiaTensor(analytic_inertia, scale, density); | ||
212 | |||
213 | // compute the mesh | ||
214 | std::vector< S32 > triangle_indices; | ||
215 | triangle_indices.push_back(0); | ||
216 | triangle_indices.push_back(2); | ||
217 | triangle_indices.push_back(1); | ||
218 | |||
219 | triangle_indices.push_back(0); | ||
220 | triangle_indices.push_back(1); | ||
221 | triangle_indices.push_back(3); | ||
222 | |||
223 | triangle_indices.push_back(0); | ||
224 | triangle_indices.push_back(3); | ||
225 | triangle_indices.push_back(2); | ||
226 | |||
227 | triangle_indices.push_back(1); | ||
228 | triangle_indices.push_back(2); | ||
229 | triangle_indices.push_back(3); | ||
230 | |||
231 | // compute the same inertia using a mesh | ||
232 | { | ||
233 | LLPrimMassProperties mesh; | ||
234 | mesh.setUnitMesh(points, triangle_indices); | ||
235 | |||
236 | // the two properties should agree | ||
237 | F32 error = ( tetrahedron.getVolume() - mesh.getVolume() ) / tetrahedron.getVolume(); | ||
238 | ensure("tetrahedron and mesh volume should match", error < SMALL_RELATIVE_ERROR); | ||
239 | |||
240 | error = ( tetrahedron.getCenterOfMass() - mesh.getCenterOfMass() ).length(); | ||
241 | ensure("tetrahedron and mesh centers should match", error < SMALL_RELATIVE_ERROR); | ||
242 | |||
243 | LLMatrix3 mesh_inertia; | ||
244 | mesh.getScaledInertiaTensor(mesh_inertia, scale, density); | ||
245 | |||
246 | for (S32 i=0; i<3; ++i) | ||
247 | { | ||
248 | for (S32 j=0; j<3; ++j) | ||
249 | { | ||
250 | // only verify the non-small elements | ||
251 | if (analytic_inertia.mMatrix[i][j] > SMALL_RELATIVE_ERROR) | ||
252 | { | ||
253 | error = fabs(1.f - mesh_inertia.mMatrix[i][j] / analytic_inertia.mMatrix[i][j]); | ||
254 | ensure("LLPrimMassProperties::setUnitMesh() inertia ", error < SMALL_RELATIVE_ERROR); | ||
255 | } | ||
256 | } | ||
257 | } | ||
258 | } | ||
259 | |||
260 | // shift the whole tetrahedron away from the center of mass and recompute the mesh | ||
261 | { | ||
262 | LLVector3 shift(11.f, 7.f, 3.f); | ||
263 | for (S32 i = 0; i < (S32)points.size(); ++i) | ||
264 | { | ||
265 | points[i] += shift; | ||
266 | } | ||
267 | LLPrimMassProperties mesh; | ||
268 | mesh.setUnitMesh(points, triangle_indices); | ||
269 | |||
270 | // the two properties should agree | ||
271 | F32 error = ( tetrahedron.getVolume() - mesh.getVolume() ) / tetrahedron.getVolume(); | ||
272 | ensure("tetrahedron and mesh volume should match", error < SMALL_RELATIVE_ERROR); | ||
273 | |||
274 | LLMatrix3 mesh_inertia; | ||
275 | mesh.getScaledInertiaTensor(mesh_inertia, scale, density); | ||
276 | |||
277 | for (S32 i=0; i<3; ++i) | ||
278 | { | ||
279 | for (S32 j=0; j<3; ++j) | ||
280 | { | ||
281 | // only verify the non-small elements | ||
282 | if (analytic_inertia.mMatrix[i][j] > SMALL_RELATIVE_ERROR) | ||
283 | { | ||
284 | error = fabs(1.f - mesh_inertia.mMatrix[i][j] / analytic_inertia.mMatrix[i][j]); | ||
285 | ensure("LLPrimMassProperties::setUnitMesh() inertia ", error < SMALL_RELATIVE_ERROR); | ||
286 | } | ||
287 | } | ||
288 | } | ||
289 | } | ||
290 | } | ||
291 | |||
292 | template<> template<> | ||
293 | void mass_properties::test<4>() | ||
294 | { | ||
295 | // test tetrahedron utilities | ||
296 | |||
297 | // from the paper described here: | ||
298 | // from the numerical example in this paper: | ||
299 | // http://www.journaldatabase.org/articles/87064/Explicit_Exact_Formulas_f.html | ||
300 | |||
301 | // initialize info about the tetrahedron | ||
302 | std::vector< LLVector3 > points; | ||
303 | points.push_back( LLVector3( 8.33220f, -11.86875f, 0.93355f) ); | ||
304 | points.push_back( LLVector3( 0.75523f, 5.00000f, 16.37072f) ); | ||
305 | points.push_back( LLVector3( 52.61236f, 5.00000f, - 5.38580f) ); | ||
306 | points.push_back( LLVector3( 2.00000f, 5.00000f, 3.00000f) ); | ||
307 | |||
308 | LLVector3 expected_center( 15.92492f, 0.78281f, 3.732962f); | ||
309 | |||
310 | LLMatrix3 expected_inertia; | ||
311 | expected_inertia.mMatrix[0][0] = 43520.33257f; | ||
312 | expected_inertia.mMatrix[1][1] = 194711.28938f; | ||
313 | expected_inertia.mMatrix[2][2] = 191168.76173f; | ||
314 | |||
315 | expected_inertia.mMatrix[0][1] = -11996.20119f; | ||
316 | expected_inertia.mMatrix[1][0] = -11996.20119f; | ||
317 | |||
318 | expected_inertia.mMatrix[0][2] = 46343.16662f; | ||
319 | expected_inertia.mMatrix[2][0] = 46343.16662f; | ||
320 | |||
321 | expected_inertia.mMatrix[2][1] = -4417.66150f; | ||
322 | expected_inertia.mMatrix[1][2] = -4417.66150f; | ||
323 | |||
324 | // measure tetrahedron bounding box max dimension | ||
325 | // for relative error estimates | ||
326 | LLVector3 box_min(FLT_MAX, FLT_MAX, FLT_MAX); | ||
327 | LLVector3 box_max(-FLT_MAX, -FLT_MAX, -FLT_MAX); | ||
328 | for (S32 point_index = 0; point_index < (S32)points.size(); ++point_index) | ||
329 | { | ||
330 | for (S32 i = 0; i < 3; ++i) | ||
331 | { | ||
332 | if (points[point_index].mV[i] < box_min.mV[i]) | ||
333 | { | ||
334 | box_min.mV[i] = points[point_index].mV[i]; | ||
335 | } | ||
336 | if (points[point_index].mV[i] > box_max.mV[i]) | ||
337 | { | ||
338 | box_max.mV[i] = points[point_index].mV[i]; | ||
339 | } | ||
340 | } | ||
341 | } | ||
342 | F32 tetrahedron_max_dimension = (box_max - box_min).length(); | ||
343 | |||
344 | |||
345 | // test LLPrimMassProperties::addSignedTetrahedron() | ||
346 | { | ||
347 | LLPrimMassProperties tetrahedron; | ||
348 | tetrahedron.addSignedTetrahedron(1.f, points[0], points[1], points[2], points[3]); | ||
349 | // we must manually center the inertia tensor here | ||
350 | // since addSignedTetrahedron() does not do it automatically | ||
351 | tetrahedron.centerInertiaTensor(); | ||
352 | |||
353 | // check the center of mass | ||
354 | LLVector3 center = tetrahedron.getCenterOfMass(); | ||
355 | F32 error = (center - expected_center).length() / tetrahedron_max_dimension; | ||
356 | |||
357 | ensure("LLPrimMassProperties::addSignedTetrahedron() center of mass ", error < SMALL_RELATIVE_ERROR); | ||
358 | |||
359 | // check the inertia tensor | ||
360 | LLMatrix3 computed_inertia; | ||
361 | LLVector3 scale(1.f, 1.f, 1.f); | ||
362 | F32 density = 1.f; | ||
363 | tetrahedron.getScaledInertiaTensor(computed_inertia, scale, density); | ||
364 | |||
365 | for (S32 i=0; i<3; ++i) | ||
366 | { | ||
367 | for (S32 j=0; j<3; ++j) | ||
368 | { | ||
369 | error = fabs(1.f - computed_inertia.mMatrix[i][j] / expected_inertia.mMatrix[i][j]); | ||
370 | ensure("LLPrimMassProperties::addSignedTetrahedron inertia ", error < SMALL_RELATIVE_ERROR); | ||
371 | } | ||
372 | } | ||
373 | } | ||
374 | |||
375 | // test LLPrimMassProperties::addUnitMesh() | ||
376 | { | ||
377 | std::vector< S32 > triangle_indices; | ||
378 | triangle_indices.push_back(0); | ||
379 | triangle_indices.push_back(2); | ||
380 | triangle_indices.push_back(1); | ||
381 | |||
382 | triangle_indices.push_back(1); | ||
383 | triangle_indices.push_back(3); | ||
384 | triangle_indices.push_back(0); | ||
385 | |||
386 | triangle_indices.push_back(2); | ||
387 | triangle_indices.push_back(0); | ||
388 | triangle_indices.push_back(3); | ||
389 | |||
390 | triangle_indices.push_back(3); | ||
391 | triangle_indices.push_back(1); | ||
392 | triangle_indices.push_back(2); | ||
393 | |||
394 | LLPrimMassProperties mesh; | ||
395 | mesh.setUnitMesh(points, triangle_indices); | ||
396 | |||
397 | // check the center of mass | ||
398 | LLVector3 center = mesh.getCenterOfMass(); | ||
399 | F32 error = (center - expected_center).length() / tetrahedron_max_dimension; | ||
400 | |||
401 | ensure("LLPrimMassProperties::setUnitMesh() center of mass ", error < SMALL_RELATIVE_ERROR); | ||
402 | |||
403 | // check the inertia tensor | ||
404 | LLMatrix3 computed_inertia; | ||
405 | LLVector3 scale(1.f, 1.f, 1.f); | ||
406 | F32 density = 1.f; | ||
407 | mesh.getScaledInertiaTensor(computed_inertia, scale, density); | ||
408 | |||
409 | for (S32 i=0; i<3; ++i) | ||
410 | { | ||
411 | for (S32 j=0; j<3; ++j) | ||
412 | { | ||
413 | error = fabs(1.f - computed_inertia.mMatrix[i][j] / expected_inertia.mMatrix[i][j]); | ||
414 | ensure("LLPrimMassProperties::setUnitMesh() inertia diagonal elements mismatch", error < SMALL_RELATIVE_ERROR); | ||
415 | } | ||
416 | } | ||
417 | } | ||
418 | } | ||
419 | |||
420 | template<> template<> | ||
421 | void mass_properties::test<5>() | ||
422 | { | ||
423 | // test LLPrimMassProperties | ||
424 | |||
425 | // unit shape box | ||
426 | LLPrimMassProperties box; | ||
427 | box.setUnitBox(); | ||
428 | |||
429 | // unit shape mesh -- box | ||
430 | |||
431 | // | ||
432 | // 4-----------0 | ||
433 | // z /| /| | ||
434 | // | / | / | | ||
435 | // | / | / | | ||
436 | // | 6-----------2 | | ||
437 | // | | | | | | ||
438 | // | | 5-------|---1 | ||
439 | // | | / | / | ||
440 | // | | / | / | ||
441 | // | y |/ |/ | ||
442 | // |/ 7-----------3 | ||
443 | // +------------------------ x | ||
444 | |||
445 | std::vector< LLVector3 > points; | ||
446 | points.push_back( LLVector3( 0.5f, 0.5f, 0.5f) ); | ||
447 | points.push_back( LLVector3( 0.5f, 0.5f, -0.5f) ); | ||
448 | points.push_back( LLVector3( 0.5f, -0.5f, 0.5f) ); | ||
449 | points.push_back( LLVector3( 0.5f, -0.5f, -0.5f) ); | ||
450 | points.push_back( LLVector3(-0.5f, 0.5f, 0.5f) ); | ||
451 | points.push_back( LLVector3(-0.5f, 0.5f, -0.5f) ); | ||
452 | points.push_back( LLVector3(-0.5f, -0.5f, 0.5f) ); | ||
453 | points.push_back( LLVector3(-0.5f, -0.5f, -0.5f) ); | ||
454 | |||
455 | std::vector< S32 > triangle_indices; | ||
456 | // +x | ||
457 | triangle_indices.push_back(1); | ||
458 | triangle_indices.push_back(0); | ||
459 | triangle_indices.push_back(2); | ||
460 | |||
461 | triangle_indices.push_back(1); | ||
462 | triangle_indices.push_back(2); | ||
463 | triangle_indices.push_back(3); | ||
464 | |||
465 | // -y | ||
466 | triangle_indices.push_back(3); | ||
467 | triangle_indices.push_back(2); | ||
468 | triangle_indices.push_back(7); | ||
469 | |||
470 | triangle_indices.push_back(7); | ||
471 | triangle_indices.push_back(2); | ||
472 | triangle_indices.push_back(6); | ||
473 | |||
474 | // -x | ||
475 | triangle_indices.push_back(7); | ||
476 | triangle_indices.push_back(6); | ||
477 | triangle_indices.push_back(4); | ||
478 | |||
479 | triangle_indices.push_back(7); | ||
480 | triangle_indices.push_back(4); | ||
481 | triangle_indices.push_back(5); | ||
482 | |||
483 | // +y | ||
484 | triangle_indices.push_back(5); | ||
485 | triangle_indices.push_back(4); | ||
486 | triangle_indices.push_back(1); | ||
487 | |||
488 | triangle_indices.push_back(1); | ||
489 | triangle_indices.push_back(4); | ||
490 | triangle_indices.push_back(0); | ||
491 | |||
492 | // +z | ||
493 | triangle_indices.push_back(0); | ||
494 | triangle_indices.push_back(4); | ||
495 | triangle_indices.push_back(6); | ||
496 | |||
497 | triangle_indices.push_back(0); | ||
498 | triangle_indices.push_back(6); | ||
499 | triangle_indices.push_back(2); | ||
500 | |||
501 | // -z | ||
502 | triangle_indices.push_back(7); | ||
503 | triangle_indices.push_back(5); | ||
504 | triangle_indices.push_back(3); | ||
505 | |||
506 | triangle_indices.push_back(3); | ||
507 | triangle_indices.push_back(5); | ||
508 | triangle_indices.push_back(1); | ||
509 | |||
510 | LLPrimMassProperties mesh; | ||
511 | mesh.setUnitMesh(points, triangle_indices); | ||
512 | |||
513 | // the unit box and unit mesh mass properties should be nearly the same | ||
514 | |||
515 | // volume should agree | ||
516 | F32 error = fabs(box.getVolume() - mesh.getVolume()) / box.getVolume(); | ||
517 | ensure("UnitBox and UnitMesh(box) should have same volume", error < SMALL_RELATIVE_ERROR); | ||
518 | |||
519 | // center of mass should agree | ||
520 | LLVector3 box_center = box.getCenterOfMass(); | ||
521 | LLVector3 mesh_center = mesh.getCenterOfMass(); | ||
522 | error = fabs( (box_center - mesh_center).length() ); | ||
523 | ensure("UnitBox and UnitMesh(box) centers of mass should agree", error < SMALL_RELATIVE_ERROR ); | ||
524 | |||
525 | LLVector3 scale(1.f, 1.f, 1.f); | ||
526 | F32 density = 1.f; | ||
527 | LLMatrix3 box_inertia, mesh_inertia; | ||
528 | box.getScaledInertiaTensor(box_inertia, scale, density); | ||
529 | mesh.getScaledInertiaTensor(mesh_inertia, scale, density); | ||
530 | |||
531 | // mesh eigenvalues should be uniform | ||
532 | for (S32 i = 0; i < 2; ++i) | ||
533 | { | ||
534 | error = fabs(mesh_inertia.mMatrix[i][i] - mesh_inertia.mMatrix[i+1][i+1]) / mesh_inertia.mMatrix[i][i]; | ||
535 | ensure("UnitMesh(box) should have uniform eigenvalues", error < SMALL_RELATIVE_ERROR); | ||
536 | } | ||
537 | // inertias should agree | ||
538 | for (S32 i = 0; i < 3; ++i) | ||
539 | { | ||
540 | for (S32 j = 0; j < 3; ++j) | ||
541 | { | ||
542 | error = fabs(box_inertia.mMatrix[i][j] - mesh_inertia.mMatrix[i][j]); | ||
543 | if (error > 0.f | ||
544 | && box_inertia.mMatrix[i][j] != 0.f) | ||
545 | { | ||
546 | error /= box_inertia.mMatrix[i][j]; | ||
547 | } | ||
548 | ensure("UnitBox and UnitMesh(box) should have same inertia", error < SMALL_RELATIVE_ERROR); | ||
549 | } | ||
550 | } | ||
551 | |||
552 | // Here we test the boundary of the LLPrimLinkInfo::canLink() method | ||
553 | // between semi-random middle-sized objects. | ||
554 | } | ||
555 | |||
556 | template<> template<> | ||
557 | void mass_properties::test<6>() | ||
558 | { | ||
559 | // test LLObjectMassProperties | ||
560 | |||
561 | // we make a large single-prim box, then a similarly shaped object | ||
562 | // that is multiple prims, and compare their mass properties | ||
563 | |||
564 | LLPrimMassProperties box; | ||
565 | box.setUnitBox(); | ||
566 | |||
567 | F32 density = 3.7f; | ||
568 | LLVector3 big_scale(1.f, 2.f, 3.f); | ||
569 | LLObjectMassProperties big_box(box, big_scale, density); | ||
570 | |||
571 | LLObjectMassProperties multiple_box; | ||
572 | LLVector3 position; | ||
573 | LLQuaternion rotation; | ||
574 | rotation.loadIdentity(); | ||
575 | |||
576 | F32 small_box_size = 0.5f; | ||
577 | LLVector3 small_scale( small_box_size, small_box_size, small_box_size); | ||
578 | S32 num_boxes_x = S32(big_scale.mV[VX] / small_box_size); | ||
579 | S32 num_boxes_y = S32(big_scale.mV[VY] / small_box_size); | ||
580 | S32 num_boxes_z = S32(big_scale.mV[VZ] / small_box_size); | ||
581 | LLVector3 start_pos = 0.5f * (small_scale - big_scale); | ||
582 | for (S32 x = 0; x < num_boxes_x; ++x) | ||
583 | { | ||
584 | for (S32 y = 0; y < num_boxes_y; ++y) | ||
585 | { | ||
586 | for (S32 z = 0; z < num_boxes_z; ++z) | ||
587 | { | ||
588 | position.set( F32(x) * small_box_size, F32(y) * small_box_size, F32(z) * small_box_size ); | ||
589 | position += start_pos; | ||
590 | |||
591 | multiple_box.add(box, small_scale, density, position, rotation); | ||
592 | } | ||
593 | } | ||
594 | } | ||
595 | |||
596 | // the mass properties of the two boxes should match | ||
597 | |||
598 | // mass | ||
599 | F32 big_mass = big_box.getMass(); | ||
600 | F32 multiple_mass = multiple_box.getMass(); | ||
601 | F32 error = (big_mass - multiple_mass) / big_mass; | ||
602 | ensure("Big box and equivalent multi-prim box should have same mass", error < SMALL_RELATIVE_ERROR); | ||
603 | |||
604 | // center of mass | ||
605 | LLVector3 big_center, multiple_center; | ||
606 | big_box.getCenterOfMass(big_center); | ||
607 | multiple_box.getCenterOfMass(multiple_center); | ||
608 | error = (big_center - multiple_center).length(); | ||
609 | ensure("Big box and equivalent multi-prim box should have same center", error < SMALL_RELATIVE_ERROR); | ||
610 | |||
611 | // inertia | ||
612 | LLMatrix3 big_inertia, multiple_inertia; | ||
613 | big_box.getInertiaLocal(big_inertia); | ||
614 | multiple_box.getInertiaLocal(multiple_inertia); | ||
615 | for (S32 i = 0; i < 3; ++i) | ||
616 | { | ||
617 | for (S32 j = 0; j < 3; ++j) | ||
618 | { | ||
619 | error = fabs(big_inertia.mMatrix[i][j] - multiple_inertia.mMatrix[i][j]); | ||
620 | if (error > 0.f | ||
621 | && big_inertia.mMatrix[i][j] != 0.f) | ||
622 | { | ||
623 | error /= big_inertia.mMatrix[i][j]; | ||
624 | } | ||
625 | ensure("UnitBox and UnitMesh(box) should have same inertia", error < SMALL_RELATIVE_ERROR); | ||
626 | } | ||
627 | } | ||
628 | } | ||
629 | |||
630 | template<> template<> | ||
631 | void mass_properties::test<7>() | ||
632 | { | ||
633 | // test LLObjectMassProperties with rotations | ||
634 | |||
635 | // we make a large single-prim box via mesh, then a similarly shaped | ||
636 | // object that is multiple prims (implicit boxes), and compare their | ||
637 | // mass properties | ||
638 | |||
639 | // | ||
640 | // 4-----------0 | ||
641 | // z /| /| | ||
642 | // | / | / | | ||
643 | // | / | / | | ||
644 | // | 6-----------2 | | ||
645 | // | | | | | | ||
646 | // | | 5-------|---1 | ||
647 | // | | / | / | ||
648 | // | | / | / | ||
649 | // | y |/ |/ | ||
650 | // |/ 7-----------3 | ||
651 | // +------------------------ x | ||
652 | |||
653 | std::vector< LLVector3 > points; | ||
654 | points.push_back( LLVector3( 0.5f, 0.5f, 0.5f) ); | ||
655 | points.push_back( LLVector3( 0.5f, 0.5f, -0.5f) ); | ||
656 | points.push_back( LLVector3( 0.5f, -0.5f, 0.5f) ); | ||
657 | points.push_back( LLVector3( 0.5f, -0.5f, -0.5f) ); | ||
658 | points.push_back( LLVector3(-0.5f, 0.5f, 0.5f) ); | ||
659 | points.push_back( LLVector3(-0.5f, 0.5f, -0.5f) ); | ||
660 | points.push_back( LLVector3(-0.5f, -0.5f, 0.5f) ); | ||
661 | points.push_back( LLVector3(-0.5f, -0.5f, -0.5f) ); | ||
662 | |||
663 | std::vector< S32 > triangle_indices; | ||
664 | // +x | ||
665 | triangle_indices.push_back(1); | ||
666 | triangle_indices.push_back(0); | ||
667 | triangle_indices.push_back(2); | ||
668 | |||
669 | triangle_indices.push_back(1); | ||
670 | triangle_indices.push_back(2); | ||
671 | triangle_indices.push_back(3); | ||
672 | |||
673 | // -y | ||
674 | triangle_indices.push_back(3); | ||
675 | triangle_indices.push_back(2); | ||
676 | triangle_indices.push_back(7); | ||
677 | |||
678 | triangle_indices.push_back(7); | ||
679 | triangle_indices.push_back(2); | ||
680 | triangle_indices.push_back(6); | ||
681 | |||
682 | // -x | ||
683 | triangle_indices.push_back(7); | ||
684 | triangle_indices.push_back(6); | ||
685 | triangle_indices.push_back(4); | ||
686 | |||
687 | triangle_indices.push_back(7); | ||
688 | triangle_indices.push_back(4); | ||
689 | triangle_indices.push_back(5); | ||
690 | |||
691 | // +y | ||
692 | triangle_indices.push_back(5); | ||
693 | triangle_indices.push_back(4); | ||
694 | triangle_indices.push_back(1); | ||
695 | |||
696 | triangle_indices.push_back(1); | ||
697 | triangle_indices.push_back(4); | ||
698 | triangle_indices.push_back(0); | ||
699 | |||
700 | // +z | ||
701 | triangle_indices.push_back(0); | ||
702 | triangle_indices.push_back(4); | ||
703 | triangle_indices.push_back(6); | ||
704 | |||
705 | triangle_indices.push_back(0); | ||
706 | triangle_indices.push_back(6); | ||
707 | triangle_indices.push_back(2); | ||
708 | |||
709 | // -z | ||
710 | triangle_indices.push_back(7); | ||
711 | triangle_indices.push_back(5); | ||
712 | triangle_indices.push_back(3); | ||
713 | |||
714 | triangle_indices.push_back(3); | ||
715 | triangle_indices.push_back(5); | ||
716 | triangle_indices.push_back(1); | ||
717 | |||
718 | F32 angle_step = F_PI / (2.f * 3.f); | ||
719 | for (F32 angle = 0.f; angle < 0.51f * F_PI; angle += angle_step) | ||
720 | { | ||
721 | // scale and rotate mesh points | ||
722 | LLVector3 axis(0.f, 0.f, angle); | ||
723 | LLQuaternion mesh_rotation(angle, axis); | ||
724 | LLVector3 big_scale(3.f, 5.f, 7.f); | ||
725 | std::vector< LLVector3 > new_points; | ||
726 | for (S32 p = 0; p < (S32)points.size(); ++p) | ||
727 | { | ||
728 | LLVector3 new_point = points[p]; | ||
729 | for (S32 i = 0; i < 3; ++i) | ||
730 | { | ||
731 | new_point.mV[i] *= big_scale.mV[i]; | ||
732 | } | ||
733 | new_points.push_back( new_point * mesh_rotation ); | ||
734 | } | ||
735 | |||
736 | // build the big mesh box | ||
737 | LLPrimMassProperties mesh_box; | ||
738 | mesh_box.setUnitMesh(new_points, triangle_indices); | ||
739 | |||
740 | F32 density = 3.7f; | ||
741 | LLVector3 unit_scale(1.f, 1.f, 1.f); | ||
742 | LLObjectMassProperties big_box(mesh_box, unit_scale, density); | ||
743 | |||
744 | // build the multiple_box | ||
745 | LLPrimMassProperties box; | ||
746 | box.setUnitBox(); | ||
747 | |||
748 | LLObjectMassProperties multiple_box; | ||
749 | LLVector3 position; | ||
750 | |||
751 | F32 small_box_size = 0.5f; | ||
752 | LLVector3 small_scale( small_box_size, small_box_size, small_box_size); | ||
753 | S32 num_boxes_x = S32(big_scale.mV[VX] / small_box_size); | ||
754 | S32 num_boxes_y = S32(big_scale.mV[VY] / small_box_size); | ||
755 | S32 num_boxes_z = S32(big_scale.mV[VZ] / small_box_size); | ||
756 | LLVector3 start_pos = (0.5f * (small_scale - big_scale)) * mesh_rotation; | ||
757 | for (S32 x = 0; x < num_boxes_x; ++x) | ||
758 | { | ||
759 | for (S32 y = 0; y < num_boxes_y; ++y) | ||
760 | { | ||
761 | for (S32 z = 0; z < num_boxes_z; ++z) | ||
762 | { | ||
763 | position.set( F32(x) * small_box_size, F32(y) * small_box_size, F32(z) * small_box_size ); | ||
764 | position *= mesh_rotation; | ||
765 | position += start_pos; | ||
766 | multiple_box.add(box, small_scale, density, position, mesh_rotation); | ||
767 | } | ||
768 | } | ||
769 | } | ||
770 | |||
771 | // the mass properties of the two boxes should match | ||
772 | |||
773 | // mass | ||
774 | F32 big_mass = big_box.getMass(); | ||
775 | F32 multiple_mass = multiple_box.getMass(); | ||
776 | F32 error = (big_mass - multiple_mass) / big_mass; | ||
777 | ensure("Big box and equivalent multi-prim box should have same mass", error < SMALL_RELATIVE_ERROR); | ||
778 | |||
779 | // center of mass | ||
780 | LLVector3 big_center, multiple_center; | ||
781 | big_box.getCenterOfMass(big_center); | ||
782 | multiple_box.getCenterOfMass(multiple_center); | ||
783 | error = (big_center - multiple_center).length(); | ||
784 | ensure("Big box and equivalent multi-prim box should have same center", error < SMALL_RELATIVE_ERROR); | ||
785 | |||
786 | LLMatrix3 big_inertia, multiple_inertia; | ||
787 | big_box.getInertiaLocal(big_inertia); | ||
788 | multiple_box.getInertiaLocal(multiple_inertia); | ||
789 | |||
790 | for (S32 i = 0; i < 3; ++i) | ||
791 | { | ||
792 | for (S32 j = 0; j < 3; ++j) | ||
793 | { | ||
794 | error = fabs(big_inertia.mMatrix[i][j] - multiple_inertia.mMatrix[i][j]); | ||
795 | if (error > 0.f | ||
796 | && big_inertia.mMatrix[i][j] > SMALL_RELATIVE_ERROR) | ||
797 | { | ||
798 | error /= big_inertia.mMatrix[i][j]; | ||
799 | } | ||
800 | ensure("UnitBox and UnitMesh(box) should have same inertia", error < SMALL_RELATIVE_ERROR); | ||
801 | } | ||
802 | } | ||
803 | } | ||
804 | } | ||
805 | |||
806 | template<> template<> | ||
807 | void mass_properties::test<8>() | ||
808 | { | ||
809 | // test LLPhysicsVolumeManager | ||
810 | |||
811 | // we make a large single-prim box, then a similarly shaped object | ||
812 | // that is multiple prims, and compare their mass properties | ||
813 | |||
814 | // first we make the single-prim giant | ||
815 | // | ||
816 | // 4-----------0 | ||
817 | // z /| /| | ||
818 | // | / | / | | ||
819 | // | / | / | | ||
820 | // | 6-----------2 | | ||
821 | // | | | | | | ||
822 | // | | 5-------|---1 | ||
823 | // | | / | / | ||
824 | // | | / | / | ||
825 | // | y |/ |/ | ||
826 | // |/ 7-----------3 | ||
827 | // +------------------------ x | ||
828 | |||
829 | std::vector< LLVector3 > points; | ||
830 | points.push_back( LLVector3( 0.5f, 0.5f, 0.5f) ); | ||
831 | points.push_back( LLVector3( 0.5f, 0.5f, -0.5f) ); | ||
832 | points.push_back( LLVector3( 0.5f, -0.5f, 0.5f) ); | ||
833 | points.push_back( LLVector3( 0.5f, -0.5f, -0.5f) ); | ||
834 | points.push_back( LLVector3(-0.5f, 0.5f, 0.5f) ); | ||
835 | points.push_back( LLVector3(-0.5f, 0.5f, -0.5f) ); | ||
836 | points.push_back( LLVector3(-0.5f, -0.5f, 0.5f) ); | ||
837 | points.push_back( LLVector3(-0.5f, -0.5f, -0.5f) ); | ||
838 | |||
839 | std::vector< S32 > triangle_indices; | ||
840 | // +x | ||
841 | triangle_indices.push_back(1); | ||
842 | triangle_indices.push_back(0); | ||
843 | triangle_indices.push_back(2); | ||
844 | |||
845 | triangle_indices.push_back(1); | ||
846 | triangle_indices.push_back(2); | ||
847 | triangle_indices.push_back(3); | ||
848 | |||
849 | // -y | ||
850 | triangle_indices.push_back(3); | ||
851 | triangle_indices.push_back(2); | ||
852 | triangle_indices.push_back(7); | ||
853 | |||
854 | triangle_indices.push_back(7); | ||
855 | triangle_indices.push_back(2); | ||
856 | triangle_indices.push_back(6); | ||
857 | |||
858 | // -x | ||
859 | triangle_indices.push_back(7); | ||
860 | triangle_indices.push_back(6); | ||
861 | triangle_indices.push_back(4); | ||
862 | |||
863 | triangle_indices.push_back(7); | ||
864 | triangle_indices.push_back(4); | ||
865 | triangle_indices.push_back(5); | ||
866 | |||
867 | // +y | ||
868 | triangle_indices.push_back(5); | ||
869 | triangle_indices.push_back(4); | ||
870 | triangle_indices.push_back(1); | ||
871 | |||
872 | triangle_indices.push_back(1); | ||
873 | triangle_indices.push_back(4); | ||
874 | triangle_indices.push_back(0); | ||
875 | |||
876 | // +z | ||
877 | triangle_indices.push_back(0); | ||
878 | triangle_indices.push_back(4); | ||
879 | triangle_indices.push_back(6); | ||
880 | |||
881 | triangle_indices.push_back(0); | ||
882 | triangle_indices.push_back(6); | ||
883 | triangle_indices.push_back(2); | ||
884 | |||
885 | // -z | ||
886 | triangle_indices.push_back(7); | ||
887 | triangle_indices.push_back(5); | ||
888 | triangle_indices.push_back(3); | ||
889 | |||
890 | triangle_indices.push_back(3); | ||
891 | triangle_indices.push_back(5); | ||
892 | triangle_indices.push_back(1); | ||
893 | |||
894 | // scale the mesh points | ||
895 | LLVector3 big_scale(1.f, 2.f, 3.f); | ||
896 | std::vector< LLVector3 > new_points; | ||
897 | for (S32 p = 0; p < (S32)points.size(); ++p) | ||
898 | { | ||
899 | LLVector3 new_point = points[p]; | ||
900 | for (S32 i = 0; i < 3; ++i) | ||
901 | { | ||
902 | new_point.mV[i] *= big_scale.mV[i]; | ||
903 | } | ||
904 | new_points.push_back( new_point ); | ||
905 | } | ||
906 | |||
907 | // build the big mesh box (primitive) | ||
908 | LLPrimMassProperties mesh_box; | ||
909 | mesh_box.setUnitMesh(new_points, triangle_indices); | ||
910 | |||
911 | F32 density = DEFAULT_OBJECT_DENSITY; | ||
912 | LLVector3 unit_scale(1.f, 1.f, 1.f); | ||
913 | LLObjectMassProperties big_box(mesh_box, unit_scale, density); | ||
914 | |||
915 | // build the multi-prim box (object) | ||
916 | S32 TEST_VOLUME_DETAIL = 1; | ||
917 | |||
918 | LLVolumeParams volume_params; | ||
919 | volume_params.setCube(); | ||
920 | |||
921 | LLObjectMassProperties multiple_box; | ||
922 | F32 small_box_size = 0.5f; | ||
923 | LLVector3 small_scale( small_box_size, small_box_size, small_box_size); | ||
924 | { | ||
925 | // hijack the volume manager used by LLPrimitive | ||
926 | LLPhysicsVolumeManager* volume_manager = new LLPhysicsVolumeManager(); | ||
927 | //volume_manager->setThreadSafe(false); | ||
928 | LLPrimitive::setVolumeManager(volume_manager); | ||
929 | |||
930 | std::vector< const LLPrimitive* > prim_list; | ||
931 | |||
932 | F32 angle = 0.f; | ||
933 | LLVector3 axis(0.f, 0.f, angle); | ||
934 | LLVector3 position; | ||
935 | LLQuaternion rotation(angle, axis); | ||
936 | S32 num_boxes_x = S32(big_scale.mV[VX] / small_box_size); | ||
937 | S32 num_boxes_y = S32(big_scale.mV[VY] / small_box_size); | ||
938 | S32 num_boxes_z = S32(big_scale.mV[VZ] / small_box_size); | ||
939 | |||
940 | for (S32 x = 0; x < num_boxes_x; ++x) | ||
941 | { | ||
942 | for (S32 y = 0; y < num_boxes_y; ++y) | ||
943 | { | ||
944 | for (S32 z = 0; z < num_boxes_z; ++z) | ||
945 | { | ||
946 | LLPrimitive* primp = new LLPrimitive(); | ||
947 | primp->setVolume( volume_params, TEST_VOLUME_DETAIL); | ||
948 | |||
949 | position.set( F32(x) * small_box_size, F32(y) * small_box_size, F32(z) * small_box_size ); | ||
950 | position *= rotation; | ||
951 | |||
952 | primp->setPosition(position); | ||
953 | primp->setRotation(rotation); | ||
954 | primp->setScale(small_scale); | ||
955 | |||
956 | prim_list.push_back(primp); | ||
957 | } | ||
958 | } | ||
959 | } | ||
960 | |||
961 | volume_manager->getObjectMassProperties(multiple_box, prim_list); | ||
962 | |||
963 | for (S32 i = 0; i < (S32)prim_list.size(); ++i) | ||
964 | { | ||
965 | delete prim_list[i]; | ||
966 | prim_list[i] = NULL; | ||
967 | } | ||
968 | LLPrimitive::cleanupVolumeManager(); | ||
969 | } | ||
970 | |||
971 | // mass | ||
972 | F32 big_mass = big_box.getMass(); | ||
973 | F32 multiple_mass = multiple_box.getMass(); | ||
974 | F32 error = (big_mass - multiple_mass) / big_mass; | ||
975 | ensure("Big box and equivalent multi-prim box should have same mass", error < SMALL_RELATIVE_ERROR); | ||
976 | |||
977 | // center of mass | ||
978 | LLVector3 big_center, multiple_center; | ||
979 | big_box.getCenterOfMass(big_center); | ||
980 | multiple_box.getCenterOfMass(multiple_center); | ||
981 | LLVector3 expected_shift = 0.5f * ( big_scale - small_scale ); | ||
982 | error = ( big_center - (multiple_center - expected_shift) ).length(); | ||
983 | ensure("Big box and equivalent multi-prim box should have same center", error < SMALL_RELATIVE_ERROR); | ||
984 | |||
985 | // inertia | ||
986 | LLMatrix3 big_inertia, multiple_inertia; | ||
987 | big_box.getInertiaLocal(big_inertia); | ||
988 | multiple_box.getInertiaLocal(multiple_inertia); | ||
989 | |||
990 | for (S32 i = 0; i < 3; ++i) | ||
991 | { | ||
992 | for (S32 j = 0; j < 3; ++j) | ||
993 | { | ||
994 | error = fabs(big_inertia.mMatrix[i][j] - multiple_inertia.mMatrix[i][j]); | ||
995 | if (error > 0.f | ||
996 | && big_inertia.mMatrix[i][j] > SMALL_RELATIVE_ERROR) | ||
997 | { | ||
998 | error /= big_inertia.mMatrix[i][j]; | ||
999 | } | ||
1000 | bool ok = error < SMALL_RELATIVE_ERROR | ||
1001 | || (i != j | ||
1002 | && error < SMALL_RELATIVE_ERROR); | ||
1003 | ensure("UnitBox and UnitMesh(box) should have same inertia", ok ); | ||
1004 | } | ||
1005 | } | ||
1006 | } | ||
1007 | } | ||
1008 | |||
diff --git a/linden/indra/test/math.cpp b/linden/indra/test/math.cpp index 9cab3fe..405b8a3 100644 --- a/linden/indra/test/math.cpp +++ b/linden/indra/test/math.cpp | |||
@@ -34,9 +34,13 @@ | |||
34 | #include "linden_common.h" | 34 | #include "linden_common.h" |
35 | #include "lltut.h" | 35 | #include "lltut.h" |
36 | 36 | ||
37 | #include "llcrc.h" | ||
38 | #include "llline.h" | ||
37 | #include "llmath.h" | 39 | #include "llmath.h" |
40 | #include "llrand.h" | ||
41 | #include "llsphere.h" | ||
38 | #include "lluuid.h" | 42 | #include "lluuid.h" |
39 | #include "llcrc.h" | 43 | #include "v3math.h" |
40 | 44 | ||
41 | namespace tut | 45 | namespace tut |
42 | { | 46 | { |
@@ -277,3 +281,439 @@ namespace tut | |||
277 | ensure_equals("crc update 2", c1.getCRC(), c2.getCRC()); | 281 | ensure_equals("crc update 2", c1.getCRC(), c2.getCRC()); |
278 | } | 282 | } |
279 | } | 283 | } |
284 | |||
285 | namespace tut | ||
286 | { | ||
287 | struct sphere_data | ||
288 | { | ||
289 | }; | ||
290 | typedef test_group<sphere_data> sphere_test; | ||
291 | typedef sphere_test::object sphere_object; | ||
292 | tut::sphere_test tsphere("LLSphere"); | ||
293 | |||
294 | template<> template<> | ||
295 | void sphere_object::test<1>() | ||
296 | { | ||
297 | // test LLSphere::contains() and ::overlaps() | ||
298 | S32 number_of_tests = 10; | ||
299 | for (S32 test = 0; test < number_of_tests; ++test) | ||
300 | { | ||
301 | LLVector3 first_center(1.f, 1.f, 1.f); | ||
302 | F32 first_radius = 3.f; | ||
303 | LLSphere first_sphere( first_center, first_radius ); | ||
304 | |||
305 | F32 half_millimeter = 0.0005f; | ||
306 | LLVector3 direction( ll_frand(2.f) - 1.f, ll_frand(2.f) - 1.f, ll_frand(2.f) - 1.f); | ||
307 | direction.normalize(); | ||
308 | |||
309 | F32 distance = ll_frand(first_radius - 2.f * half_millimeter); | ||
310 | LLVector3 second_center = first_center + distance * direction; | ||
311 | F32 second_radius = first_radius - distance - half_millimeter; | ||
312 | LLSphere second_sphere( second_center, second_radius ); | ||
313 | ensure("first sphere should contain the second", first_sphere.contains(second_sphere)); | ||
314 | ensure("first sphere should overlap the second", first_sphere.overlaps(second_sphere)); | ||
315 | |||
316 | distance = first_radius + ll_frand(first_radius); | ||
317 | second_center = first_center + distance * direction; | ||
318 | second_radius = distance - first_radius + half_millimeter; | ||
319 | second_sphere.set( second_center, second_radius ); | ||
320 | ensure("first sphere should NOT contain the second", !first_sphere.contains(second_sphere)); | ||
321 | ensure("first sphere should overlap the second", first_sphere.overlaps(second_sphere)); | ||
322 | |||
323 | distance = first_radius + ll_frand(first_radius) + half_millimeter; | ||
324 | second_center = first_center + distance * direction; | ||
325 | second_radius = distance - first_radius - half_millimeter; | ||
326 | second_sphere.set( second_center, second_radius ); | ||
327 | ensure("first sphere should NOT contain the second", !first_sphere.contains(second_sphere)); | ||
328 | ensure("first sphere should NOT overlap the second", !first_sphere.overlaps(second_sphere)); | ||
329 | } | ||
330 | } | ||
331 | |||
332 | template<> template<> | ||
333 | void sphere_object::test<2>() | ||
334 | { | ||
335 | // test LLSphere::getBoundingSphere() | ||
336 | S32 number_of_tests = 100; | ||
337 | S32 number_of_spheres = 10; | ||
338 | F32 sphere_center_range = 32.f; | ||
339 | F32 sphere_radius_range = 5.f; | ||
340 | |||
341 | for (S32 test = 0; test < number_of_tests; ++test) | ||
342 | { | ||
343 | // gegnerate a bunch of random sphere | ||
344 | std::vector< LLSphere > sphere_list; | ||
345 | for (S32 sphere_count=0; sphere_count < number_of_spheres; ++sphere_count) | ||
346 | { | ||
347 | LLVector3 direction( ll_frand(2.f) - 1.f, ll_frand(2.f) - 1.f, ll_frand(2.f) - 1.f); | ||
348 | direction.normalize(); | ||
349 | F32 distance = ll_frand(sphere_center_range); | ||
350 | LLVector3 center = distance * direction; | ||
351 | F32 radius = ll_frand(sphere_radius_range); | ||
352 | LLSphere sphere( center, radius ); | ||
353 | sphere_list.push_back(sphere); | ||
354 | } | ||
355 | |||
356 | // compute the bounding sphere | ||
357 | LLSphere bounding_sphere = LLSphere::getBoundingSphere(sphere_list); | ||
358 | |||
359 | // make sure all spheres are inside the bounding sphere | ||
360 | { | ||
361 | std::vector< LLSphere >::const_iterator sphere_itr; | ||
362 | for (sphere_itr = sphere_list.begin(); sphere_itr != sphere_list.end(); ++sphere_itr) | ||
363 | { | ||
364 | ensure("sphere should be contained by the bounding sphere", bounding_sphere.contains(*sphere_itr)); | ||
365 | } | ||
366 | } | ||
367 | |||
368 | // TODO -- improve LLSphere::getBoundingSphere() to the point where | ||
369 | // we can reduce the 'expansion' in the two tests below to about | ||
370 | // 2 mm or less | ||
371 | |||
372 | F32 expansion = 0.005f; | ||
373 | // move all spheres out a little bit | ||
374 | // and count how many are NOT contained | ||
375 | { | ||
376 | std::vector< LLVector3 > uncontained_directions; | ||
377 | std::vector< LLSphere >::iterator sphere_itr; | ||
378 | for (sphere_itr = sphere_list.begin(); sphere_itr != sphere_list.end(); ++sphere_itr) | ||
379 | { | ||
380 | LLVector3 direction = sphere_itr->getCenter() - bounding_sphere.getCenter(); | ||
381 | direction.normalize(); | ||
382 | |||
383 | sphere_itr->setCenter( sphere_itr->getCenter() + expansion * direction ); | ||
384 | if (! bounding_sphere.contains( *sphere_itr ) ) | ||
385 | { | ||
386 | uncontained_directions.push_back(direction); | ||
387 | } | ||
388 | } | ||
389 | ensure("when moving spheres out there should be at least two uncontained spheres", | ||
390 | uncontained_directions.size() > 1); | ||
391 | |||
392 | /* TODO -- when the bounding sphere algorithm is improved we can open up this test | ||
393 | * at the moment it occasionally fails when the sphere collection is tight and small | ||
394 | * (2 meters or less) | ||
395 | if (2 == uncontained_directions.size() ) | ||
396 | { | ||
397 | // if there were only two uncontained spheres then | ||
398 | // the two directions should be nearly opposite | ||
399 | F32 dir_dot = uncontained_directions[0] * uncontained_directions[1]; | ||
400 | ensure("two uncontained spheres should lie opposite the bounding center", dir_dot < -0.95f); | ||
401 | } | ||
402 | */ | ||
403 | } | ||
404 | |||
405 | // compute the new bounding sphere | ||
406 | bounding_sphere = LLSphere::getBoundingSphere(sphere_list); | ||
407 | |||
408 | // increase the size of all spheres a little bit | ||
409 | // and count how many are NOT contained | ||
410 | { | ||
411 | std::vector< LLVector3 > uncontained_directions; | ||
412 | std::vector< LLSphere >::iterator sphere_itr; | ||
413 | for (sphere_itr = sphere_list.begin(); sphere_itr != sphere_list.end(); ++sphere_itr) | ||
414 | { | ||
415 | LLVector3 direction = sphere_itr->getCenter() - bounding_sphere.getCenter(); | ||
416 | direction.normalize(); | ||
417 | |||
418 | sphere_itr->setRadius( sphere_itr->getRadius() + expansion ); | ||
419 | if (! bounding_sphere.contains( *sphere_itr ) ) | ||
420 | { | ||
421 | uncontained_directions.push_back(direction); | ||
422 | } | ||
423 | } | ||
424 | ensure("when boosting sphere radii there should be at least two uncontained spheres", | ||
425 | uncontained_directions.size() > 1); | ||
426 | |||
427 | /* TODO -- when the bounding sphere algorithm is improved we can open up this test | ||
428 | * at the moment it occasionally fails when the sphere collection is tight and small | ||
429 | * (2 meters or less) | ||
430 | if (2 == uncontained_directions.size() ) | ||
431 | { | ||
432 | // if there were only two uncontained spheres then | ||
433 | // the two directions should be nearly opposite | ||
434 | F32 dir_dot = uncontained_directions[0] * uncontained_directions[1]; | ||
435 | ensure("two uncontained spheres should lie opposite the bounding center", dir_dot < -0.95f); | ||
436 | } | ||
437 | */ | ||
438 | } | ||
439 | } | ||
440 | } | ||
441 | } | ||
442 | |||
443 | namespace tut | ||
444 | { | ||
445 | F32 SMALL_RADIUS = 1.0f; | ||
446 | F32 MEDIUM_RADIUS = 5.0f; | ||
447 | F32 LARGE_RADIUS = 10.0f; | ||
448 | |||
449 | struct line_data | ||
450 | { | ||
451 | }; | ||
452 | typedef test_group<line_data> line_test; | ||
453 | typedef line_test::object line_object; | ||
454 | tut::line_test tline("LLLine"); | ||
455 | |||
456 | template<> template<> | ||
457 | void line_object::test<1>() | ||
458 | { | ||
459 | // this is a test for LLLine::intersects(point) which returns TRUE | ||
460 | // if the line passes within some tolerance of point | ||
461 | |||
462 | // these tests will have some floating point error, | ||
463 | // so we need to specify how much error is ok | ||
464 | F32 allowable_relative_error = 0.00001f; | ||
465 | S32 number_of_tests = 100; | ||
466 | for (S32 test = 0; test < number_of_tests; ++test) | ||
467 | { | ||
468 | // generate some random point to be on the line | ||
469 | LLVector3 point_on_line( ll_frand(2.f) - 1.f, | ||
470 | ll_frand(2.f) - 1.f, | ||
471 | ll_frand(2.f) - 1.f); | ||
472 | point_on_line.normalize(); | ||
473 | point_on_line *= ll_frand(LARGE_RADIUS); | ||
474 | |||
475 | // generate some random point to "intersect" | ||
476 | LLVector3 random_direction ( ll_frand(2.f) - 1.f, | ||
477 | ll_frand(2.f) - 1.f, | ||
478 | ll_frand(2.f) - 1.f); | ||
479 | random_direction.normalize(); | ||
480 | |||
481 | LLVector3 random_offset( ll_frand(2.f) - 1.f, | ||
482 | ll_frand(2.f) - 1.f, | ||
483 | ll_frand(2.f) - 1.f); | ||
484 | random_offset.normalize(); | ||
485 | random_offset *= ll_frand(SMALL_RADIUS); | ||
486 | |||
487 | LLVector3 point = point_on_line + MEDIUM_RADIUS * random_direction | ||
488 | + random_offset; | ||
489 | |||
490 | // compute the axis of approach (a unit vector between the points) | ||
491 | LLVector3 axis_of_approach = point - point_on_line; | ||
492 | axis_of_approach.normalize(); | ||
493 | |||
494 | // compute the direction of the the first line (perp to axis_of_approach) | ||
495 | LLVector3 first_dir( ll_frand(2.f) - 1.f, | ||
496 | ll_frand(2.f) - 1.f, | ||
497 | ll_frand(2.f) - 1.f); | ||
498 | first_dir.normalize(); | ||
499 | F32 dot = first_dir * axis_of_approach; | ||
500 | first_dir -= dot * axis_of_approach; // subtract component parallel to axis | ||
501 | first_dir.normalize(); | ||
502 | |||
503 | // construct the line | ||
504 | LLVector3 another_point_on_line = point_on_line + ll_frand(LARGE_RADIUS) * first_dir; | ||
505 | LLLine line(another_point_on_line, point_on_line); | ||
506 | |||
507 | // test that the intersection point is within MEDIUM_RADIUS + SMALL_RADIUS | ||
508 | F32 test_radius = MEDIUM_RADIUS + SMALL_RADIUS; | ||
509 | test_radius += (LARGE_RADIUS * allowable_relative_error); | ||
510 | ensure("line should pass near intersection point", line.intersects(point, test_radius)); | ||
511 | |||
512 | test_radius = allowable_relative_error * (point - point_on_line).length(); | ||
513 | ensure("line should intersect point used to define it", line.intersects(point_on_line, test_radius)); | ||
514 | } | ||
515 | } | ||
516 | |||
517 | template<> template<> | ||
518 | void line_object::test<2>() | ||
519 | { | ||
520 | // this is a test for LLLine::nearestApproach(LLLIne) method | ||
521 | // which computes the point on a line nearest another line | ||
522 | |||
523 | // these tests will have some floating point error, | ||
524 | // so we need to specify how much error is ok | ||
525 | // TODO -- make nearestApproach() algorithm more accurate so | ||
526 | // we can tighten the allowable_error. Most tests are tighter | ||
527 | // than one milimeter, however when doing randomized testing | ||
528 | // you can walk into inaccurate cases. | ||
529 | F32 allowable_relative_error = 0.001f; | ||
530 | S32 number_of_tests = 100; | ||
531 | for (S32 test = 0; test < number_of_tests; ++test) | ||
532 | { | ||
533 | // generate two points to be our known nearest approaches | ||
534 | LLVector3 some_point( ll_frand(2.f) - 1.f, | ||
535 | ll_frand(2.f) - 1.f, | ||
536 | ll_frand(2.f) - 1.f); | ||
537 | some_point.normalize(); | ||
538 | some_point *= ll_frand(LARGE_RADIUS); | ||
539 | |||
540 | LLVector3 another_point( ll_frand(2.f) - 1.f, | ||
541 | ll_frand(2.f) - 1.f, | ||
542 | ll_frand(2.f) - 1.f); | ||
543 | another_point.normalize(); | ||
544 | another_point *= ll_frand(LARGE_RADIUS); | ||
545 | |||
546 | // compute the axis of approach (a unit vector between the points) | ||
547 | LLVector3 axis_of_approach = another_point - some_point; | ||
548 | axis_of_approach.normalize(); | ||
549 | |||
550 | // compute the direction of the the first line (perp to axis_of_approach) | ||
551 | LLVector3 first_dir( ll_frand(2.f) - 1.f, | ||
552 | ll_frand(2.f) - 1.f, | ||
553 | ll_frand(2.f) - 1.f); | ||
554 | F32 dot = first_dir * axis_of_approach; | ||
555 | first_dir -= dot * axis_of_approach; // subtract component parallel to axis | ||
556 | first_dir.normalize(); // normalize | ||
557 | |||
558 | // compute the direction of the the second line | ||
559 | LLVector3 second_dir( ll_frand(2.f) - 1.f, | ||
560 | ll_frand(2.f) - 1.f, | ||
561 | ll_frand(2.f) - 1.f); | ||
562 | dot = second_dir * axis_of_approach; | ||
563 | second_dir -= dot * axis_of_approach; | ||
564 | second_dir.normalize(); | ||
565 | |||
566 | // make sure the lines aren't too parallel, | ||
567 | dot = fabsf(first_dir * second_dir); | ||
568 | if (dot > 0.99f) | ||
569 | { | ||
570 | // skip this test, we're not interested in testing | ||
571 | // the intractible cases | ||
572 | continue; | ||
573 | } | ||
574 | |||
575 | // construct the lines | ||
576 | LLVector3 first_point = some_point + ll_frand(LARGE_RADIUS) * first_dir; | ||
577 | LLLine first_line(first_point, some_point); | ||
578 | |||
579 | LLVector3 second_point = another_point + ll_frand(LARGE_RADIUS) * second_dir; | ||
580 | LLLine second_line(second_point, another_point); | ||
581 | |||
582 | // compute the points of nearest approach | ||
583 | LLVector3 some_computed_point = first_line.nearestApproach(second_line); | ||
584 | LLVector3 another_computed_point = second_line.nearestApproach(first_line); | ||
585 | |||
586 | // compute the error | ||
587 | F32 first_error = (some_point - some_computed_point).length(); | ||
588 | F32 scale = llmax((some_point - another_point).length(), some_point.length()); | ||
589 | scale = llmax(scale, another_point.length()); | ||
590 | scale = llmax(scale, 1.f); | ||
591 | F32 first_relative_error = first_error / scale; | ||
592 | |||
593 | F32 second_error = (another_point - another_computed_point).length(); | ||
594 | F32 second_relative_error = second_error / scale; | ||
595 | |||
596 | //if (first_relative_error > allowable_relative_error) | ||
597 | //{ | ||
598 | // std::cout << "first_error = " << first_error | ||
599 | // << " first_relative_error = " << first_relative_error | ||
600 | // << " scale = " << scale | ||
601 | // << " dir_dot = " << (first_dir * second_dir) | ||
602 | // << std::endl; | ||
603 | //} | ||
604 | //if (second_relative_error > allowable_relative_error) | ||
605 | //{ | ||
606 | // std::cout << "second_error = " << second_error | ||
607 | // << " second_relative_error = " << second_relative_error | ||
608 | // << " scale = " << scale | ||
609 | // << " dist = " << (some_point - another_point).length() | ||
610 | // << " dir_dot = " << (first_dir * second_dir) | ||
611 | // << std::endl; | ||
612 | //} | ||
613 | |||
614 | // test that the errors are small | ||
615 | ensure("first line should accurately compute its closest approach", | ||
616 | first_relative_error <= allowable_relative_error); | ||
617 | ensure("second line should accurately compute its closest approach", | ||
618 | second_relative_error <= allowable_relative_error); | ||
619 | } | ||
620 | } | ||
621 | |||
622 | F32 ALMOST_PARALLEL = 0.99f; | ||
623 | template<> template<> | ||
624 | void line_object::test<3>() | ||
625 | { | ||
626 | // this is a test for LLLine::getIntersectionBetweenTwoPlanes() method | ||
627 | |||
628 | // first some known tests | ||
629 | LLLine xy_plane(LLVector3(0.f, 0.f, 2.f), LLVector3(0.f, 0.f, 3.f)); | ||
630 | LLLine yz_plane(LLVector3(2.f, 0.f, 0.f), LLVector3(3.f, 0.f, 0.f)); | ||
631 | LLLine zx_plane(LLVector3(0.f, 2.f, 0.f), LLVector3(0.f, 3.f, 0.f)); | ||
632 | |||
633 | LLLine x_line; | ||
634 | LLLine y_line; | ||
635 | LLLine z_line; | ||
636 | |||
637 | bool x_success = LLLine::getIntersectionBetweenTwoPlanes(x_line, xy_plane, zx_plane); | ||
638 | bool y_success = LLLine::getIntersectionBetweenTwoPlanes(y_line, yz_plane, xy_plane); | ||
639 | bool z_success = LLLine::getIntersectionBetweenTwoPlanes(z_line, zx_plane, yz_plane); | ||
640 | |||
641 | ensure("xy and zx planes should intersect", x_success); | ||
642 | ensure("yz and xy planes should intersect", y_success); | ||
643 | ensure("zx and yz planes should intersect", z_success); | ||
644 | |||
645 | LLVector3 direction = x_line.getDirection(); | ||
646 | ensure("x_line should be parallel to x_axis", fabs(direction.mV[VX]) == 1.f | ||
647 | && 0.f == direction.mV[VY] | ||
648 | && 0.f == direction.mV[VZ] ); | ||
649 | direction = y_line.getDirection(); | ||
650 | ensure("y_line should be parallel to y_axis", 0.f == direction.mV[VX] | ||
651 | && fabs(direction.mV[VY]) == 1.f | ||
652 | && 0.f == direction.mV[VZ] ); | ||
653 | direction = z_line.getDirection(); | ||
654 | ensure("z_line should be parallel to z_axis", 0.f == direction.mV[VX] | ||
655 | && 0.f == direction.mV[VY] | ||
656 | && fabs(direction.mV[VZ]) == 1.f ); | ||
657 | |||
658 | // next some random tests | ||
659 | F32 allowable_relative_error = 0.0001f; | ||
660 | S32 number_of_tests = 20; | ||
661 | for (S32 test = 0; test < number_of_tests; ++test) | ||
662 | { | ||
663 | // generate the known line | ||
664 | LLVector3 some_point( ll_frand(2.f) - 1.f, | ||
665 | ll_frand(2.f) - 1.f, | ||
666 | ll_frand(2.f) - 1.f); | ||
667 | some_point.normalize(); | ||
668 | some_point *= ll_frand(LARGE_RADIUS); | ||
669 | LLVector3 another_point( ll_frand(2.f) - 1.f, | ||
670 | ll_frand(2.f) - 1.f, | ||
671 | ll_frand(2.f) - 1.f); | ||
672 | another_point.normalize(); | ||
673 | another_point *= ll_frand(LARGE_RADIUS); | ||
674 | LLLine known_intersection(some_point, another_point); | ||
675 | |||
676 | // compute a plane that intersect the line | ||
677 | LLVector3 point_on_plane( ll_frand(2.f) - 1.f, | ||
678 | ll_frand(2.f) - 1.f, | ||
679 | ll_frand(2.f) - 1.f); | ||
680 | point_on_plane.normalize(); | ||
681 | point_on_plane *= ll_frand(LARGE_RADIUS); | ||
682 | LLVector3 plane_normal = (point_on_plane - some_point) % known_intersection.getDirection(); | ||
683 | plane_normal.normalize(); | ||
684 | LLLine first_plane(point_on_plane, point_on_plane + plane_normal); | ||
685 | |||
686 | // compute a different plane that intersect the line | ||
687 | LLVector3 point_on_different_plane( ll_frand(2.f) - 1.f, | ||
688 | ll_frand(2.f) - 1.f, | ||
689 | ll_frand(2.f) - 1.f); | ||
690 | point_on_different_plane.normalize(); | ||
691 | point_on_different_plane *= ll_frand(LARGE_RADIUS); | ||
692 | LLVector3 different_plane_normal = (point_on_different_plane - another_point) % known_intersection.getDirection(); | ||
693 | different_plane_normal.normalize(); | ||
694 | LLLine second_plane(point_on_different_plane, point_on_different_plane + different_plane_normal); | ||
695 | |||
696 | if (fabs(plane_normal * different_plane_normal) > ALMOST_PARALLEL) | ||
697 | { | ||
698 | // the two planes are approximately parallel, so we won't test this case | ||
699 | continue; | ||
700 | } | ||
701 | |||
702 | LLLine measured_intersection; | ||
703 | bool success = LLLine::getIntersectionBetweenTwoPlanes( | ||
704 | measured_intersection, | ||
705 | first_plane, | ||
706 | second_plane); | ||
707 | |||
708 | ensure("plane intersection should succeed", success); | ||
709 | |||
710 | F32 dot = fabs(known_intersection.getDirection() * measured_intersection.getDirection()); | ||
711 | ensure("measured intersection should be parallel to known intersection", | ||
712 | dot > ALMOST_PARALLEL); | ||
713 | |||
714 | ensure("measured intersection should pass near known point", | ||
715 | measured_intersection.intersects(some_point, LARGE_RADIUS * allowable_relative_error)); | ||
716 | } | ||
717 | } | ||
718 | } | ||
719 | |||
diff --git a/linden/indra/test/message_tut.cpp b/linden/indra/test/message_tut.cpp index 60a249c..b619d38 100644 --- a/linden/indra/test/message_tut.cpp +++ b/linden/indra/test/message_tut.cpp | |||
@@ -62,7 +62,7 @@ namespace tut | |||
62 | if(! init) | 62 | if(! init) |
63 | { | 63 | { |
64 | ll_init_apr(); | 64 | ll_init_apr(); |
65 | init_prehash_data(); | 65 | //init_prehash_data(); |
66 | init = true; | 66 | init = true; |
67 | } | 67 | } |
68 | 68 | ||
diff --git a/linden/indra/test/prim_linkability_tut.cpp b/linden/indra/test/prim_linkability_tut.cpp new file mode 100644 index 0000000..c5f2958 --- /dev/null +++ b/linden/indra/test/prim_linkability_tut.cpp | |||
@@ -0,0 +1,490 @@ | |||
1 | /** | ||
2 | * @file linkability.cpp | ||
3 | * @author andrew@lindenlab.com | ||
4 | * @date 2007-04-23 | ||
5 | * @brief Tests for the LLPrimLinkInfo template which computes the linkability of prims | ||
6 | * | ||
7 | * $LicenseInfo:firstyear=2007&license=internal$ | ||
8 | * | ||
9 | * Copyright (c) 2007-2008, Linden Research, Inc. | ||
10 | * | ||
11 | * The following source code is PROPRIETARY AND CONFIDENTIAL. Use of | ||
12 | * this source code is governed by the Linden Lab Source Code Disclosure | ||
13 | * Agreement ("Agreement") previously entered between you and Linden | ||
14 | * Lab. By accessing, using, copying, modifying or distributing this | ||
15 | * software, you acknowledge that you have been informed of your | ||
16 | * obligations under the Agreement and agree to abide by those obligations. | ||
17 | * | ||
18 | * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO | ||
19 | * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, | ||
20 | * COMPLETENESS OR PERFORMANCE. | ||
21 | * $/LicenseInfo$ | ||
22 | */ | ||
23 | |||
24 | #include "linden_common.h" | ||
25 | #include "lltut.h" | ||
26 | #include "llprimlinkinfo.h" | ||
27 | #include "llrand.h" | ||
28 | |||
29 | |||
30 | // helper function | ||
31 | void randomize_sphere(LLSphere& sphere, F32 center_range, F32 radius_range) | ||
32 | { | ||
33 | F32 radius = ll_frand(2.f * radius_range) - radius_range; | ||
34 | LLVector3 center; | ||
35 | for (S32 i=0; i<3; ++i) | ||
36 | { | ||
37 | center.mV[i] = ll_frand(2.f * center_range) - center_range; | ||
38 | } | ||
39 | sphere.setRadius(radius); | ||
40 | sphere.setCenter(center); | ||
41 | } | ||
42 | |||
43 | // helper function. Same as above with a min and max radius. | ||
44 | void randomize_sphere(LLSphere& sphere, F32 center_range, F32 minimum_radius, F32 maximum_radius) | ||
45 | { | ||
46 | F32 radius = ll_frand(maximum_radius - minimum_radius) + minimum_radius; | ||
47 | LLVector3 center; | ||
48 | for (S32 i=0; i<3; ++i) | ||
49 | { | ||
50 | center.mV[i] = ll_frand(2.f * center_range) - center_range; | ||
51 | } | ||
52 | sphere.setRadius(radius); | ||
53 | sphere.setCenter(center); | ||
54 | } | ||
55 | |||
56 | // helper function | ||
57 | bool random_sort( const LLPrimLinkInfo< S32 >&, const LLPrimLinkInfo< S32 >& b) | ||
58 | { | ||
59 | return (ll_rand(64) < 32); | ||
60 | } | ||
61 | |||
62 | namespace tut | ||
63 | { | ||
64 | struct linkable_data | ||
65 | { | ||
66 | LLPrimLinkInfo<S32> info; | ||
67 | }; | ||
68 | |||
69 | typedef test_group<linkable_data> linkable_test; | ||
70 | typedef linkable_test::object linkable_object; | ||
71 | tut::linkable_test wtf("prim linkability"); | ||
72 | |||
73 | template<> template<> | ||
74 | void linkable_object::test<1>() | ||
75 | { | ||
76 | // Here we test the boundary of the LLPrimLinkInfo::canLink() method | ||
77 | // between semi-random middle-sized objects. | ||
78 | |||
79 | S32 number_of_tests = 100; | ||
80 | for (S32 test = 0; test < number_of_tests; ++test) | ||
81 | { | ||
82 | // compute the radii that would provide the above max link distance | ||
83 | F32 first_radius = 0.f; | ||
84 | F32 second_radius = 0.f; | ||
85 | |||
86 | // compute a random center for the first sphere | ||
87 | // compute some random max link distance | ||
88 | F32 max_link_span = ll_frand(MAX_OBJECT_SPAN); | ||
89 | if (max_link_span < OBJECT_SPAN_BONUS) | ||
90 | { | ||
91 | max_link_span += OBJECT_SPAN_BONUS; | ||
92 | } | ||
93 | LLVector3 first_center( | ||
94 | ll_frand(2.f * max_link_span) - max_link_span, | ||
95 | ll_frand(2.f * max_link_span) - max_link_span, | ||
96 | ll_frand(2.f * max_link_span) - max_link_span); | ||
97 | |||
98 | // put the second sphere at the right distance from the origin | ||
99 | // such that it is within the max_link_distance of the first | ||
100 | LLVector3 direction(ll_frand(2.f) - 1.f, ll_frand(2.f) - 1.f, ll_frand(2.f) - 1.f); | ||
101 | direction.normalize(); | ||
102 | F32 half_milimeter = 0.0005f; | ||
103 | LLVector3 second_center; | ||
104 | |||
105 | // max_span = 3 * (first_radius + second_radius) + OBJECT_SPAN_BONUS | ||
106 | // make sure they link at short distances | ||
107 | { | ||
108 | second_center = first_center + (OBJECT_SPAN_BONUS - half_milimeter) * direction; | ||
109 | LLPrimLinkInfo<S32> first_info(0, LLSphere(first_center, first_radius) ); | ||
110 | LLPrimLinkInfo<S32> second_info(1, LLSphere(second_center, second_radius) ); | ||
111 | ensure("these nearby objects should link", first_info.canLink(second_info) ); | ||
112 | } | ||
113 | |||
114 | // make sure they fail to link if we move them apart just a little bit | ||
115 | { | ||
116 | second_center = first_center + (OBJECT_SPAN_BONUS + half_milimeter) * direction; | ||
117 | LLPrimLinkInfo<S32> first_info(0, LLSphere(first_center, first_radius) ); | ||
118 | LLPrimLinkInfo<S32> second_info(1, LLSphere(second_center, second_radius) ); | ||
119 | ensure("these nearby objects should NOT link", !first_info.canLink(second_info) ); | ||
120 | } | ||
121 | |||
122 | // make sure the objects link or not at medium distances | ||
123 | { | ||
124 | first_radius = 0.3f * ll_frand(max_link_span - OBJECT_SPAN_BONUS); | ||
125 | |||
126 | // This is the exact second radius that will link at exactly our random max_link_distance | ||
127 | second_radius = ((max_link_span - OBJECT_SPAN_BONUS) / 3.f) - first_radius; | ||
128 | second_center = first_center + (max_link_span - first_radius - second_radius - half_milimeter) * direction; | ||
129 | |||
130 | LLPrimLinkInfo<S32> first_info(0, LLSphere(first_center, first_radius) ); | ||
131 | LLPrimLinkInfo<S32> second_info(1, LLSphere(second_center, second_radius) ); | ||
132 | |||
133 | ensure("these objects should link", first_info.canLink(second_info) ); | ||
134 | } | ||
135 | |||
136 | // make sure they fail to link if we move them apart just a little bit | ||
137 | { | ||
138 | // move the second sphere such that it is a little too far from the first | ||
139 | second_center += (2.f * half_milimeter) * direction; | ||
140 | LLPrimLinkInfo<S32> first_info(0, LLSphere(first_center, first_radius) ); | ||
141 | LLPrimLinkInfo<S32> second_info(1, LLSphere(second_center, second_radius) ); | ||
142 | |||
143 | ensure("these objects should NOT link", !first_info.canLink(second_info) ); | ||
144 | } | ||
145 | |||
146 | // make sure things don't link at far distances | ||
147 | { | ||
148 | second_center = first_center + (MAX_OBJECT_SPAN + 2.f * half_milimeter) * direction; | ||
149 | second_radius = 0.3f * MAX_OBJECT_SPAN; | ||
150 | LLPrimLinkInfo<S32> first_info(0, LLSphere(first_center, first_radius) ); | ||
151 | LLPrimLinkInfo<S32> second_info(1, LLSphere(second_center, second_radius) ); | ||
152 | ensure("these objects should NOT link", !first_info.canLink(second_info) ); | ||
153 | } | ||
154 | |||
155 | } | ||
156 | } | ||
157 | |||
158 | template<> template<> | ||
159 | void linkable_object::test<2>() | ||
160 | { | ||
161 | |||
162 | // Consider a row of eight spheres in a row, each 10m in diameter and centered | ||
163 | // at 10m intervals: 01234567. | ||
164 | |||
165 | F32 radius = 5.f; | ||
166 | F32 spacing = 10.f; | ||
167 | |||
168 | LLVector3 line_direction(ll_frand(2.f) - 1.f, ll_frand(2.f) - 1.f, ll_frand(2.f) - 1.f); | ||
169 | line_direction.normalize(); | ||
170 | |||
171 | LLVector3 first_center(ll_frand(2.f * spacing) -spacing, ll_frand(2.f * spacing) - spacing, ll_frand(2.f * spacing) - spacing); | ||
172 | |||
173 | LLPrimLinkInfo<S32> infos[8]; | ||
174 | |||
175 | for (S32 index = 0; index < 8; ++index) | ||
176 | { | ||
177 | LLVector3 center = first_center + ((F32)(index) * spacing) * line_direction; | ||
178 | infos[index].set(index, LLSphere(center, radius)); | ||
179 | } | ||
180 | |||
181 | // Max span for 2 spheres of 5m radius is 3 * (5 + 5) + 1 = 31m | ||
182 | // spheres 0&2 have a 30m span (from outside edge to outside edge) and should link | ||
183 | { | ||
184 | LLPrimLinkInfo<S32> root_info = infos[0]; | ||
185 | std::list< LLPrimLinkInfo<S32> > info_list; | ||
186 | info_list.push_back(infos[2]); | ||
187 | root_info.mergeLinkableSet(info_list); | ||
188 | S32 prim_count = root_info.getPrimCount(); | ||
189 | ensure_equals("0&2 prim count should be 2", prim_count, 2); | ||
190 | ensure_equals("0&2 unlinkable list should have length 0", (S32) info_list.size(), 0); | ||
191 | } | ||
192 | |||
193 | |||
194 | // spheres 0&3 have a 40 meter span and should NOT link outright | ||
195 | { | ||
196 | LLPrimLinkInfo<S32> root_info = infos[0]; | ||
197 | std::list< LLPrimLinkInfo<S32> > info_list; | ||
198 | info_list.push_back(infos[3]); | ||
199 | root_info.mergeLinkableSet(info_list); | ||
200 | S32 prim_count = root_info.getPrimCount(); | ||
201 | ensure_equals("0&4 prim count should be 1", prim_count, 1); | ||
202 | ensure_equals("0&4 unlinkable list should have length 1", (S32) info_list.size(), 1); | ||
203 | } | ||
204 | |||
205 | |||
206 | // spheres 0-4 should link no matter what order : 01234 | ||
207 | // Total span = 50m, 012 link with a r=15.5 giving max span of 3 * (15.5 + 5) + 1 = 62.5, but the cap is 54m | ||
208 | { | ||
209 | LLPrimLinkInfo<S32> root_info = infos[0]; | ||
210 | std::list< LLPrimLinkInfo<S32> > info_list; | ||
211 | for (S32 index = 1; index < 5; ++index) | ||
212 | { | ||
213 | info_list.push_back(infos[index]); | ||
214 | } | ||
215 | root_info.mergeLinkableSet(info_list); | ||
216 | S32 prim_count = root_info.getPrimCount(); | ||
217 | ensure_equals("01234 prim count should be 5", prim_count, 5); | ||
218 | ensure_equals("01234 unlinkable list should have length 0", (S32) info_list.size(), 0); | ||
219 | } | ||
220 | |||
221 | |||
222 | // spheres 0-5 should link no matter what order : 04321 | ||
223 | { | ||
224 | LLPrimLinkInfo<S32> root_info = infos[0]; | ||
225 | std::list< LLPrimLinkInfo<S32> > info_list; | ||
226 | for (S32 index = 4; index > 0; --index) | ||
227 | { | ||
228 | info_list.push_back(infos[index]); | ||
229 | } | ||
230 | root_info.mergeLinkableSet(info_list); | ||
231 | S32 prim_count = root_info.getPrimCount(); | ||
232 | ensure_equals("04321 prim count should be 5", prim_count, 5); | ||
233 | ensure_equals("04321 unlinkable list should have length 0", (S32) info_list.size(), 0); | ||
234 | } | ||
235 | |||
236 | // spheres 0-4 should link no matter what order : 01423 | ||
237 | { | ||
238 | LLPrimLinkInfo<S32> root_info = infos[0]; | ||
239 | std::list< LLPrimLinkInfo<S32> > info_list; | ||
240 | info_list.push_back(infos[1]); | ||
241 | info_list.push_back(infos[4]); | ||
242 | info_list.push_back(infos[2]); | ||
243 | info_list.push_back(infos[3]); | ||
244 | root_info.mergeLinkableSet(info_list); | ||
245 | S32 prim_count = root_info.getPrimCount(); | ||
246 | ensure_equals("01423 prim count should be 5", prim_count, 5); | ||
247 | ensure_equals("01423 unlinkable list should have length 0", (S32) info_list.size(), 0); | ||
248 | } | ||
249 | |||
250 | // spheres 0-5 should NOT fully link, only 0-4 | ||
251 | { | ||
252 | LLPrimLinkInfo<S32> root_info = infos[0]; | ||
253 | std::list< LLPrimLinkInfo<S32> > info_list; | ||
254 | for (S32 index = 1; index < 6; ++index) | ||
255 | { | ||
256 | info_list.push_back(infos[index]); | ||
257 | } | ||
258 | root_info.mergeLinkableSet(info_list); | ||
259 | S32 prim_count = root_info.getPrimCount(); | ||
260 | ensure_equals("012345 prim count should be 5", prim_count, 5); | ||
261 | ensure_equals("012345 unlinkable list should have length 1", (S32) info_list.size(), 1); | ||
262 | std::list< LLPrimLinkInfo<S32> >::iterator info_itr = info_list.begin(); | ||
263 | if (info_itr != info_list.end()) | ||
264 | { | ||
265 | // examine the contents of the unlinked info | ||
266 | std::list<S32> unlinked_indecies; | ||
267 | info_itr->getData(unlinked_indecies); | ||
268 | // make sure there is only one index in the unlinked_info | ||
269 | ensure_equals("012345 unlinkable index count should be 1", (S32) unlinked_indecies.size(), 1); | ||
270 | // make sure its value is 6 | ||
271 | std::list<S32>::iterator unlinked_index_itr = unlinked_indecies.begin(); | ||
272 | S32 unlinkable_index = *unlinked_index_itr; | ||
273 | ensure_equals("012345 unlinkable index should be 5", (S32) unlinkable_index, 5); | ||
274 | } | ||
275 | } | ||
276 | |||
277 | // spheres 0-7 should NOT fully link, only 0-5 | ||
278 | { | ||
279 | LLPrimLinkInfo<S32> root_info = infos[0]; | ||
280 | std::list< LLPrimLinkInfo<S32> > info_list; | ||
281 | for (S32 index = 1; index < 8; ++index) | ||
282 | { | ||
283 | info_list.push_back(infos[index]); | ||
284 | } | ||
285 | root_info.mergeLinkableSet(info_list); | ||
286 | S32 prim_count = root_info.getPrimCount(); | ||
287 | ensure_equals("01234567 prim count should be 5", prim_count, 5); | ||
288 | // Should be 1 linkinfo on unlinkable that has 2 prims | ||
289 | ensure_equals("01234567 unlinkable list should have length 1", (S32) info_list.size(), 1); | ||
290 | std::list< LLPrimLinkInfo<S32> >::iterator info_itr = info_list.begin(); | ||
291 | if (info_itr != info_list.end()) | ||
292 | { | ||
293 | // make sure there is only one index in the unlinked_info | ||
294 | std::list<S32> unlinked_indecies; | ||
295 | info_itr->getData(unlinked_indecies); | ||
296 | ensure_equals("0123456 unlinkable index count should be 3", (S32) unlinked_indecies.size(), 3); | ||
297 | |||
298 | // make sure its values are 6 and 7 | ||
299 | std::list<S32>::iterator unlinked_index_itr = unlinked_indecies.begin(); | ||
300 | S32 unlinkable_index = *unlinked_index_itr; | ||
301 | ensure_equals("0123456 first unlinkable index should be 5", (S32) unlinkable_index, 5); | ||
302 | ++unlinked_index_itr; | ||
303 | unlinkable_index = *unlinked_index_itr; | ||
304 | ensure_equals("0123456 second unlinkable index should be 6", (S32) unlinkable_index, 6); | ||
305 | ++unlinked_index_itr; | ||
306 | unlinkable_index = *unlinked_index_itr; | ||
307 | ensure_equals("0123456 third unlinkable index should be 7", (S32) unlinkable_index, 7); | ||
308 | |||
309 | } | ||
310 | } | ||
311 | } | ||
312 | |||
313 | template<> template<> | ||
314 | void linkable_object::test<3>() | ||
315 | { | ||
316 | // Here we test the link results between an LLPrimLinkInfo and a set of | ||
317 | // randomized LLPrimLinkInfos where the expected results are known. | ||
318 | S32 number_of_tests = 5; | ||
319 | for (S32 test = 0; test < number_of_tests; ++test) | ||
320 | { | ||
321 | // the radii are known | ||
322 | F32 first_radius = 1.f; | ||
323 | F32 second_radius = 2.f; | ||
324 | F32 third_radius = 3.f; | ||
325 | |||
326 | // compute the distances | ||
327 | F32 half_milimeter = 0.0005f; | ||
328 | F32 max_first_second_span = 3.f * (first_radius + second_radius) + OBJECT_SPAN_BONUS; | ||
329 | F32 linkable_distance = max_first_second_span - first_radius - second_radius - half_milimeter; | ||
330 | |||
331 | F32 max_full_span = 3.f * (0.5f * max_first_second_span + third_radius) + OBJECT_SPAN_BONUS; | ||
332 | F32 unlinkable_distance = max_full_span - 0.5f * linkable_distance - third_radius + half_milimeter; | ||
333 | |||
334 | // compute some random directions | ||
335 | LLVector3 first_direction(ll_frand(2.f) - 1.f, ll_frand(2.f) - 1.f, ll_frand(2.f) - 1.f); | ||
336 | first_direction.normalize(); | ||
337 | LLVector3 second_direction(ll_frand(2.f) - 1.f, ll_frand(2.f) - 1.f, ll_frand(2.f) - 1.f); | ||
338 | second_direction.normalize(); | ||
339 | LLVector3 third_direction(ll_frand(2.f) - 1.f, ll_frand(2.f) - 1.f, ll_frand(2.f) - 1.f); | ||
340 | third_direction.normalize(); | ||
341 | |||
342 | // compute the centers | ||
343 | LLVector3 first_center = ll_frand(10.f) * first_direction; | ||
344 | LLVector3 second_center = first_center + ll_frand(linkable_distance) * second_direction; | ||
345 | LLVector3 first_join_center = 0.5f * (first_center + second_center); | ||
346 | LLVector3 third_center = first_join_center + unlinkable_distance * third_direction; | ||
347 | |||
348 | // make sure the second info links and the third does not | ||
349 | { | ||
350 | // initialize the infos | ||
351 | S32 index = 0; | ||
352 | LLPrimLinkInfo<S32> first_info(index++, LLSphere(first_center, first_radius)); | ||
353 | LLPrimLinkInfo<S32> second_info(index++, LLSphere(second_center, second_radius)); | ||
354 | LLPrimLinkInfo<S32> third_info(index++, LLSphere(third_center, third_radius)); | ||
355 | |||
356 | // put the second and third infos in a list | ||
357 | std::list< LLPrimLinkInfo<S32> > info_list; | ||
358 | info_list.push_back(second_info); | ||
359 | info_list.push_back(third_info); | ||
360 | |||
361 | // merge the list with the first_info | ||
362 | first_info.mergeLinkableSet(info_list); | ||
363 | S32 prim_count = first_info.getPrimCount(); | ||
364 | |||
365 | ensure_equals("prim count should be 2", prim_count, 2); | ||
366 | ensure_equals("unlinkable list should have length 1", (S32) info_list.size(), 1); | ||
367 | } | ||
368 | |||
369 | // reverse the order and make sure we get the same results | ||
370 | { | ||
371 | // initialize the infos | ||
372 | S32 index = 0; | ||
373 | LLPrimLinkInfo<S32> first_info(index++, LLSphere(first_center, first_radius)); | ||
374 | LLPrimLinkInfo<S32> second_info(index++, LLSphere(second_center, second_radius)); | ||
375 | LLPrimLinkInfo<S32> third_info(index++, LLSphere(third_center, third_radius)); | ||
376 | |||
377 | // build the list in the reverse order | ||
378 | std::list< LLPrimLinkInfo<S32> > info_list; | ||
379 | info_list.push_back(third_info); | ||
380 | info_list.push_back(second_info); | ||
381 | |||
382 | // merge the list with the first_info | ||
383 | first_info.mergeLinkableSet(info_list); | ||
384 | S32 prim_count = first_info.getPrimCount(); | ||
385 | |||
386 | ensure_equals("prim count should be 2", prim_count, 2); | ||
387 | ensure_equals("unlinkable list should have length 1", (S32) info_list.size(), 1); | ||
388 | } | ||
389 | } | ||
390 | } | ||
391 | |||
392 | template<> template<> | ||
393 | void linkable_object::test<4>() | ||
394 | { | ||
395 | // Here we test whether linkability is invarient under permutations | ||
396 | // of link order. To do this we generate a bunch of random spheres | ||
397 | // and then try to link them in different ways. | ||
398 | // | ||
399 | // NOTE: the linkability will only be invarient if there is only one | ||
400 | // linkable solution. Multiple solutions will exist if the set of | ||
401 | // candidates are larger than the maximum linkable distance, or more | ||
402 | // numerous than a single linked object can contain. This is easily | ||
403 | // understood by considering a very large set of link candidates, | ||
404 | // and first linking preferentially to the left until linking fails, | ||
405 | // then doing the same to the right -- the final solutions will differ. | ||
406 | // Hence for this test we must generate candidate sets that lie within | ||
407 | // the linkability envelope of a single object. | ||
408 | // | ||
409 | // NOTE: a random set of objects will tend to either be totally linkable | ||
410 | // or totally not. That is, the random orientations that | ||
411 | |||
412 | F32 root_center_range = 0.f; | ||
413 | F32 min_prim_radius = 0.1f; | ||
414 | F32 max_prim_radius = 2.f; | ||
415 | |||
416 | // Linkability is min(MAX_OBJECT_SPAN,3 *( R1 + R2 ) + BONUS) | ||
417 | // 3 * (min_prim_radius + min_prim_radius) + OBJECT_SPAN_BONUS = 6 * min_prim_radius + OBJECT_SPAN_BONUS; | ||
418 | // Use .45 instead of .5 to gaurantee objects are within the minimum span. | ||
419 | F32 child_center_range = 0.45f * ( (6*min_prim_radius) + OBJECT_SPAN_BONUS ); | ||
420 | |||
421 | S32 number_of_tests = 100; | ||
422 | S32 number_of_spheres = 10; | ||
423 | S32 number_of_scrambles = 10; | ||
424 | S32 number_of_random_bubble_sorts = 10; | ||
425 | |||
426 | for (S32 test = 0; test < number_of_tests; ++test) | ||
427 | { | ||
428 | LLSphere sphere; | ||
429 | S32 sphere_index = 0; | ||
430 | |||
431 | // build the root piece | ||
432 | randomize_sphere(sphere, root_center_range, min_prim_radius, max_prim_radius); | ||
433 | info.set( sphere_index++, sphere ); | ||
434 | |||
435 | // build the unlinked pieces | ||
436 | std::list< LLPrimLinkInfo<S32> > info_list; | ||
437 | for (; sphere_index < number_of_spheres; ++sphere_index) | ||
438 | { | ||
439 | randomize_sphere(sphere, child_center_range, min_prim_radius, max_prim_radius); | ||
440 | LLPrimLinkInfo<S32> child_info( sphere_index, sphere ); | ||
441 | info_list.push_back(child_info); | ||
442 | } | ||
443 | |||
444 | // declare the variables used to store the results | ||
445 | std::list<S32> first_linked_list; | ||
446 | |||
447 | { | ||
448 | // the link attempt will modify our original info's, so we | ||
449 | // have to make copies of the originals for testing | ||
450 | LLPrimLinkInfo<S32> test_info( 0, LLSphere(info.getCenter(), 0.5f * info.getDiameter()) ); | ||
451 | std::list< LLPrimLinkInfo<S32> > test_list; | ||
452 | test_list.assign(info_list.begin(), info_list.end()); | ||
453 | |||
454 | // try to link | ||
455 | test_info.mergeLinkableSet(test_list); | ||
456 | |||
457 | ensure("All prims should link, but did not.",test_list.empty()); | ||
458 | |||
459 | // store the results | ||
460 | test_info.getData(first_linked_list); | ||
461 | first_linked_list.sort(); | ||
462 | } | ||
463 | |||
464 | // try to link the spheres in various random orders | ||
465 | for (S32 scramble = 0; scramble < number_of_scrambles; ++scramble) | ||
466 | { | ||
467 | LLPrimLinkInfo<S32> test_info(0, LLSphere(info.getCenter(), 0.5f * info.getDiameter()) ); | ||
468 | |||
469 | // scramble the order of the info_list | ||
470 | std::list< LLPrimLinkInfo<S32> > test_list; | ||
471 | test_list.assign(info_list.begin(), info_list.end()); | ||
472 | for (S32 i = 0; i < number_of_random_bubble_sorts; i++) | ||
473 | { | ||
474 | test_list.sort(random_sort); | ||
475 | } | ||
476 | |||
477 | // try to link | ||
478 | test_info.mergeLinkableSet(test_list); | ||
479 | |||
480 | // get the results | ||
481 | std::list<S32> linked_list; | ||
482 | test_info.getData(linked_list); | ||
483 | linked_list.sort(); | ||
484 | |||
485 | ensure_equals("linked set size should be order independent",linked_list.size(),first_linked_list.size()); | ||
486 | } | ||
487 | } | ||
488 | } | ||
489 | } | ||
490 | |||
diff --git a/linden/indra/test/test.vcproj b/linden/indra/test/test.vcproj index 4476c2e..f720d9a 100644 --- a/linden/indra/test/test.vcproj +++ b/linden/indra/test/test.vcproj | |||
@@ -20,7 +20,7 @@ | |||
20 | <Tool | 20 | <Tool |
21 | Name="VCCLCompilerTool" | 21 | Name="VCCLCompilerTool" |
22 | Optimization="0" | 22 | Optimization="0" |
23 | AdditionalIncludeDirectories="..\llcharacter;..\llcommon;..\lldatabase;..\llinventory;..\llmath;..\llmessage;..\llxml;"..\..\libraries\i686-win32\include";..\..\libraries\include" | 23 | AdditionalIncludeDirectories="..\;..\llcharacter;..\llcommon;..\lldatabase;..\llinventory;..\llmath;..\llmessage;..\llprimitive;..\llxml;"..\..\libraries\i686-win32\include";..\..\libraries\include" |
24 | PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;LL_WINDOWS;LL_DEBUG" | 24 | PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;LL_WINDOWS;LL_DEBUG" |
25 | MinimalRebuild="FALSE" | 25 | MinimalRebuild="FALSE" |
26 | BasicRuntimeChecks="3" | 26 | BasicRuntimeChecks="3" |
@@ -35,7 +35,7 @@ | |||
35 | <Tool | 35 | <Tool |
36 | Name="VCLinkerTool" | 36 | Name="VCLinkerTool" |
37 | AdditionalOptions="/FORCE:MULTIPLE" | 37 | AdditionalOptions="/FORCE:MULTIPLE" |
38 | AdditionalDependencies="advapi32.lib apr-1.lib aprutil-1.lib comdlg32.lib dinput8.lib dsound.lib dxerr8.lib dxguid.lib freetype.lib gdi32.lib glu32.lib jpeglib_6b.lib kernel32.lib libboost_regex-vc71-mt-s.lib libcurld.lib libeay32.lib libexpatMT.lib llcommon.lib llprimitive.lib llvfs.lib llxml.lib lscript_library.lib mswsock.lib netapi32.lib odbc32.lib odbccp32.lib ole32.lib oleaut32.lib opengl32.lib psapi.lib shell32.lib ssleay32.lib user32.lib Vfw32.lib winmm.lib winspool.lib ws2_32.lib xmlrpcepi.lib zlib.lib" | 38 | AdditionalDependencies="advapi32.lib apr-1.lib aprutil-1.lib comdlg32.lib dinput8.lib dsound.lib dxerr8.lib dxguid.lib freetype.lib gdi32.lib glu32.lib jpeglib_6b.lib kernel32.lib libboost_regex-vc71-mt-sgd-1_34_1.lib libcurld.lib libeay32.lib libexpatMT.lib llcommon.lib llphysics.lib llprimitive.lib llvfs.lib llxml.lib lscript_library.lib mswsock.lib netapi32.lib odbc32.lib odbccp32.lib ole32.lib oleaut32.lib opengl32.lib psapi.lib shell32.lib ssleay32.lib user32.lib Vfw32.lib winmm.lib winspool.lib ws2_32.lib xmlrpcepi.lib zlib.lib" |
39 | OutputFile="$(OutDir)/test.exe" | 39 | OutputFile="$(OutDir)/test.exe" |
40 | LinkIncremental="2" | 40 | LinkIncremental="2" |
41 | AdditionalLibraryDirectories=""../lib_$(ConfigurationName)/i686-win32";"../../libraries/i686-win32/lib_debug"" | 41 | AdditionalLibraryDirectories=""../lib_$(ConfigurationName)/i686-win32";"../../libraries/i686-win32/lib_debug"" |
@@ -74,7 +74,7 @@ | |||
74 | <Tool | 74 | <Tool |
75 | Name="VCCLCompilerTool" | 75 | Name="VCCLCompilerTool" |
76 | Optimization="0" | 76 | Optimization="0" |
77 | AdditionalIncludeDirectories="..\llcharacter;..\llcommon;..\lldatabase;..\llinventory;..\llmath;..\llmessage;..\llxml;"..\..\libraries\i686-win32\include";..\..\libraries\include" | 77 | AdditionalIncludeDirectories="..\;..\llcharacter;..\llcommon;..\lldatabase;..\llinventory;..\llmath;..\llmessage;..\llprimitive;..\llxml;"..\..\libraries\i686-win32\include";..\..\libraries\include" |
78 | PreprocessorDefinitions="WIN32;__WIN32;NDEBUG;_WINDOWS;LL_WINDOWS;LL_RELEASE;APR_DECLARE_STATIC;LL_HTTPD=1" | 78 | PreprocessorDefinitions="WIN32;__WIN32;NDEBUG;_WINDOWS;LL_WINDOWS;LL_RELEASE;APR_DECLARE_STATIC;LL_HTTPD=1" |
79 | MinimalRebuild="FALSE" | 79 | MinimalRebuild="FALSE" |
80 | BasicRuntimeChecks="3" | 80 | BasicRuntimeChecks="3" |
@@ -90,7 +90,7 @@ | |||
90 | <Tool | 90 | <Tool |
91 | Name="VCLinkerTool" | 91 | Name="VCLinkerTool" |
92 | AdditionalOptions="/FORCE:MULTIPLE" | 92 | AdditionalOptions="/FORCE:MULTIPLE" |
93 | AdditionalDependencies="advapi32.lib apr-1.lib aprutil-1.lib comdlg32.lib dinput8.lib dsound.lib dxerr8.lib dxguid.lib freetype.lib gdi32.lib glu32.lib jpeglib_6b.lib kernel32.lib libboost_regex-vc71-mt-s.lib libcurl.lib libeay32.lib libexpatMT.lib llcommon.lib llprimitive.lib llvfs.lib llxml.lib lscript_library.lib mswsock.lib netapi32.lib odbc32.lib odbccp32.lib ole32.lib oleaut32.lib opengl32.lib psapi.lib shell32.lib ssleay32.lib user32.lib Vfw32.lib winmm.lib winspool.lib ws2_32.lib xmlrpcepi.lib zlib.lib" | 93 | AdditionalDependencies="advapi32.lib apr-1.lib aprutil-1.lib comdlg32.lib dinput8.lib dsound.lib dxerr8.lib dxguid.lib freetype.lib gdi32.lib glu32.lib jpeglib_6b.lib kernel32.lib libboost_regex-vc71-mt-s-1_34_1.lib libcurl.lib libeay32.lib libexpatMT.lib llcommon.lib llphysics.lib llprimitive.lib llvfs.lib llxml.lib lscript_library.lib mswsock.lib netapi32.lib odbc32.lib odbccp32.lib ole32.lib oleaut32.lib opengl32.lib psapi.lib shell32.lib ssleay32.lib user32.lib Vfw32.lib winmm.lib winspool.lib ws2_32.lib xmlrpcepi.lib zlib.lib" |
94 | OutputFile="$(OutDir)/test.exe" | 94 | OutputFile="$(OutDir)/test.exe" |
95 | LinkIncremental="2" | 95 | LinkIncremental="2" |
96 | AdditionalLibraryDirectories=""../lib_$(ConfigurationName)/i686-win32";"../../libraries/i686-win32/lib_release"" | 96 | AdditionalLibraryDirectories=""../lib_$(ConfigurationName)/i686-win32";"../../libraries/i686-win32/lib_release"" |
@@ -130,7 +130,7 @@ | |||
130 | <Tool | 130 | <Tool |
131 | Name="VCCLCompilerTool" | 131 | Name="VCCLCompilerTool" |
132 | Optimization="0" | 132 | Optimization="0" |
133 | AdditionalIncludeDirectories="..\llcharacter;..\llcommon;..\lldatabase;..\llinventory;..\llmath;..\llmessage;..\llxml;"..\..\libraries\i686-win32\include";..\..\libraries\include" | 133 | AdditionalIncludeDirectories="..\;..\llcharacter;..\llcommon;..\lldatabase;..\llinventory;..\llmath;..\llmessage;..\llprimitive;..\llxml;"..\..\libraries\i686-win32\include";..\..\libraries\include" |
134 | PreprocessorDefinitions="WIN32;__WIN32;NDEBUG;_WINDOWS;LL_WINDOWS;LL_RELEASE;APR_DECLARE_STATIC;LL_HTTPD=1" | 134 | PreprocessorDefinitions="WIN32;__WIN32;NDEBUG;_WINDOWS;LL_WINDOWS;LL_RELEASE;APR_DECLARE_STATIC;LL_HTTPD=1" |
135 | MinimalRebuild="FALSE" | 135 | MinimalRebuild="FALSE" |
136 | BasicRuntimeChecks="3" | 136 | BasicRuntimeChecks="3" |
@@ -145,7 +145,7 @@ | |||
145 | Name="VCCustomBuildTool"/> | 145 | Name="VCCustomBuildTool"/> |
146 | <Tool | 146 | <Tool |
147 | Name="VCLinkerTool" | 147 | Name="VCLinkerTool" |
148 | AdditionalDependencies="advapi32.lib apr-1.lib aprutil-1.lib comdlg32.lib gdi32.lib jpeglib_6b.lib kernel32.lib libboost_regex-vc71-mt-s.lib libcurl.lib libeay32.lib libexpatMT.lib mswsock.lib netapi32.lib odbc32.lib odbccp32.lib ole32.lib oleaut32.lib psapi.lib shell32.lib ssleay32.lib user32.lib winmm.lib winspool.lib ws2_32.lib xmlrpcepi.lib zlib.lib" | 148 | AdditionalDependencies="advapi32.lib apr-1.lib aprutil-1.lib comdlg32.lib gdi32.lib jpeglib_6b.lib kernel32.lib libboost_regex-vc71-mt-s-1_34_1.lib libcurl.lib libeay32.lib libexpatMT.lib mswsock.lib netapi32.lib odbc32.lib odbccp32.lib ole32.lib oleaut32.lib psapi.lib shell32.lib ssleay32.lib user32.lib winmm.lib winspool.lib ws2_32.lib xmlrpcepi.lib zlib.lib" |
149 | OutputFile="$(OutDir)/test.exe" | 149 | OutputFile="$(OutDir)/test.exe" |
150 | LinkIncremental="2" | 150 | LinkIncremental="2" |
151 | AdditionalLibraryDirectories=""../lib_$(ConfigurationName)/i686-win32";"../../libraries/i686-win32/lib_release"" | 151 | AdditionalLibraryDirectories=""../lib_$(ConfigurationName)/i686-win32";"../../libraries/i686-win32/lib_release"" |
@@ -219,6 +219,9 @@ | |||
219 | RelativePath=".\lljoint_tut.cpp"> | 219 | RelativePath=".\lljoint_tut.cpp"> |
220 | </File> | 220 | </File> |
221 | <File | 221 | <File |
222 | RelativePath=".\llmessageconfig_tut.cpp"> | ||
223 | </File> | ||
224 | <File | ||
222 | RelativePath=".\llmime_tut.cpp"> | 225 | RelativePath=".\llmime_tut.cpp"> |
223 | </File> | 226 | </File> |
224 | <File | 227 | <File |
@@ -281,10 +284,14 @@ | |||
281 | <File | 284 | <File |
282 | RelativePath=".\lluuidhashmap_tut.cpp"> | 285 | RelativePath=".\lluuidhashmap_tut.cpp"> |
283 | </File> | 286 | </File> |
287 | |||
284 | <File | 288 | <File |
285 | RelativePath=".\math.cpp"> | 289 | RelativePath=".\math.cpp"> |
286 | </File> | 290 | </File> |
287 | <File | 291 | <File |
292 | RelativePath=".\prim_linkability_tut.cpp"> | ||
293 | </File> | ||
294 | <File | ||
288 | RelativePath=".\reflection_tut.cpp"> | 295 | RelativePath=".\reflection_tut.cpp"> |
289 | </File> | 296 | </File> |
290 | <File | 297 | <File |
diff --git a/linden/indra/test/test_vc8.vcproj b/linden/indra/test/test_vc8.vcproj index 2f607cb..6d47de8 100644 --- a/linden/indra/test/test_vc8.vcproj +++ b/linden/indra/test/test_vc8.vcproj | |||
@@ -65,7 +65,7 @@ | |||
65 | <Tool | 65 | <Tool |
66 | Name="VCLinkerTool" | 66 | Name="VCLinkerTool" |
67 | AdditionalOptions="/FORCE:MULTIPLE" | 67 | AdditionalOptions="/FORCE:MULTIPLE" |
68 | AdditionalDependencies="advapi32.lib apr-1.lib aprutil-1.lib comdlg32.lib dinput8.lib dsound.lib dxerr8.lib dxguid.lib freetype.lib gdi32.lib glu32.lib jpeglib_6b.lib kernel32.lib libboost_regex-vc80-mt-s.lib libcurl.lib libeay32.lib libexpatMT.lib llcommon.lib llprimitive.lib llvfs.lib llxml.lib lscript_library.lib mswsock.lib netapi32.lib odbc32.lib odbccp32.lib ole32.lib oleaut32.lib opengl32.lib shell32.lib ssleay32.lib user32.lib Vfw32.lib winmm.lib winspool.lib ws2_32.lib xmlrpcepi.lib zlib.lib" | 68 | AdditionalDependencies="advapi32.lib apr-1.lib aprutil-1.lib comdlg32.lib dinput8.lib dsound.lib dxerr8.lib dxguid.lib freetype.lib gdi32.lib glu32.lib jpeglib_6b.lib kernel32.lib libboost_regex-vc80-mt-sgd-1_34_1.lib libboost_signals-vc80-mt-sgd-1_34_1.lib libcurl.lib libeay32.lib libexpatMT.lib llcommon.lib llprimitive.lib llvfs.lib llxml.lib lscript_library.lib mswsock.lib netapi32.lib odbc32.lib odbccp32.lib ole32.lib oleaut32.lib opengl32.lib shell32.lib ssleay32.lib user32.lib Vfw32.lib winmm.lib winspool.lib ws2_32.lib xmlrpcepi.lib zlib.lib" |
69 | OutputFile="$(OutDir)/test.exe" | 69 | OutputFile="$(OutDir)/test.exe" |
70 | LinkIncremental="2" | 70 | LinkIncremental="2" |
71 | AdditionalLibraryDirectories=""../lib_$(ConfigurationName)/i686-win32";"../../libraries/i686-win32/lib_debug"" | 71 | AdditionalLibraryDirectories=""../lib_$(ConfigurationName)/i686-win32";"../../libraries/i686-win32/lib_debug"" |
@@ -155,7 +155,7 @@ | |||
155 | <Tool | 155 | <Tool |
156 | Name="VCLinkerTool" | 156 | Name="VCLinkerTool" |
157 | AdditionalOptions="/FORCE:MULTIPLE" | 157 | AdditionalOptions="/FORCE:MULTIPLE" |
158 | AdditionalDependencies="advapi32.lib apr-1.lib aprutil-1.lib comdlg32.lib dinput8.lib dsound.lib dxerr8.lib dxguid.lib freetype.lib gdi32.lib glu32.lib jpeglib_6b.lib kernel32.lib libboost_regex-vc80-mt-s.lib libcurl.lib libeay32.lib libexpatMT.lib llcommon.lib llprimitive.lib llvfs.lib llxml.lib lscript_library.lib mswsock.lib netapi32.lib odbc32.lib odbccp32.lib ole32.lib oleaut32.lib opengl32.lib shell32.lib ssleay32.lib user32.lib Vfw32.lib winmm.lib winspool.lib ws2_32.lib xmlrpcepi.lib zlib.lib" | 158 | AdditionalDependencies="advapi32.lib apr-1.lib aprutil-1.lib comdlg32.lib dinput8.lib dsound.lib dxerr8.lib dxguid.lib freetype.lib gdi32.lib glu32.lib jpeglib_6b.lib kernel32.lib libboost_regex-vc80-mt-s-1_34_1.lib libboost_signals-vc80-mt-s-1_34_1.lib libcurl.lib libeay32.lib libexpatMT.lib llcommon.lib llprimitive.lib llvfs.lib llxml.lib lscript_library.lib mswsock.lib netapi32.lib odbc32.lib odbccp32.lib ole32.lib oleaut32.lib opengl32.lib shell32.lib ssleay32.lib user32.lib Vfw32.lib winmm.lib winspool.lib ws2_32.lib xmlrpcepi.lib zlib.lib" |
159 | OutputFile="$(OutDir)/test.exe" | 159 | OutputFile="$(OutDir)/test.exe" |
160 | LinkIncremental="2" | 160 | LinkIncremental="2" |
161 | AdditionalLibraryDirectories=""../lib_$(ConfigurationName)/i686-win32";"../../libraries/i686-win32/lib_release"" | 161 | AdditionalLibraryDirectories=""../lib_$(ConfigurationName)/i686-win32";"../../libraries/i686-win32/lib_release"" |
@@ -243,7 +243,7 @@ | |||
243 | /> | 243 | /> |
244 | <Tool | 244 | <Tool |
245 | Name="VCLinkerTool" | 245 | Name="VCLinkerTool" |
246 | AdditionalDependencies="advapi32.lib apr-1.lib aprutil-1.lib comdlg32.lib dinput8.lib dsound.lib dxerr8.lib dxguid.lib freetype.lib gdi32.lib glu32.lib jpeglib_6b.lib kernel32.lib libboost_regex-vc80-mt-s.lib libcurl.lib libeay32.lib libexpatMT.lib llcommon.lib llprimitive.lib llvfs.lib llxml.lib lscript_library.lib mswsock.lib netapi32.lib odbc32.lib odbccp32.lib ole32.lib oleaut32.lib opengl32.lib shell32.lib ssleay32.lib user32.lib Vfw32.lib winmm.lib winspool.lib ws2_32.lib xmlrpcepi.lib zlib.lib" | 246 | AdditionalDependencies="advapi32.lib apr-1.lib aprutil-1.lib comdlg32.lib dinput8.lib dsound.lib dxerr8.lib dxguid.lib freetype.lib gdi32.lib glu32.lib jpeglib_6b.lib kernel32.lib libboost_regex-vc80-mt-s-1_34_1.lib libboost_signals-vc80-mt-s-1_34_1.lib libcurl.lib libeay32.lib libexpatMT.lib llcommon.lib llprimitive.lib llvfs.lib llxml.lib lscript_library.lib mswsock.lib netapi32.lib odbc32.lib odbccp32.lib ole32.lib oleaut32.lib opengl32.lib shell32.lib ssleay32.lib user32.lib Vfw32.lib winmm.lib winspool.lib ws2_32.lib xmlrpcepi.lib zlib.lib" |
247 | OutputFile="$(OutDir)/test.exe" | 247 | OutputFile="$(OutDir)/test.exe" |
248 | LinkIncremental="2" | 248 | LinkIncremental="2" |
249 | AdditionalLibraryDirectories=""../lib_$(ConfigurationName)/i686-win32";"../../libraries/i686-win32/lib_release"" | 249 | AdditionalLibraryDirectories=""../lib_$(ConfigurationName)/i686-win32";"../../libraries/i686-win32/lib_release"" |
diff --git a/linden/indra/test/test_vc9.vcproj b/linden/indra/test/test_vc9.vcproj index 7230df4..d7fcfae 100644 --- a/linden/indra/test/test_vc9.vcproj +++ b/linden/indra/test/test_vc9.vcproj | |||
@@ -242,7 +242,7 @@ | |||
242 | /> | 242 | /> |
243 | <Tool | 243 | <Tool |
244 | Name="VCLinkerTool" | 244 | Name="VCLinkerTool" |
245 | AdditionalDependencies="advapi32.lib apr-1.lib aprutil-1.lib comdlg32.lib dinput8.lib dsound.lib dxerr8.lib dxguid.lib freetype.lib gdi32.lib glu32.lib jpeglib_6b.lib kernel32.lib libboost_regex-vc80-mt-s.lib libcurl.lib libeay32.lib libexpatMT.lib llcommon.lib llprimitive.lib llvfs.lib llxml.lib lscript_library.lib mswsock.lib netapi32.lib odbc32.lib odbccp32.lib ole32.lib oleaut32.lib opengl32.lib shell32.lib ssleay32.lib user32.lib Vfw32.lib winmm.lib winspool.lib ws2_32.lib xmlrpcepi.lib zlib.lib" | 245 | AdditionalDependencies="advapi32.lib apr-1.lib aprutil-1.lib comdlg32.lib dinput8.lib dsound.lib dxerr.lib dxguid.lib freetype.lib gdi32.lib glu32.lib jpeglib_6b.lib kernel32.lib libboost_regex-vc80-mt-s.lib libcurl.lib libeay32.lib libexpatMT.lib llcommon.lib llprimitive.lib llvfs.lib llxml.lib lscript_library.lib mswsock.lib netapi32.lib odbc32.lib odbccp32.lib ole32.lib oleaut32.lib opengl32.lib shell32.lib ssleay32.lib user32.lib Vfw32.lib winmm.lib winspool.lib ws2_32.lib xmlrpcepi.lib zlib.lib" |
246 | OutputFile="$(OutDir)/test.exe" | 246 | OutputFile="$(OutDir)/test.exe" |
247 | LinkIncremental="2" | 247 | LinkIncremental="2" |
248 | AdditionalLibraryDirectories=""../lib_$(ConfigurationName)/i686-win32";"../../libraries/i686-win32/lib_release"" | 248 | AdditionalLibraryDirectories=""../lib_$(ConfigurationName)/i686-win32";"../../libraries/i686-win32/lib_release"" |