diff --git a/indra/newview/rlvdefines.h b/indra/newview/rlvdefines.h index 0c3d05f444..d79833430a 100644 --- a/indra/newview/rlvdefines.h +++ b/indra/newview/rlvdefines.h @@ -164,6 +164,7 @@ enum ERlvBehaviour { RLV_BHVR_DETACHTHISEXCEPT, // "detachthis_except" RLV_BHVR_ADJUSTHEIGHT, // "adjustheight" RLV_BHVR_TPTO, // "tpto" + RLV_BHVR_CAMFOCUS, RLV_BHVR_VERSION, // "version" RLV_BHVR_VERSIONNEW, // "versionnew" RLV_BHVR_VERSIONNUM, // "versionnum" diff --git a/indra/newview/rlvhandler.cpp b/indra/newview/rlvhandler.cpp index 8fc3b851c2..fdb92ab5d3 100644 --- a/indra/newview/rlvhandler.cpp +++ b/indra/newview/rlvhandler.cpp @@ -36,6 +36,7 @@ #include "llsidepanelappearance.h" // @showinv - "Appearance / Edit appearance" panel #include "lltabcontainer.h" // @showinv - Tab container control for inventory tabs #include "lltoolmgr.h" // @edit +#include "llviewercamera.h" // @camfocus // RLVa includes #include "rlvfloaters.h" @@ -463,6 +464,70 @@ bool RlvHandler::handleEvent(LLPointer event, const LLSD& return false; } +// Handles: @camfocus:[;[;]]=force +template<> template<> +ERlvCmdRet RlvForceHandler::onCommand(const RlvCommand& rlvCmd) +{ + std::vector optionList; + if (!RlvCommandOptionHelper::parseStringList(rlvCmd.getOption(), optionList)) + return RLV_RET_FAILED_OPTION; + + LLVector3 posAgent; + LLVector3d posGlobal; + F32 camDistance; + + // Get the focus position/object (and verify it is known) + LLUUID idObject; LLVector3 posRegion; + if (RlvCommandOptionHelper::parseOption(optionList[0], idObject)) + { + const LLViewerObject* pObj = gObjectList.findObject(idObject); + if (!pObj) + return RLV_RET_FAILED_OPTION; + posAgent = pObj->getPositionAgent(); + posGlobal = pObj->getPositionGlobal(); + camDistance = pObj->getScale().magVec(); + } + else if (RlvCommandOptionHelper::parseOption(optionList[0], posRegion)) + { + const LLViewerRegion* pRegion = gAgent.getRegion(); + if (!pRegion) + return RLV_RET_FAILED_UNKNOWN; + posAgent = pRegion->getPosAgentFromRegion(posRegion); + posGlobal = pRegion->getPosGlobalFromRegion(posRegion); + camDistance = 0.0f; + } + else + { + return RLV_RET_FAILED_OPTION; + } + + // Get the camera distance + if ( (optionList.size() > 1) && (!optionList[1].empty()) ) + { + if (!RlvCommandOptionHelper::parseOption(optionList[1], camDistance)) + return RLV_RET_FAILED_OPTION; + } + + // Get the directional vector (or calculate it from the current camera position) + LLVector3 camDirection; + if ( (optionList.size() > 2) && (!optionList[2].empty()) ) + { + if (!RlvCommandOptionHelper::parseOption(optionList[2], camDirection)) + return RLV_RET_FAILED_OPTION; + } + else + { + camDirection = LLViewerCamera::getInstance()->getOrigin() - posAgent; + } + camDirection.normVec(); + + // Move the camera in place + gAgentCamera.setFocusOnAvatar(FALSE, ANIMATE); + gAgentCamera.setCameraPosAndFocusGlobal(posGlobal + LLVector3d(camDirection * llmax(F_APPROXIMATELY_ZERO, camDistance)), posGlobal, idObject); + + return RLV_RET_SUCCESS; +} + // Checked: 2010-08-29 (RLVa-1.2.1c) | Modified: RLVa-1.2.1c void RlvHandler::onSitOrStand(bool fSitting) { diff --git a/indra/newview/rlvhelper.cpp b/indra/newview/rlvhelper.cpp index 862e31c1f4..3d5182669c 100644 --- a/indra/newview/rlvhelper.cpp +++ b/indra/newview/rlvhelper.cpp @@ -199,6 +199,7 @@ RlvBehaviourDictionary::RlvBehaviourDictionary() // Force-only // addEntry(new RlvBehaviourInfo("adjustheight", RLV_BHVR_ADJUSTHEIGHT, RLV_TYPE_FORCE)); + addEntry(new RlvForceProcessor("camfocus", RlvBehaviourInfo::BHVR_EXPERIMENTAL)); addEntry(new RlvForceProcessor("detachme")); addEntry(new RlvForceProcessor("setgroup")); addEntry(new RlvForceProcessor("sit")); @@ -413,12 +414,12 @@ bool RlvBehaviourModifier::convertOptionValue(const std::string& optionValue, Rl { if (typeid(float) == m_DefaultValue.type()) { - modValue = std::stof(optionValue.c_str()); + modValue = std::stof(optionValue); return true; } else if (typeid(int) == m_DefaultValue.type()) { - modValue = std::stoi(optionValue.c_str()); + modValue = std::stoi(optionValue); return true; } return false;