aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/llinventory/lllandmark.cpp
diff options
context:
space:
mode:
authorJacek Antonelli2008-08-15 23:44:46 -0500
committerJacek Antonelli2008-08-15 23:44:46 -0500
commit38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4 (patch)
treeadca584755d22ca041a2dbfc35d4eca01f70b32c /linden/indra/llinventory/lllandmark.cpp
parentREADME.txt (diff)
downloadmeta-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.cpp277
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
39std::pair<LLUUID, U64> LLLandmark::mLocalRegion;
40LLLandmark::region_map_t LLLandmark::mRegions;
41LLLandmark::region_callback_t LLLandmark::mRegionCallback;
42
43LLLandmark::LLLandmark() :
44 mGlobalPositionKnown(false)
45{
46}
47
48LLLandmark::LLLandmark(const LLVector3d& pos) :
49 mGlobalPositionKnown(true),
50 mGlobalPos( pos )
51{
52}
53
54bool 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
87void LLLandmark::setGlobalPos(const LLVector3d& pos)
88{
89 mGlobalPos = pos;
90 mGlobalPositionKnown = true;
91}
92
93bool LLLandmark::getRegionID(LLUUID& region_id)
94{
95 if(mRegionID.notNull())
96 {
97 region_id = mRegionID;
98 return true;
99 }
100 return false;
101}
102
103LLVector3 LLLandmark::getRegionPos() const
104{
105 return mRegionPos;
106}
107
108
109// static
110LLLandmark* 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
163void LLLandmark::registerCallbacks(LLMessageSystem* msg)
164{
165 msg->setHandlerFunc("RegionIDAndHandleReply", &processRegionIDAndHandle);
166}
167
168// static
169void 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
227void 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
235void 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
264void 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}