diff options
author | Jacek Antonelli | 2008-08-15 23:44:46 -0500 |
---|---|---|
committer | Jacek Antonelli | 2008-08-15 23:44:46 -0500 |
commit | 38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4 (patch) | |
tree | adca584755d22ca041a2dbfc35d4eca01f70b32c /linden/indra/llinventory/lllandmark.cpp | |
parent | README.txt (diff) | |
download | meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.zip meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.gz meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.bz2 meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.xz |
Second Life viewer sources 1.13.2.12
Diffstat (limited to 'linden/indra/llinventory/lllandmark.cpp')
-rw-r--r-- | linden/indra/llinventory/lllandmark.cpp | 277 |
1 files changed, 277 insertions, 0 deletions
diff --git a/linden/indra/llinventory/lllandmark.cpp b/linden/indra/llinventory/lllandmark.cpp new file mode 100644 index 0000000..bca64d1 --- /dev/null +++ b/linden/indra/llinventory/lllandmark.cpp | |||
@@ -0,0 +1,277 @@ | |||
1 | /** | ||
2 | * @file lllandmark.cpp | ||
3 | * @brief Landmark asset class | ||
4 | * | ||
5 | * Copyright (c) 2002-2007, Linden Research, Inc. | ||
6 | * | ||
7 | * The source code in this file ("Source Code") is provided by Linden Lab | ||
8 | * to you under the terms of the GNU General Public License, version 2.0 | ||
9 | * ("GPL"), unless you have obtained a separate licensing agreement | ||
10 | * ("Other License"), formally executed by you and Linden Lab. Terms of | ||
11 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | ||
12 | * online at http://secondlife.com/developers/opensource/gplv2 | ||
13 | * | ||
14 | * There are special exceptions to the terms and conditions of the GPL as | ||
15 | * it is applied to this Source Code. View the full text of the exception | ||
16 | * in the file doc/FLOSS-exception.txt in this software distribution, or | ||
17 | * online at http://secondlife.com/developers/opensource/flossexception | ||
18 | * | ||
19 | * By copying, modifying or distributing this software, you acknowledge | ||
20 | * that you have read and understood your obligations described above, | ||
21 | * and agree to abide by those obligations. | ||
22 | * | ||
23 | * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO | ||
24 | * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, | ||
25 | * COMPLETENESS OR PERFORMANCE. | ||
26 | */ | ||
27 | |||
28 | #include "linden_common.h" | ||
29 | #include "lllandmark.h" | ||
30 | |||
31 | #include <stdlib.h> | ||
32 | #include <string.h> | ||
33 | #include <errno.h> | ||
34 | #include <stdio.h> // for sscanf() on linux | ||
35 | |||
36 | #include "message.h" | ||
37 | #include "llregionhandle.h" | ||
38 | |||
39 | std::pair<LLUUID, U64> LLLandmark::mLocalRegion; | ||
40 | LLLandmark::region_map_t LLLandmark::mRegions; | ||
41 | LLLandmark::region_callback_t LLLandmark::mRegionCallback; | ||
42 | |||
43 | LLLandmark::LLLandmark() : | ||
44 | mGlobalPositionKnown(false) | ||
45 | { | ||
46 | } | ||
47 | |||
48 | LLLandmark::LLLandmark(const LLVector3d& pos) : | ||
49 | mGlobalPositionKnown(true), | ||
50 | mGlobalPos( pos ) | ||
51 | { | ||
52 | } | ||
53 | |||
54 | bool LLLandmark::getGlobalPos(LLVector3d& pos) | ||
55 | { | ||
56 | if(mGlobalPositionKnown) | ||
57 | { | ||
58 | pos = mGlobalPos; | ||
59 | } | ||
60 | else if(mRegionID.notNull()) | ||
61 | { | ||
62 | F32 g_x = -1.0; | ||
63 | F32 g_y = -1.0; | ||
64 | if(mRegionID == mLocalRegion.first) | ||
65 | { | ||
66 | from_region_handle(mLocalRegion.second, &g_x, &g_y); | ||
67 | } | ||
68 | else | ||
69 | { | ||
70 | region_map_t::iterator it = mRegions.find(mRegionID); | ||
71 | if(it != mRegions.end()) | ||
72 | { | ||
73 | from_region_handle((*it).second.mRegionHandle, &g_x, &g_y); | ||
74 | } | ||
75 | } | ||
76 | if((g_x > 0.f) && (g_y > 0.f)) | ||
77 | { | ||
78 | pos.mdV[0] = g_x + mRegionPos.mV[0]; | ||
79 | pos.mdV[1] = g_y + mRegionPos.mV[1]; | ||
80 | pos.mdV[2] = mRegionPos.mV[2]; | ||
81 | setGlobalPos(pos); | ||
82 | } | ||
83 | } | ||
84 | return mGlobalPositionKnown; | ||
85 | } | ||
86 | |||
87 | void LLLandmark::setGlobalPos(const LLVector3d& pos) | ||
88 | { | ||
89 | mGlobalPos = pos; | ||
90 | mGlobalPositionKnown = true; | ||
91 | } | ||
92 | |||
93 | bool LLLandmark::getRegionID(LLUUID& region_id) | ||
94 | { | ||
95 | if(mRegionID.notNull()) | ||
96 | { | ||
97 | region_id = mRegionID; | ||
98 | return true; | ||
99 | } | ||
100 | return false; | ||
101 | } | ||
102 | |||
103 | LLVector3 LLLandmark::getRegionPos() const | ||
104 | { | ||
105 | return mRegionPos; | ||
106 | } | ||
107 | |||
108 | |||
109 | // static | ||
110 | LLLandmark* LLLandmark::constructFromString(const char *buffer) | ||
111 | { | ||
112 | const char* cur = buffer; | ||
113 | S32 chars_read = 0; | ||
114 | S32 count = 0; | ||
115 | U32 version = 0; | ||
116 | |||
117 | // read version | ||
118 | count = sscanf( cur, "Landmark version %u\n%n", &version, &chars_read ); | ||
119 | if(count != 1) | ||
120 | { | ||
121 | goto error; | ||
122 | } | ||
123 | |||
124 | if(version == 1) | ||
125 | { | ||
126 | LLVector3d pos; | ||
127 | cur += chars_read; | ||
128 | // read position | ||
129 | count = sscanf( cur, "position %lf %lf %lf\n%n", pos.mdV+VX, pos.mdV+VY, pos.mdV+VZ, &chars_read ); | ||
130 | if( count != 3 ) | ||
131 | { | ||
132 | goto error; | ||
133 | } | ||
134 | cur += chars_read; | ||
135 | // llinfos << "Landmark read: " << pos << llendl; | ||
136 | |||
137 | return new LLLandmark(pos); | ||
138 | } | ||
139 | else if(version == 2) | ||
140 | { | ||
141 | char region_id_str[MAX_STRING]; | ||
142 | LLVector3 pos; | ||
143 | cur += chars_read; | ||
144 | count = sscanf(cur, "region_id %s\n%n", region_id_str, &chars_read); | ||
145 | if(count != 1) goto error; | ||
146 | cur += chars_read; | ||
147 | count = sscanf(cur, "local_pos %f %f %f\n%n", pos.mV+VX, pos.mV+VY, pos.mV+VZ, &chars_read); | ||
148 | if(count != 3) goto error; | ||
149 | cur += chars_read; | ||
150 | LLLandmark* lm = new LLLandmark; | ||
151 | lm->mRegionID.set(region_id_str); | ||
152 | lm->mRegionPos = pos; | ||
153 | return lm; | ||
154 | } | ||
155 | |||
156 | error: | ||
157 | llinfos << "Bad Landmark Asset: bad _DATA_ block." << llendl; | ||
158 | return NULL; | ||
159 | } | ||
160 | |||
161 | |||
162 | // static | ||
163 | void LLLandmark::registerCallbacks(LLMessageSystem* msg) | ||
164 | { | ||
165 | msg->setHandlerFunc("RegionIDAndHandleReply", &processRegionIDAndHandle); | ||
166 | } | ||
167 | |||
168 | // static | ||
169 | void LLLandmark::requestRegionHandle( | ||
170 | LLMessageSystem* msg, | ||
171 | const LLHost& upstream_host, | ||
172 | const LLUUID& region_id, | ||
173 | LLRegionHandleCallback* callback) | ||
174 | { | ||
175 | if(region_id.isNull()) | ||
176 | { | ||
177 | // don't bother with checking - it's 0. | ||
178 | lldebugs << "requestRegionHandle: null" << llendl; | ||
179 | if(callback) | ||
180 | { | ||
181 | const U64 U64_ZERO = 0; | ||
182 | callback->dataReady(region_id, U64_ZERO); | ||
183 | } | ||
184 | } | ||
185 | else | ||
186 | { | ||
187 | if(region_id == mLocalRegion.first) | ||
188 | { | ||
189 | lldebugs << "requestRegionHandle: local" << llendl; | ||
190 | if(callback) | ||
191 | { | ||
192 | callback->dataReady(region_id, mLocalRegion.second); | ||
193 | } | ||
194 | } | ||
195 | else | ||
196 | { | ||
197 | region_map_t::iterator it = mRegions.find(region_id); | ||
198 | if(it == mRegions.end()) | ||
199 | { | ||
200 | lldebugs << "requestRegionHandle: upstream" << llendl; | ||
201 | if(callback) | ||
202 | { | ||
203 | region_callback_t::value_type vt(region_id, callback); | ||
204 | mRegionCallback.insert(vt); | ||
205 | } | ||
206 | lldebugs << "Landmark requesting information about: " | ||
207 | << region_id << llendl; | ||
208 | msg->newMessage("RegionHandleRequest"); | ||
209 | msg->nextBlock("RequestBlock"); | ||
210 | msg->addUUID("RegionID", region_id); | ||
211 | msg->sendReliable(upstream_host); | ||
212 | } | ||
213 | else if(callback) | ||
214 | { | ||
215 | // we have the answer locally - just call the callack. | ||
216 | lldebugs << "requestRegionHandle: ready" << llendl; | ||
217 | callback->dataReady(region_id, (*it).second.mRegionHandle); | ||
218 | } | ||
219 | } | ||
220 | } | ||
221 | |||
222 | // As good a place as any to expire old entries. | ||
223 | expireOldEntries(); | ||
224 | } | ||
225 | |||
226 | // static | ||
227 | void LLLandmark::setRegionHandle(const LLUUID& region_id, U64 region_handle) | ||
228 | { | ||
229 | mLocalRegion.first = region_id; | ||
230 | mLocalRegion.second = region_handle; | ||
231 | } | ||
232 | |||
233 | |||
234 | // static | ||
235 | void LLLandmark::processRegionIDAndHandle(LLMessageSystem* msg, void**) | ||
236 | { | ||
237 | LLUUID region_id; | ||
238 | msg->getUUID("ReplyBlock", "RegionID", region_id); | ||
239 | mRegions.erase(region_id); | ||
240 | CacheInfo info; | ||
241 | const F32 CACHE_EXPIRY_SECONDS = 60.0f * 10.0f; // ten minutes | ||
242 | info.mTimer.setTimerExpirySec(CACHE_EXPIRY_SECONDS); | ||
243 | msg->getU64("ReplyBlock", "RegionHandle", info.mRegionHandle); | ||
244 | region_map_t::value_type vt(region_id, info); | ||
245 | mRegions.insert(vt); | ||
246 | |||
247 | #if LL_DEBUG | ||
248 | U32 grid_x, grid_y; | ||
249 | grid_from_region_handle(info.mRegionHandle, &grid_x, &grid_y); | ||
250 | lldebugs << "Landmark got reply for region: " << region_id << " " | ||
251 | << grid_x << "," << grid_y << llendl; | ||
252 | #endif | ||
253 | |||
254 | // make all the callbacks here. | ||
255 | region_callback_t::iterator it; | ||
256 | while((it = mRegionCallback.find(region_id)) != mRegionCallback.end()) | ||
257 | { | ||
258 | (*it).second->dataReady(region_id, info.mRegionHandle); | ||
259 | mRegionCallback.erase(it); | ||
260 | } | ||
261 | } | ||
262 | |||
263 | // static | ||
264 | void LLLandmark::expireOldEntries() | ||
265 | { | ||
266 | for(region_map_t::iterator it = mRegions.begin(); it != mRegions.end(); ) | ||
267 | { | ||
268 | if((*it).second.mTimer.hasExpired()) | ||
269 | { | ||
270 | mRegions.erase(it++); | ||
271 | } | ||
272 | else | ||
273 | { | ||
274 | ++it; | ||
275 | } | ||
276 | } | ||
277 | } | ||