From 5fc9867f8b889e22521ca6a681af5d983074b378 Mon Sep 17 00:00:00 2001 From: CharleyLevenque Date: Sat, 28 Aug 2010 21:28:06 -0400 Subject: [PATCH 1/3] Turn LookAt beacons on by default. --- indra/newview/llhudeffectlookat.cpp | 1430 +++++++++++++-------------- 1 file changed, 715 insertions(+), 715 deletions(-) diff --git a/indra/newview/llhudeffectlookat.cpp b/indra/newview/llhudeffectlookat.cpp index 3baacb7a8..c8460cf60 100644 --- a/indra/newview/llhudeffectlookat.cpp +++ b/indra/newview/llhudeffectlookat.cpp @@ -1,715 +1,715 @@ -/** - * @file llhudeffectlookat.cpp - * @brief LLHUDEffectLookAt class implementation - * - * $LicenseInfo:firstyear=2002&license=viewergpl$ - * - * Copyright (c) 2002-2009, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ - -#include "llviewerprecompiledheaders.h" - -#include "llhudeffectlookat.h" - -#include "llrender.h" - -#include "message.h" -#include "llagent.h" -#include "llvoavatar.h" -#include "lldrawable.h" -#include "llviewerobjectlist.h" -#include "llrendersphere.h" -#include "llselectmgr.h" -#include "llglheaders.h" - - -#include "llxmltree.h" -// -#include "llresmgr.h" -#include "llhudrender.h" -#include "llviewerwindow.h" -#include "llviewercontrol.h" -// - - -BOOL LLHUDEffectLookAt::sDebugLookAt = FALSE; - -// packet layout -const S32 SOURCE_AVATAR = 0; -const S32 TARGET_OBJECT = 16; -const S32 TARGET_POS = 32; -const S32 LOOKAT_TYPE = 56; -const S32 PKT_SIZE = 57; - -// throttle -const F32 MAX_SENDS_PER_SEC = 4.f; - -const F32 MIN_DELTAPOS_FOR_UPDATE = 0.05f; -const F32 MIN_TARGET_OFFSET_SQUARED = 0.0001f; - - -// can't use actual F32_MAX, because we add this to the current frametime -const F32 MAX_TIMEOUT = F32_MAX / 2.f; - -/** - * Simple data class holding values for a particular type of attention. - */ -class LLAttention -{ -public: - LLAttention() - : mTimeout(0.f), - mPriority(0.f) - {} - LLAttention(F32 timeout, F32 priority, const std::string& name, LLColor3 color) : - mTimeout(timeout), mPriority(priority), mName(name), mColor(color) - { - } - F32 mTimeout, mPriority; - std::string mName; - LLColor3 mColor; -}; - -/** - * Simple data class holding a list of attentions, one for every type. - */ -class LLAttentionSet -{ -public: - LLAttentionSet(const LLAttention attentions[]) - { - for(int i=0; igetAttributeString("name", str); - LLAttentionSet& attentions = (str.compare("Masculine") == 0) ? gBoyAttentions : gGirlAttentions; - for (LLXmlTreeNode* attention_node = gender->getChildByName( "param" ); - attention_node; - attention_node = gender->getNextNamedChild()) - { - attention_node->getAttributeString("attention", str); - LLAttention* attention; - if (str == "idle") attention = &attentions[LOOKAT_TARGET_IDLE]; - else if(str == "auto_listen") attention = &attentions[LOOKAT_TARGET_AUTO_LISTEN]; - else if(str == "freelook") attention = &attentions[LOOKAT_TARGET_FREELOOK]; - else if(str == "respond") attention = &attentions[LOOKAT_TARGET_RESPOND]; - else if(str == "hover") attention = &attentions[LOOKAT_TARGET_HOVER]; - else if(str == "conversation") attention = &attentions[LOOKAT_TARGET_CONVERSATION]; - else if(str == "select") attention = &attentions[LOOKAT_TARGET_SELECT]; - else if(str == "focus") attention = &attentions[LOOKAT_TARGET_FOCUS]; - else if(str == "mouselook") attention = &attentions[LOOKAT_TARGET_MOUSELOOK]; - else return FALSE; - - F32 priority, timeout; - attention_node->getAttributeF32("priority", priority); - attention_node->getAttributeF32("timeout", timeout); - if(timeout < 0) timeout = MAX_TIMEOUT; - attention->mPriority = priority; - attention->mTimeout = timeout; - } - return TRUE; -} - -static BOOL loadAttentions() -{ - static BOOL first_time = TRUE; - if( ! first_time) - { - return TRUE; // maybe not ideal but otherwise it can continue to fail forever. - } - first_time = FALSE; - - std::string filename; - filename = gDirUtilp->getExpandedFilename(LL_PATH_CHARACTER,"attentions.xml"); - LLXmlTree xml_tree; - BOOL success = xml_tree.parseFile( filename, FALSE ); - if( !success ) - { - return FALSE; - } - LLXmlTreeNode* root = xml_tree.getRoot(); - if( !root ) - { - return FALSE; - } - - //------------------------------------------------------------------------- - // (root) - //------------------------------------------------------------------------- - if( !root->hasName( "linden_attentions" ) ) - { - llwarns << "Invalid linden_attentions file header: " << filename << llendl; - return FALSE; - } - - std::string version; - static LLStdStringHandle version_string = LLXmlTree::addAttributeString("version"); - if( !root->getFastAttributeString( version_string, version ) || (version != "1.0") ) - { - llwarns << "Invalid linden_attentions file version: " << version << llendl; - return FALSE; - } - - //------------------------------------------------------------------------- - // - //------------------------------------------------------------------------- - for (LLXmlTreeNode* child = root->getChildByName( "gender" ); - child; - child = root->getNextNamedChild()) - { - if( !loadGender( child ) ) - { - return FALSE; - } - } - - return TRUE; -} - - - - -//----------------------------------------------------------------------------- -// LLHUDEffectLookAt() -//----------------------------------------------------------------------------- -LLHUDEffectLookAt::LLHUDEffectLookAt(const U8 type) : - LLHUDEffect(type), - mKillTime(0.f), - mLastSendTime(0.f) -{ - clearLookAtTarget(); - // parse the default sets - loadAttentions(); - // initialize current attention set. switches when avatar sex changes. - mAttentions = &gGirlAttentions; -} - -//----------------------------------------------------------------------------- -// ~LLHUDEffectLookAt() -//----------------------------------------------------------------------------- -LLHUDEffectLookAt::~LLHUDEffectLookAt() -{ -} - -//----------------------------------------------------------------------------- -// packData() -//----------------------------------------------------------------------------- -void LLHUDEffectLookAt::packData(LLMessageSystem *mesgsys) -{ - // Pack the default data - LLHUDEffect::packData(mesgsys); - - // Pack the type-specific data. Uses a fun packed binary format. Whee! - U8 packed_data[PKT_SIZE]; - memset(packed_data, 0, PKT_SIZE); - - if (mSourceObject) - { - htonmemcpy(&(packed_data[SOURCE_AVATAR]), mSourceObject->mID.mData, MVT_LLUUID, 16); - } - else - { - htonmemcpy(&(packed_data[SOURCE_AVATAR]), LLUUID::null.mData, MVT_LLUUID, 16); - } - - // pack both target object and position - // position interpreted as offset if target object is non-null - if (mTargetObject) - { - htonmemcpy(&(packed_data[TARGET_OBJECT]), mTargetObject->mID.mData, MVT_LLUUID, 16); - } - else - { - htonmemcpy(&(packed_data[TARGET_OBJECT]), LLUUID::null.mData, MVT_LLUUID, 16); - } - - htonmemcpy(&(packed_data[TARGET_POS]), mTargetOffsetGlobal.mdV, MVT_LLVector3d, 24); - - U8 lookAtTypePacked = (U8)mTargetType; - - htonmemcpy(&(packed_data[LOOKAT_TYPE]), &lookAtTypePacked, MVT_U8, 1); - - mesgsys->addBinaryDataFast(_PREHASH_TypeData, packed_data, PKT_SIZE); - - mLastSendTime = mTimer.getElapsedTimeF32(); -} - -//----------------------------------------------------------------------------- -// unpackData() -//----------------------------------------------------------------------------- -void LLHUDEffectLookAt::unpackData(LLMessageSystem *mesgsys, S32 blocknum) -{ - LLVector3d new_target; - U8 packed_data[PKT_SIZE]; - - LLUUID dataId; - mesgsys->getUUIDFast(_PREHASH_Effect, _PREHASH_ID, dataId, blocknum); - - if (!gAgent.mLookAt.isNull() && dataId == gAgent.mLookAt->getID()) - { - return; - } - - LLHUDEffect::unpackData(mesgsys, blocknum); - LLUUID source_id; - LLUUID target_id; - S32 size = mesgsys->getSizeFast(_PREHASH_Effect, blocknum, _PREHASH_TypeData); - if (size != PKT_SIZE) - { - llwarns << "LookAt effect with bad size " << size << llendl; - return; - } - mesgsys->getBinaryDataFast(_PREHASH_Effect, _PREHASH_TypeData, packed_data, PKT_SIZE, blocknum); - - htonmemcpy(source_id.mData, &(packed_data[SOURCE_AVATAR]), MVT_LLUUID, 16); - - LLViewerObject *objp = gObjectList.findObject(source_id); - if (objp && objp->isAvatar()) - { - setSourceObject(objp); - } - else - { - //llwarns << "Could not find source avatar for lookat effect" << llendl; - return; - } - - htonmemcpy(target_id.mData, &(packed_data[TARGET_OBJECT]), MVT_LLUUID, 16); - - objp = gObjectList.findObject(target_id); - - htonmemcpy(new_target.mdV, &(packed_data[TARGET_POS]), MVT_LLVector3d, 24); - - if (objp) - { - setTargetObjectAndOffset(objp, new_target); - } - else if (target_id.isNull()) - { - setTargetPosGlobal(new_target); - } - else - { - //llwarns << "Could not find target object for lookat effect" << llendl; - } - - U8 lookAtTypeUnpacked = 0; - htonmemcpy(&lookAtTypeUnpacked, &(packed_data[LOOKAT_TYPE]), MVT_U8, 1); - mTargetType = (ELookAtType)lookAtTypeUnpacked; - - if (mTargetType == LOOKAT_TARGET_NONE) - { - clearLookAtTarget(); - } -} - -//----------------------------------------------------------------------------- -// setTargetObjectAndOffset() -//----------------------------------------------------------------------------- -void LLHUDEffectLookAt::setTargetObjectAndOffset(LLViewerObject *objp, LLVector3d offset) -{ - mTargetObject = objp; - mTargetOffsetGlobal = offset; -} - -//----------------------------------------------------------------------------- -// setTargetPosGlobal() -//----------------------------------------------------------------------------- -void LLHUDEffectLookAt::setTargetPosGlobal(const LLVector3d &target_pos_global) -{ - mTargetObject = NULL; - mTargetOffsetGlobal = target_pos_global; -} - -//----------------------------------------------------------------------------- -// setLookAt() -// called by agent logic to set look at behavior locally, and propagate to sim -//----------------------------------------------------------------------------- -BOOL LLHUDEffectLookAt::setLookAt(ELookAtType target_type, LLViewerObject *object, LLVector3 position) -{ - if (!mSourceObject) - { - return FALSE; - } - - if (target_type >= LOOKAT_NUM_TARGETS) - { - llwarns << "Bad target_type " << (int)target_type << " - ignoring." << llendl; - return FALSE; - } - - // must be same or higher priority than existing effect - if ((*mAttentions)[target_type].mPriority < (*mAttentions)[mTargetType].mPriority) - { - return FALSE; - } - - F32 current_time = mTimer.getElapsedTimeF32(); - - // type of lookat behavior or target object has changed - BOOL lookAtChanged = (target_type != mTargetType) || (object != mTargetObject); - - // lookat position has moved a certain amount and we haven't just sent an update - lookAtChanged = lookAtChanged || ((dist_vec(position, mLastSentOffsetGlobal) > MIN_DELTAPOS_FOR_UPDATE) && - ((current_time - mLastSendTime) > (1.f / MAX_SENDS_PER_SEC))); - - if (lookAtChanged) - { - mLastSentOffsetGlobal = position; - F32 timeout = (*mAttentions)[target_type].mTimeout; - setDuration(timeout); - setNeedsSendToSim(TRUE); - } - - if (target_type == LOOKAT_TARGET_CLEAR) - { - clearLookAtTarget(); - } - else - { - mTargetType = target_type; - mTargetObject = object; - if (object) - { - mTargetOffsetGlobal.setVec(position); - } - else - { - mTargetOffsetGlobal = gAgent.getPosGlobalFromAgent(position); - } - mKillTime = mTimer.getElapsedTimeF32() + mDuration; - - update(); - } - return TRUE; -} - -//----------------------------------------------------------------------------- -// clearLookAtTarget() -//----------------------------------------------------------------------------- -void LLHUDEffectLookAt::clearLookAtTarget() -{ - mTargetObject = NULL; - mTargetOffsetGlobal.clearVec(); - mTargetType = LOOKAT_TARGET_NONE; - if (mSourceObject.notNull()) - { - ((LLVOAvatar*)(LLViewerObject*)mSourceObject)->stopMotion(ANIM_AGENT_HEAD_ROT); - } -} - -//----------------------------------------------------------------------------- -// markDead() -//----------------------------------------------------------------------------- -void LLHUDEffectLookAt::markDead() -{ - if (mSourceObject.notNull()) - { - ((LLVOAvatar*)(LLViewerObject*)mSourceObject)->removeAnimationData("LookAtPoint"); - } - - mSourceObject = NULL; - clearLookAtTarget(); - LLHUDEffect::markDead(); -} - -void LLHUDEffectLookAt::setSourceObject(LLViewerObject* objectp) -{ - // restrict source objects to avatars - if (objectp && objectp->isAvatar()) - { - LLHUDEffect::setSourceObject(objectp); - } -} - -//----------------------------------------------------------------------------- -// render() -//----------------------------------------------------------------------------- -void LLHUDEffectLookAt::render() -{ - if (gSavedSettings.getBOOL("PrivateLookAt") && - (gAgent.getAvatarObject() == ((LLVOAvatar*)(LLViewerObject*)mSourceObject))) return; - if (sDebugLookAt && mSourceObject.notNull()) - { - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - - LLVector3 target = mTargetPos + ((LLVOAvatar*)(LLViewerObject*)mSourceObject)->mHeadp->getWorldPosition(); - glMatrixMode(GL_MODELVIEW); - gGL.pushMatrix(); - gGL.translatef(target.mV[VX], target.mV[VY], target.mV[VZ]); - glScalef(0.3f, 0.3f, 0.3f); - gGL.begin(LLRender::LINES); - { - LLColor3 color = (*mAttentions)[mTargetType].mColor; - gGL.color3f(color.mV[VRED], color.mV[VGREEN], color.mV[VBLUE]); - gGL.vertex3f(-1.f, 0.f, 0.f); - gGL.vertex3f(1.f, 0.f, 0.f); - - gGL.vertex3f(0.f, -1.f, 0.f); - gGL.vertex3f(0.f, 1.f, 0.f); - - gGL.vertex3f(0.f, 0.f, -1.f); - gGL.vertex3f(0.f, 0.f, 1.f); - } gGL.end(); - gGL.popMatrix(); - // - const std::string text = ((LLVOAvatar*)(LLViewerObject*)mSourceObject)->getFullname(); - LLVector3 offset = gAgent.getCameraPositionAgent() - target; - offset.normalize(); - LLVector3 shadow_offset = offset * 0.49f; - offset *= 0.5f; - const LLFontGL* font = LLResMgr::getInstance()->getRes(LLFONT_SANSSERIF); - LLGLEnable gl_blend(GL_BLEND); - glPushMatrix(); - gViewerWindow->setupViewport(); - hud_render_utf8text(text, - target + shadow_offset, - *font, - LLFontGL::NORMAL, - -0.5f * font->getWidthF32(text) + 2.0f, - -2.0f, - LLColor4::black, - FALSE); - hud_render_utf8text(text, - target + offset, - *font, - LLFontGL::NORMAL, - -0.5f * font->getWidthF32(text), - 0.0f, - (*mAttentions)[mTargetType].mColor, - FALSE); - glPopMatrix(); - // - } -} - -//----------------------------------------------------------------------------- -// update() -//----------------------------------------------------------------------------- -void LLHUDEffectLookAt::update() -{ - // If the target object is dead, set the target object to NULL - if (!mTargetObject.isNull() && mTargetObject->isDead()) - { - clearLookAtTarget(); - } - - // if source avatar is null or dead, mark self as dead and return - if (mSourceObject.isNull() || mSourceObject->isDead()) - { - markDead(); - return; - } - - // make sure the proper set of avatar attention are currently being used. - LLVOAvatar* source_avatar = (LLVOAvatar*)(LLViewerObject*)mSourceObject; - // for now the first cut will just switch on sex. future development could adjust - // timeouts according to avatar age and/or other features. - mAttentions = (source_avatar->getSex() == SEX_MALE) ? &gBoyAttentions : &gGirlAttentions; - //printf("updated to %s\n", (source_avatar->getSex() == SEX_MALE) ? "male" : "female"); - - F32 time = mTimer.getElapsedTimeF32(); - - // clear out the effect if time is up - if (mKillTime != 0.f && time > mKillTime) - { - if (mTargetType != LOOKAT_TARGET_NONE) - { - clearLookAtTarget(); - // look at timed out (only happens on own avatar), so tell everyone - setNeedsSendToSim(TRUE); - } - } - - if (mTargetType != LOOKAT_TARGET_NONE) - { - if (calcTargetPosition()) - { - LLMotion* head_motion = ((LLVOAvatar*)(LLViewerObject*)mSourceObject)->findMotion(ANIM_AGENT_HEAD_ROT); - if (!head_motion || head_motion->isStopped()) - { - ((LLVOAvatar*)(LLViewerObject*)mSourceObject)->startMotion(ANIM_AGENT_HEAD_ROT); - } - } - } - - if (sDebugLookAt) - { - ((LLVOAvatar*)(LLViewerObject*)mSourceObject)->addDebugText((*mAttentions)[mTargetType].mName); - } -} - -/** - * Initializes the mTargetPos member from the current mSourceObjec and mTargetObject - * (and possibly mTargetOffsetGlobal). - * When mTargetObject is another avatar, it sets mTargetPos to be their eyes. - * - * Has the side-effect of also calling setAnimationData("LookAtPoint") with the new - * mTargetPos on the source object which is assumed to be an avatar. - * - * Returns whether we successfully calculated a finite target position. - */ -bool LLHUDEffectLookAt::calcTargetPosition() -{ - if (gNoRender) - { - return false; - } - - LLViewerObject *target_obj = (LLViewerObject *)mTargetObject; - LLVector3 local_offset; - - if (target_obj) - { - local_offset.setVec(mTargetOffsetGlobal); - } - else - { - local_offset = gAgent.getPosAgentFromGlobal(mTargetOffsetGlobal); - } - - LLVOAvatar* source_avatar = (LLVOAvatar*)(LLViewerObject*)mSourceObject; - - if (target_obj && target_obj->mDrawable.notNull()) - { - LLQuaternion target_rot; - if (target_obj->isAvatar()) - { - LLVOAvatar *target_av = (LLVOAvatar *)target_obj; - - BOOL looking_at_self = source_avatar->isSelf() && target_av->isSelf(); - - // if selecting self, stare forward - if (looking_at_self && mTargetOffsetGlobal.magVecSquared() < MIN_TARGET_OFFSET_SQUARED) - { - //sets the lookat point in front of the avatar - mTargetOffsetGlobal.setVec(5.0, 0.0, 0.0); - local_offset.setVec(mTargetOffsetGlobal); - } - - // look the other avatar in the eye. note: what happens if target is self? -MG - mTargetPos = target_av->mHeadp->getWorldPosition(); - if (mTargetType == LOOKAT_TARGET_MOUSELOOK || mTargetType == LOOKAT_TARGET_FREELOOK) - { - // mouselook and freelook target offsets are absolute - target_rot = LLQuaternion::DEFAULT; - } - else if (looking_at_self && gAgent.cameraCustomizeAvatar()) - { - // *NOTE: We have to do this because animation - // overrides do not set lookat behavior. - // *TODO: animation overrides for lookat behavior. - target_rot = target_av->mPelvisp->getWorldRotation(); - } - else - { - target_rot = target_av->mRoot.getWorldRotation(); - } - } - else // target obj is not an avatar - { - if (target_obj->mDrawable->getGeneration() == -1) - { - mTargetPos = target_obj->getPositionAgent(); - target_rot = target_obj->getWorldRotation(); - } - else - { - mTargetPos = target_obj->getRenderPosition(); - target_rot = target_obj->getRenderRotation(); - } - } - - mTargetPos += (local_offset * target_rot); - } - else // no target obj or it's not drawable - { - mTargetPos = local_offset; - } - - mTargetPos -= source_avatar->mHeadp->getWorldPosition(); - - if (!mTargetPos.isFinite()) - return false; - - source_avatar->setAnimationData("LookAtPoint", (void *)&mTargetPos); - source_avatar->mIdleTimer.reset(); - return true; -} +/** + * @file llhudeffectlookat.cpp + * @brief LLHUDEffectLookAt class implementation + * + * $LicenseInfo:firstyear=2002&license=viewergpl$ + * + * Copyright (c) 2002-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llhudeffectlookat.h" + +#include "llrender.h" + +#include "message.h" +#include "llagent.h" +#include "llvoavatar.h" +#include "lldrawable.h" +#include "llviewerobjectlist.h" +#include "llrendersphere.h" +#include "llselectmgr.h" +#include "llglheaders.h" + + +#include "llxmltree.h" +// +#include "llresmgr.h" +#include "llhudrender.h" +#include "llviewerwindow.h" +#include "llviewercontrol.h" +// + + +BOOL LLHUDEffectLookAt::sDebugLookAt = TRUE; + +// packet layout +const S32 SOURCE_AVATAR = 0; +const S32 TARGET_OBJECT = 16; +const S32 TARGET_POS = 32; +const S32 LOOKAT_TYPE = 56; +const S32 PKT_SIZE = 57; + +// throttle +const F32 MAX_SENDS_PER_SEC = 4.f; + +const F32 MIN_DELTAPOS_FOR_UPDATE = 0.05f; +const F32 MIN_TARGET_OFFSET_SQUARED = 0.0001f; + + +// can't use actual F32_MAX, because we add this to the current frametime +const F32 MAX_TIMEOUT = F32_MAX / 2.f; + +/** + * Simple data class holding values for a particular type of attention. + */ +class LLAttention +{ +public: + LLAttention() + : mTimeout(0.f), + mPriority(0.f) + {} + LLAttention(F32 timeout, F32 priority, const std::string& name, LLColor3 color) : + mTimeout(timeout), mPriority(priority), mName(name), mColor(color) + { + } + F32 mTimeout, mPriority; + std::string mName; + LLColor3 mColor; +}; + +/** + * Simple data class holding a list of attentions, one for every type. + */ +class LLAttentionSet +{ +public: + LLAttentionSet(const LLAttention attentions[]) + { + for(int i=0; igetAttributeString("name", str); + LLAttentionSet& attentions = (str.compare("Masculine") == 0) ? gBoyAttentions : gGirlAttentions; + for (LLXmlTreeNode* attention_node = gender->getChildByName( "param" ); + attention_node; + attention_node = gender->getNextNamedChild()) + { + attention_node->getAttributeString("attention", str); + LLAttention* attention; + if (str == "idle") attention = &attentions[LOOKAT_TARGET_IDLE]; + else if(str == "auto_listen") attention = &attentions[LOOKAT_TARGET_AUTO_LISTEN]; + else if(str == "freelook") attention = &attentions[LOOKAT_TARGET_FREELOOK]; + else if(str == "respond") attention = &attentions[LOOKAT_TARGET_RESPOND]; + else if(str == "hover") attention = &attentions[LOOKAT_TARGET_HOVER]; + else if(str == "conversation") attention = &attentions[LOOKAT_TARGET_CONVERSATION]; + else if(str == "select") attention = &attentions[LOOKAT_TARGET_SELECT]; + else if(str == "focus") attention = &attentions[LOOKAT_TARGET_FOCUS]; + else if(str == "mouselook") attention = &attentions[LOOKAT_TARGET_MOUSELOOK]; + else return FALSE; + + F32 priority, timeout; + attention_node->getAttributeF32("priority", priority); + attention_node->getAttributeF32("timeout", timeout); + if(timeout < 0) timeout = MAX_TIMEOUT; + attention->mPriority = priority; + attention->mTimeout = timeout; + } + return TRUE; +} + +static BOOL loadAttentions() +{ + static BOOL first_time = TRUE; + if( ! first_time) + { + return TRUE; // maybe not ideal but otherwise it can continue to fail forever. + } + first_time = FALSE; + + std::string filename; + filename = gDirUtilp->getExpandedFilename(LL_PATH_CHARACTER,"attentions.xml"); + LLXmlTree xml_tree; + BOOL success = xml_tree.parseFile( filename, FALSE ); + if( !success ) + { + return FALSE; + } + LLXmlTreeNode* root = xml_tree.getRoot(); + if( !root ) + { + return FALSE; + } + + //------------------------------------------------------------------------- + // (root) + //------------------------------------------------------------------------- + if( !root->hasName( "linden_attentions" ) ) + { + llwarns << "Invalid linden_attentions file header: " << filename << llendl; + return FALSE; + } + + std::string version; + static LLStdStringHandle version_string = LLXmlTree::addAttributeString("version"); + if( !root->getFastAttributeString( version_string, version ) || (version != "1.0") ) + { + llwarns << "Invalid linden_attentions file version: " << version << llendl; + return FALSE; + } + + //------------------------------------------------------------------------- + // + //------------------------------------------------------------------------- + for (LLXmlTreeNode* child = root->getChildByName( "gender" ); + child; + child = root->getNextNamedChild()) + { + if( !loadGender( child ) ) + { + return FALSE; + } + } + + return TRUE; +} + + + + +//----------------------------------------------------------------------------- +// LLHUDEffectLookAt() +//----------------------------------------------------------------------------- +LLHUDEffectLookAt::LLHUDEffectLookAt(const U8 type) : + LLHUDEffect(type), + mKillTime(0.f), + mLastSendTime(0.f) +{ + clearLookAtTarget(); + // parse the default sets + loadAttentions(); + // initialize current attention set. switches when avatar sex changes. + mAttentions = &gGirlAttentions; +} + +//----------------------------------------------------------------------------- +// ~LLHUDEffectLookAt() +//----------------------------------------------------------------------------- +LLHUDEffectLookAt::~LLHUDEffectLookAt() +{ +} + +//----------------------------------------------------------------------------- +// packData() +//----------------------------------------------------------------------------- +void LLHUDEffectLookAt::packData(LLMessageSystem *mesgsys) +{ + // Pack the default data + LLHUDEffect::packData(mesgsys); + + // Pack the type-specific data. Uses a fun packed binary format. Whee! + U8 packed_data[PKT_SIZE]; + memset(packed_data, 0, PKT_SIZE); + + if (mSourceObject) + { + htonmemcpy(&(packed_data[SOURCE_AVATAR]), mSourceObject->mID.mData, MVT_LLUUID, 16); + } + else + { + htonmemcpy(&(packed_data[SOURCE_AVATAR]), LLUUID::null.mData, MVT_LLUUID, 16); + } + + // pack both target object and position + // position interpreted as offset if target object is non-null + if (mTargetObject) + { + htonmemcpy(&(packed_data[TARGET_OBJECT]), mTargetObject->mID.mData, MVT_LLUUID, 16); + } + else + { + htonmemcpy(&(packed_data[TARGET_OBJECT]), LLUUID::null.mData, MVT_LLUUID, 16); + } + + htonmemcpy(&(packed_data[TARGET_POS]), mTargetOffsetGlobal.mdV, MVT_LLVector3d, 24); + + U8 lookAtTypePacked = (U8)mTargetType; + + htonmemcpy(&(packed_data[LOOKAT_TYPE]), &lookAtTypePacked, MVT_U8, 1); + + mesgsys->addBinaryDataFast(_PREHASH_TypeData, packed_data, PKT_SIZE); + + mLastSendTime = mTimer.getElapsedTimeF32(); +} + +//----------------------------------------------------------------------------- +// unpackData() +//----------------------------------------------------------------------------- +void LLHUDEffectLookAt::unpackData(LLMessageSystem *mesgsys, S32 blocknum) +{ + LLVector3d new_target; + U8 packed_data[PKT_SIZE]; + + LLUUID dataId; + mesgsys->getUUIDFast(_PREHASH_Effect, _PREHASH_ID, dataId, blocknum); + + if (!gAgent.mLookAt.isNull() && dataId == gAgent.mLookAt->getID()) + { + return; + } + + LLHUDEffect::unpackData(mesgsys, blocknum); + LLUUID source_id; + LLUUID target_id; + S32 size = mesgsys->getSizeFast(_PREHASH_Effect, blocknum, _PREHASH_TypeData); + if (size != PKT_SIZE) + { + llwarns << "LookAt effect with bad size " << size << llendl; + return; + } + mesgsys->getBinaryDataFast(_PREHASH_Effect, _PREHASH_TypeData, packed_data, PKT_SIZE, blocknum); + + htonmemcpy(source_id.mData, &(packed_data[SOURCE_AVATAR]), MVT_LLUUID, 16); + + LLViewerObject *objp = gObjectList.findObject(source_id); + if (objp && objp->isAvatar()) + { + setSourceObject(objp); + } + else + { + //llwarns << "Could not find source avatar for lookat effect" << llendl; + return; + } + + htonmemcpy(target_id.mData, &(packed_data[TARGET_OBJECT]), MVT_LLUUID, 16); + + objp = gObjectList.findObject(target_id); + + htonmemcpy(new_target.mdV, &(packed_data[TARGET_POS]), MVT_LLVector3d, 24); + + if (objp) + { + setTargetObjectAndOffset(objp, new_target); + } + else if (target_id.isNull()) + { + setTargetPosGlobal(new_target); + } + else + { + //llwarns << "Could not find target object for lookat effect" << llendl; + } + + U8 lookAtTypeUnpacked = 0; + htonmemcpy(&lookAtTypeUnpacked, &(packed_data[LOOKAT_TYPE]), MVT_U8, 1); + mTargetType = (ELookAtType)lookAtTypeUnpacked; + + if (mTargetType == LOOKAT_TARGET_NONE) + { + clearLookAtTarget(); + } +} + +//----------------------------------------------------------------------------- +// setTargetObjectAndOffset() +//----------------------------------------------------------------------------- +void LLHUDEffectLookAt::setTargetObjectAndOffset(LLViewerObject *objp, LLVector3d offset) +{ + mTargetObject = objp; + mTargetOffsetGlobal = offset; +} + +//----------------------------------------------------------------------------- +// setTargetPosGlobal() +//----------------------------------------------------------------------------- +void LLHUDEffectLookAt::setTargetPosGlobal(const LLVector3d &target_pos_global) +{ + mTargetObject = NULL; + mTargetOffsetGlobal = target_pos_global; +} + +//----------------------------------------------------------------------------- +// setLookAt() +// called by agent logic to set look at behavior locally, and propagate to sim +//----------------------------------------------------------------------------- +BOOL LLHUDEffectLookAt::setLookAt(ELookAtType target_type, LLViewerObject *object, LLVector3 position) +{ + if (!mSourceObject) + { + return FALSE; + } + + if (target_type >= LOOKAT_NUM_TARGETS) + { + llwarns << "Bad target_type " << (int)target_type << " - ignoring." << llendl; + return FALSE; + } + + // must be same or higher priority than existing effect + if ((*mAttentions)[target_type].mPriority < (*mAttentions)[mTargetType].mPriority) + { + return FALSE; + } + + F32 current_time = mTimer.getElapsedTimeF32(); + + // type of lookat behavior or target object has changed + BOOL lookAtChanged = (target_type != mTargetType) || (object != mTargetObject); + + // lookat position has moved a certain amount and we haven't just sent an update + lookAtChanged = lookAtChanged || ((dist_vec(position, mLastSentOffsetGlobal) > MIN_DELTAPOS_FOR_UPDATE) && + ((current_time - mLastSendTime) > (1.f / MAX_SENDS_PER_SEC))); + + if (lookAtChanged) + { + mLastSentOffsetGlobal = position; + F32 timeout = (*mAttentions)[target_type].mTimeout; + setDuration(timeout); + setNeedsSendToSim(TRUE); + } + + if (target_type == LOOKAT_TARGET_CLEAR) + { + clearLookAtTarget(); + } + else + { + mTargetType = target_type; + mTargetObject = object; + if (object) + { + mTargetOffsetGlobal.setVec(position); + } + else + { + mTargetOffsetGlobal = gAgent.getPosGlobalFromAgent(position); + } + mKillTime = mTimer.getElapsedTimeF32() + mDuration; + + update(); + } + return TRUE; +} + +//----------------------------------------------------------------------------- +// clearLookAtTarget() +//----------------------------------------------------------------------------- +void LLHUDEffectLookAt::clearLookAtTarget() +{ + mTargetObject = NULL; + mTargetOffsetGlobal.clearVec(); + mTargetType = LOOKAT_TARGET_NONE; + if (mSourceObject.notNull()) + { + ((LLVOAvatar*)(LLViewerObject*)mSourceObject)->stopMotion(ANIM_AGENT_HEAD_ROT); + } +} + +//----------------------------------------------------------------------------- +// markDead() +//----------------------------------------------------------------------------- +void LLHUDEffectLookAt::markDead() +{ + if (mSourceObject.notNull()) + { + ((LLVOAvatar*)(LLViewerObject*)mSourceObject)->removeAnimationData("LookAtPoint"); + } + + mSourceObject = NULL; + clearLookAtTarget(); + LLHUDEffect::markDead(); +} + +void LLHUDEffectLookAt::setSourceObject(LLViewerObject* objectp) +{ + // restrict source objects to avatars + if (objectp && objectp->isAvatar()) + { + LLHUDEffect::setSourceObject(objectp); + } +} + +//----------------------------------------------------------------------------- +// render() +//----------------------------------------------------------------------------- +void LLHUDEffectLookAt::render() +{ + if (gSavedSettings.getBOOL("PrivateLookAt") && + (gAgent.getAvatarObject() == ((LLVOAvatar*)(LLViewerObject*)mSourceObject))) return; + if (sDebugLookAt && mSourceObject.notNull()) + { + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + + LLVector3 target = mTargetPos + ((LLVOAvatar*)(LLViewerObject*)mSourceObject)->mHeadp->getWorldPosition(); + glMatrixMode(GL_MODELVIEW); + gGL.pushMatrix(); + gGL.translatef(target.mV[VX], target.mV[VY], target.mV[VZ]); + glScalef(0.3f, 0.3f, 0.3f); + gGL.begin(LLRender::LINES); + { + LLColor3 color = (*mAttentions)[mTargetType].mColor; + gGL.color3f(color.mV[VRED], color.mV[VGREEN], color.mV[VBLUE]); + gGL.vertex3f(-1.f, 0.f, 0.f); + gGL.vertex3f(1.f, 0.f, 0.f); + + gGL.vertex3f(0.f, -1.f, 0.f); + gGL.vertex3f(0.f, 1.f, 0.f); + + gGL.vertex3f(0.f, 0.f, -1.f); + gGL.vertex3f(0.f, 0.f, 1.f); + } gGL.end(); + gGL.popMatrix(); + // + const std::string text = ((LLVOAvatar*)(LLViewerObject*)mSourceObject)->getFullname(); + LLVector3 offset = gAgent.getCameraPositionAgent() - target; + offset.normalize(); + LLVector3 shadow_offset = offset * 0.49f; + offset *= 0.5f; + const LLFontGL* font = LLResMgr::getInstance()->getRes(LLFONT_SANSSERIF); + LLGLEnable gl_blend(GL_BLEND); + glPushMatrix(); + gViewerWindow->setupViewport(); + hud_render_utf8text(text, + target + shadow_offset, + *font, + LLFontGL::NORMAL, + -0.5f * font->getWidthF32(text) + 2.0f, + -2.0f, + LLColor4::black, + FALSE); + hud_render_utf8text(text, + target + offset, + *font, + LLFontGL::NORMAL, + -0.5f * font->getWidthF32(text), + 0.0f, + (*mAttentions)[mTargetType].mColor, + FALSE); + glPopMatrix(); + // + } +} + +//----------------------------------------------------------------------------- +// update() +//----------------------------------------------------------------------------- +void LLHUDEffectLookAt::update() +{ + // If the target object is dead, set the target object to NULL + if (!mTargetObject.isNull() && mTargetObject->isDead()) + { + clearLookAtTarget(); + } + + // if source avatar is null or dead, mark self as dead and return + if (mSourceObject.isNull() || mSourceObject->isDead()) + { + markDead(); + return; + } + + // make sure the proper set of avatar attention are currently being used. + LLVOAvatar* source_avatar = (LLVOAvatar*)(LLViewerObject*)mSourceObject; + // for now the first cut will just switch on sex. future development could adjust + // timeouts according to avatar age and/or other features. + mAttentions = (source_avatar->getSex() == SEX_MALE) ? &gBoyAttentions : &gGirlAttentions; + //printf("updated to %s\n", (source_avatar->getSex() == SEX_MALE) ? "male" : "female"); + + F32 time = mTimer.getElapsedTimeF32(); + + // clear out the effect if time is up + if (mKillTime != 0.f && time > mKillTime) + { + if (mTargetType != LOOKAT_TARGET_NONE) + { + clearLookAtTarget(); + // look at timed out (only happens on own avatar), so tell everyone + setNeedsSendToSim(TRUE); + } + } + + if (mTargetType != LOOKAT_TARGET_NONE) + { + if (calcTargetPosition()) + { + LLMotion* head_motion = ((LLVOAvatar*)(LLViewerObject*)mSourceObject)->findMotion(ANIM_AGENT_HEAD_ROT); + if (!head_motion || head_motion->isStopped()) + { + ((LLVOAvatar*)(LLViewerObject*)mSourceObject)->startMotion(ANIM_AGENT_HEAD_ROT); + } + } + } + + if (sDebugLookAt) + { + ((LLVOAvatar*)(LLViewerObject*)mSourceObject)->addDebugText((*mAttentions)[mTargetType].mName); + } +} + +/** + * Initializes the mTargetPos member from the current mSourceObjec and mTargetObject + * (and possibly mTargetOffsetGlobal). + * When mTargetObject is another avatar, it sets mTargetPos to be their eyes. + * + * Has the side-effect of also calling setAnimationData("LookAtPoint") with the new + * mTargetPos on the source object which is assumed to be an avatar. + * + * Returns whether we successfully calculated a finite target position. + */ +bool LLHUDEffectLookAt::calcTargetPosition() +{ + if (gNoRender) + { + return false; + } + + LLViewerObject *target_obj = (LLViewerObject *)mTargetObject; + LLVector3 local_offset; + + if (target_obj) + { + local_offset.setVec(mTargetOffsetGlobal); + } + else + { + local_offset = gAgent.getPosAgentFromGlobal(mTargetOffsetGlobal); + } + + LLVOAvatar* source_avatar = (LLVOAvatar*)(LLViewerObject*)mSourceObject; + + if (target_obj && target_obj->mDrawable.notNull()) + { + LLQuaternion target_rot; + if (target_obj->isAvatar()) + { + LLVOAvatar *target_av = (LLVOAvatar *)target_obj; + + BOOL looking_at_self = source_avatar->isSelf() && target_av->isSelf(); + + // if selecting self, stare forward + if (looking_at_self && mTargetOffsetGlobal.magVecSquared() < MIN_TARGET_OFFSET_SQUARED) + { + //sets the lookat point in front of the avatar + mTargetOffsetGlobal.setVec(5.0, 0.0, 0.0); + local_offset.setVec(mTargetOffsetGlobal); + } + + // look the other avatar in the eye. note: what happens if target is self? -MG + mTargetPos = target_av->mHeadp->getWorldPosition(); + if (mTargetType == LOOKAT_TARGET_MOUSELOOK || mTargetType == LOOKAT_TARGET_FREELOOK) + { + // mouselook and freelook target offsets are absolute + target_rot = LLQuaternion::DEFAULT; + } + else if (looking_at_self && gAgent.cameraCustomizeAvatar()) + { + // *NOTE: We have to do this because animation + // overrides do not set lookat behavior. + // *TODO: animation overrides for lookat behavior. + target_rot = target_av->mPelvisp->getWorldRotation(); + } + else + { + target_rot = target_av->mRoot.getWorldRotation(); + } + } + else // target obj is not an avatar + { + if (target_obj->mDrawable->getGeneration() == -1) + { + mTargetPos = target_obj->getPositionAgent(); + target_rot = target_obj->getWorldRotation(); + } + else + { + mTargetPos = target_obj->getRenderPosition(); + target_rot = target_obj->getRenderRotation(); + } + } + + mTargetPos += (local_offset * target_rot); + } + else // no target obj or it's not drawable + { + mTargetPos = local_offset; + } + + mTargetPos -= source_avatar->mHeadp->getWorldPosition(); + + if (!mTargetPos.isFinite()) + return false; + + source_avatar->setAnimationData("LookAtPoint", (void *)&mTargetPos); + source_avatar->mIdleTimer.reset(); + return true; +} From ae4dcc283cc3b6f2c0b07f82adfe42d39773198e Mon Sep 17 00:00:00 2001 From: CharleyLevenque Date: Sun, 29 Aug 2010 00:40:22 -0400 Subject: [PATCH 2/3] Whole bunch of crash fixes and compiler junk. --- indra/develop.py | 2 +- indra/llimagej2coj/llimagej2coj.cpp | 6 +- .../skins/default/xui/uk/mime_types.xml | 460 +++++++-------- .../skins/default/xui/zh/mime_types.xml | 524 +++++++++--------- indra/newview/viewer_manifest.py | 8 +- 5 files changed, 502 insertions(+), 498 deletions(-) diff --git a/indra/develop.py b/indra/develop.py index 48fc7427e..883e81234 100755 --- a/indra/develop.py +++ b/indra/develop.py @@ -656,7 +656,7 @@ class WindowsSetup(PlatformSetup): continue vstool_cmd = (os.path.join('tools','vstool','VSTool.exe') + ' --solution ' + - os.path.join(build_dir,'SecondLife.sln') + + os.path.join(build_dir,'Ascent.sln') + ' --config ' + self.build_type + ' --startup secondlife-bin') print 'Running %r in %r' % (vstool_cmd, getcwd()) diff --git a/indra/llimagej2coj/llimagej2coj.cpp b/indra/llimagej2coj/llimagej2coj.cpp index 97a4e358e..26c6f76ee 100644 --- a/indra/llimagej2coj/llimagej2coj.cpp +++ b/indra/llimagej2coj/llimagej2coj.cpp @@ -115,6 +115,8 @@ BOOL LLImageJ2COJ::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decod // if (!base.getData()) return FALSE; if (!base.getDataSize()) return FALSE; + if (!raw_image.getData()) return FALSE; + if (!raw_image.getDataSize()) return FALSE; LLTimer decode_timer; @@ -156,6 +158,7 @@ BOOL LLImageJ2COJ::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decod /* decode the stream and fill the image structure */ if (!cio) return FALSE; + if (cio->bp == NULL) return FALSE; if (!dinfo) return FALSE; image = opj_decode(dinfo, cio); @@ -463,9 +466,10 @@ BOOL LLImageJ2COJ::getMetadata(LLImageJ2C &base) /* open a byte stream */ cio = opj_cio_open((opj_common_ptr)dinfo, base.getData(), base.getDataSize()); - + /* decode the stream and fill the image structure */ if (!cio) return FALSE; + if (cio->bp == NULL) return FALSE; if (!dinfo) return FALSE; image = opj_decode(dinfo, cio); diff --git a/indra/newview/skins/default/xui/uk/mime_types.xml b/indra/newview/skins/default/xui/uk/mime_types.xml index a21f365d0..a7118073f 100644 --- a/indra/newview/skins/default/xui/uk/mime_types.xml +++ b/indra/newview/skins/default/xui/uk/mime_types.xml @@ -1,230 +1,230 @@ - - - - - - Це місце має веб-контент - - - Показати веб-контент - - - - - - Тут програється фільм - - - Програти фільм - - - - - - Тут немає медіа - - - - - - В цьому місці є зображення - - - Переглянути зображення в цьому місці - - - - - - В цьому місці програється аудіо - - - Прослухати аудіо в цьому місці - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + Це місце має веб-контент + + + Показати веб-контент + + + + + + Тут програється фільм + + + Програти фільм + + + + + + Тут немає медіа + + + + + + В цьому місці є зображення + + + Переглянути зображення в цьому місці + + + + + + В цьому місці програється аудіо + + + Прослухати аудіо в цьому місці + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/indra/newview/skins/default/xui/zh/mime_types.xml b/indra/newview/skins/default/xui/zh/mime_types.xml index 089597dac..fc5fae414 100644 --- a/indra/newview/skins/default/xui/zh/mime_types.xml +++ b/indra/newview/skins/default/xui/zh/mime_types.xml @@ -1,262 +1,262 @@ - - - - (未知) - - - 无 - - - LLMediaImplLLMozLib - - - - - 该区域有网页内容 - - - 显示网页内容 - - - - - - 这里可以播放影片 - - - 播放影片 - - - - - - 这里没有媒体 - - - - - - - 这里有图像 - - - 显示该位置的图像 - - - - - audio/* - - 这里可以播放音频 - - - 播放该位置的音频 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image - - - - - - movie - - - - - - - - - image - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text - - - LLMediaImplLLMozLib - - - - - - - - - - - - movie - - - LLMediaImplQuickTime - - - - - - - - - - - - + + + + (未知) + + + 无 + + + LLMediaImplLLMozLib + + + + + 该区域有网页内容 + + + 显示网页内容 + + + + + + 这里可以播放影片 + + + 播放影片 + + + + + + 这里没有媒体 + + + + + + + 这里有图像 + + + 显示该位置的图像 + + + + + audio/* + + 这里可以播放音频 + + + 播放该位置的音频 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image + + + + + + movie + + + + + + + + + image + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text + + + LLMediaImplLLMozLib + + + + + + + + + + + + movie + + + LLMediaImplQuickTime + + + + + + + + + + + + diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index 6420a96d2..44fab8a81 100755 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -163,13 +163,13 @@ class WindowsManifest(ViewerManifest): def final_exe(self): if self.default_channel() and self.viewer_branding_id()=="secondlife": if self.default_grid(): - return "SecondLife.exe" + return "Ascent.exe" else: - return "SecondLifePreview.exe" + return "Ascent.exe" elif(self.viewer_branding_id=="snowglobe"): - return "Snowglobe.exe" + return "Ascent.exe" else: - return ''.join(self.channel().split()) + '.exe' + return 'Ascent.exe' def construct(self): From 137dc30c148b99d8f9ce23d6e4e42ba45eefcf81 Mon Sep 17 00:00:00 2001 From: CharleyLevenque Date: Sun, 29 Aug 2010 07:01:20 -0400 Subject: [PATCH 3/3] Fully implemented Breast Physics, but the boobies still don't bounce. Put in some other stuff for OTR (I think?) Finally added the client_definitions XML file to the versioning system. --- indra/llcharacter/llcharacter.cpp | 3 +- indra/llcharacter/llcharacter.h | 6 +- indra/newview/CMakeLists.txt | 6 + .../app_settings/client_definitions.xml | 647 ++++++++++++++++++ indra/newview/app_settings/settings.xml | 88 +++ indra/newview/dhparam.cpp | 42 ++ indra/newview/dsaparam.cpp | 69 ++ indra/newview/emerald.cpp | 593 ++++++++++++++++ indra/newview/emerald.h | 107 +++ indra/newview/emeraldboobutils.cpp | 189 +++++ indra/newview/emeraldboobutils.h | 197 ++++++ indra/newview/llviewercontrol.cpp | 51 ++ indra/newview/llvoavatar.cpp | 245 ++++--- indra/newview/llvoavatar.h | 102 +-- .../en-us/panel_preferences_ascent_vanity.xml | 29 +- 15 files changed, 2212 insertions(+), 162 deletions(-) create mode 100644 indra/newview/app_settings/client_definitions.xml create mode 100644 indra/newview/dhparam.cpp create mode 100644 indra/newview/dsaparam.cpp create mode 100644 indra/newview/emerald.cpp create mode 100644 indra/newview/emerald.h create mode 100644 indra/newview/emeraldboobutils.cpp create mode 100644 indra/newview/emeraldboobutils.h diff --git a/indra/llcharacter/llcharacter.cpp b/indra/llcharacter/llcharacter.cpp index 6633c6531..dcdfe074e 100644 --- a/indra/llcharacter/llcharacter.cpp +++ b/indra/llcharacter/llcharacter.cpp @@ -55,7 +55,8 @@ LLCharacter::LLCharacter() mPreferredPelvisHeight( 0.f ), mSex( SEX_FEMALE ), mAppearanceSerialNum( 0 ), - mSkeletonSerialNum( 0 ) + mSkeletonSerialNum( 0 ), + mInAppearance( false ) { mMotionController.setCharacter( this ); sInstances.push_back(this); diff --git a/indra/llcharacter/llcharacter.h b/indra/llcharacter/llcharacter.h index 011278888..a7d9d348e 100644 --- a/indra/llcharacter/llcharacter.h +++ b/indra/llcharacter/llcharacter.h @@ -253,6 +253,10 @@ public: ESex getSex() { return mSex; } void setSex( ESex sex ) { mSex = sex; } + // set appearance flag + void setAppearanceFlag( bool flag ) { mInAppearance = flag; } + bool getAppearanceFlag() { return mInAppearance; } + U32 getAppearanceSerialNum() const { return mAppearanceSerialNum; } void setAppearanceSerialNum( U32 num ) { mAppearanceSerialNum = num; } @@ -272,7 +276,7 @@ protected: U32 mAppearanceSerialNum; U32 mSkeletonSerialNum; LLAnimPauseRequest mPauseRequest; - + BOOL mInAppearance; private: // visual parameter stuff diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 4ae918fa7..f464a5ea0 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -64,6 +64,10 @@ include_directories( ) set(viewer_SOURCE_FILES + dhparam.cpp + dsaparam.cpp + emerald.cpp + emeraldboobutils.cpp dofloaterhex.cpp dohexeditor.cpp floatersculptpreview.cpp @@ -509,6 +513,8 @@ set(viewer_HEADER_FILES CMakeLists.txt ViewerInstall.cmake + emerald.h + emeraldboobutils.h dofloaterhex.h dohexeditor.h floatersculptpreview.h diff --git a/indra/newview/app_settings/client_definitions.xml b/indra/newview/app_settings/client_definitions.xml new file mode 100644 index 000000000..004c63002 --- /dev/null +++ b/indra/newview/app_settings/client_definitions.xml @@ -0,0 +1,647 @@ + + + 8873757c-092a-98fb-1afd-ecd347566fcd + + color + + 0.0375 + 1 + 1 + 1 + + multiple + 0 + name + Ascent + + f12457b5-762e-52a7-efad-8f17f3b022ee + + color + + 0.69999999999999996 + 0.80000000000000004 + 1.6000000238418579 + 1 + + multiple + 2 + name + Anti-Life + + 0f6723d2-5b23-6b58-08ab-308112b33786 + + color + + 0 + 2 + 2 + 1 + + multiple + 2 + name + CryoLife + + e52d21f7-3c8b-819f-a3db-65c432295dac + + color + + 0 + 2 + 2 + 1 + + multiple + 2 + name + CryoLife + + d0091f21-1eef-a4ad-b358-249a8e5432ea + + color + + 0 + 2 + 2 + 1 + + multiple + 2 + name + CryoLife + + 7c4d47a3-0c51-04d1-fa47-e4f3ac12f59b + + color + + 0 + 2 + 2 + 1 + + multiple + 2 + name + CryoLife + + 8183e823-c443-2142-6eb6-2ab763d4f81c + + color + + 0 + 0 + 1 + 1 + + multiple + 1 + name + Day Oh proxy + + emeraldTags + + Blue + 4eb67510-0924-ebb1-50ca-8af5694cd267 + Default + bf33bd15-7020-cce1-3725-48923440b7ee + Fuchsia + e4117c3f-cc02-d537-665d-c31b8c11bb18 + Green + ccda2b3b-e72c-a112-e126-fee238b67218 + Orange + e741e2bf-cf8c-191c-97f2-b2709a843dfc + Pink + 072343d0-1ce9-0952-4106-5312af4a789a + Purple + 0ae2f973-98c1-a4e8-9f4b-9db2044ab079 + Red + 1da8eb54-a70f-bd4a-77e5-c7b815c3b2a2 + Violet + 602243f4-8fb1-ac00-d5bc-7ab50c4433b7 + White + 1e0948ab-706a-b309-434c-a694436a79be + Yellow + 8078ffb3-840c-d037-caf3-5cd02c2e7040 + + 072343d0-1ce9-0952-4106-5312af4a789a + + color + + 2 + 1 + 1.6000000000000001 + 1 + + multiple + 2 + name + Emerald + + 0ae2f973-98c1-a4e8-9f4b-9db2044ab079 + + color + + 1.2 + 0.40000000000000002 + 1.6000000000000001 + 1 + + multiple + 2 + name + Emerald + + 1da8eb54-a70f-bd4a-77e5-c7b815c3b2a2 + + color + + 2 + 0 + 0 + 1 + + multiple + 2 + name + Emerald + + 1e0948ab-706a-b309-434c-a694436a79be + + color + + 2 + 2 + 2 + 1 + + multiple + 1 + name + Emerald + + 4eb67510-0924-ebb1-50ca-8af5694cd267 + + color + + 0.34999999999999998 + 0.34999999999999998 + 2 + 1 + + multiple + 0 + name + Emerald + + 602243f4-8fb1-ac00-d5bc-7ab50c4433b7 + + color + + 0.5 + 0 + 2 + 1 + + multiple + 0 + name + Emerald + + 8078ffb3-840c-d037-caf3-5cd02c2e7040 + + color + + 2 + 2 + 0 + 1 + + multiple + 1 + name + Emerald + + bf33bd15-7020-cce1-3725-48923440b7ee + + color + + 0.97999999999999998 + 0.68999999999999995 + 0.34000000000000002 + 1 + + multiple + 0 + name + Emerald + + ccda2b3b-e72c-a112-e126-fee238b67218 + + color + + 0 + 2 + 0 + 1 + + multiple + 2 + name + Emerald + + e4117c3f-cc02-d537-665d-c31b8c11bb18 + + color + + 2 + 0 + 2 + 1 + + multiple + 0 + name + Emerald + + e741e2bf-cf8c-191c-97f2-b2709a843dfc + + color + + 2 + 0.5 + 0 + 1 + + multiple + 2 + name + Emerald + + 734fed29-4c51-63e5-1648-6589949d7585 + + color + + 0.6 + 0.42745 + 0.80784 + 1 + + multiple + 0 + name + Explicit + + 1c29480c-c608-df87-28bb-964fb64c5366 + + color + + 1.6000000238418579 + 1.6000000238418579 + 0.80000001192092896 + 1 + + multiple + 0 + name + Gemini + + 4da16427-d81e-e816-f346-aaf4741b8056 + + color + + 2 + 2 + 2 + 2 + + multiple + 2 + name + iLife + + cc7a030f-282f-c165-44d2-b5ee572e72bf + + color + + 6.2999999999999998 + 3.5 + 7 + 1 + + multiple + 8 + name + Imprudence + + 5aa5c70d-d787-571b-0495-4fc1bdef1500 + + color + + 2 + 0 + 0 + 1 + + multiple + 2 + name + LGG proxy + + 2a9a406c-f448-68f2-4e38-878f8c46c190 + + color + + 1 + 0.89999997615814209 + 0.69999998807907104 + 1 + + multiple + 1 + name + Meerkat + + b6820989-bf42-ff59-ddde-fd3fd3a74fe4 + + color + + 1 + 0.89999997615814209 + 0.69999998807907104 + 1 + + multiple + 1 + name + Meerkat + + 0bcd5f5d-a4ce-9ea4-f9e8-15132653b3d8 + + color + + 2 + 1 + 1.6000000238418579 + 1 + + multiple + 2 + name + MoyMix + + 9ba526b6-f43d-6b60-42de-ce62a25ee7fb + + color + + 1 + 1 + 1 + 1 + + multiple + 0 + name + nolife + + 77662f23-c77a-9b4d-5558-26b757b2144c + + color + + 0.60000002384185791 + 0.20000000298023224 + 0.80000001192092896 + 1 + + multiple + 1 + name + PSL + + d95e0d9a-4d40-ea1b-a054-8db87f583f58 + + color + + 2 + 2 + 0 + 1 + + multiple + 0 + name + NeilLife + + e6f9c019-8783-dc3e-b265-41f1510333fc + + color + + 2 + 2 + 0 + 1 + + multiple + 0 + name + NeilLife + + f5a48821-9a98-d09e-8d6a-50cc08ba9a47 + + color + + 2 + 2 + 0 + 1 + + multiple + 2 + name + NeilLife + + f5feab57-bde5-2074-97af-517290213eaa + + color + + 2 + 2 + 0 + 1 + + multiple + 2 + name + NeilLife + + f3fd74a6-fee7-4b2f-93ae-ddcb5991da04 + + color + + 0.60000002384185791 + 0.20000000298023224 + 0.80000001192092896 + 1 + + multiple + 1 + name + PSL + + d3eb4a5f-aec5-4bcb-b007-cce9efe89d37 + + color + + 0 + 0.60000002384185791 + 0 + 2 + + multiple + 2 + name + rivlife + + ccb509cf-cc69-e569-38f1-5086c687afd1 + + color + + 1.6000000238418579 + 0.20000000298023224 + 0.80000001192092896 + 2 + + multiple + 2 + name + Ruby + + 872c0005-3095-0967-866d-11cd71115c22 + + color + + 0 + 1 + 2 + 3 + + multiple + 3 + name + Simfed + + 11ad2452-ce54-8d65-7c23-05589b59f516 + + color + + 0 + 0.5 + 1 + 1 + + multiple + 1 + name + VerticalLife + + e734563e-1c31-2a35-3ed5-8552c807439f + + color + + 0 + 0.5 + 1 + 1 + + multiple + 1 + name + VerticalLife + + 3ab7e2fa-9572-ef36-1a30-d855dbea4f92 + + color + + 0 + 0.5 + 1 + 1 + + multiple + 1 + name + VerticalLife + + 58a8b7ec-1455-7162-5d96-d3c3ead2ed71 + + color + + 0 + 0.5 + 1 + 1 + + multiple + 1 + name + VerticalLife + + 841ef25b-3b90-caf9-ea3d-5649e755db65 + + color + + 0 + 0.5 + 1 + 1 + + multiple + 1 + name + VerticalLife + + c228d1cf-4b5d-4ba8-84f4-899a0796aa97 + + color + + 1 + 0.55000000000000004 + 0.75 + 1 + + multiple + 1 + name + Viewer 2.0 + + c252d89d-6f7c-7d90-f430-d140d2e3fbbe + + color + + 1 + 0 + 0 + 1 + + multiple + 1 + name + VLife + + c58fca06-33b3-827d-d81c-a886a631affc + + color + + 1 + 0.61175999999999997 + 0 + 1 + + multiple + 0 + name + Whale + + isComplete + true + + diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 11a7afb9a..291e08e46 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -114,6 +114,94 @@ 0 + EmeraldBoobMass + + Comment + Mass of boobs. + Persist + 1 + Type + F32 + Value + 54.0 + + EmeraldBoobHardness + + Comment + Hardness (dampening) of boobs. + Persist + 1 + Type + F32 + Value + 51 + + EmeraldBreastPhysicsToggle + + Comment + Enables/Disables breast physics + Persist + 1 + Type + Boolean + Value + 1 + + EmeraldBreastSportsBra + + Comment + allows disabling the physics for 1 av, in case their outfit looks wrong with it on + Persist + 1 + Type + Boolean + Value + 0 + + EmeraldBoobVelMax + + Comment + Max amount of velocity boobs can have + Persist + 1 + Type + F32 + Value + 64 + + EmeraldBoobFriction + + Comment + Internal friction (brings boobs to rest). Shouldn't ever be above 1. + Persist + 1 + Type + F32 + Value + 80 + + EmeraldBoobVelMin + + Comment + Friction Fraction of FPS (used to keep friction uniform through FPS change). + Persist + 1 + Type + F32 + Value + 24 + + EmeraldBoobXYInfluence + + Comment + Amount of influence along the X and Y planes. + Persist + 1 + Type + F32 + Value + 0.1 + AscentCmdLine Comment diff --git a/indra/newview/dhparam.cpp b/indra/newview/dhparam.cpp new file mode 100644 index 000000000..917eb714d --- /dev/null +++ b/indra/newview/dhparam.cpp @@ -0,0 +1,42 @@ +/* Generated using openssl */ +#include "llviewerprecompiledheaders.h" +#include + +DH *get_dh2048() + { + static unsigned char dh2048_p[]={ + 0xAC,0x31,0xAA,0xFD,0x76,0x1B,0x47,0x24,0x99,0x6D,0xF8,0xD5, + 0x5B,0x4B,0xD1,0x7E,0xF9,0x1A,0x41,0xF6,0x29,0xCC,0xA9,0x02, + 0x6B,0xED,0xFD,0xC9,0x37,0xCE,0xF6,0x11,0x78,0x6F,0x37,0x38, + 0x7D,0x49,0x3F,0x78,0x36,0x83,0x0A,0x6F,0xBA,0x6F,0x74,0xD9, + 0xB1,0xC1,0xC4,0x5A,0x7D,0x84,0x26,0x56,0x8B,0x53,0xF4,0xFE, + 0xD1,0x34,0xF1,0xE0,0x08,0x65,0xA6,0xFD,0xDB,0x5D,0xAC,0x14, + 0xCD,0xC9,0x7E,0x79,0xE9,0x3B,0xAF,0x92,0xC7,0x4D,0x91,0x15, + 0x0B,0x1E,0x2F,0x0A,0x56,0x4E,0x0D,0x3A,0x4D,0x9E,0xB0,0xB5, + 0xFC,0x0D,0xB1,0x55,0x40,0xC6,0x30,0x99,0xCD,0xE8,0x7E,0x72, + 0x08,0x93,0x9C,0x7F,0x55,0x23,0x27,0x09,0xF4,0x50,0xF2,0x96, + 0xB5,0x30,0x35,0x6A,0x99,0x4C,0xD6,0x85,0x72,0x8D,0x9C,0x19, + 0x70,0x9A,0x77,0x52,0xE8,0x33,0x03,0x7A,0x00,0xDA,0xFE,0xD7, + 0x98,0xD0,0x7B,0x26,0xBA,0xD7,0xFF,0xD1,0x49,0x61,0x27,0x3E, + 0xFC,0x12,0x81,0xC9,0xB0,0xAF,0x34,0x14,0x97,0x66,0xFB,0xEF, + 0xD3,0xFE,0xC9,0x01,0x25,0xEC,0xF4,0xE8,0xA8,0xD8,0x21,0x45, + 0x20,0x6F,0xFC,0xA8,0xB3,0xCE,0xCF,0x0D,0xA1,0x14,0xCC,0x38, + 0x81,0x74,0x6A,0x5E,0x36,0x09,0x1D,0xBE,0x4C,0x08,0x52,0x5E, + 0xC2,0x5F,0xA4,0x48,0x3A,0x71,0x85,0xF2,0x97,0x32,0xEC,0x3B, + 0xFB,0x1B,0x9A,0x8A,0x4B,0x20,0x32,0xFE,0x6A,0x94,0x4C,0x02, + 0xB2,0xD7,0xC3,0x1B,0xF8,0x90,0x54,0x76,0x70,0x49,0x81,0x86, + 0x30,0x12,0xD2,0x91,0xF0,0xFD,0x1B,0x53,0x2E,0x60,0x13,0x78, + 0x8B,0x3F,0x1B,0x13, + }; + static unsigned char dh2048_g[]={ + 0x05, + }; + DH *dh; + + if ((dh=DH_new()) == NULL) return(NULL); + dh->p=BN_bin2bn(dh2048_p,sizeof(dh2048_p),NULL); + dh->g=BN_bin2bn(dh2048_g,sizeof(dh2048_g),NULL); + if ((dh->p == NULL) || (dh->g == NULL)) + { DH_free(dh); return(NULL); } + return(dh); + } diff --git a/indra/newview/dsaparam.cpp b/indra/newview/dsaparam.cpp new file mode 100644 index 000000000..e4c89d40e --- /dev/null +++ b/indra/newview/dsaparam.cpp @@ -0,0 +1,69 @@ +/* Generated using openssl */ +#include "llviewerprecompiledheaders.h" +#include + +static unsigned char dsa2048_p[]={ + 0xD4,0x63,0x93,0xFA,0x69,0x87,0xDB,0x60,0x68,0xFB,0xCC,0x8F, + 0x55,0x85,0x7A,0xAC,0xAD,0x1F,0x8E,0xF0,0x2C,0x62,0x2F,0xE6, + 0xA6,0xA4,0xF3,0x57,0x42,0xDC,0xF0,0xE0,0x0E,0xC6,0x67,0x01, + 0x95,0x22,0x6F,0x03,0x00,0x2A,0xB4,0xBF,0x62,0x6D,0xA1,0xBD, + 0xB7,0x10,0x81,0xB4,0x20,0x1C,0x7D,0x41,0x75,0xCE,0x0F,0xCF, + 0x9D,0x03,0xEC,0xE6,0x7E,0xBC,0x76,0x97,0xBC,0x5C,0x70,0xFE, + 0xD5,0x64,0x15,0x20,0xD8,0xA8,0x25,0x73,0xD4,0xA2,0x77,0x99, + 0xC7,0x3B,0xF7,0x4E,0x20,0x40,0x43,0xD7,0x7C,0xFD,0xBC,0x2F, + 0x75,0xB5,0x18,0xA3,0x8C,0x85,0x79,0x86,0x53,0x62,0x73,0xBA, + 0x66,0x73,0xE2,0x48,0x15,0xAF,0x04,0x65,0xE2,0x4D,0x15,0x47, + 0x74,0x33,0x79,0xAE,0xBF,0x90,0xC0,0xF7,0x2F,0x04,0xFB,0xEE, + 0x29,0xEC,0x42,0xC7,0x36,0x14,0xAC,0xB2,0xBC,0xE1,0x71,0x13, + 0x65,0xBA,0x0D,0x61,0x11,0x89,0x49,0x41,0x5D,0xCC,0xE2,0x72, + 0x7B,0x93,0xF2,0x2E,0xD1,0x23,0x37,0xF9,0xFF,0x55,0x59,0xF6, + 0x41,0x78,0x87,0xC9,0xCD,0x95,0xD2,0xE5,0x1B,0x3A,0x25,0x7A, + 0xD8,0x16,0x2F,0x58,0xFE,0x3B,0xD5,0xB1,0x59,0x63,0x3C,0x90, + 0xA0,0xBF,0xA0,0x21,0x54,0xB0,0xB0,0x3F,0x9D,0xC6,0xB5,0x31, + 0xBA,0x86,0xDC,0x86,0x41,0xB7,0xBA,0xCE,0x58,0x09,0x8B,0xD9, + 0xD4,0xF1,0xD2,0x3B,0x5F,0x87,0xEE,0x66,0xFD,0x77,0x8C,0x2C, + 0x66,0x3E,0xC9,0xDA,0x3E,0x2A,0x38,0x03,0x23,0x71,0xC9,0x04, + 0x3E,0x9D,0x18,0x7F,0xBB,0x82,0x21,0x8E,0x5F,0xF0,0xAF,0xC8, + 0x08,0x2D,0xA6,0x3F, + }; +static unsigned char dsa2048_q[]={ + 0xAE,0xCA,0x67,0x69,0x21,0x7A,0xE1,0x9B,0x64,0x74,0xED,0x58, + 0xF0,0x28,0xE0,0x45,0x2B,0x39,0xBC,0x79, + }; +static unsigned char dsa2048_g[]={ + 0x51,0x1D,0xB0,0xF6,0x4E,0x8B,0xAF,0x1C,0x59,0x71,0x62,0x3C, + 0xC3,0xE2,0x44,0x35,0xCE,0x11,0xB4,0x49,0x04,0x41,0xA1,0x1C, + 0x22,0x59,0x47,0x8C,0x70,0x1D,0xA1,0x0C,0x51,0xFE,0x86,0x43, + 0x7B,0x75,0x5C,0xB7,0x68,0xA5,0xBE,0x81,0x9C,0x6F,0x6D,0x32, + 0x03,0xB0,0x28,0xA4,0x6B,0x5B,0x37,0xC3,0x35,0xCF,0xBD,0x92, + 0xC3,0x66,0x2E,0xAB,0xB4,0x13,0xEC,0x23,0xA3,0xE3,0x09,0x4E, + 0x47,0x7D,0xA5,0x90,0x33,0x80,0x5D,0x68,0xD6,0x39,0x54,0xBE, + 0x35,0xB0,0x61,0x5B,0x96,0x63,0x05,0x67,0xB7,0x3C,0x21,0x17, + 0x37,0x50,0x17,0x78,0xEA,0xC0,0x10,0x73,0xDF,0xE2,0x70,0x19, + 0x17,0xF7,0x11,0x82,0x73,0xDB,0xFF,0x3E,0x8D,0x98,0x2F,0x2F, + 0xA2,0x12,0xC3,0xB4,0x08,0xB2,0x2C,0x5B,0xA3,0x51,0xAA,0x7F, + 0x3D,0xE0,0x74,0x39,0xE5,0xAF,0x81,0x32,0xF8,0x45,0x75,0x11, + 0x35,0xD9,0x90,0xA1,0xA3,0x91,0x1A,0xEE,0xE9,0xAC,0x97,0x30, + 0x4C,0xD5,0x5B,0x38,0x49,0x12,0x3B,0xCC,0x0C,0x84,0xA2,0x59, + 0x78,0xB4,0xFD,0x46,0xAC,0x49,0x43,0x08,0xDB,0xF4,0x23,0xFF, + 0x23,0xF8,0x9A,0xFD,0x15,0xAF,0x6B,0x81,0xCE,0x15,0x22,0xEF, + 0x09,0x64,0x0A,0x1F,0x4D,0x6B,0xF1,0x9F,0x16,0x00,0x3E,0xE8, + 0xFC,0x9A,0x24,0x58,0x1C,0xB4,0x5F,0x56,0x3E,0x83,0x8C,0x0C, + 0x51,0x43,0x72,0x25,0xA8,0x1D,0x08,0x30,0x7E,0x17,0xC8,0xD6, + 0x66,0x57,0x0C,0x59,0x76,0xE4,0xA6,0x0C,0x05,0xA8,0x60,0x1D, + 0xA4,0x8F,0xBC,0xC4,0x67,0x55,0x0E,0x81,0x8F,0x66,0xED,0x1B, + 0x84,0xCD,0x02,0x9F, + }; + +DSA *get_dsa2048() + { + DSA *dsa; + + if ((dsa=DSA_new()) == NULL) return(NULL); + dsa->p=BN_bin2bn(dsa2048_p,sizeof(dsa2048_p),NULL); + dsa->q=BN_bin2bn(dsa2048_q,sizeof(dsa2048_q),NULL); + dsa->g=BN_bin2bn(dsa2048_g,sizeof(dsa2048_g),NULL); + if ((dsa->p == NULL) || (dsa->q == NULL) || (dsa->g == NULL)) + { DSA_free(dsa); return(NULL); } + return(dsa); + } \ No newline at end of file diff --git a/indra/newview/emerald.cpp b/indra/newview/emerald.cpp new file mode 100644 index 000000000..1d89381cf --- /dev/null +++ b/indra/newview/emerald.cpp @@ -0,0 +1,593 @@ +// Copyright (c)2009 Thomas Shikami +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +#include "llviewerprecompiledheaders.h" +#include "emerald.h" +#include +#include + +#include +#include +#include + +//-- Ascii85 encoder and decoder + +typedef unsigned int U32; + +static void encodeU32(unsigned int in, char *out) +{ + out[4] = char(in % 85) + char(33); + in /= 85; + out[3] = char(in % 85) + char(33); + in /= 85; + out[2] = char(in % 85) + char(33); + in /= 85; + out[1] = char(in % 85) + char(33); + in /= 85; + out[0] = char(in % 85) + char(33); +} + +static unsigned int decodeU32(const char *in) +{ + U32 out; + + out = U32(in[0] - 33); + out *= 85; + out += U32(in[1] - 33); + out *= 85; + out += U32(in[2] - 33); + out *= 85; + out += U32(in[3] - 33); + out *= 85; + out += U32(in[4] - 33); + + return out; +} + +// static +std::string EAscii85::encode(const std::vector &in) +{ + std::ostringstream out; + U32 tuple; + int count; + char block[6]; + block[5] = '\0'; + + out << "<~"; + + count = 0; + tuple = 0; + for(size_t i = 0; i < in.size(); i++) + { + tuple <<= 8; + tuple += in[i]; + if(++count == 4) + { + if(tuple == 0) + { + out << "z"; + } + else + { + encodeU32(tuple, block); + out << block; + } + count = 0; + } + } + + switch(count) + { + case 1: + tuple <<= 8; + tuple += 255; + // pass through + case 2: + tuple <<= 8; + tuple += 255; + // pass through + case 3: + tuple <<= 8; + tuple += 255; + } + + encodeU32(tuple, block); + + switch(count) + { + case 1: + block[2] = '\0'; + break; + case 2: + block[3] = '\0'; + break; + case 3: + block[4] = '\0'; + break; + } + + if(count > 0) + out << block; + + out << "~>"; + + return out.str(); +} + +// static +std::vector EAscii85::decode(const std::string &in) +{ + std::vector out; + size_t len; + int count = 0; + char block[6]; + block[5] = '\0'; + U32 tuple; + + // approximate length + len = in.length() / 5 * 4; + + out.clear(); + + if(in.length() < 4) return out; + + std::string::const_iterator i = in.begin(); + + if(*i != '<') return out; + i++; + if(*i != '~') return out; + i++; + + out.reserve(len); + + for(; i != in.end(); i++) + { + char c = *i; + + if(c >= '!' && c < 'v') + { + block[count++] = c; + } + + switch(c) + { + case 'z': + if(count == 1) + { + for(count = 0; count < 4; count++) + out.push_back(0); + count = 0; + } + break; + case '~': + if(count > 1) + { + switch(count) + { + case 2: + block[2] = 'u'; + case 3: + block[3] = 'u'; + case 4: + block[4] = 'u'; + } + tuple = decodeU32(block); + for(;count > 1; count--) + { + out.push_back(char(tuple >> 24)); + tuple <<= 8; + } + count = 0; + } + } + + if(count == 5) + { + tuple = decodeU32(block); + for(count = 0; count < 4; count++) + { + out.push_back(char(tuple >> 24)); + tuple <<= 8; + } + count = 0; + } + } + + return out; +} + +//-- AES wrapper + +class EAESEncrypt::EncryptImpl { +public: + EncryptImpl(const unsigned char *key, const unsigned char *iv); + ~EncryptImpl(); + + std::vector encrypt(const std::string &in); + + EVP_CIPHER_CTX ctx; +}; + +EAESEncrypt::EAESEncrypt(const unsigned char *key, const unsigned char *iv) +{ + mEncryptImpl = new EAESEncrypt::EncryptImpl(key, iv); +} + +EAESEncrypt::EAESEncrypt(const std::vector &key, const std::vector &iv) +{ + mEncryptImpl = new EAESEncrypt::EncryptImpl(&key[0], &iv[0]); +} + +EAESEncrypt::~EAESEncrypt() +{ + delete mEncryptImpl; +} + +std::vector EAESEncrypt::encrypt(const std::string &in) +{ + return mEncryptImpl->encrypt(in); +} + +EAESEncrypt::EncryptImpl::EncryptImpl(const unsigned char *key, const unsigned char *iv) +{ + EVP_CIPHER_CTX_init(&ctx); + EVP_EncryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL, key, iv); +} + +EAESEncrypt::EncryptImpl::~EncryptImpl() +{ + EVP_CIPHER_CTX_cleanup(&ctx); +} + +std::vector EAESEncrypt::EncryptImpl::encrypt(const std::string &in) +{ + std::vector out; + int outlen; + int tmplen; + + out.resize(in.length() + 32); + + EVP_EncryptUpdate(&ctx, &out[0], &outlen, reinterpret_cast(in.c_str()), in.length()); + EVP_EncryptFinal_ex(&ctx, &out[outlen], &tmplen); + + out.resize(outlen + tmplen); + + return out; +} + +class EAESDecrypt::DecryptImpl { +public: + DecryptImpl(const unsigned char *key, const unsigned char *iv); + ~DecryptImpl(); + + std::string decrypt(const std::vector &in); + + EVP_CIPHER_CTX ctx; +}; + +EAESDecrypt::EAESDecrypt(const unsigned char *key, const unsigned char *iv) +{ + mDecryptImpl = new EAESDecrypt::DecryptImpl(key, iv); +} + +EAESDecrypt::EAESDecrypt(const std::vector &key, const std::vector &iv) +{ + mDecryptImpl = new EAESDecrypt::DecryptImpl(&key[0], &iv[0]); +} + +EAESDecrypt::~EAESDecrypt() +{ + delete mDecryptImpl; +} + +EAESDecrypt::DecryptImpl::DecryptImpl(const unsigned char *key, const unsigned char *iv) +{ + EVP_CIPHER_CTX_init(&ctx); + EVP_DecryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL, key, iv); +} + +EAESDecrypt::DecryptImpl::~DecryptImpl() +{ + EVP_CIPHER_CTX_cleanup(&ctx); +} + +std::string EAESDecrypt::decrypt(const std::vector &in) +{ + return mDecryptImpl->decrypt(in); +} + +std::string EAESDecrypt::DecryptImpl::decrypt(const std::vector &in) +{ + std::vector out; + int outlen; + int tmplen; + + if(in.size() == 0) return ""; + + out.resize(in.size() + 32); + + EVP_DecryptUpdate(&ctx, &out[0], &outlen, &in[0], in.size()); + EVP_DecryptFinal_ex(&ctx, &out[outlen], &tmplen); + + out.resize(outlen + tmplen); + + if(out.empty()) + return ""; + + return std::string(reinterpret_cast(&out[0]), out.size()); +} + +EGenKey::EGenKey(const std::string &password, const unsigned char *salt) +{ + EVP_BytesToKey(EVP_aes_128_cbc(), EVP_sha1(), salt, + reinterpret_cast(password.c_str()), password.length(), + 1000, mKey, mIv); +} + +EGenKey::~EGenKey() +{ + memset(mKey, 0, 16); + memset(mIv, 0, 16); +} + +DH *get_dh2048(); + +class BigNum +{ +public: + BigNum(const std::vector &bin) + { + mBN = BN_bin2bn(&(bin[0]), bin.size(), NULL); + } + + BigNum() + { + mBN = BN_new(); + } + + BigNum(const BigNum &other) + { + mBN = BN_dup(*other); + } + + BigNum(BIGNUM *bn) + { + mBN = BN_dup(bn); + } + + ~BigNum() + { + BN_clear_free(mBN); + mBN = NULL; + } + + friend BIGNUM* operator*(const BigNum&); + + BigNum& operator=(const std::vector &bin) + { + mBN = BN_bin2bn(&(bin[0]), bin.size(), mBN); + return *this; + } + + BigNum& operator=(const BigNum& other) + { + BN_copy(mBN, *other); + return *this; + } + + void to(std::vector &dest) + { + dest.resize(BN_num_bytes(mBN)); + BN_bn2bin(mBN, &(dest[0])); + } + + BIGNUM* to(BIGNUM *ret) + { + return BN_copy(ret, mBN); + } + + BIGNUM* dup() + { + return BN_dup(mBN); + } + + static BIGNUM* dup(const std::vector &bin) + { + return BN_bin2bn(&(bin[0]), bin.size(), NULL); + } + +private: + BIGNUM *mBN; +}; + +BIGNUM* operator*(const BigNum& o) { return o.mBN; } + +class EDH::DHImpl +{ +public: + DH *mDH; +}; + +EDH::EDH(const std::vector &priv_key) +{ + mDHImpl = new DHImpl(); + + mDHImpl->mDH = get_dh2048(); + mDHImpl->mDH->priv_key = BigNum::dup(priv_key); + + DH_generate_key(mDHImpl->mDH); +} + +EDH::EDH() +{ + mDHImpl = new DHImpl(); + + mDHImpl->mDH = get_dh2048(); + + DH_generate_key(mDHImpl->mDH); +} + +EDH::~EDH() +{ + if(mDHImpl) + { + if(mDHImpl->mDH) + { + mDHImpl->mDH->priv_key = NULL; + mDHImpl->mDH->pub_key = NULL; + DH_free(mDHImpl->mDH); + mDHImpl->mDH = NULL; + } + delete mDHImpl; + mDHImpl = NULL; + } +} + +void EDH::secretTo(std::vector &secret) +{ + BigNum(mDHImpl->mDH->priv_key).to(secret); +} + +void EDH::publicTo(std::vector &pub) +{ + BigNum(mDHImpl->mDH->pub_key).to(pub); +} + +std::vector EDH::computeKey(const std::vector &other_pub) +{ + std::vector temp; + BigNum pub(other_pub); + temp.resize(DH_size(mDHImpl->mDH)); + + DH_compute_key(&(temp[0]), *pub, mDHImpl->mDH); + + return temp; +} + +DSA *get_dsa2048(); + +class EDSA::DSAImpl +{ +public: + DSA *mDSA; +}; + +EDSA::EDSA() +{ + mDSAImpl = new DSAImpl(); + mDSAImpl->mDSA = get_dsa2048(); +} + +EDSA::EDSA(const std::vector &secret) +{ + mDSAImpl = new DSAImpl(); + + const unsigned char *buf = &(secret[0]); + + mDSAImpl->mDSA = d2i_DSAPrivateKey(NULL, &buf, secret.size()); +} + +std::vector EDSA::generateSecret() +{ + DSA_generate_key(mDSAImpl->mDSA); + + std::vector temp; + + int size = i2d_DSAPrivateKey(mDSAImpl->mDSA, NULL); + + temp.resize(size); + + unsigned char *buf = &(temp[0]); + + i2d_DSAPrivateKey(mDSAImpl->mDSA, &buf); + + return temp; +} + +std::vector EDSA::getPublic() +{ + std::vector temp; + + mDSAImpl->mDSA->write_params = 0; + + int size = i2d_DSAPublicKey(mDSAImpl->mDSA, NULL); + + temp.resize(size); + + unsigned char *buf = &(temp[0]); + + i2d_DSAPublicKey(mDSAImpl->mDSA, &buf); + + return temp; +} + +void EDSA::setPublic(const std::vector &pub) +{ + const unsigned char *buf = &(pub[0]); + + d2i_DSAPublicKey(&mDSAImpl->mDSA, &buf, pub.size()); +} + +bool EDSA::verify(const std::vector &dgst, const std::vector &sig) +{ + bool result = false; + + if(DSA_verify(0, &(dgst[0]), dgst.size(), &(sig[0]), sig.size(), mDSAImpl->mDSA) == 1) + { + result = true; + } + + return result; +} + +// static +bool EDSA::verify(const std::vector &dgst, const std::vector &sig, const std::vector &pub) +{ + const unsigned char *buf = &(pub[0]); + DSA *dsa; + bool result = false; + + dsa = get_dsa2048(); + + d2i_DSAPublicKey(&dsa, &buf, pub.size()); + + if(DSA_verify(0, &(dgst[0]), dgst.size(), &(sig[0]), sig.size(), dsa) == 1) + { + result = true; + } + + DSA_free(dsa); + + return result; +} + +std::vector EDSA::sign(const std::vector &dgst) +{ + std::vector sig; + unsigned int size = DSA_size(mDSAImpl->mDSA); + + sig.resize(size); + + DSA_sign(0, &(dgst[0]), dgst.size(), &(sig[0]), &size, mDSAImpl->mDSA); + + sig.resize(size); + + return sig; +} + +EDSA::~EDSA() +{ + delete mDSAImpl; + mDSAImpl = NULL; +} \ No newline at end of file diff --git a/indra/newview/emerald.h b/indra/newview/emerald.h new file mode 100644 index 000000000..a4d2126c6 --- /dev/null +++ b/indra/newview/emerald.h @@ -0,0 +1,107 @@ +// Copyright (c)2009 Thomas Shikami +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +#include +#include + +class EAscii85 { +private: + EAscii85() { } +public: + static std::string encode(const std::vector &in); + static std::vector decode(const std::string &in); +}; + +class EAESEncrypt { +public: + EAESEncrypt(const unsigned char *key, const unsigned char *iv); + EAESEncrypt(const std::vector &key, const std::vector &iv); + ~EAESEncrypt(); + + std::vector encrypt(const std::string &in); + +private: + EAESEncrypt(const EAESEncrypt&) {} + + class EncryptImpl; + + EncryptImpl *mEncryptImpl; +}; + +class EAESDecrypt { +public: + EAESDecrypt(const unsigned char *key, const unsigned char *iv); + EAESDecrypt(const std::vector &key, const std::vector &iv); + ~EAESDecrypt(); + + std::string decrypt(const std::vector &in); + +private: + EAESDecrypt(const EAESDecrypt&) {} + class DecryptImpl; + + DecryptImpl *mDecryptImpl; +}; + +class EGenKey { +public: + EGenKey(const std::string &password, const unsigned char *salt = 0); + ~EGenKey(); + + const unsigned char *key() const { return mKey; } + const unsigned char *iv() const { return mIv; } + +private: + unsigned char mKey[16]; + unsigned char mIv[16]; +}; + +class EDH { +public: + EDH(const std::vector &secret); + EDH(); + ~EDH(); + + void secretTo(std::vector &secret); + void publicTo(std::vector &pub); + std::vector computeKey(const std::vector &other_pub); + +private: + EDH(const EDH&) {} + + class DHImpl; + + DHImpl *mDHImpl; +}; + +class EDSA { +public: + EDSA(const std::vector &secret); + EDSA(); + ~EDSA(); + + std::vector getPublic(); + void setPublic(const std::vector &pub); + std::vector generateSecret(); + static bool verify(const std::vector &dgst, const std::vector &sig, const std::vector &pub); + bool verify(const std::vector &dgst, const std::vector &sig); + std::vector sign(const std::vector &dgst); + +private: + EDSA(const EDSA&) {} + + class DSAImpl; + + DSAImpl *mDSAImpl; +}; diff --git a/indra/newview/emeraldboobutils.cpp b/indra/newview/emeraldboobutils.cpp new file mode 100644 index 000000000..12b784a7e --- /dev/null +++ b/indra/newview/emeraldboobutils.cpp @@ -0,0 +1,189 @@ +#include "llviewerprecompiledheaders.h" +#include "emeraldboobutils.h" + +std::ostream &operator<<(std::ostream &os, const EmeraldGlobalBoobConfig &v) +{ + os << "EmeraldBoobConfig" << std::endl; + os << "enabled: " << v.enabled << std::endl; + os << "mass: " << v.mass << std::endl; + os << "hardness: " << v.hardness << std::endl; + os << "zMax: " << v.zMax << std::endl; + os << "velMin: " << v.velMin << std::endl; + os << "velMax: " << v.velMax << std::endl; + os << "zInfluence: " << v.zInfluence << std::endl; + os << "friction: " << v.friction << std::endl; + return os; +} + +std::ostream &operator<<(std::ostream &os, const EmeraldAvatarLocalBoobConfig &v) +{ + os << "EmeraldAvatarLocalBoobConfig" << std::endl; + os << "actualBoobGrav: " << v.actualBoobGrav << std::endl; + os << "boobSize: " << v.boobSize << std::endl; + return os; +} + +std::ostream &operator<<(std::ostream &os, const EmeraldBoobState &v) +{ + os << "EmeraldBoobState" << std::endl; + os << "boobGrav: " << v.boobGrav << std::endl; + os << "chestPosition: " << v.chestPosition << std::endl; + os << "chestRotation: " << v.chestRotation << std::endl; + os << "elapsedTime: " << v.elapsedTime << std::endl; + os << "frameDuration: " << v.frameDuration << std::endl; + os << "chestDisplacement: " << v.chestDisplacement << std::endl; + os << "localChestDisplacement: " << v.localChestDisplacement << std::endl; + os << "displacementForce: " << v.displacementForce << std::endl; + os << "mysteryValue: " << v.mysteryValue << std::endl; + os << "Number of bounceStates: " << v.bounceStates.size() << std::endl; + return os; +} + +std::ostream &operator<<(std::ostream &os, const EmeraldBoobInputs &v) +{ + os << "EmeraldBoobInputs" << std::endl; + os << "chestPosition: " << v.chestPosition << std::endl; + os << "chestRotation: " << v.chestRotation << std::endl; + os << "elapsedTime: " << v.elapsedTime << std::endl; + os << "appearanceFlag: " << v.appearanceFlag << std::endl; + os << "appearanceAnimating: " << v.appearanceAnimating << std::endl; + return os; +} + +std::ostream &operator<<(std::ostream &os, const EmeraldBoobBounceState &v) +{ + os << "EmeraldBoobBounceState" << std::endl; + os << "bounceStart: " << v.bounceStart << std::endl; + os << "bounceStartAmplitude: " << v.bounceStartAmplitude << std::endl; + os << "bounceStartFrameDuration: " << v.bounceStartFrameDuration << std::endl; + return os; +} + +F32 EmeraldBoobUtils::convertMass(F32 displayMass) +{ return displayMass/100.f*150.f; }; + +F32 EmeraldBoobUtils::convertHardness(F32 displayHardness) +{ return displayHardness/100.f*50; }; + +F32 EmeraldBoobUtils::convertVelMax(F32 displayVelMax) +{ return displayVelMax/100.f*0.01f; }; + +F32 EmeraldBoobUtils::convertFriction(F32 displayFriction) +{ return displayFriction/100.f*1.0f; }; + +F32 EmeraldBoobUtils::convertVelMin(F32 displayVelMin) +{ return displayVelMin/100.f; }; + +EmeraldBoobState EmeraldBoobUtils::idleUpdate(const EmeraldGlobalBoobConfig &config, const EmeraldAvatarLocalBoobConfig &localConfig, const EmeraldBoobState &oldState, const EmeraldBoobInputs &inputs) +{ + EmeraldBoobState newState; + F32 avatarLocalMass = 0.0f; + F32 partMod = 1.f; + + if(!config.enabled || inputs.appearanceFlag || inputs.appearanceAnimating) + return newState; + + if(inputs.type == 0) + { + newState.boobGrav = localConfig.actualBoobGrav; + avatarLocalMass = (llclamp(localConfig.boobSize, 0.0f, 0.5f) / 0.5f); + } + if(inputs.type == 1) + { + newState.boobGrav = localConfig.actualButtGrav; + partMod = 1.5f; + avatarLocalMass = llclamp(localConfig.actualButtGrav, 0.0f, 0.5f) / 0.5f; + } + if(inputs.type == 2) + { + newState.boobGrav = localConfig.actualFatGrav; + partMod = 1.3f; + avatarLocalMass = localConfig.actualFatGrav; + } + + + newState.elapsedTime = inputs.elapsedTime; + // seemed to create incorrect amounts of velocity when FPS varied + newState.frameDuration = inputs.elapsedTime - oldState.elapsedTime; + newState.chestPosition = inputs.chestPosition; + newState.chestRotation = inputs.chestRotation; + newState.chestDisplacement = inputs.chestPosition - oldState.chestPosition; + newState.localChestDisplacement = newState.chestDisplacement * ~inputs.chestRotation; + + + std::list bounceStates = oldState.bounceStates; + + if(fabs(newState.localChestDisplacement.length()) > 0.f) + { + F32 boobVel = 0.f; + boobVel = newState.localChestDisplacement.mV[VZ]; + boobVel += newState.localChestDisplacement[VX] * config.XYInfluence; + boobVel += newState.localChestDisplacement.mV[VY] * config.XYInfluence; + boobVel *= newState.frameDuration * 0.3f * 100.f; + boobVel = llclamp(boobVel, -config.velMax, config.velMax); + if(fabs(boobVel) <= config.velMax * config.velMin * newState.frameDuration * 100.f) + boobVel = 0.0f; + else + { + EmeraldBoobBounceState bounceState; + bounceState.bounceStart = inputs.elapsedTime; + bounceState.bounceStartFrameDuration = newState.frameDuration; + bounceState.bounceStartAmplitude = boobVel; + bounceState.bounceStartAmplitude *= avatarLocalMass; + bounceState.bounceStartAmplitude *= config.mass; + bounceStates.push_front(bounceState); + } + } + + /*if(fabs(newState.localChestDisplacement.length()) >= 0.f) { + LLVector3 displacementInfluence = newState.localChestDisplacement; + displacementInfluence *= LLVector3(0.3f, 0.3f, 1.0f); + F32 clampedDisplacementInfluenceLength = llclamp(displacementInfluence.length(), 0.0f, config.velMax); + if(displacementInfluence[VZ]<0.f) + clampedDisplacementInfluenceLength= -clampedDisplacementInfluenceLength; + EmeraldBoobBounceState bounceState; + bounceState.bounceStart = inputs.elapsedTime; + bounceState.bounceStartFrameDuration = newState.frameDuration; + bounceState.bounceStartAmplitude = clampedDisplacementInfluenceLength; + if(fabs(bounceState.bounceStartAmplitude) < config.velMin * config.velMax) + bounceState.bounceStartAmplitude = 0.0f; + else + { + bounceState.bounceStartAmplitude *= config.mass; + bounceStates.push_front(bounceState); + } + } + */ + + F32 totalNewAmplitude = 0.0f; + //std::cout << "Beginning bounce State processing at time " << inputs.elapsedTime << std::endl; + while(!bounceStates.empty()) { + EmeraldBoobBounceState bounceState = bounceStates.front(); + //std::cout << "Now processing " << bounceState; + bounceStates.pop_front(); + F32 bounceTime = newState.elapsedTime-bounceState.bounceStart; + F32 newAmplitude = bounceState.bounceStartAmplitude*pow(60.f*config.friction, -bounceTime)*cos(config.hardness*partMod*bounceTime); + if(fabs(newAmplitude) < 0.005f) { + newAmplitude = 0.0f; + } else { + newState.bounceStates.push_front(bounceState); + } + totalNewAmplitude+=newAmplitude; + } + //std::cout << "Total new amplitude: " << totalNewAmplitude << std::endl; + /* + if(inputs.type == 0) + newState.boobGrav = localConfig.actualBoobGrav + totalNewAmplitude; + if(inputs.type == 1) + newState.boobGrav = localConfig.actualButtGrav + totalNewAmplitude; + if(inputs.type == 2) + newState.boobGrav = localConfig.actualFatGrav + totalNewAmplitude; + */ + + newState.boobGrav = totalNewAmplitude; + + + newState.boobGrav = llclamp(newState.boobGrav, -1.5f, 2.0f); + + return newState; +} \ No newline at end of file diff --git a/indra/newview/emeraldboobutils.h b/indra/newview/emeraldboobutils.h new file mode 100644 index 000000000..26008f9de --- /dev/null +++ b/indra/newview/emeraldboobutils.h @@ -0,0 +1,197 @@ +#ifndef __emeraldboobutils_h +#define __emeraldboobutils_h + +#include +#include + +#include "stdtypes.h" +#include "v3math.h" +#include "llquaternion.h" + +struct EmeraldGlobalBoobConfig +{ + bool enabled; + F32 mass; + F32 hardness; + F32 zMax; + F32 velMin; + F32 velMax; + F32 zInfluence; + F32 friction; + F32 XYInfluence; + + EmeraldGlobalBoobConfig() + : enabled(false), + mass(6.4f), + hardness(0.67f), + zMax(1.29f), + velMin(0.0027f*0.017f), + velMax(0.0027f), + zInfluence(0.0f), + friction(0.35f), + XYInfluence(0.3f) + { + } + + bool operator==(const EmeraldGlobalBoobConfig &other) const + { + return + enabled == other.enabled && + mass == other.mass && + zMax == other.zMax && + velMax == other.velMax && + velMin == other.velMin && + zInfluence == other.zInfluence && + XYInfluence == other.XYInfluence && + friction == other.friction; + } +}; + +std::ostream &operator<<(std::ostream &os, const EmeraldGlobalBoobConfig &v); + +struct EmeraldAvatarLocalBoobConfig +{ + F32 actualBoobGrav; + F32 actualButtGrav; + F32 actualFatGrav; + F32 boobSize; + + EmeraldAvatarLocalBoobConfig() + : actualBoobGrav(0.0f), + actualButtGrav(0.0f), + actualFatGrav(0.0f), + boobSize(0.0f) + { + } + + bool operator==(const EmeraldAvatarLocalBoobConfig &other) const + { + return + actualBoobGrav == other.actualBoobGrav && + actualButtGrav == other.actualButtGrav && + actualFatGrav == other.actualFatGrav && + boobSize == other.boobSize; + } + +}; + +std::ostream &operator<<(std::ostream &os, const EmeraldAvatarLocalBoobConfig &v); + +struct EmeraldBoobBounceState; + +struct EmeraldBoobState +{ + F32 boobGrav; + LLVector3 chestPosition; + LLQuaternion chestRotation; + F32 elapsedTime; + F32 frameDuration; + LLVector3 chestDisplacement; + LLVector3 localChestDisplacement; + LLVector3 displacementForce; + F32 mysteryValue; + std::list bounceStates; + + EmeraldBoobState() + : boobGrav(0.0f), + chestPosition(0.0f,0.0f,0.0f), + chestRotation(0.0f,0.0f,0.0f,1.0f), + elapsedTime(0.0f), + frameDuration(0.0f), + chestDisplacement(0.0f,0.0f,0.0f), + localChestDisplacement(0.0f,0.0f,0.0f), + displacementForce(0.0f,0.0f,0.0f), + mysteryValue(0.0f) + { + } + + bool operator==(const EmeraldBoobState &other) const + { + return + boobGrav == other.boobGrav && + chestPosition == other.chestPosition && + chestRotation == other.chestRotation && + elapsedTime == other.elapsedTime && + frameDuration == other.frameDuration && + chestDisplacement == other.chestDisplacement && + localChestDisplacement == other.localChestDisplacement && + displacementForce == other.displacementForce && + mysteryValue == other.mysteryValue && + bounceStates == other.bounceStates; + } +}; + +std::ostream &operator<<(std::ostream &os, const EmeraldBoobState &v); + +struct EmeraldBoobInputs +{ + LLVector3 chestPosition; + LLQuaternion chestRotation; + F32 elapsedTime; + bool appearanceFlag; + bool appearanceAnimating; + S32 type; + + EmeraldBoobInputs() + : chestPosition(0.0f,0.0f,0.0f), + chestRotation(0.0f,0.0f,0.0f,1.0f), + elapsedTime(0.0f), + appearanceFlag(false), + appearanceAnimating(false), + type(0) + { + } + + bool operator==(const EmeraldBoobInputs &other) const + { + return + chestPosition == other.chestPosition && + chestRotation == other.chestRotation && + elapsedTime == other.elapsedTime && + appearanceFlag == other.appearanceFlag && + appearanceAnimating == other.appearanceAnimating && + type == other.type; + } +}; + +std::ostream &operator<<(std::ostream &os, const EmeraldBoobInputs &v); + +struct EmeraldBoobBounceState +{ + F32 bounceStart; + F32 bounceStartAmplitude; + F32 bounceStartFrameDuration; + + EmeraldBoobBounceState() + : bounceStart(0.0f), + bounceStartAmplitude(0.0f), + bounceStartFrameDuration(0.0f) + { + }; + + bool operator==(const EmeraldBoobBounceState &other) const + { + return + bounceStart == other.bounceStart && + bounceStartAmplitude == other.bounceStartAmplitude && + bounceStartFrameDuration == other.bounceStartFrameDuration; + } +}; + +std::ostream &operator<<(std::ostream &os, const EmeraldBoobBounceState &v); + + +struct EmeraldBoobUtils +{ +public: + static EmeraldBoobState idleUpdate(const EmeraldGlobalBoobConfig &config, const EmeraldAvatarLocalBoobConfig &localConfig, const EmeraldBoobState &oldState, const EmeraldBoobInputs &inputs); + + static F32 convertMass(F32 displayMass); + static F32 convertHardness(F32 displayHardness); + static F32 convertVelMax(F32 displayVelMax); + static F32 convertFriction(F32 displayFriction); + static F32 convertVelMin(F32 displayVelMin); +}; + + +#endif diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp index 9c9a3f706..af8e5388f 100644 --- a/indra/newview/llviewercontrol.cpp +++ b/indra/newview/llviewercontrol.cpp @@ -71,6 +71,7 @@ #include "llvowlsky.h" #include "llrender.h" #include "llfloaterchat.h" +#include "emeraldboobutils.h" #ifdef TOGGLE_HACKED_GODLIKE_VIEWER BOOL gHackGodmode = FALSE; @@ -119,6 +120,49 @@ static bool handleSetShaderChanged(const LLSD& newvalue) return true; } +static bool handleAvatarBoobMassChanged(const LLSD& newvalue) +{ + LLVOAvatar::sBoobConfig.mass = EmeraldBoobUtils::convertMass((F32) newvalue.asReal()); + return true; +} + +static bool handleAvatarBoobHardnessChanged(const LLSD& newvalue) +{ + LLVOAvatar::sBoobConfig.hardness = EmeraldBoobUtils::convertHardness((F32) newvalue.asReal()); + return true; +} + +static bool handleAvatarBoobVelMaxChanged(const LLSD& newvalue) +{ + LLVOAvatar::sBoobConfig.velMax = EmeraldBoobUtils::convertVelMax((F32) newvalue.asReal()); + LLVOAvatar::sBoobConfig.velMin = LLVOAvatar::sBoobConfig.velMin*LLVOAvatar::sBoobConfig.velMax; + return true; +} + +static bool handleAvatarBoobFrictionChanged(const LLSD& newvalue) +{ + LLVOAvatar::sBoobConfig.friction = EmeraldBoobUtils::convertFriction((F32) newvalue.asReal()); + return true; +} + +static bool handleAvatarBoobVelMinChanged(const LLSD& newvalue) +{ + LLVOAvatar::sBoobConfig.velMin = EmeraldBoobUtils::convertVelMin((F32) newvalue.asReal())*LLVOAvatar::sBoobConfig.velMax; + return true; +} + +static bool handleAvatarBoobToggleChanged(const LLSD& newvalue) +{ + LLVOAvatar::sBoobConfig.enabled = (BOOL) newvalue.asReal(); + return true; +} + +static bool handleAvatarBoobXYInfluence(const LLSD& newvalue) +{ + LLVOAvatar::sBoobConfig.XYInfluence = (F32) newvalue.asReal(); + return true; +} + static bool handleSetSelfInvisible( const LLSD& newvalue) { LLVOAvatar::onChangeSelfInvisible( newvalue.asBoolean() ); @@ -468,6 +512,13 @@ void settings_setup_listeners() gSavedSettings.getControl("RenderFlexTimeFactor")->getSignal()->connect(boost::bind(&handleFlexLODChanged, _1)); gSavedSettings.getControl("ThrottleBandwidthKBPS")->getSignal()->connect(boost::bind(&handleBandwidthChanged, _1)); gSavedSettings.getControl("RenderGamma")->getSignal()->connect(boost::bind(&handleGammaChanged, _1)); + gSavedSettings.getControl("EmeraldBoobMass")->getSignal()->connect(boost::bind(&handleAvatarBoobMassChanged, _1)); + gSavedSettings.getControl("EmeraldBoobHardness")->getSignal()->connect(boost::bind(&handleAvatarBoobHardnessChanged, _1)); + gSavedSettings.getControl("EmeraldBoobVelMax")->getSignal()->connect(boost::bind(&handleAvatarBoobVelMaxChanged, _1)); + gSavedSettings.getControl("EmeraldBoobFriction")->getSignal()->connect(boost::bind(&handleAvatarBoobFrictionChanged, _1)); + gSavedSettings.getControl("EmeraldBoobVelMin")->getSignal()->connect(boost::bind(&handleAvatarBoobVelMinChanged, _1)); + gSavedSettings.getControl("EmeraldBreastPhysicsToggle")->getSignal()->connect(boost::bind(&handleAvatarBoobToggleChanged, _1)); + gSavedSettings.getControl("EmeraldBoobXYInfluence")->getSignal()->connect(boost::bind(&handleAvatarBoobXYInfluence, _1)); gSavedSettings.getControl("RenderFogRatio")->getSignal()->connect(boost::bind(&handleFogRatioChanged, _1)); gSavedSettings.getControl("RenderMaxPartCount")->getSignal()->connect(boost::bind(&handleMaxPartCountChanged, _1)); gSavedSettings.getControl("RenderDynamicLOD")->getSignal()->connect(boost::bind(&handleRenderDynamicLODChanged, _1)); diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index a143d7815..aabb514ac 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -86,6 +86,7 @@ #include "llvoiceclient.h" #include "llvoicevisualizer.h" // Ventrella + #include "llsdserialize.h" // #include "llfloaterexploreanimations.h" @@ -707,16 +708,13 @@ F32 LLVOAvatar::sLODFactor = 1.f; BOOL LLVOAvatar::sUseImpostors = FALSE; BOOL LLVOAvatar::sJointDebug = FALSE; - - - - +EmeraldGlobalBoobConfig LLVOAvatar::sBoobConfig; F32 LLVOAvatar::sUnbakedTime = 0.f; F32 LLVOAvatar::sUnbakedUpdateTime = 0.f; F32 LLVOAvatar::sGreyTime = 0.f; F32 LLVOAvatar::sGreyUpdateTime = 0.f; - +bool LLVOAvatar::sDoProperArc = true; //----------------------------------------------------------------------------- // Helper functions @@ -768,7 +766,10 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id, mUpdatePeriod(1), mFullyLoadedInitialized(FALSE), mHasBakedHair( FALSE ), - mSupportsAlphaLayers(FALSE) + mSupportsAlphaLayers(FALSE), + mFirstSetActualBoobGravRan( false ) + //mFirstSetActualButtGravRan( false ), + //mFirstSetActualFatGravRan( false ) // // mNametagSaysIdle(false), // mIdleForever(true), @@ -996,6 +997,16 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id, } + // grab the boob savedparams (prob a better place for this) + sBoobConfig.mass = EmeraldBoobUtils::convertMass(gSavedSettings.getF32("EmeraldBoobMass")); + sBoobConfig.hardness = EmeraldBoobUtils::convertHardness(gSavedSettings.getF32("EmeraldBoobHardness")); + sBoobConfig.velMax = EmeraldBoobUtils::convertVelMax(gSavedSettings.getF32("EmeraldBoobVelMax")); + sBoobConfig.velMin = EmeraldBoobUtils::convertVelMin(gSavedSettings.getF32("EmeraldBoobVelMin")); + sBoobConfig.friction = EmeraldBoobUtils::convertFriction(gSavedSettings.getF32("EmeraldBoobFriction")); + sBoobConfig.enabled = gSavedSettings.getBOOL("EmeraldBreastPhysicsToggle"); + sBoobConfig.XYInfluence = gSavedSettings.getF32("EmeraldBoobXYInfluence"); + sDoProperArc = (bool)gSavedSettings.getBOOL("EmeraldUseProperArc"); + if (gNoRender) { return; @@ -2712,7 +2723,7 @@ BOOL LLVOAvatar::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) idleUpdateVoiceVisualizer( voice_enabled ); idleUpdateMisc( detailed_update ); idleUpdateAppearanceAnimation(); - + idleUpdateBoobEffect(); idleUpdateLipSync( voice_enabled ); idleUpdateLoadingEffect(); idleUpdateBelowWater(); // wind effect uses this @@ -2994,105 +3005,105 @@ void LLVOAvatar::idleUpdateAppearanceAnimation() } } - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// ------------------------------------------------------------ +// Danny: ZOMG Boob Phsyics go! +// ------------------------------------------------------------ +void LLVOAvatar::idleUpdateBoobEffect() +{ + if(mFirstSetActualBoobGravRan) + { + // should probably be moved somewhere where it is only called when boobsize changes + LLVisualParam *param; + + // BOOBS + param = getVisualParam(105); //boob size + mLocalBoobConfig.boobSize = param->getCurrentWeight(); + EmeraldBoobInputs boobInputs; + boobInputs.type = 0; + boobInputs.chestPosition = mChestp->getWorldPosition(); + boobInputs.chestRotation = mChestp->getWorldRotation(); + boobInputs.elapsedTime = mBoobBounceTimer.getElapsedTimeF32(); + boobInputs.appearanceFlag = getAppearanceFlag(); + + + EmeraldBoobState newBoobState = EmeraldBoobUtils::idleUpdate(sBoobConfig, mLocalBoobConfig, mBoobState, boobInputs); + + if(mBoobState.boobGrav != newBoobState.boobGrav) + { + LLVisualParam *param; + param = getVisualParam(507); + + ESex avatar_sex = getSex(); + + param->stopAnimating(FALSE); + param->setWeight(llclamp(newBoobState.boobGrav+getActualBoobGrav(), -1.5f, 2.f), FALSE); + param->apply(avatar_sex); + updateVisualParams(); + } + + mBoobState = newBoobState; + } + /* + if(mFirstSetActualButtGravRan) + { + // BUTT + EmeraldBoobInputs buttInputs; + buttInputs.type = 1; + buttInputs.chestPosition = mPelvisp->getWorldPosition(); + buttInputs.chestRotation = mPelvisp->getWorldRotation(); + buttInputs.elapsedTime = mBoobBounceTimer.getElapsedTimeF32(); + buttInputs.appearanceFlag = getAppearanceFlag(); + + + EmeraldBoobState newButtState = EmeraldBoobUtils::idleUpdate(sBoobConfig, mLocalBoobConfig, mButtState, buttInputs); + + if(mButtState.boobGrav != newButtState.boobGrav) + { + LLVisualParam *param; + param = getVisualParam(795); + + ESex avatar_sex = getSex(); + + param->stopAnimating(FALSE); + param->setWeight(newButtState.boobGrav*0.3f+getActualButtGrav(), FALSE); + param->apply(avatar_sex); + updateVisualParams(); + } + + mButtState = newButtState; + } + + if(mFirstSetActualFatGravRan) + { + // FAT + EmeraldBoobInputs fatInputs; + fatInputs.type = 2; + fatInputs.chestPosition = mPelvisp->getWorldPosition(); + fatInputs.chestRotation = mPelvisp->getWorldRotation(); + fatInputs.elapsedTime = mBoobBounceTimer.getElapsedTimeF32(); + fatInputs.appearanceFlag = getAppearanceFlag(); + + + EmeraldBoobState newFatState = EmeraldBoobUtils::idleUpdate(sBoobConfig, mLocalBoobConfig, mFatState, fatInputs); + + if(mFatState.boobGrav != newFatState.boobGrav) + { + LLVisualParam *param; + param = getVisualParam(157); + + ESex avatar_sex = getSex(); + + param->stopAnimating(FALSE); + param->setWeight(newFatState.boobGrav*0.3f+getActualFatGrav(), FALSE); + param->apply(avatar_sex); + updateVisualParams(); + } + + mFatState = newFatState; + } + */ + +} void LLVOAvatar::idleUpdateLipSync(bool voice_enabled) { @@ -10419,11 +10430,33 @@ void LLVOAvatar::idleUpdateRenderCost() } } + if(sDoProperArc) + { + std::set::const_iterator tex_iter; + for(tex_iter = textures.begin();tex_iter != textures.end();++tex_iter) + { + LLViewerImage* img = gImageList.getImage(*tex_iter); + if(img) + { + shame += (img->getHeight() * img->getWidth()) >> 4; + } + } + } shame += textures.size() * 5; setDebugText(llformat("%d", shame)); F32 green = 1.f-llclamp(((F32) shame-1024.f)/1024.f, 0.f, 1.f); F32 red = llmin((F32) shame/1024.f, 1.f); + if(sDoProperArc) + { + green = 1.f-llclamp(((F32)shame-1000000.f)/1000000.f, 0.f, 1.f); + red = llmin((F32)shame/1000000.f, 1.f); + } + else + { + green = 1.f-llclamp(((F32)shame-1024.f)/1024.f, 0.f, 1.f); + red = llmin((F32)shame/1024.f, 1.f); + } mText->setColor(LLColor4(red,green,0,1)); } diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index a98629d90..a01ccd855 100644 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -49,7 +49,7 @@ #include "llrendertarget.h" #include "llwearable.h" #include "llvoavatardefines.h" - +#include "emeraldboobutils.h" extern const LLUUID ANIM_AGENT_BODY_NOISE; @@ -118,7 +118,7 @@ public: void idleUpdateLipSync(bool voice_enabled); void idleUpdateLoadingEffect(); void idleUpdateWindEffect(); - + void idleUpdateBoobEffect(); void idleUpdateNameTag(const LLVector3& root_pos_last); void idleUpdateRenderCost(); void idleUpdateTractorBeam(); @@ -525,58 +525,57 @@ private: BOOL mAppearanceAnimSetByUser; F32 mLastAppearanceBlendTime; + //-------------------------------------------------------------------- + // boob bounce stuff + //-------------------------------------------------------------------- +private: + bool mFirstSetActualBoobGravRan; + //bool mFirstSetActualButtGravRan; + //bool mFirstSetActualFatGravRan; + LLFrameTimer mBoobBounceTimer; + EmeraldAvatarLocalBoobConfig mLocalBoobConfig; + EmeraldBoobState mBoobState; + //EmeraldBoobState mButtState; + //EmeraldBoobState mFatState; +public: + //boob + F32 getActualBoobGrav() { return mLocalBoobConfig.actualBoobGrav; } + void setActualBoobGrav(F32 grav) + { + mLocalBoobConfig.actualBoobGrav = grav; + if(!mFirstSetActualBoobGravRan) + { + mBoobState.boobGrav = grav; + mFirstSetActualBoobGravRan = true; + } + } - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + //butt + /*F32 getActualButtGrav() { return mLocalBoobConfig.actualButtGrav; } + void setActualButtGrav(F32 grav) + { + mLocalBoobConfig.actualButtGrav = grav; + if(!mFirstSetActualButtGravRan) + { + mButtState.boobGrav = grav; + mFirstSetActualButtGravRan = true; + } + } + //fat + F32 getActualFatGrav() { return mLocalBoobConfig.actualFatGrav; } + void setActualFatGrav(F32 grav) + { + mLocalBoobConfig.actualFatGrav = grav; + if(!mFirstSetActualFatGravRan) + { + mFatState.boobGrav = grav; + mFirstSetActualFatGravRan = true; + } + } + */ + static EmeraldGlobalBoobConfig sBoobConfig; //-------------------------------------------------------------------- // Attachments @@ -870,6 +869,7 @@ public: static F32 sUnbakedUpdateTime; // Last time stats were updated (to prevent multiple updates per frame) static F32 sGreyTime; // Total seconds with >=1 grey avatars static F32 sGreyUpdateTime; // Last time stats were updated (to prevent multiple updates per frame) + static bool sDoProperArc; const std::string getBakedStatusForPrintout() const; }; diff --git a/indra/newview/skins/default/xui/en-us/panel_preferences_ascent_vanity.xml b/indra/newview/skins/default/xui/en-us/panel_preferences_ascent_vanity.xml index da2abed87..8e8fe8e3c 100644 --- a/indra/newview/skins/default/xui/en-us/panel_preferences_ascent_vanity.xml +++ b/indra/newview/skins/default/xui/en-us/panel_preferences_ascent_vanity.xml @@ -3,15 +3,38 @@ border="true" label="Ascent Vanity" name="ascvan" enabled="true" mouse_opaque="true"> - - - + + + + + + +