diff options
author | McCabe Maxsted | 2010-09-23 16:29:24 -0700 |
---|---|---|
committer | McCabe Maxsted | 2010-09-23 16:29:24 -0700 |
commit | 8f7b8b0c853ce66d59b16f1c6f03192295bbb96c (patch) | |
tree | 053d5bc184a75e31bdd219c93a376dd479260691 /linden | |
parent | Added empty indra/cmake/CMakeLists.txt to suppress a CMake 2.8 warning. (diff) | |
parent | More sanity checks in OpenJPEG decodes for #355 (diff) | |
download | meta-impy-8f7b8b0c853ce66d59b16f1c6f03192295bbb96c.zip meta-impy-8f7b8b0c853ce66d59b16f1c6f03192295bbb96c.tar.gz meta-impy-8f7b8b0c853ce66d59b16f1c6f03192295bbb96c.tar.bz2 meta-impy-8f7b8b0c853ce66d59b16f1c6f03192295bbb96c.tar.xz |
Merge remote branch 'thickbrick/weekly' into weekly
Diffstat (limited to 'linden')
-rw-r--r-- | linden/indra/llimagej2coj/llimagej2coj.cpp | 45 | ||||
-rw-r--r-- | linden/indra/newview/chatbar_as_cmdline.cpp | 4 | ||||
-rw-r--r-- | linden/indra/newview/llagent.cpp | 81 | ||||
-rw-r--r-- | linden/indra/newview/llagent.h | 9 | ||||
-rw-r--r-- | linden/indra/newview/llviewermenu.cpp | 4 | ||||
-rwxr-xr-x | linden/indra/newview/llviewermessage.cpp | 8 |
6 files changed, 93 insertions, 58 deletions
diff --git a/linden/indra/llimagej2coj/llimagej2coj.cpp b/linden/indra/llimagej2coj/llimagej2coj.cpp index b7a1b82..829dceb 100644 --- a/linden/indra/llimagej2coj/llimagej2coj.cpp +++ b/linden/indra/llimagej2coj/llimagej2coj.cpp | |||
@@ -152,8 +152,13 @@ BOOL LLImageJ2COJ::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decod | |||
152 | /* open a byte stream */ | 152 | /* open a byte stream */ |
153 | cio = opj_cio_open((opj_common_ptr)dinfo, base.getData(), base.getDataSize()); | 153 | cio = opj_cio_open((opj_common_ptr)dinfo, base.getData(), base.getDataSize()); |
154 | 154 | ||
155 | /* decode the stream and fill the image structure */ | 155 | /* decode the stream and fill the image structure, also fill in an additional |
156 | image = opj_decode(dinfo, cio); | 156 | structure to get the decoding result. This structure is a bit unusual in that |
157 | it is not received through opj, but still has some dynamically allocated fields | ||
158 | that need to be cleared up at the end by calling a destroy function. */ | ||
159 | opj_codestream_info_t cinfo; | ||
160 | memset(&cinfo, 0, sizeof(opj_codestream_info_t)); | ||
161 | image = opj_decode_with_info(dinfo, cio, &cinfo); | ||
157 | 162 | ||
158 | /* close the byte stream */ | 163 | /* close the byte stream */ |
159 | opj_cio_close(cio); | 164 | opj_cio_close(cio); |
@@ -180,6 +185,7 @@ BOOL LLImageJ2COJ::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decod | |||
180 | LL_DEBUGS("Openjpeg") << "ERROR -> decodeImpl: failed to decode image wrong number of components: " << img_components << LL_ENDL; | 185 | LL_DEBUGS("Openjpeg") << "ERROR -> decodeImpl: failed to decode image wrong number of components: " << img_components << LL_ENDL; |
181 | if (image) | 186 | if (image) |
182 | { | 187 | { |
188 | opj_destroy_cstr_info(&cinfo); | ||
183 | opj_image_destroy(image); | 189 | opj_image_destroy(image); |
184 | } | 190 | } |
185 | 191 | ||
@@ -187,23 +193,40 @@ BOOL LLImageJ2COJ::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decod | |||
187 | } | 193 | } |
188 | 194 | ||
189 | // sometimes we get bad data out of the cache - check to see if the decode succeeded | 195 | // sometimes we get bad data out of the cache - check to see if the decode succeeded |
190 | for (S32 i = 0; i < img_components; i++) | 196 | int decompdifference = 0; |
197 | if (cinfo.numdecompos) // sanity | ||
191 | { | 198 | { |
192 | if (image->comps[i].factor != base.getRawDiscardLevel()) | 199 | for (int comp = 0; comp < image->numcomps; comp++) |
200 | { /* get maximum decomposition level difference, first field is from the COD header and the second | ||
201 | is what is actually met in the codestream, NB: if everything was ok, this calculation will | ||
202 | return what was set in the cp_reduce value! */ | ||
203 | decompdifference = std::max(decompdifference, cinfo.numdecompos[comp] - image->comps[comp].resno_decoded); | ||
204 | } | ||
205 | if (decompdifference < 0) // sanity | ||
193 | { | 206 | { |
194 | // if we didn't get the discard level we're expecting, fail | 207 | decompdifference = 0; |
195 | if (image) //anyway somthing odd with the image, better check than crash | ||
196 | opj_image_destroy(image); | ||
197 | base.mDecoding = FALSE; | ||
198 | return TRUE; | ||
199 | } | 208 | } |
200 | } | 209 | } |
201 | 210 | ||
211 | |||
212 | /* if OpenJPEG failed to decode all requested decomposition levels | ||
213 | the difference will be greater than this level */ | ||
214 | if (decompdifference > base.getRawDiscardLevel()) | ||
215 | { | ||
216 | llwarns << "not enough data for requested discard level, setting mDecoding to FALSE, difference: " << (decompdifference - base.getRawDiscardLevel()) << llendl; | ||
217 | opj_destroy_cstr_info(&cinfo); | ||
218 | opj_image_destroy(image); | ||
219 | base.mDecoding = FALSE; | ||
220 | return TRUE; | ||
221 | } | ||
222 | |||
202 | if(img_components <= first_channel) | 223 | if(img_components <= first_channel) |
203 | { | 224 | { |
225 | // sanity | ||
204 | LL_DEBUGS("Openjpeg") << "trying to decode more channels than are present in image: numcomps: " << img_components << " first_channel: " << first_channel << LL_ENDL; | 226 | LL_DEBUGS("Openjpeg") << "trying to decode more channels than are present in image: numcomps: " << img_components << " first_channel: " << first_channel << LL_ENDL; |
205 | if (image) | 227 | if (image) |
206 | { | 228 | { |
229 | opj_destroy_cstr_info(&cinfo); | ||
207 | opj_image_destroy(image); | 230 | opj_image_destroy(image); |
208 | } | 231 | } |
209 | 232 | ||
@@ -252,15 +275,17 @@ BOOL LLImageJ2COJ::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decod | |||
252 | else // Some rare OpenJPEG versions have this bug. | 275 | else // Some rare OpenJPEG versions have this bug. |
253 | { | 276 | { |
254 | llwarns << "ERROR -> decodeImpl: failed to decode image! (NULL comp data - OpenJPEG bug)" << llendl; | 277 | llwarns << "ERROR -> decodeImpl: failed to decode image! (NULL comp data - OpenJPEG bug)" << llendl; |
278 | opj_destroy_cstr_info(&cinfo); | ||
255 | opj_image_destroy(image); | 279 | opj_image_destroy(image); |
256 | 280 | ||
257 | return TRUE; // done | 281 | return TRUE; // done |
258 | } | 282 | } |
259 | } | 283 | } |
260 | 284 | ||
261 | /* free image data structure */ | 285 | /* free opj data structures */ |
262 | if (image) | 286 | if (image) |
263 | { | 287 | { |
288 | opj_destroy_cstr_info(&cinfo); | ||
264 | opj_image_destroy(image); | 289 | opj_image_destroy(image); |
265 | } | 290 | } |
266 | 291 | ||
diff --git a/linden/indra/newview/chatbar_as_cmdline.cpp b/linden/indra/newview/chatbar_as_cmdline.cpp index 59804c0..9359444 100644 --- a/linden/indra/newview/chatbar_as_cmdline.cpp +++ b/linden/indra/newview/chatbar_as_cmdline.cpp | |||
@@ -16,7 +16,7 @@ | |||
16 | * may be used to endorse or promote products derived from this | 16 | * may be used to endorse or promote products derived from this |
17 | * software without specific prior written permission. | 17 | * software without specific prior written permission. |
18 | * | 18 | * |
19 | * THIS SOFTWARE IS PROVIDED BY MODULAR SYSTEMS AND CONTRIBUTORS “AS IS” | 19 | * THIS SOFTWARE IS PROVIDED BY MODULAR SYSTEMS AND CONTRIBUTORS "AS IS" |
20 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, | 20 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, |
21 | * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | 21 | * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
22 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MODULAR SYSTEMS OR CONTRIBUTORS | 22 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MODULAR SYSTEMS OR CONTRIBUTORS |
@@ -331,7 +331,7 @@ bool cmd_line_chat(std::string revised_text, EChatType type) | |||
331 | } | 331 | } |
332 | else if(command == *sCmdLineChatbarTeleportToCam) | 332 | else if(command == *sCmdLineChatbarTeleportToCam) |
333 | { | 333 | { |
334 | gAgent.teleportViaLocation(gAgent.getCameraPositionGlobal()); | 334 | gAgent.teleportViaLocationLookAt(gAgent.getCameraPositionGlobal()); |
335 | return false; | 335 | return false; |
336 | } | 336 | } |
337 | /*else if(command == *sCmdLineChatbarUndeform) | 337 | /*else if(command == *sCmdLineChatbarUndeform) |
diff --git a/linden/indra/newview/llagent.cpp b/linden/indra/newview/llagent.cpp index 51b6c53..077da53 100644 --- a/linden/indra/newview/llagent.cpp +++ b/linden/indra/newview/llagent.cpp | |||
@@ -400,7 +400,8 @@ LLAgent::LLAgent() : | |||
400 | mAgentWearablesUpdateSerialNum(0), | 400 | mAgentWearablesUpdateSerialNum(0), |
401 | mWearablesLoaded(FALSE), | 401 | mWearablesLoaded(FALSE), |
402 | mTextureCacheQueryID(0), | 402 | mTextureCacheQueryID(0), |
403 | mAppearanceSerialNum(0) | 403 | mAppearanceSerialNum(0), |
404 | mbTeleportKeepsLookAt(false) | ||
404 | { | 405 | { |
405 | U32 i; | 406 | U32 i; |
406 | for (i = 0; i < TOTAL_CONTROLS; i++) | 407 | for (i = 0; i < TOTAL_CONTROLS; i++) |
@@ -6099,16 +6100,21 @@ bool LLAgent::teleportCore(bool is_local) | |||
6099 | 6100 | ||
6100 | void LLAgent::teleportRequest( | 6101 | void LLAgent::teleportRequest( |
6101 | const U64& region_handle, | 6102 | const U64& region_handle, |
6102 | const LLVector3& pos_local) | 6103 | const LLVector3& pos_local, |
6104 | bool keep_look_at) | ||
6103 | { | 6105 | { |
6104 | LLViewerRegion* regionp = getRegion(); | 6106 | LLViewerRegion* regionp = getRegion(); |
6105 | 6107 | if (!regionp) | |
6108 | { | ||
6109 | return; | ||
6110 | } | ||
6106 | // Set last region data for teleport history | 6111 | // Set last region data for teleport history |
6107 | gAgent.setLastRegionData(regionp->getName(),gAgent.getPositionAgent()); | 6112 | gAgent.setLastRegionData(regionp->getName(),gAgent.getPositionAgent()); |
6108 | 6113 | ||
6109 | if(regionp && teleportCore()) | 6114 | bool is_local = (region_handle == to_region_handle(getPositionGlobal())); |
6115 | if(teleportCore(is_local)) | ||
6110 | { | 6116 | { |
6111 | llinfos << "TeleportRequest: '" << region_handle << "':" << pos_local | 6117 | llinfos << "TeleportLocationRequest: '" << region_handle << "':" << pos_local |
6112 | << llendl; | 6118 | << llendl; |
6113 | LLMessageSystem* msg = gMessageSystem; | 6119 | LLMessageSystem* msg = gMessageSystem; |
6114 | msg->newMessage("TeleportLocationRequest"); | 6120 | msg->newMessage("TeleportLocationRequest"); |
@@ -6119,6 +6125,10 @@ void LLAgent::teleportRequest( | |||
6119 | msg->addU64("RegionHandle", region_handle); | 6125 | msg->addU64("RegionHandle", region_handle); |
6120 | msg->addVector3("Position", pos_local); | 6126 | msg->addVector3("Position", pos_local); |
6121 | LLVector3 look_at(0,1,0); | 6127 | LLVector3 look_at(0,1,0); |
6128 | if (keep_look_at) | ||
6129 | { | ||
6130 | look_at = LLViewerCamera::getInstance()->getAtAxis(); | ||
6131 | } | ||
6122 | msg->addVector3("LookAt", look_at); | 6132 | msg->addVector3("LookAt", look_at); |
6123 | sendReliableMessage(); | 6133 | sendReliableMessage(); |
6124 | } | 6134 | } |
@@ -6219,46 +6229,29 @@ void LLAgent::teleportViaLocation(const LLVector3d& pos_global) | |||
6219 | } | 6229 | } |
6220 | // [/RLVa:KB] | 6230 | // [/RLVa:KB] |
6221 | 6231 | ||
6222 | LLViewerRegion* regionp = getRegion(); | 6232 | U64 region_handle = to_region_handle(pos_global); |
6223 | LLSimInfo* info = LLWorldMap::getInstance()->simInfoFromPosGlobal(pos_global); | 6233 | LLVector3 pos_local = (LLVector3)(pos_global - from_region_handle(region_handle)); |
6224 | if(regionp && info) | 6234 | teleportRequest(region_handle, pos_local, false); |
6225 | { | 6235 | } |
6226 | U32 x_pos; | ||
6227 | U32 y_pos; | ||
6228 | from_region_handle(info->mHandle, &x_pos, &y_pos); | ||
6229 | LLVector3 pos_local( | ||
6230 | (F32)(pos_global.mdV[VX] - x_pos), | ||
6231 | (F32)(pos_global.mdV[VY] - y_pos), | ||
6232 | (F32)(pos_global.mdV[VZ])); | ||
6233 | teleportRequest(info->mHandle, pos_local); | ||
6234 | } | ||
6235 | else if(regionp && | ||
6236 | teleportCore(regionp->getHandle() == to_region_handle_global((F32)pos_global.mdV[VX], (F32)pos_global.mdV[VY]))) | ||
6237 | { | ||
6238 | llwarns << "Using deprecated teleportlocationrequest." << llendl; | ||
6239 | // send the message | ||
6240 | LLMessageSystem* msg = gMessageSystem; | ||
6241 | msg->newMessageFast(_PREHASH_TeleportLocationRequest); | ||
6242 | msg->nextBlockFast(_PREHASH_AgentData); | ||
6243 | msg->addUUIDFast(_PREHASH_AgentID, getID()); | ||
6244 | msg->addUUIDFast(_PREHASH_SessionID, getSessionID()); | ||
6245 | 6236 | ||
6246 | msg->nextBlockFast(_PREHASH_Info); | 6237 | // Teleport to global position, but keep facing in the same direction |
6247 | F32 width = regionp->getWidth(); | 6238 | void LLAgent::teleportViaLocationLookAt(const LLVector3d& pos_global) |
6248 | LLVector3 pos(fmod((F32)pos_global.mdV[VX], width), | 6239 | { |
6249 | fmod((F32)pos_global.mdV[VY], width), | 6240 | // RLVa stuff copied from LLAgent::teleportViaLocation |
6250 | (F32)pos_global.mdV[VZ]); | 6241 | if ( (rlv_handler_t::isEnabled()) && |
6251 | F32 region_x = (F32)(pos_global.mdV[VX]); | 6242 | ( (gRlvHandler.hasBehaviourExcept(RLV_BHVR_TPLOC, gRlvHandler.getCurrentObject())) || |
6252 | F32 region_y = (F32)(pos_global.mdV[VY]); | 6243 | ( (mAvatarObject.notNull()) && (mAvatarObject->mIsSitting) && |
6253 | U64 region_handle = to_region_handle_global(region_x, region_y); | 6244 | (gRlvHandler.hasBehaviourExcept(RLV_BHVR_UNSIT, gRlvHandler.getCurrentObject()))) ) ) |
6254 | msg->addU64Fast(_PREHASH_RegionHandle, region_handle); | 6245 | { |
6255 | msg->addVector3Fast(_PREHASH_Position, pos); | 6246 | return; |
6256 | pos.mV[VX] += 1; | ||
6257 | msg->addVector3Fast(_PREHASH_LookAt, pos); | ||
6258 | sendReliableMessage(); | ||
6259 | } | 6247 | } |
6260 | } | ||
6261 | 6248 | ||
6249 | mbTeleportKeepsLookAt = true; | ||
6250 | setFocusOnAvatar(FALSE, ANIMATE); // detach camera form avatar, so it keeps direction | ||
6251 | U64 region_handle = to_region_handle(pos_global); | ||
6252 | LLVector3 pos_local = (LLVector3)(pos_global - from_region_handle(region_handle)); | ||
6253 | teleportRequest(region_handle, pos_local, mbTeleportKeepsLookAt); | ||
6254 | } | ||
6262 | 6255 | ||
6263 | void LLAgent::teleportHome() | 6256 | void LLAgent::teleportHome() |
6264 | { | 6257 | { |
@@ -6286,6 +6279,10 @@ bool LLAgent::teleportHomeCallback( const LLSD& notification, const LLSD& respon | |||
6286 | void LLAgent::setTeleportState(ETeleportState state) | 6279 | void LLAgent::setTeleportState(ETeleportState state) |
6287 | { | 6280 | { |
6288 | mTeleportState = state; | 6281 | mTeleportState = state; |
6282 | if (mTeleportState == TELEPORT_NONE) | ||
6283 | { | ||
6284 | mbTeleportKeepsLookAt = false; | ||
6285 | } | ||
6289 | if (mTeleportState > TELEPORT_NONE && gSavedSettings.getBOOL("FreezeTime")) | 6286 | if (mTeleportState > TELEPORT_NONE && gSavedSettings.getBOOL("FreezeTime")) |
6290 | { | 6287 | { |
6291 | LLFloaterSnapshot::hide(0); | 6288 | LLFloaterSnapshot::hide(0); |
diff --git a/linden/indra/newview/llagent.h b/linden/indra/newview/llagent.h index 3a39448..f1cad9c 100644 --- a/linden/indra/newview/llagent.h +++ b/linden/indra/newview/llagent.h | |||
@@ -496,7 +496,8 @@ public: | |||
496 | // go to a named location home | 496 | // go to a named location home |
497 | void teleportRequest( | 497 | void teleportRequest( |
498 | const U64& region_handle, | 498 | const U64& region_handle, |
499 | const LLVector3& pos_local); | 499 | const LLVector3& pos_local, |
500 | bool keep_look_at); | ||
500 | 501 | ||
501 | // teleport to a landmark | 502 | // teleport to a landmark |
502 | void teleportViaLandmark(const LLUUID& landmark_id); | 503 | void teleportViaLandmark(const LLUUID& landmark_id); |
@@ -513,6 +514,9 @@ public: | |||
513 | // deprecated. | 514 | // deprecated. |
514 | void teleportViaLocation(const LLVector3d& pos_global); | 515 | void teleportViaLocation(const LLVector3d& pos_global); |
515 | 516 | ||
517 | // to a global location, preserving camera rotation | ||
518 | void teleportViaLocationLookAt(const LLVector3d& pos_global); | ||
519 | |||
516 | // cancel the teleport, may or may not be allowed by server | 520 | // cancel the teleport, may or may not be allowed by server |
517 | void teleportCancel(); | 521 | void teleportCancel(); |
518 | 522 | ||
@@ -521,6 +525,8 @@ public: | |||
521 | 525 | ||
522 | const std::string getTeleportSourceSLURL() const { return mTeleportSourceSLURL; } | 526 | const std::string getTeleportSourceSLURL() const { return mTeleportSourceSLURL; } |
523 | 527 | ||
528 | // whether look-at resets after this teleport | ||
529 | bool getTeleportKeepsLookAt() const { return mbTeleportKeepsLookAt; } | ||
524 | 530 | ||
525 | // Setting the ability for this avatar to proxy for another avatar. | 531 | // Setting the ability for this avatar to proxy for another avatar. |
526 | //static void processAddModifyAbility(LLMessageSystem* msg, void**); | 532 | //static void processAddModifyAbility(LLMessageSystem* msg, void**); |
@@ -781,6 +787,7 @@ public: | |||
781 | EDoubleTapRunMode mDoubleTapRunMode; | 787 | EDoubleTapRunMode mDoubleTapRunMode; |
782 | 788 | ||
783 | private: | 789 | private: |
790 | bool mbTeleportKeepsLookAt; | ||
784 | bool mbAlwaysRun; // should the avatar run by default rather than walk | 791 | bool mbAlwaysRun; // should the avatar run by default rather than walk |
785 | bool mbRunning; // is the avatar trying to run right now | 792 | bool mbRunning; // is the avatar trying to run right now |
786 | 793 | ||
diff --git a/linden/indra/newview/llviewermenu.cpp b/linden/indra/newview/llviewermenu.cpp index 681216a..026f652 100644 --- a/linden/indra/newview/llviewermenu.cpp +++ b/linden/indra/newview/llviewermenu.cpp | |||
@@ -2576,9 +2576,9 @@ bool handle_go_to_callback(const LLSD& notification, const LLSD& response) | |||
2576 | 2576 | ||
2577 | if (action == "teleport") | 2577 | if (action == "teleport") |
2578 | { | 2578 | { |
2579 | LLVector3d hips_offset(0.0f, 0.0f, 1.2f); | 2579 | pos.mdV[VZ] += gAgent.getAvatarObject()->getPelvisToFoot() + 0.2f; |
2580 | gAgent.setControlFlags(AGENT_CONTROL_STAND_UP); | 2580 | gAgent.setControlFlags(AGENT_CONTROL_STAND_UP); |
2581 | gAgent.teleportViaLocation(pos + hips_offset); | 2581 | gAgent.teleportViaLocationLookAt(pos); |
2582 | } | 2582 | } |
2583 | else if (action == "move") | 2583 | else if (action == "move") |
2584 | { | 2584 | { |
diff --git a/linden/indra/newview/llviewermessage.cpp b/linden/indra/newview/llviewermessage.cpp index bfd1045..e216c44 100755 --- a/linden/indra/newview/llviewermessage.cpp +++ b/linden/indra/newview/llviewermessage.cpp | |||
@@ -3540,6 +3540,12 @@ void process_agent_movement_complete(LLMessageSystem* msg, void**) | |||
3540 | 3540 | ||
3541 | if( is_teleport ) | 3541 | if( is_teleport ) |
3542 | { | 3542 | { |
3543 | if (gAgent.getTeleportKeepsLookAt()) | ||
3544 | { | ||
3545 | // *NOTE: the LookAt data we get from the sim here doesn't | ||
3546 | // seem to be useful, so get it from the camera instead. | ||
3547 | look_at = LLViewerCamera::getInstance()->getAtAxis(); | ||
3548 | } | ||
3543 | // Force the camera back onto the agent, don't animate. | 3549 | // Force the camera back onto the agent, don't animate. |
3544 | gAgent.setFocusOnAvatar(TRUE, FALSE); | 3550 | gAgent.setFocusOnAvatar(TRUE, FALSE); |
3545 | gAgent.slamLookAt(look_at); | 3551 | gAgent.slamLookAt(look_at); |
@@ -3601,7 +3607,7 @@ void process_agent_movement_complete(LLMessageSystem* msg, void**) | |||
3601 | { | 3607 | { |
3602 | LLTracker::stopTracking(NULL); | 3608 | LLTracker::stopTracking(NULL); |
3603 | } | 3609 | } |
3604 | else if ( is_teleport ) | 3610 | else if ( is_teleport && !gAgent.getTeleportKeepsLookAt() ) |
3605 | { | 3611 | { |
3606 | //look at the beacon | 3612 | //look at the beacon |
3607 | LLVector3 global_agent_pos = agent_pos; | 3613 | LLVector3 global_agent_pos = agent_pos; |