diff options
-rw-r--r-- | indra/llinventory/llinventory.cpp | 6 | ||||
-rw-r--r-- | indra/llui/llfloater.cpp | 61 | ||||
-rw-r--r-- | indra/llui/llfloater.h | 3 | ||||
-rw-r--r-- | indra/llui/llfolderview.cpp | 45 | ||||
-rw-r--r-- | indra/llui/llmultifloater.cpp | 3 | ||||
-rw-r--r-- | indra/llui/llmultifloater.h | 9 | ||||
-rw-r--r-- | indra/newview/llhudobject.h | 2 | ||||
-rw-r--r-- | indra/newview/llimconversation.cpp | 44 | ||||
-rw-r--r-- | indra/newview/llimconversation.h | 8 | ||||
-rw-r--r-- | indra/newview/llimfloater.cpp | 18 | ||||
-rw-r--r-- | indra/newview/llimfloater.h | 3 | ||||
-rw-r--r-- | indra/newview/llimfloatercontainer.cpp | 5 | ||||
-rw-r--r-- | indra/newview/llinventorypanel.cpp | 5 | ||||
-rw-r--r-- | indra/newview/llnearbychat.cpp | 111 | ||||
-rw-r--r-- | indra/newview/llnearbychat.h | 8 | ||||
-rw-r--r-- | indra/newview/llvoavatar.cpp | 2 | ||||
-rw-r--r-- | indra/newview/llvoicevisualizer.cpp | 1285 | ||||
-rw-r--r-- | indra/newview/llvoicevisualizer.h | 1 | ||||
-rw-r--r-- | indra/newview/llvopartgroup.cpp | 4 | ||||
-rw-r--r-- | indra/newview/skins/default/xui/en/floater_im_session.xml | 3 |
20 files changed, 802 insertions, 824 deletions
diff --git a/indra/llinventory/llinventory.cpp b/indra/llinventory/llinventory.cpp index 6e54f9d78a..a80ae73dca 100644 --- a/indra/llinventory/llinventory.cpp +++ b/indra/llinventory/llinventory.cpp @@ -75,13 +75,15 @@ LLInventoryObject::LLInventoryObject(const LLUUID& uuid, mUUID(uuid), mParentUUID(parent_uuid), mType(type), - mName(name) + mName(name), + mCreationDate(0) { correctInventoryName(mName); } LLInventoryObject::LLInventoryObject() : - mType(LLAssetType::AT_NONE) + mType(LLAssetType::AT_NONE), + mCreationDate(0) { } diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp index a1c902d562..8145d6d347 100644 --- a/indra/llui/llfloater.cpp +++ b/indra/llui/llfloater.cpp @@ -1175,7 +1175,6 @@ void LLFloater::setMinimized(BOOL minimize) { // minimized flag should be turned on before release focus mMinimized = TRUE; - mExpandedRect = getRect(); // If the floater has been dragged while minimized in the @@ -1248,7 +1247,6 @@ void LLFloater::setMinimized(BOOL minimize) } setOrigin( mExpandedRect.mLeft, mExpandedRect.mBottom ); - if (mButtonsEnabled[BUTTON_RESTORE]) { mButtonsEnabled[BUTTON_MINIMIZE] = TRUE; @@ -1284,7 +1282,6 @@ void LLFloater::setMinimized(BOOL minimize) // Reshape *after* setting mMinimized reshape( mExpandedRect.getWidth(), mExpandedRect.getHeight(), TRUE ); - applyPositioning(NULL, false); } make_ui_sound("UISndWindowClose"); @@ -1658,10 +1655,12 @@ void LLFloater::onClickTearOff(LLFloater* self) gFloaterView->addChild(self); self->openFloater(self->getKey()); - - // only force position for floaters that don't have that data saved - if (self->mRectControl.empty()) + if (self->mSaveRect && !self->mRectControl.empty()) { + self->applyRectControl(); + } + else + { // only force position for floaters that don't have that data saved new_rect.setLeftTopAndSize(host_floater->getRect().mLeft + 5, host_floater->getRect().mTop - floater_header_size - 5, self->getRect().getWidth(), self->getRect().getHeight()); self->setRect(new_rect); } @@ -1675,6 +1674,10 @@ void LLFloater::onClickTearOff(LLFloater* self) LLMultiFloater* new_host = (LLMultiFloater*)self->mLastHostHandle.get(); if (new_host) { + if (self->mSaveRect) + { + self->storeRectControl(); + } self->setMinimized(FALSE); // to reenable minimize button if it was minimized new_host->showFloater(self); // make sure host is visible @@ -1709,6 +1712,18 @@ void LLFloater::onClickHelp( LLFloater* self ) } } +void LLFloater::initRectControl() +{ + // save_rect and save_visibility only apply to registered floaters + if (mSaveRect) + { + std::string ctrl_name = getControlName(mInstanceName, mKey); + mRectControl = LLFloaterReg::declareRectControl(ctrl_name); + mPosXControl = LLFloaterReg::declarePosXControl(ctrl_name); + mPosYControl = LLFloaterReg::declarePosYControl(ctrl_name); + } +} + // static LLFloater* LLFloater::getClosableFloaterFromFocus() { @@ -2940,28 +2955,22 @@ void LLFloaterView::popVisibleAll(const skip_list_t& skip_list) void LLFloater::setInstanceName(const std::string& name) { - if (name == mInstanceName) - return; - llassert_always(mInstanceName.empty()); - mInstanceName = name; - if (!mInstanceName.empty()) + if (name != mInstanceName) { - std::string ctrl_name = getControlName(mInstanceName, mKey); - - // save_rect and save_visibility only apply to registered floaters - if (mSaveRect) - { - mRectControl = LLFloaterReg::declareRectControl(ctrl_name); - mPosXControl = LLFloaterReg::declarePosXControl(ctrl_name); - mPosYControl = LLFloaterReg::declarePosYControl(ctrl_name); - } - if (!mVisibilityControl.empty()) + llassert_always(mInstanceName.empty()); + mInstanceName = name; + if (!mInstanceName.empty()) { - mVisibilityControl = LLFloaterReg::declareVisibilityControl(ctrl_name); - } - if(!mDocStateControl.empty()) - { - mDocStateControl = LLFloaterReg::declareDockStateControl(ctrl_name); + std::string ctrl_name = getControlName(mInstanceName, mKey); + initRectControl(); + if (!mVisibilityControl.empty()) + { + mVisibilityControl = LLFloaterReg::declareVisibilityControl(ctrl_name); + } + if(!mDocStateControl.empty()) + { + mDocStateControl = LLFloaterReg::declareDockStateControl(ctrl_name); + } } } } diff --git a/indra/llui/llfloater.h b/indra/llui/llfloater.h index 17402b8d63..a1cac64a4a 100644 --- a/indra/llui/llfloater.h +++ b/indra/llui/llfloater.h @@ -324,7 +324,7 @@ public: virtual void setDocked(bool docked, bool pop_on_undock = true); virtual void setTornOff(bool torn_off) { mTornOff = torn_off; } - bool getTornOff() {return mTornOff;} + bool isTornOff() {return mTornOff;} void setOpenPositioning(LLFloaterEnums::EOpenPositioning pos) {mPositioning = pos;} // Return a closeable floater, if any, given the current focus. @@ -358,6 +358,7 @@ protected: void stackWith(LLFloater& other); + virtual void initRectControl(); virtual bool applyRectControl(); bool applyDockState(); void applyPositioning(LLFloater* other, bool on_open); diff --git a/indra/llui/llfolderview.cpp b/indra/llui/llfolderview.cpp index fb09f7f0aa..fedb8bc014 100644 --- a/indra/llui/llfolderview.cpp +++ b/indra/llui/llfolderview.cpp @@ -1649,9 +1649,6 @@ void LLFolderView::scrollToShowItem(LLFolderViewItem* item, const LLRect& constr if(item) { LLRect local_rect = item->getLocalRect(); - LLRect item_scrolled_rect; // item position relative to display area of scroller - LLRect visible_doc_rect = mScrollContainer->getVisibleContentRect(); - S32 icon_height = mIcon.isNull() ? 0 : mIcon->getHeight(); S32 label_height = getLabelFontForStyle(mLabelStyle)->getLineHeight(); // when navigating with keyboard, only move top of opened folder on screen, otherwise show whole folder @@ -1760,6 +1757,20 @@ void LLFolderView::update() mNeedsAutoSelect = FALSE; } + BOOL is_visible = isInVisibleChain(); + + //Puts folders/items in proper positions + if ( is_visible ) + { + sanitizeSelection(); + if( needsArrange() ) + { + S32 height = 0; + S32 width = 0; + S32 total_height = arrange( &width, &height ); + notifyParent(LLSD().with("action", "size_changes").with("height", total_height)); + } + } // during filtering process, try to pin selected item's location on screen // this will happen when searching your inventory and when new items arrive @@ -1771,18 +1782,26 @@ void LLFolderView::update() // lets pin it! mPinningSelectedItem = TRUE; - LLRect visible_content_rect = (mScrollContainer ? mScrollContainer->getVisibleContentRect() : LLRect()); + //Computes visible area + const LLRect visible_content_rect = (mScrollContainer ? mScrollContainer->getVisibleContentRect() : LLRect()); LLFolderViewItem* selected_item = mSelectedItems.back(); + //Computes location of selected content, content outside visible area will be scrolled to using below code LLRect item_rect; selected_item->localRectToOtherView(selected_item->getLocalRect(), &item_rect, this); - // if item is visible in scrolled region - if (visible_content_rect.overlaps(item_rect)) + + //Computes intersected region of the selected content and visible area + LLRect overlap_rect(item_rect); + overlap_rect.intersectWith(visible_content_rect); + + //Don't scroll when the selected content exists within the visible area + if (overlap_rect.getHeight() >= selected_item->getItemHeight()) { // then attempt to keep it in same place on screen mScrollConstraintRect = item_rect; mScrollConstraintRect.translate(-visible_content_rect.mLeft, -visible_content_rect.mBottom); } + //Scroll because the selected content is outside the visible area else { // otherwise we just want it onscreen somewhere @@ -1813,20 +1832,6 @@ void LLFolderView::update() constraint_rect.setOriginAndSize(0, 0, content_rect.getWidth(), content_rect.getHeight()); } - BOOL is_visible = isInVisibleChain(); - - if ( is_visible ) - { - sanitizeSelection(); - if( needsArrange() ) - { - S32 height = 0; - S32 width = 0; - S32 total_height = arrange( &width, &height ); - notifyParent(LLSD().with("action", "size_changes").with("height", total_height)); - } - } - if (mSelectedItems.size() && mNeedsScroll) { scrollToShowItem(mSelectedItems.back(), constraint_rect); diff --git a/indra/llui/llmultifloater.cpp b/indra/llui/llmultifloater.cpp index e80799b16d..02ff64dbc6 100644 --- a/indra/llui/llmultifloater.cpp +++ b/indra/llui/llmultifloater.cpp @@ -188,11 +188,13 @@ void LLMultiFloater::addFloater(LLFloater* floaterp, BOOL select_added_floater, floater_data.mHeight = floaterp->getRect().getHeight(); floater_data.mCanMinimize = floaterp->isMinimizeable(); floater_data.mCanResize = floaterp->isResizable(); + floater_data.mSaveRect = floaterp->mSaveRect; // remove minimize and close buttons floaterp->setCanMinimize(FALSE); floaterp->setCanResize(FALSE); floaterp->setCanDrag(FALSE); + floaterp->mSaveRect = FALSE; floaterp->storeRectControl(); // avoid double rendering of floater background (makes it more opaque) floaterp->setBackgroundVisible(FALSE); @@ -291,6 +293,7 @@ void LLMultiFloater::removeFloater(LLFloater* floaterp) { LLFloaterData& floater_data = found_data_it->second; floaterp->setCanMinimize(floater_data.mCanMinimize); + floaterp->mSaveRect = floater_data.mSaveRect; if (!floater_data.mCanResize) { // restore original size diff --git a/indra/llui/llmultifloater.h b/indra/llui/llmultifloater.h index 44514a6246..d992212650 100644 --- a/indra/llui/llmultifloater.h +++ b/indra/llui/llmultifloater.h @@ -79,10 +79,11 @@ public: protected: struct LLFloaterData { - S32 mWidth; - S32 mHeight; - BOOL mCanMinimize; - BOOL mCanResize; + S32 mWidth; + S32 mHeight; + BOOL mCanMinimize; + BOOL mCanResize; + BOOL mSaveRect; }; LLTabContainer* mTabContainer; diff --git a/indra/newview/llhudobject.h b/indra/newview/llhudobject.h index 21cf5fe17c..32cffe6839 100644 --- a/indra/newview/llhudobject.h +++ b/indra/newview/llhudobject.h @@ -39,6 +39,8 @@ #include "lldrawpool.h" // TODO: eliminate, unused below #include <list> +#define XXX_STINSON_CHUI_REWORK // temporarily re-enabling the in-world voice-dot + class LLViewerCamera; class LLFontGL; class LLFace; diff --git a/indra/newview/llimconversation.cpp b/indra/newview/llimconversation.cpp index ec534b903d..b56f30312a 100644 --- a/indra/newview/llimconversation.cpp +++ b/indra/newview/llimconversation.cpp @@ -94,20 +94,24 @@ BOOL LLIMConversation::postBuild() mTearOffBtn->setCommitCallback(boost::bind(&LLIMConversation::onTearOffClicked, this)); mChatHistory = getChild<LLChatHistory>("chat_history"); - mInputEditor = getChild<LLChatEntry>("chat_editor"); + mInputEditor = getChild<LLChatEntry>("chat_editor"); mInputEditor->setTextExpandedCallback(boost::bind(&LLIMConversation::reshapeChatHistory, this)); + mInputEditor->setCommitOnFocusLost( FALSE ); + mInputEditor->setPassDelete(TRUE); + mInputEditor->setFont(LLViewerChat::getChatFont()); + mInputEditorTopPad = mChatHistory->getRect().mBottom - mInputEditor->getRect().mTop; - if (!getTornOff()) - { - setOpenPositioning(LLFloaterEnums::POSITIONING_RELATIVE); - } + setOpenPositioning(LLFloaterEnums::POSITIONING_RELATIVE); buildParticipantList(); updateHeaderAndToolbar(); + mSaveRect = isTornOff(); + initRectControl(); + if (isChatMultiTab()) { if (mIsNearbyChat) @@ -221,18 +225,16 @@ bool LLIMConversation::onIMShowModesMenuItemEnable(const LLSD& userdata) void LLIMConversation::hideOrShowTitle() { - bool is_hosted = getHost() != NULL; - const LLFloater::Params& default_params = LLFloater::getDefaultParams(); S32 floater_header_size = default_params.header_height; LLView* floater_contents = getChild<LLView>("contents_view"); LLRect floater_rect = getLocalRect(); - S32 top_border_of_contents = floater_rect.mTop - (is_hosted? 0 : floater_header_size); + S32 top_border_of_contents = floater_rect.mTop - (isTornOff()? floater_header_size : 0); LLRect handle_rect (0, floater_rect.mTop, floater_rect.mRight, top_border_of_contents); LLRect contents_rect (0, top_border_of_contents, floater_rect.mRight, floater_rect.mBottom); mDragHandle->setShape(handle_rect); - mDragHandle->setVisible(! is_hosted); + mDragHandle->setVisible(isTornOff()); floater_contents->setShape(contents_rect); } @@ -250,9 +252,8 @@ void LLIMConversation::hideAllStandardButtons() void LLIMConversation::updateHeaderAndToolbar() { - bool is_hosted = getHost() != NULL; - - if (is_hosted) + bool is_torn_off = isTornOff(); + if (!is_torn_off) { hideAllStandardButtons(); } @@ -261,7 +262,7 @@ void LLIMConversation::updateHeaderAndToolbar() // Participant list should be visible only in torn off floaters. bool is_participant_list_visible = - !is_hosted + is_torn_off && gSavedSettings.getBOOL("IMShowControlPanel") && !mIsP2PChat; @@ -269,21 +270,21 @@ void LLIMConversation::updateHeaderAndToolbar() // Display collapse image (<<) if the floater is hosted // or if it is torn off but has an open control panel. - bool is_expanded = is_hosted || is_participant_list_visible; + bool is_expanded = !is_torn_off || is_participant_list_visible; mExpandCollapseBtn->setImageOverlay(getString(is_expanded ? "collapse_icon" : "expand_icon")); // toggle floater's drag handle and title visibility if (mDragHandle) { - mDragHandle->setTitleVisible(!is_hosted); + mDragHandle->setTitleVisible(is_torn_off); } // The button (>>) should be disabled for torn off P2P conversations. - mExpandCollapseBtn->setEnabled(is_hosted || !mIsP2PChat); + mExpandCollapseBtn->setEnabled(!is_torn_off || !mIsP2PChat); - mTearOffBtn->setImageOverlay(getString(is_hosted ? "tear_off_icon" : "return_icon")); + mTearOffBtn->setImageOverlay(getString(is_torn_off? "return_icon" : "tear_off_icon")); - mCloseBtn->setVisible(is_hosted && !mIsNearbyChat); + mCloseBtn->setVisible(!is_torn_off && !mIsNearbyChat); enableDisableCallBtn(); @@ -363,12 +364,14 @@ void LLIMConversation::onSlide(LLIMConversation* self) void LLIMConversation::onOpen(const LLSD& key) { LLIMFloaterContainer* host_floater = dynamic_cast<LLIMFloaterContainer*>(getHost()); - if (host_floater) + bool is_hosted = !!host_floater; + if (is_hosted) { // Show the messages pane when opening a floater hosted in the Conversations host_floater->collapseMessagesPane(false); } + setTornOff(!is_hosted); updateHeaderAndToolbar(); } @@ -388,6 +391,9 @@ void LLIMConversation::onClose(bool app_quitting) void LLIMConversation::onTearOffClicked() { + setFollows(isTornOff()? FOLLOWS_ALL : FOLLOWS_NONE); + mSaveRect = isTornOff(); + initRectControl(); LLFloater::onClickTearOff(this); updateHeaderAndToolbar(); } diff --git a/indra/newview/llimconversation.h b/indra/newview/llimconversation.h index c3dff96d5d..649c200899 100644 --- a/indra/newview/llimconversation.h +++ b/indra/newview/llimconversation.h @@ -99,6 +99,10 @@ protected: LLParticipantList* mParticipantList; LLUUID mSessionID; + LLChatHistory* mChatHistory; + LLChatEntry* mInputEditor; + int mInputEditorTopPad; // padding between input field and chat history + LLButton* mExpandCollapseBtn; LLButton* mTearOffBtn; LLButton* mCloseBtn; @@ -117,10 +121,6 @@ private: */ void reshapeChatHistory(); - LLChatHistory* mChatHistory; - LLChatEntry* mInputEditor; - int mInputEditorTopPad; // padding between input field and chat history - LLTimer* mRefreshTimer; ///< Defines the rate at which refresh() is called. }; diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp index 1b08c454b7..3399a88c9e 100644 --- a/indra/newview/llimfloater.cpp +++ b/indra/newview/llimfloater.cpp @@ -66,11 +66,9 @@ LLIMFloater::LLIMFloater(const LLUUID& session_id) : LLIMConversation(session_id), mLastMessageIndex(-1), mDialog(IM_NOTHING_SPECIAL), - mInputEditor(NULL), mSavedTitle(), mTypingStart(), mShouldSendTypingState(false), - mChatHistory(NULL), mMeTyping(false), mOtherTyping(false), mTypingTimer(), @@ -80,6 +78,7 @@ LLIMFloater::LLIMFloater(const LLUUID& session_id) mStartConferenceInSameFloater(false) { mIsNearbyChat = false; + initIMSession(session_id); setOverlapsScreenChannel(true); @@ -313,9 +312,8 @@ void LLIMFloater::initIMFloater() //virtual BOOL LLIMFloater::postBuild() { - LLIMConversation::postBuild(); + BOOL result = LLIMConversation::postBuild(); - mInputEditor = getChild<LLChatEntry>("chat_editor"); mInputEditor->setMaxTextLength(1023); // enable line history support for instant message bar // XXX stinson TODO : resolve merge by adding autoreplace to text editors @@ -323,19 +321,11 @@ BOOL LLIMFloater::postBuild() // *TODO Establish LineEditor with autoreplace callback mInputEditor->setAutoreplaceCallback(boost::bind(&LLAutoReplace::autoreplaceCallback, LLAutoReplace::getInstance(), _1, _2)); #endif - - LLFontGL* font = LLViewerChat::getChatFont(); - mInputEditor->setFont(font); mInputEditor->setFocusReceivedCallback( boost::bind(onInputEditorFocusReceived, _1, this) ); mInputEditor->setFocusLostCallback( boost::bind(onInputEditorFocusLost, _1, this) ); mInputEditor->setKeystrokeCallback( boost::bind(onInputEditorKeystroke, _1, this) ); - mInputEditor->setCommitOnFocusLost( FALSE ); - mInputEditor->setPassDelete( TRUE ); - mInputEditor->setCommitCallback(boost::bind(onSendMsg, _1, this)); - - mChatHistory = getChild<LLChatHistory>("chat_history"); setDocked(true); @@ -358,7 +348,7 @@ BOOL LLIMFloater::postBuild() LLIMFloaterContainer* im_box = LLIMFloaterContainer::getInstance(); im_box->addConversationListItem(getTitle(), getKey(), this); - return TRUE; + return result; } void LLIMFloater::onAddButtonClicked() @@ -1004,7 +994,7 @@ void LLIMFloater::onInputEditorKeystroke(LLTextEditor* caller, void* userdata) // Deleting all text counts as stopping typing. self->setTyping(!text.empty()); - } +} void LLIMFloater::setTyping(bool typing) { diff --git a/indra/newview/llimfloater.h b/indra/newview/llimfloater.h index 7e45cf42c2..434613ff43 100644 --- a/indra/newview/llimfloater.h +++ b/indra/newview/llimfloater.h @@ -184,11 +184,8 @@ private: LLIMModel::LLIMSession* mSession; S32 mLastMessageIndex; - LLChatHistory* mChatHistory; - EInstantMessage mDialog; LLUUID mOtherParticipantUUID; - LLChatEntry* mInputEditor; bool mPositioned; std::string mSavedTitle; diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp index cc094fcaa1..d618e7491a 100644 --- a/indra/newview/llimfloatercontainer.cpp +++ b/indra/newview/llimfloatercontainer.cpp @@ -174,6 +174,11 @@ void LLIMFloaterContainer::addFloater(LLFloater* floaterp, mSessions[session_id] = floaterp; floaterp->mCloseSignal.connect(boost::bind(&LLIMFloaterContainer::onCloseFloater, this, session_id)); } + + // forced resize of the floater + LLRect wrapper_rect = this->mTabContainer->getLocalRect(); + floaterp->setRect(wrapper_rect); + mTabContainer->setTabImage(floaterp, icon); } diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp index b02d08955f..d6a685541f 100644 --- a/indra/newview/llinventorypanel.cpp +++ b/indra/newview/llinventorypanel.cpp @@ -514,10 +514,13 @@ void LLInventoryPanel::modelChanged(U32 mask) } else { + // Remove the item ID before destroying the view because the view-model-item gets + // destroyed when the view is destroyed + removeItemID(viewmodel_item->getUUID()); + // Item is to be moved outside the panel's directory (e.g. moved to trash for a panel that // doesn't include trash). Just remove the item's UI. view_item->destroyView(); - removeItemID(viewmodel_item->getUUID()); } } } diff --git a/indra/newview/llnearbychat.cpp b/indra/newview/llnearbychat.cpp index 3bd5f96add..8f0e6b4c83 100644 --- a/indra/newview/llnearbychat.cpp +++ b/indra/newview/llnearbychat.cpp @@ -125,30 +125,24 @@ static LLChatTypeTrigger sChatTypeTriggers[] = { LLNearbyChat::LLNearbyChat(const LLSD& key) : LLIMConversation(key), - mChatBox(NULL), - mChatHistory(NULL), //mOutputMonitor(NULL), mSpeakerMgr(NULL), mExpandedHeight(COLLAPSED_HEIGHT + EXPANDED_HEIGHT) { + mIsNearbyChat = true; setIsChrome(TRUE); mKey = LLSD(); - mIsNearbyChat = true; mSpeakerMgr = LLLocalSpeakerMgr::getInstance(); } //virtual BOOL LLNearbyChat::postBuild() { - mChatBox = getChild<LLChatEntry>("chat_editor"); - - mChatBox->setCommitCallback(boost::bind(&LLNearbyChat::onChatBoxCommit, this)); - mChatBox->setKeystrokeCallback(boost::bind(&onChatBoxKeystroke, _1, this)); - mChatBox->setFocusLostCallback(boost::bind(&onChatBoxFocusLost, _1, this)); - mChatBox->setFocusReceivedCallback(boost::bind(&LLNearbyChat::onChatBoxFocusReceived, this)); - mChatBox->setCommitOnFocusLost( FALSE ); - mChatBox->setPassDelete(TRUE); - mChatBox->setFont(LLViewerChat::getChatFont()); + BOOL result = LLIMConversation::postBuild(); + mInputEditor->setCommitCallback(boost::bind(&LLNearbyChat::onChatBoxCommit, this)); + mInputEditor->setKeystrokeCallback(boost::bind(&onChatBoxKeystroke, _1, this)); + mInputEditor->setFocusLostCallback(boost::bind(&onChatBoxFocusLost, _1, this)); + mInputEditor->setFocusReceivedCallback(boost::bind(&LLNearbyChat::onChatBoxFocusReceived, this)); // mOutputMonitor = getChild<LLOutputMonitorCtrl>("chat_zone_indicator"); // mOutputMonitor->setVisible(FALSE); @@ -156,8 +150,6 @@ BOOL LLNearbyChat::postBuild() // Register for font change notifications LLViewerChat::setFontChangedCallback(boost::bind(&LLNearbyChat::onChatFontChange, this, _1)); - enableResizeCtrls(true, true, false); - // title must be defined BEFORE call addConversationListItem() because // it is used for show the item's name in the conversations list setTitle(getString("NearbyChatTitle")); @@ -180,7 +172,6 @@ BOOL LLNearbyChat::postBuild() // obsolete, but may be needed for backward compatibility? gSavedSettings.declareS32("nearbychat_showicons_and_names", 2, "NearByChat header settings", true); - mChatHistory = getChild<LLChatHistory>("chat_history"); if (gSavedPerAccountSettings.getBOOL("LogShowHistory")) { loadHistory(); @@ -190,7 +181,7 @@ BOOL LLNearbyChat::postBuild() LLIMFloaterContainer* im_box = LLIMFloaterContainer::getInstance(); im_box->addConversationListItem(getTitle(), LLSD(), this); - return LLIMConversation::postBuild(); + return result; } // virtual @@ -227,10 +218,6 @@ bool LLNearbyChat::onNearbyChatCheckContextMenuItem(const LLSD& userdata) return false; } -void LLNearbyChat::getAllowedRect(LLRect& rect) -{ - rect = gViewerWindow->getWorldViewRectScaled(); -} //////////////////////////////////////////////////////////////////////////////// // void LLNearbyChat::onFocusReceived() @@ -352,10 +339,8 @@ void LLNearbyChat::onTearOffClicked() { LLIMConversation::onTearOffClicked(); - LLIMFloaterContainer* im_box = LLIMFloaterContainer::getInstance(); - // see CHUI-170: Save torn-off state of the nearby chat between sessions - BOOL in_the_multifloater = (getHost() == im_box); + BOOL in_the_multifloater = !isTornOff(); gSavedSettings.setBOOL("NearbyChatIsNotTornOff", in_the_multifloater); } @@ -389,18 +374,12 @@ void LLNearbyChat::onOpen(const LLSD& key) showTranslationCheckbox(LLTranslate::isTranslationConfigured()); } -bool LLNearbyChat::applyRectControl() -{ - setResizeLimits(getMinWidth(), EXPANDED_MIN_HEIGHT); - return LLFloater::applyRectControl(); -} - void LLNearbyChat::onChatFontChange(LLFontGL* fontp) { // Update things with the new font whohoo - if (mChatBox) + if (mInputEditor) { - mChatBox->setFont(fontp); + mInputEditor->setFont(fontp); } } @@ -416,33 +395,20 @@ void LLNearbyChat::show() { openFloater(getKey()); } - setVisible(TRUE); } bool LLNearbyChat::isChatVisible() const { bool isVisible = false; - - if (isChatMultiTab()) - { - LLIMFloaterContainer* im_box = LLIMFloaterContainer::getInstance(); - // Is the IM floater container ever null? - llassert(im_box != NULL); - if (im_box != NULL) - { - if (gSavedSettings.getBOOL("NearbyChatIsNotTornOff")) - { - isVisible = (im_box->getVisible() && !im_box->isMinimized()); - } - else - { - isVisible = (getVisible() && !isMinimized()); - } - } - } - else + LLIMFloaterContainer* im_box = LLIMFloaterContainer::getInstance(); + // Is the IM floater container ever null? + llassert(im_box != NULL); + if (im_box != NULL) { - isVisible = (getVisible() && !isMinimized()); + isVisible = + isChatMultiTab() && gSavedSettings.getBOOL("NearbyChatIsNotTornOff")? + im_box->getVisible() && !im_box->isMinimized() : + getVisible() && !isMinimized(); } return isVisible; @@ -452,22 +418,11 @@ void LLNearbyChat::showHistory() { openFloater(); setResizeLimits(getMinWidth(), EXPANDED_MIN_HEIGHT); - - bool is_torn_off = getHost() == NULL; - - // Reshape and enable resize controls only if it's a torn off floater. - // Otherwise all the size changes should be handled by LLIMFloaterContainer. - if (is_torn_off) - { - reshape(getRect().getWidth(), mExpandedHeight); - enableResizeCtrls(true); - storeRectControl(); - } } std::string LLNearbyChat::getCurrentChat() { - return mChatBox ? mChatBox->getText() : LLStringUtil::null; + return mInputEditor ? mInputEditor->getText() : LLStringUtil::null; } // virtual @@ -516,7 +471,7 @@ void LLNearbyChat::onChatBoxKeystroke(LLTextEditor* caller, void* userdata) LLNearbyChat* self = (LLNearbyChat *)userdata; - LLWString raw_text = self->mChatBox->getWText(); + LLWString raw_text = self->mInputEditor->getWText(); // Can't trim the end, because that will cause autocompletion // to eat trailing spaces that might be part of a gesture. @@ -563,17 +518,17 @@ void LLNearbyChat::onChatBoxKeystroke(LLTextEditor* caller, void* userdata) if (LLGestureMgr::instance().matchPrefix(utf8_trigger, &utf8_out_str)) { std::string rest_of_match = utf8_out_str.substr(utf8_trigger.size()); - self->mChatBox->setText(utf8_trigger + rest_of_match); // keep original capitalization for user-entered part + self->mInputEditor->setText(utf8_trigger + rest_of_match); // keep original capitalization for user-entered part // Select to end of line, starting from the character // after the last one the user typed. - self->mChatBox->selectNext(rest_of_match, false); + self->mInputEditor->selectNext(rest_of_match, false); } else if (matchChatTypeTrigger(utf8_trigger, &utf8_out_str)) { std::string rest_of_match = utf8_out_str.substr(utf8_trigger.size()); - self->mChatBox->setText(utf8_trigger + rest_of_match + " "); // keep original capitalization for user-entered part - self->mChatBox->endOfDoc(); + self->mInputEditor->setText(utf8_trigger + rest_of_match + " "); // keep original capitalization for user-entered part + self->mInputEditor->endOfDoc(); } //llinfos << "GESTUREDEBUG " << trigger @@ -592,7 +547,7 @@ void LLNearbyChat::onChatBoxFocusLost(LLFocusableElement* caller, void* userdata void LLNearbyChat::onChatBoxFocusReceived() { - mChatBox->setEnabled(!gDisconnected); + mInputEditor->setEnabled(!gDisconnected); } EChatType LLNearbyChat::processChatTypeTriggers(EChatType type, std::string &str) @@ -629,9 +584,9 @@ EChatType LLNearbyChat::processChatTypeTriggers(EChatType type, std::string &str void LLNearbyChat::sendChat( EChatType type ) { - if (mChatBox) + if (mInputEditor) { - LLWString text = mChatBox->getWText(); + LLWString text = mInputEditor->getWText(); LLWStringUtil::trim(text); LLWStringUtil::replaceChar(text,182,'\n'); // Convert paragraph symbols back into newlines. if (!text.empty()) @@ -664,7 +619,7 @@ void LLNearbyChat::sendChat( EChatType type ) } } - mChatBox->setText(LLStringExplicit("")); + mInputEditor->setText(LLStringExplicit("")); } gAgent.stopTyping(); @@ -735,7 +690,7 @@ void LLNearbyChat::addMessage(const LLChat& chat,bool archive,const LLSD &args) void LLNearbyChat::onChatBoxCommit() { - if (mChatBox->getText().length() > 0) + if (mInputEditor->getText().length() > 0) { sendChat(CHAT_TYPE_NORMAL); } @@ -837,15 +792,15 @@ void LLNearbyChat::startChat(const char* line) cb->show(); cb->setVisible(TRUE); cb->setFocus(TRUE); - cb->mChatBox->setFocus(TRUE); + cb->mInputEditor->setFocus(TRUE); if (line) { std::string line_string(line); - cb->mChatBox->setText(line_string); + cb->mInputEditor->setText(line_string); } - cb->mChatBox->endOfDoc(); + cb->mInputEditor->endOfDoc(); } } @@ -857,7 +812,7 @@ void LLNearbyChat::stopChat() if (cb) { - cb->mChatBox->setFocus(FALSE); + cb->mInputEditor->setFocus(FALSE); // stop typing animation gAgent.stopTyping(); diff --git a/indra/newview/llnearbychat.h b/indra/newview/llnearbychat.h index a0928e67ef..7c58e3037e 100644 --- a/indra/newview/llnearbychat.h +++ b/indra/newview/llnearbychat.h @@ -39,7 +39,6 @@ #include "llpanel.h" class LLResizeBar; -class LLChatHistory; class LLNearbyChat : public LLIMConversation @@ -73,7 +72,7 @@ public: void onNearbyChatContextMenuItemClicked(const LLSD& userdata); bool onNearbyChatCheckContextMenuItem(const LLSD& userdata); - LLChatEntry* getChatBox() { return mChatBox; } + LLChatEntry* getChatBox() { return mInputEditor; } std::string getCurrentChat(); @@ -98,8 +97,6 @@ protected: void onChatBoxCommit(); void onChatFontChange(LLFontGL* fontp); - /* virtual */ bool applyRectControl(); - /*virtual*/ void onTearOffClicked(); static LLWString stripChannelNumber(const LLWString &mesg, S32* channel); @@ -113,7 +110,6 @@ protected: // Which non-zero channel did we last chat on? static S32 sLastSpecialChatChannel; - LLChatEntry* mChatBox; LLOutputMonitorCtrl* mOutputMonitor; LLLocalSpeakerMgr* mSpeakerMgr; @@ -121,7 +117,6 @@ protected: private: - void getAllowedRect (LLRect& rect); // prepare chat's params and out one message to chatHistory void appendMessage(const LLChat& chat, const LLSD &args = 0); void onNearbySpeakers (); @@ -130,7 +125,6 @@ private: LLHandle<LLView> mPopupMenuHandle; std::vector<LLChat> mMessageArchive; - LLChatHistory* mChatHistory; }; diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 2871b7b018..20b33b5bea 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -34,6 +34,8 @@ #include "llvoavatar.h" +#define XXX_STINSON_CHUI_REWORK // temporarily re-enabling the in-world voice-dot + #include <stdio.h> #include <ctype.h> diff --git a/indra/newview/llvoicevisualizer.cpp b/indra/newview/llvoicevisualizer.cpp index dcf33bce10..d380a8672f 100644 --- a/indra/newview/llvoicevisualizer.cpp +++ b/indra/newview/llvoicevisualizer.cpp @@ -1,642 +1,643 @@ -/**
- * @file llvoicevisualizer.cpp
- * @brief Draws in-world speaking indicators.
- *
- * $LicenseInfo:firstyear=2000&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-//----------------------------------------------------------------------
-// Voice Visualizer
-// author: JJ Ventrella
-// (information about this stuff can be found in "llvoicevisualizer.h")
-//----------------------------------------------------------------------
-#include "llviewerprecompiledheaders.h"
-#include "llviewercontrol.h"
-#include "llglheaders.h"
-#include "llsphere.h"
-#include "llvoicevisualizer.h"
-#include "llviewercamera.h"
-#include "llviewerobject.h"
-#include "llviewertexture.h"
-#include "llviewertexturelist.h"
-#include "llvoiceclient.h"
-#include "llrender.h"
-
-//brent's wave image
-//29de489d-0491-fb00-7dab-f9e686d31e83
-
-
-#ifdef XXX_STINSON_CHUI_REWORK
-//--------------------------------------------------------------------------------------
-// sound symbol constants
-//--------------------------------------------------------------------------------------
-const F32 HEIGHT_ABOVE_HEAD = 0.3f; // how many meters vertically above the av's head the voice symbol will appear
-const F32 RED_THRESHOLD = LLVoiceClient::OVERDRIVEN_POWER_LEVEL; // value above which speaking amplitude causes the voice symbol to turn red
-const F32 GREEN_THRESHOLD = 0.2f; // value above which speaking amplitude causes the voice symbol to turn green
-const F32 FADE_OUT_DURATION = 0.4f; // how many seconds it takes for a pair of waves to fade away
-const F32 EXPANSION_RATE = 1.0f; // how many seconds it takes for the waves to expand to twice their original size
-const F32 EXPANSION_MAX = 1.5f; // maximum size scale to which the waves can expand before popping back to 1.0
-const F32 WAVE_WIDTH_SCALE = 0.03f; // base width of the waves
-const F32 WAVE_HEIGHT_SCALE = 0.02f; // base height of the waves
-const F32 BASE_BRIGHTNESS = 0.7f; // gray level of the voice indicator when quiet (below green threshold)
-const F32 DOT_SIZE = 0.05f; // size of the dot billboard texture
-const F32 DOT_OPACITY = 0.7f; // how opaque the dot is
-const F32 WAVE_MOTION_RATE = 1.5f; // scalar applied to consecutive waves as a function of speaking amplitude
-#endif // XXX_STINSON_CHUI_REWORK
-
-//--------------------------------------------------------------------------------------
-// gesticulation constants
-//--------------------------------------------------------------------------------------
-const F32 DEFAULT_MINIMUM_GESTICULATION_AMPLITUDE = 0.2f;
-const F32 DEFAULT_MAXIMUM_GESTICULATION_AMPLITUDE = 1.0f;
-
-#ifdef XXX_STINSON_CHUI_REWORK
-//--------------------------------------------------------------------------------------
-// other constants
-//--------------------------------------------------------------------------------------
-const F32 ONE_HALF = 1.0f; // to clarify intent and reduce magic numbers in the code.
-const LLVector3 WORLD_UPWARD_DIRECTION = LLVector3( 0.0f, 0.0f, 1.0f ); // Z is up in SL
-#endif // XXX_STINSON_CHUI_REWORK
-
-//------------------------------------------------------------------
-// Initialize the statics
-//------------------------------------------------------------------
-bool LLVoiceVisualizer::sPrefsInitialized = false;
-BOOL LLVoiceVisualizer::sLipSyncEnabled = FALSE;
-F32* LLVoiceVisualizer::sOoh = NULL;
-F32* LLVoiceVisualizer::sAah = NULL;
-U32 LLVoiceVisualizer::sOohs = 0;
-U32 LLVoiceVisualizer::sAahs = 0;
-F32 LLVoiceVisualizer::sOohAahRate = 0.0f;
-F32* LLVoiceVisualizer::sOohPowerTransfer = NULL;
-U32 LLVoiceVisualizer::sOohPowerTransfers = 0;
-F32 LLVoiceVisualizer::sOohPowerTransfersf = 0.0f;
-F32* LLVoiceVisualizer::sAahPowerTransfer = NULL;
-U32 LLVoiceVisualizer::sAahPowerTransfers = 0;
-F32 LLVoiceVisualizer::sAahPowerTransfersf = 0.0f;
-
-
-//-----------------------------------------------
-// constructor
-//-----------------------------------------------
-#ifdef XXX_STINSON_CHUI_REWORK
-LLVoiceVisualizer::LLVoiceVisualizer( const U8 type )
-#else // XXX_STINSON_CHUI_REWORK
-LLVoiceVisualizer::LLVoiceVisualizer()
- : LLRefCount(),
- mTimer(),
- mStartTime(0.0),
- mCurrentlySpeaking(false),
- mSpeakingAmplitude(0.0f),
- mMaxGesticulationAmplitude(DEFAULT_MAXIMUM_GESTICULATION_AMPLITUDE),
- mMinGesticulationAmplitude(DEFAULT_MINIMUM_GESTICULATION_AMPLITUDE)
-#endif // XXX_STINSON_CHUI_REWORK
-{
-#ifdef XXX_STINSON_CHUI_REWORK
- mCurrentTime = mTimer.getTotalSeconds();
- mPreviousTime = mCurrentTime;
- mStartTime = mCurrentTime;
-#else // XXX_STINSON_CHUI_REWORK
- mStartTime = mTimer.getTotalSeconds();
-#endif // XXX_STINSON_CHUI_REWORK
-#ifdef XXX_STINSON_CHUI_REWORK
- mVoiceSourceWorldPosition = LLVector3( 0.0f, 0.0f, 0.0f );
- mSpeakingAmplitude = 0.0f;
- mCurrentlySpeaking = false;
- mVoiceEnabled = false;
- mMinGesticulationAmplitude = DEFAULT_MINIMUM_GESTICULATION_AMPLITUDE;
- mMaxGesticulationAmplitude = DEFAULT_MAXIMUM_GESTICULATION_AMPLITUDE;
- mSoundSymbol.mActive = true;
- mSoundSymbol.mPosition = LLVector3( 0.0f, 0.0f, 0.0f );
-#endif // XXX_STINSON_CHUI_REWORK
-
- mTimer.reset();
-
-#ifdef XXX_STINSON_CHUI_REWORK
- const char* sound_level_img[] =
- {
- "voice_meter_dot.j2c",
- "voice_meter_rings.j2c",
- "voice_meter_rings.j2c",
- "voice_meter_rings.j2c",
- "voice_meter_rings.j2c",
- "voice_meter_rings.j2c",
- "voice_meter_rings.j2c"
- };
-
- for (int i=0; i<NUM_VOICE_SYMBOL_WAVES; i++)
- {
- mSoundSymbol.mWaveFadeOutStartTime [i] = mCurrentTime;
- mSoundSymbol.mTexture [i] = LLViewerTextureManager::getFetchedTextureFromFile(sound_level_img[i], FALSE, LLViewerTexture::BOOST_UI);
- mSoundSymbol.mWaveActive [i] = false;
- mSoundSymbol.mWaveOpacity [i] = 1.0f;
- mSoundSymbol.mWaveExpansion [i] = 1.0f;
- }
-
- mSoundSymbol.mTexture[0]->setFilteringOption(LLTexUnit::TFO_ANISOTROPIC);
-#endif // XXX_STINSON_CHUI_REWORK
-
- // The first instance loads the initial state from prefs.
- if (!sPrefsInitialized)
- {
- setPreferences();
-
- // Set up our listener to get updates on all prefs values we care about.
- gSavedSettings.getControl("LipSyncEnabled")->getSignal()->connect(boost::bind(&LLVoiceVisualizer::handleVoiceVisualizerPrefsChanged, _2));
- gSavedSettings.getControl("LipSyncOohAahRate")->getSignal()->connect(boost::bind(&LLVoiceVisualizer::handleVoiceVisualizerPrefsChanged, _2));
- gSavedSettings.getControl("LipSyncOoh")->getSignal()->connect(boost::bind(&LLVoiceVisualizer::handleVoiceVisualizerPrefsChanged, _2));
- gSavedSettings.getControl("LipSyncAah")->getSignal()->connect(boost::bind(&LLVoiceVisualizer::handleVoiceVisualizerPrefsChanged, _2));
- gSavedSettings.getControl("LipSyncOohPowerTransfer")->getSignal()->connect(boost::bind(&LLVoiceVisualizer::handleVoiceVisualizerPrefsChanged, _2));
- gSavedSettings.getControl("LipSyncAahPowerTransfer")->getSignal()->connect(boost::bind(&LLVoiceVisualizer::handleVoiceVisualizerPrefsChanged, _2));
-
- sPrefsInitialized = true;
- }
-
-}//---------------------------------------------------
-
-#ifdef XXX_STINSON_CHUI_REWORK
-//---------------------------------------------------
-void LLVoiceVisualizer::setMinGesticulationAmplitude( F32 m )
-{
- mMinGesticulationAmplitude = m;
-
-}//---------------------------------------------------
-
-//---------------------------------------------------
-void LLVoiceVisualizer::setMaxGesticulationAmplitude( F32 m )
-{
- mMaxGesticulationAmplitude = m;
-
-}//---------------------------------------------------
-
-//---------------------------------------------------
-void LLVoiceVisualizer::setVoiceEnabled( bool v )
-{
- mVoiceEnabled = v;
-
-}//---------------------------------------------------
-#endif // XXX_STINSON_CHUI_REWORK
-
-//---------------------------------------------------
-void LLVoiceVisualizer::setStartSpeaking()
-{
- mStartTime = mTimer.getTotalSeconds();
- mCurrentlySpeaking = true;
-#ifdef XXX_STINSON_CHUI_REWORK
- mSoundSymbol.mActive = true;
-#endif // XXX_STINSON_CHUI_REWORK
-
-}//---------------------------------------------------
-
-
-//---------------------------------------------------
-bool LLVoiceVisualizer::getCurrentlySpeaking()
-{
- return mCurrentlySpeaking;
-
-}//---------------------------------------------------
-
-
-//---------------------------------------------------
-void LLVoiceVisualizer::setStopSpeaking()
-{
- mCurrentlySpeaking = false;
- mSpeakingAmplitude = 0.0f;
-
-}//---------------------------------------------------
-
-
-//---------------------------------------------------
-void LLVoiceVisualizer::setSpeakingAmplitude( F32 a )
-{
- mSpeakingAmplitude = a;
-
-}//---------------------------------------------------
-
-//------------------------------------------------------------------
-// handles parameter updates
-//------------------------------------------------------------------
-bool LLVoiceVisualizer::handleVoiceVisualizerPrefsChanged(const LLSD& newvalue)
-{
- // Note: Ignore the specific event value, we look up the ones we want
- LLVoiceVisualizer::setPreferences();
- return true;
-}
-
-//---------------------------------------------------
-void LLVoiceVisualizer::setPreferences( )
-{
- sLipSyncEnabled = gSavedSettings.getBOOL("LipSyncEnabled");
- sOohAahRate = gSavedSettings.getF32("LipSyncOohAahRate");
-
- std::string oohString = gSavedSettings.getString("LipSyncOoh");
- lipStringToF32s (oohString, sOoh, sOohs);
-
- std::string aahString = gSavedSettings.getString("LipSyncAah");
- lipStringToF32s (aahString, sAah, sAahs);
-
- std::string oohPowerString = gSavedSettings.getString("LipSyncOohPowerTransfer");
- lipStringToF32s (oohPowerString, sOohPowerTransfer, sOohPowerTransfers);
- sOohPowerTransfersf = (F32) sOohPowerTransfers;
-
- std::string aahPowerString = gSavedSettings.getString("LipSyncAahPowerTransfer");
- lipStringToF32s (aahPowerString, sAahPowerTransfer, sAahPowerTransfers);
- sAahPowerTransfersf = (F32) sAahPowerTransfers;
-
-}//---------------------------------------------------
-
-
-//---------------------------------------------------
-// convert a string of digits to an array of floats.
-// the result for each digit is the value of the
-// digit multiplied by 0.11
-//---------------------------------------------------
-void LLVoiceVisualizer::lipStringToF32s ( std::string& in_string, F32*& out_F32s, U32& count_F32s )
-{
- delete[] out_F32s; // get rid of the current array
-
- count_F32s = in_string.length();
- if (count_F32s == 0)
- {
- // we don't like zero length arrays
-
- count_F32s = 1;
- out_F32s = new F32[1];
- out_F32s[0] = 0.0f;
- }
- else
- {
- out_F32s = new F32[count_F32s];
-
- for (U32 i=0; i<count_F32s; i++)
- {
- // we convert the characters 0 to 9 to their numeric value
- // anything else we take the low order four bits with a ceiling of 9
-
- U8 digit = in_string[i];
- U8 four_bits = digit % 16;
- if (four_bits > 9)
- {
- four_bits = 9;
- }
- out_F32s[i] = 0.11f * (F32) four_bits;
- }
- }
-
-}//---------------------------------------------------
-
-
-//--------------------------------------------------------------------------
-// find the amount to blend the ooh and aah mouth morphs
-//--------------------------------------------------------------------------
-void LLVoiceVisualizer::lipSyncOohAah( F32& ooh, F32& aah )
-{
- if( ( sLipSyncEnabled == TRUE ) && mCurrentlySpeaking )
- {
- U32 transfer_index = (U32) (sOohPowerTransfersf * mSpeakingAmplitude);
- if (transfer_index >= sOohPowerTransfers)
- {
- transfer_index = sOohPowerTransfers - 1;
- }
- F32 transfer_ooh = sOohPowerTransfer[transfer_index];
-
- transfer_index = (U32) (sAahPowerTransfersf * mSpeakingAmplitude);
- if (transfer_index >= sAahPowerTransfers)
- {
- transfer_index = sAahPowerTransfers - 1;
- }
- F32 transfer_aah = sAahPowerTransfer[transfer_index];
-
- F64 current_time = mTimer.getTotalSeconds();
- F64 elapsed_time = current_time - mStartTime;
- U32 elapsed_frames = (U32) (elapsed_time * sOohAahRate);
- U32 elapsed_oohs = elapsed_frames % sOohs;
- U32 elapsed_aahs = elapsed_frames % sAahs;
-
- ooh = transfer_ooh * sOoh[elapsed_oohs];
- aah = transfer_aah * sAah[elapsed_aahs];
-
- /*
- llinfos << " elapsed frames " << elapsed_frames
- << " ooh " << ooh
- << " aah " << aah
- << " transfer ooh" << transfer_ooh
- << " transfer aah" << transfer_aah
- << " start time " << mStartTime
- << " current time " << current_time
- << " elapsed time " << elapsed_time
- << " elapsed oohs " << elapsed_oohs
- << " elapsed aahs " << elapsed_aahs
- << llendl;
- */
- }
- else
- {
- ooh = 0.0f;
- aah = 0.0f;
- }
-
-}//---------------------------------------------------
-
-
-#ifdef XXX_STINSON_CHUI_REWORK
-//---------------------------------------------------
-// this method is inherited from HUD Effect
-//---------------------------------------------------
-void LLVoiceVisualizer::render()
-{
- if ( ! mVoiceEnabled )
- {
- return;
- }
-
- if ( mSoundSymbol.mActive )
- {
- mPreviousTime = mCurrentTime;
- mCurrentTime = mTimer.getTotalSeconds();
-
- //---------------------------------------------------------------
- // set the sound symbol position over the source (avatar's head)
- //---------------------------------------------------------------
- mSoundSymbol.mPosition = mVoiceSourceWorldPosition + WORLD_UPWARD_DIRECTION * HEIGHT_ABOVE_HEAD;
-
- //---------------------------------------------------------------
- // some gl state
- //---------------------------------------------------------------
- LLGLSPipelineAlpha alpha_blend;
- LLGLDepthTest depth(GL_TRUE, GL_FALSE);
-
- //-------------------------------------------------------------
- // create coordinates of the geometry for the dot
- //-------------------------------------------------------------
- LLViewerCamera* camera = LLViewerCamera::getInstance();
- LLVector3 l = camera->getLeftAxis() * DOT_SIZE;
- LLVector3 u = camera->getUpAxis() * DOT_SIZE;
-
- LLVector3 bottomLeft = mSoundSymbol.mPosition + l - u;
- LLVector3 bottomRight = mSoundSymbol.mPosition - l - u;
- LLVector3 topLeft = mSoundSymbol.mPosition + l + u;
- LLVector3 topRight = mSoundSymbol.mPosition - l + u;
-
- //-----------------------------
- // bind texture 0 (the dot)
- //-----------------------------
- gGL.getTexUnit(0)->bind(mSoundSymbol.mTexture[0]);
-
- //-------------------------------------------------------------
- // now render the dot
- //-------------------------------------------------------------
- gGL.color4fv( LLColor4( 1.0f, 1.0f, 1.0f, DOT_OPACITY ).mV );
-
- gGL.begin( LLRender::TRIANGLE_STRIP );
- gGL.texCoord2i( 0, 0 ); gGL.vertex3fv( bottomLeft.mV );
- gGL.texCoord2i( 1, 0 ); gGL.vertex3fv( bottomRight.mV );
- gGL.texCoord2i( 0, 1 ); gGL.vertex3fv( topLeft.mV );
- gGL.end();
-
- gGL.begin( LLRender::TRIANGLE_STRIP );
- gGL.texCoord2i( 1, 0 ); gGL.vertex3fv( bottomRight.mV );
- gGL.texCoord2i( 1, 1 ); gGL.vertex3fv( topRight.mV );
- gGL.texCoord2i( 0, 1 ); gGL.vertex3fv( topLeft.mV );
- gGL.end();
-
-
-
- //--------------------------------------------------------------------------------------
- // if currently speaking, trigger waves (1 through 6) based on speaking amplitude
- //--------------------------------------------------------------------------------------
- if ( mCurrentlySpeaking )
- {
- F32 min = 0.2f;
- F32 max = 0.7f;
- F32 fraction = ( mSpeakingAmplitude - min ) / ( max - min );
-
- // in case mSpeakingAmplitude > max....
- if ( fraction > 1.0f )
- {
- fraction = 1.0f;
- }
-
- S32 level = 1 + (int)( fraction * ( NUM_VOICE_SYMBOL_WAVES - 2 ) );
-
- for (int i=0; i<level+1; i++)
- {
- mSoundSymbol.mWaveActive [i] = true;
- mSoundSymbol.mWaveOpacity [i] = 1.0f;
- mSoundSymbol.mWaveFadeOutStartTime [i] = mCurrentTime;
- }
-
- } // if currently speaking
-
- //---------------------------------------------------
- // determine color
- //---------------------------------------------------
- F32 red = 0.0f;
- F32 green = 0.0f;
- F32 blue = 0.0f;
- if ( mSpeakingAmplitude < RED_THRESHOLD )
- {
- if ( mSpeakingAmplitude < GREEN_THRESHOLD )
- {
- red = BASE_BRIGHTNESS;
- green = BASE_BRIGHTNESS;
- blue = BASE_BRIGHTNESS;
- }
- else
- {
- //---------------------------------------------------
- // fade from gray to bright green
- //---------------------------------------------------
- F32 fraction = ( mSpeakingAmplitude - GREEN_THRESHOLD ) / ( 1.0f - GREEN_THRESHOLD );
- red = BASE_BRIGHTNESS - ( fraction * BASE_BRIGHTNESS );
- green = BASE_BRIGHTNESS + fraction * ( 1.0f - BASE_BRIGHTNESS );
- blue = BASE_BRIGHTNESS - ( fraction * BASE_BRIGHTNESS );
- }
- }
- else
- {
- //---------------------------------------------------
- // redish
- //---------------------------------------------------
- red = 1.0f;
- green = 0.2f;
- blue = 0.2f;
- }
-
- for (int i=0; i<NUM_VOICE_SYMBOL_WAVES; i++)
- {
- if ( mSoundSymbol.mWaveActive[i] )
- {
- F32 fadeOutFraction = (F32)( mCurrentTime - mSoundSymbol.mWaveFadeOutStartTime[i] ) / FADE_OUT_DURATION;
-
- mSoundSymbol.mWaveOpacity[i] = 1.0f - fadeOutFraction;
-
- if ( mSoundSymbol.mWaveOpacity[i] < 0.0f )
- {
- mSoundSymbol.mWaveFadeOutStartTime [i] = mCurrentTime;
- mSoundSymbol.mWaveOpacity [i] = 0.0f;
- mSoundSymbol.mWaveActive [i] = false;
- }
-
- //----------------------------------------------------------------------------------
- // This is where we calculate the expansion of the waves - that is, the
- // rate at which they are scaled greater than 1.0 so that they grow over time.
- //----------------------------------------------------------------------------------
- F32 timeSlice = (F32)( mCurrentTime - mPreviousTime );
- F32 waveSpeed = mSpeakingAmplitude * WAVE_MOTION_RATE;
- mSoundSymbol.mWaveExpansion[i] *= ( 1.0f + EXPANSION_RATE * timeSlice * waveSpeed );
-
- if ( mSoundSymbol.mWaveExpansion[i] > EXPANSION_MAX )
- {
- mSoundSymbol.mWaveExpansion[i] = 1.0f;
- }
-
- //----------------------------------------------------------------------------------
- // create geometry for the wave billboard textures
- //----------------------------------------------------------------------------------
- F32 width = i * WAVE_WIDTH_SCALE * mSoundSymbol.mWaveExpansion[i];
- F32 height = i * WAVE_HEIGHT_SCALE * mSoundSymbol.mWaveExpansion[i];
-
- LLVector3 l = camera->getLeftAxis() * width;
- LLVector3 u = camera->getUpAxis() * height;
-
- LLVector3 bottomLeft = mSoundSymbol.mPosition + l - u;
- LLVector3 bottomRight = mSoundSymbol.mPosition - l - u;
- LLVector3 topLeft = mSoundSymbol.mPosition + l + u;
- LLVector3 topRight = mSoundSymbol.mPosition - l + u;
-
- gGL.color4fv( LLColor4( red, green, blue, mSoundSymbol.mWaveOpacity[i] ).mV );
- gGL.getTexUnit(0)->bind(mSoundSymbol.mTexture[i]);
-
-
- //---------------------------------------------------
- // now, render the mofo
- //---------------------------------------------------
- gGL.begin( LLRender::TRIANGLE_STRIP );
- gGL.texCoord2i( 0, 0 ); gGL.vertex3fv( bottomLeft.mV );
- gGL.texCoord2i( 1, 0 ); gGL.vertex3fv( bottomRight.mV );
- gGL.texCoord2i( 0, 1 ); gGL.vertex3fv( topLeft.mV );
- gGL.end();
-
- gGL.begin( LLRender::TRIANGLE_STRIP );
- gGL.texCoord2i( 1, 0 ); gGL.vertex3fv( bottomRight.mV );
- gGL.texCoord2i( 1, 1 ); gGL.vertex3fv( topRight.mV );
- gGL.texCoord2i( 0, 1 ); gGL.vertex3fv( topLeft.mV );
- gGL.end();
-
- } //if ( mSoundSymbol.mWaveActive[i] )
-
- }// for loop
-
- }//if ( mSoundSymbol.mActive )
-
-}//---------------------------------------------------
-
-//---------------------------------------------------
-void LLVoiceVisualizer::setVoiceSourceWorldPosition( const LLVector3 &p )
-{
- mVoiceSourceWorldPosition = p;
-
-}//---------------------------------------------------
-#endif // XXX_STINSON_CHUI_REWORK
-
-//---------------------------------------------------
-VoiceGesticulationLevel LLVoiceVisualizer::getCurrentGesticulationLevel()
-{
- VoiceGesticulationLevel gesticulationLevel = VOICE_GESTICULATION_LEVEL_OFF; //default
-
- //-----------------------------------------------------------------------------------------
- // Within the range of gesticulation amplitudes, the sound signal is split into
- // three equal amplitude regimes, each specifying one of three gesticulation levels.
- //-----------------------------------------------------------------------------------------
- F32 range = mMaxGesticulationAmplitude - mMinGesticulationAmplitude;
-
- if ( mSpeakingAmplitude > mMinGesticulationAmplitude + range * 0.5f ) { gesticulationLevel = VOICE_GESTICULATION_LEVEL_HIGH; }
- else if ( mSpeakingAmplitude > mMinGesticulationAmplitude + range * 0.25f ) { gesticulationLevel = VOICE_GESTICULATION_LEVEL_MEDIUM; }
- else if ( mSpeakingAmplitude > mMinGesticulationAmplitude + range * 0.00000f ) { gesticulationLevel = VOICE_GESTICULATION_LEVEL_LOW; }
-
- return gesticulationLevel;
-
-}//---------------------------------------------------
-
-
-
-//------------------------------------
-// Destructor
-//------------------------------------
-LLVoiceVisualizer::~LLVoiceVisualizer()
-{
-}//----------------------------------------------
-
-
-#ifdef XXX_STINSON_CHUI_REWORK
-//---------------------------------------------------
-// "packData" is inherited from HUDEffect
-//---------------------------------------------------
-void LLVoiceVisualizer::packData(LLMessageSystem *mesgsys)
-{
- // Pack the default data
- LLHUDEffect::packData(mesgsys);
-
- // TODO -- pack the relevant data for voice effects
- // we'll come up with some cool configurations....TBD
- //U8 packed_data[41];
- //mesgsys->addBinaryDataFast(_PREHASH_TypeData, packed_data, 41);
- U8 packed_data = 0;
- mesgsys->addBinaryDataFast(_PREHASH_TypeData, &packed_data, 1);
-}
-
-
-//---------------------------------------------------
-// "unpackData" is inherited from HUDEffect
-//---------------------------------------------------
-void LLVoiceVisualizer::unpackData(LLMessageSystem *mesgsys, S32 blocknum)
-{
- // TODO -- find the speaker, unpack binary data, set the properties of this effect
- /*
- LLHUDEffect::unpackData(mesgsys, blocknum);
- LLUUID source_id;
- LLUUID target_id;
- S32 size = mesgsys->getSizeFast(_PREHASH_Effect, blocknum, _PREHASH_TypeData);
- if (size != 1)
- {
- llwarns << "Voice effect with bad size " << size << llendl;
- return;
- }
- mesgsys->getBinaryDataFast(_PREHASH_Effect, _PREHASH_TypeData, packed_data, 1, blocknum);
- */
-}
-
-
-//------------------------------------------------------------------
-// this method is inherited from HUD Effect
-//------------------------------------------------------------------
-void LLVoiceVisualizer::markDead()
-{
- mCurrentlySpeaking = false;
- mVoiceEnabled = false;
- mSoundSymbol.mActive = false;
-
- LLHUDEffect::markDead();
-}//------------------------------------------------------------------
-
-#endif // XXX_STINSON_CHUI_REWORK
+/** + * @file llvoicevisualizer.cpp + * @brief Draws in-world speaking indicators. + * + * $LicenseInfo:firstyear=2000&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +//---------------------------------------------------------------------- +// Voice Visualizer +// author: JJ Ventrella +// (information about this stuff can be found in "llvoicevisualizer.h") +//---------------------------------------------------------------------- +#include "llviewerprecompiledheaders.h" +#include "llviewercontrol.h" +#include "llglheaders.h" +#include "llsphere.h" +#include "llvoicevisualizer.h" +#include "llviewercamera.h" +#include "llviewerobject.h" +#include "llviewertexture.h" +#include "llviewertexturelist.h" +#include "llvoiceclient.h" +#include "llrender.h" + +//brent's wave image +//29de489d-0491-fb00-7dab-f9e686d31e83 + + +#ifdef XXX_STINSON_CHUI_REWORK +//-------------------------------------------------------------------------------------- +// sound symbol constants +//-------------------------------------------------------------------------------------- +const F32 HEIGHT_ABOVE_HEAD = 0.3f; // how many meters vertically above the av's head the voice symbol will appear +const F32 RED_THRESHOLD = LLVoiceClient::OVERDRIVEN_POWER_LEVEL; // value above which speaking amplitude causes the voice symbol to turn red +const F32 GREEN_THRESHOLD = 0.2f; // value above which speaking amplitude causes the voice symbol to turn green +const F32 FADE_OUT_DURATION = 0.4f; // how many seconds it takes for a pair of waves to fade away +const F32 EXPANSION_RATE = 1.0f; // how many seconds it takes for the waves to expand to twice their original size +const F32 EXPANSION_MAX = 1.5f; // maximum size scale to which the waves can expand before popping back to 1.0 +const F32 WAVE_WIDTH_SCALE = 0.03f; // base width of the waves +const F32 WAVE_HEIGHT_SCALE = 0.02f; // base height of the waves +const F32 BASE_BRIGHTNESS = 0.7f; // gray level of the voice indicator when quiet (below green threshold) +const F32 DOT_SIZE = 0.05f; // size of the dot billboard texture +const F32 DOT_OPACITY = 0.7f; // how opaque the dot is +const F32 WAVE_MOTION_RATE = 1.5f; // scalar applied to consecutive waves as a function of speaking amplitude +#endif // XXX_STINSON_CHUI_REWORK + +//-------------------------------------------------------------------------------------- +// gesticulation constants +//-------------------------------------------------------------------------------------- +const F32 DEFAULT_MINIMUM_GESTICULATION_AMPLITUDE = 0.2f; +const F32 DEFAULT_MAXIMUM_GESTICULATION_AMPLITUDE = 1.0f; + +#ifdef XXX_STINSON_CHUI_REWORK +//-------------------------------------------------------------------------------------- +// other constants +//-------------------------------------------------------------------------------------- +const F32 ONE_HALF = 1.0f; // to clarify intent and reduce magic numbers in the code. +const LLVector3 WORLD_UPWARD_DIRECTION = LLVector3( 0.0f, 0.0f, 1.0f ); // Z is up in SL +#endif // XXX_STINSON_CHUI_REWORK + +//------------------------------------------------------------------ +// Initialize the statics +//------------------------------------------------------------------ +bool LLVoiceVisualizer::sPrefsInitialized = false; +BOOL LLVoiceVisualizer::sLipSyncEnabled = FALSE; +F32* LLVoiceVisualizer::sOoh = NULL; +F32* LLVoiceVisualizer::sAah = NULL; +U32 LLVoiceVisualizer::sOohs = 0; +U32 LLVoiceVisualizer::sAahs = 0; +F32 LLVoiceVisualizer::sOohAahRate = 0.0f; +F32* LLVoiceVisualizer::sOohPowerTransfer = NULL; +U32 LLVoiceVisualizer::sOohPowerTransfers = 0; +F32 LLVoiceVisualizer::sOohPowerTransfersf = 0.0f; +F32* LLVoiceVisualizer::sAahPowerTransfer = NULL; +U32 LLVoiceVisualizer::sAahPowerTransfers = 0; +F32 LLVoiceVisualizer::sAahPowerTransfersf = 0.0f; + + +//----------------------------------------------- +// constructor +//----------------------------------------------- +#ifdef XXX_STINSON_CHUI_REWORK +LLVoiceVisualizer::LLVoiceVisualizer( const U8 type ) + : LLHUDEffect(type) +#else // XXX_STINSON_CHUI_REWORK +LLVoiceVisualizer::LLVoiceVisualizer() + : LLRefCount(), + mTimer(), + mStartTime(0.0), + mCurrentlySpeaking(false), + mSpeakingAmplitude(0.0f), + mMaxGesticulationAmplitude(DEFAULT_MAXIMUM_GESTICULATION_AMPLITUDE), + mMinGesticulationAmplitude(DEFAULT_MINIMUM_GESTICULATION_AMPLITUDE) +#endif // XXX_STINSON_CHUI_REWORK +{ +#ifdef XXX_STINSON_CHUI_REWORK + mCurrentTime = mTimer.getTotalSeconds(); + mPreviousTime = mCurrentTime; + mStartTime = mCurrentTime; +#else // XXX_STINSON_CHUI_REWORK + mStartTime = mTimer.getTotalSeconds(); +#endif // XXX_STINSON_CHUI_REWORK +#ifdef XXX_STINSON_CHUI_REWORK + mVoiceSourceWorldPosition = LLVector3( 0.0f, 0.0f, 0.0f ); + mSpeakingAmplitude = 0.0f; + mCurrentlySpeaking = false; + mVoiceEnabled = false; + mMinGesticulationAmplitude = DEFAULT_MINIMUM_GESTICULATION_AMPLITUDE; + mMaxGesticulationAmplitude = DEFAULT_MAXIMUM_GESTICULATION_AMPLITUDE; + mSoundSymbol.mActive = true; + mSoundSymbol.mPosition = LLVector3( 0.0f, 0.0f, 0.0f ); +#endif // XXX_STINSON_CHUI_REWORK + + mTimer.reset(); + +#ifdef XXX_STINSON_CHUI_REWORK + const char* sound_level_img[] = + { + "voice_meter_dot.j2c", + "voice_meter_rings.j2c", + "voice_meter_rings.j2c", + "voice_meter_rings.j2c", + "voice_meter_rings.j2c", + "voice_meter_rings.j2c", + "voice_meter_rings.j2c" + }; + + for (int i=0; i<NUM_VOICE_SYMBOL_WAVES; i++) + { + mSoundSymbol.mWaveFadeOutStartTime [i] = mCurrentTime; + mSoundSymbol.mTexture [i] = LLViewerTextureManager::getFetchedTextureFromFile(sound_level_img[i], FALSE, LLViewerTexture::BOOST_UI); + mSoundSymbol.mWaveActive [i] = false; + mSoundSymbol.mWaveOpacity [i] = 1.0f; + mSoundSymbol.mWaveExpansion [i] = 1.0f; + } + + mSoundSymbol.mTexture[0]->setFilteringOption(LLTexUnit::TFO_ANISOTROPIC); +#endif // XXX_STINSON_CHUI_REWORK + + // The first instance loads the initial state from prefs. + if (!sPrefsInitialized) + { + setPreferences(); + + // Set up our listener to get updates on all prefs values we care about. + gSavedSettings.getControl("LipSyncEnabled")->getSignal()->connect(boost::bind(&LLVoiceVisualizer::handleVoiceVisualizerPrefsChanged, _2)); + gSavedSettings.getControl("LipSyncOohAahRate")->getSignal()->connect(boost::bind(&LLVoiceVisualizer::handleVoiceVisualizerPrefsChanged, _2)); + gSavedSettings.getControl("LipSyncOoh")->getSignal()->connect(boost::bind(&LLVoiceVisualizer::handleVoiceVisualizerPrefsChanged, _2)); + gSavedSettings.getControl("LipSyncAah")->getSignal()->connect(boost::bind(&LLVoiceVisualizer::handleVoiceVisualizerPrefsChanged, _2)); + gSavedSettings.getControl("LipSyncOohPowerTransfer")->getSignal()->connect(boost::bind(&LLVoiceVisualizer::handleVoiceVisualizerPrefsChanged, _2)); + gSavedSettings.getControl("LipSyncAahPowerTransfer")->getSignal()->connect(boost::bind(&LLVoiceVisualizer::handleVoiceVisualizerPrefsChanged, _2)); + + sPrefsInitialized = true; + } + +}//--------------------------------------------------- + +#ifdef XXX_STINSON_CHUI_REWORK +//--------------------------------------------------- +void LLVoiceVisualizer::setMinGesticulationAmplitude( F32 m ) +{ + mMinGesticulationAmplitude = m; + +}//--------------------------------------------------- + +//--------------------------------------------------- +void LLVoiceVisualizer::setMaxGesticulationAmplitude( F32 m ) +{ + mMaxGesticulationAmplitude = m; + +}//--------------------------------------------------- + +//--------------------------------------------------- +void LLVoiceVisualizer::setVoiceEnabled( bool v ) +{ + mVoiceEnabled = v; + +}//--------------------------------------------------- +#endif // XXX_STINSON_CHUI_REWORK + +//--------------------------------------------------- +void LLVoiceVisualizer::setStartSpeaking() +{ + mStartTime = mTimer.getTotalSeconds(); + mCurrentlySpeaking = true; +#ifdef XXX_STINSON_CHUI_REWORK + mSoundSymbol.mActive = true; +#endif // XXX_STINSON_CHUI_REWORK + +}//--------------------------------------------------- + + +//--------------------------------------------------- +bool LLVoiceVisualizer::getCurrentlySpeaking() +{ + return mCurrentlySpeaking; + +}//--------------------------------------------------- + + +//--------------------------------------------------- +void LLVoiceVisualizer::setStopSpeaking() +{ + mCurrentlySpeaking = false; + mSpeakingAmplitude = 0.0f; + +}//--------------------------------------------------- + + +//--------------------------------------------------- +void LLVoiceVisualizer::setSpeakingAmplitude( F32 a ) +{ + mSpeakingAmplitude = a; + +}//--------------------------------------------------- + +//------------------------------------------------------------------ +// handles parameter updates +//------------------------------------------------------------------ +bool LLVoiceVisualizer::handleVoiceVisualizerPrefsChanged(const LLSD& newvalue) +{ + // Note: Ignore the specific event value, we look up the ones we want + LLVoiceVisualizer::setPreferences(); + return true; +} + +//--------------------------------------------------- +void LLVoiceVisualizer::setPreferences( ) +{ + sLipSyncEnabled = gSavedSettings.getBOOL("LipSyncEnabled"); + sOohAahRate = gSavedSettings.getF32("LipSyncOohAahRate"); + + std::string oohString = gSavedSettings.getString("LipSyncOoh"); + lipStringToF32s (oohString, sOoh, sOohs); + + std::string aahString = gSavedSettings.getString("LipSyncAah"); + lipStringToF32s (aahString, sAah, sAahs); + + std::string oohPowerString = gSavedSettings.getString("LipSyncOohPowerTransfer"); + lipStringToF32s (oohPowerString, sOohPowerTransfer, sOohPowerTransfers); + sOohPowerTransfersf = (F32) sOohPowerTransfers; + + std::string aahPowerString = gSavedSettings.getString("LipSyncAahPowerTransfer"); + lipStringToF32s (aahPowerString, sAahPowerTransfer, sAahPowerTransfers); + sAahPowerTransfersf = (F32) sAahPowerTransfers; + +}//--------------------------------------------------- + + +//--------------------------------------------------- +// convert a string of digits to an array of floats. +// the result for each digit is the value of the +// digit multiplied by 0.11 +//--------------------------------------------------- +void LLVoiceVisualizer::lipStringToF32s ( std::string& in_string, F32*& out_F32s, U32& count_F32s ) +{ + delete[] out_F32s; // get rid of the current array + + count_F32s = in_string.length(); + if (count_F32s == 0) + { + // we don't like zero length arrays + + count_F32s = 1; + out_F32s = new F32[1]; + out_F32s[0] = 0.0f; + } + else + { + out_F32s = new F32[count_F32s]; + + for (U32 i=0; i<count_F32s; i++) + { + // we convert the characters 0 to 9 to their numeric value + // anything else we take the low order four bits with a ceiling of 9 + + U8 digit = in_string[i]; + U8 four_bits = digit % 16; + if (four_bits > 9) + { + four_bits = 9; + } + out_F32s[i] = 0.11f * (F32) four_bits; + } + } + +}//--------------------------------------------------- + + +//-------------------------------------------------------------------------- +// find the amount to blend the ooh and aah mouth morphs +//-------------------------------------------------------------------------- +void LLVoiceVisualizer::lipSyncOohAah( F32& ooh, F32& aah ) +{ + if( ( sLipSyncEnabled == TRUE ) && mCurrentlySpeaking ) + { + U32 transfer_index = (U32) (sOohPowerTransfersf * mSpeakingAmplitude); + if (transfer_index >= sOohPowerTransfers) + { + transfer_index = sOohPowerTransfers - 1; + } + F32 transfer_ooh = sOohPowerTransfer[transfer_index]; + + transfer_index = (U32) (sAahPowerTransfersf * mSpeakingAmplitude); + if (transfer_index >= sAahPowerTransfers) + { + transfer_index = sAahPowerTransfers - 1; + } + F32 transfer_aah = sAahPowerTransfer[transfer_index]; + + F64 current_time = mTimer.getTotalSeconds(); + F64 elapsed_time = current_time - mStartTime; + U32 elapsed_frames = (U32) (elapsed_time * sOohAahRate); + U32 elapsed_oohs = elapsed_frames % sOohs; + U32 elapsed_aahs = elapsed_frames % sAahs; + + ooh = transfer_ooh * sOoh[elapsed_oohs]; + aah = transfer_aah * sAah[elapsed_aahs]; + + /* + llinfos << " elapsed frames " << elapsed_frames + << " ooh " << ooh + << " aah " << aah + << " transfer ooh" << transfer_ooh + << " transfer aah" << transfer_aah + << " start time " << mStartTime + << " current time " << current_time + << " elapsed time " << elapsed_time + << " elapsed oohs " << elapsed_oohs + << " elapsed aahs " << elapsed_aahs + << llendl; + */ + } + else + { + ooh = 0.0f; + aah = 0.0f; + } + +}//--------------------------------------------------- + + +#ifdef XXX_STINSON_CHUI_REWORK +//--------------------------------------------------- +// this method is inherited from HUD Effect +//--------------------------------------------------- +void LLVoiceVisualizer::render() +{ + if ( ! mVoiceEnabled ) + { + return; + } + + if ( mSoundSymbol.mActive ) + { + mPreviousTime = mCurrentTime; + mCurrentTime = mTimer.getTotalSeconds(); + + //--------------------------------------------------------------- + // set the sound symbol position over the source (avatar's head) + //--------------------------------------------------------------- + mSoundSymbol.mPosition = mVoiceSourceWorldPosition + WORLD_UPWARD_DIRECTION * HEIGHT_ABOVE_HEAD; + + //--------------------------------------------------------------- + // some gl state + //--------------------------------------------------------------- + LLGLSPipelineAlpha alpha_blend; + LLGLDepthTest depth(GL_TRUE, GL_FALSE); + + //------------------------------------------------------------- + // create coordinates of the geometry for the dot + //------------------------------------------------------------- + LLViewerCamera* camera = LLViewerCamera::getInstance(); + LLVector3 l = camera->getLeftAxis() * DOT_SIZE; + LLVector3 u = camera->getUpAxis() * DOT_SIZE; + + LLVector3 bottomLeft = mSoundSymbol.mPosition + l - u; + LLVector3 bottomRight = mSoundSymbol.mPosition - l - u; + LLVector3 topLeft = mSoundSymbol.mPosition + l + u; + LLVector3 topRight = mSoundSymbol.mPosition - l + u; + + //----------------------------- + // bind texture 0 (the dot) + //----------------------------- + gGL.getTexUnit(0)->bind(mSoundSymbol.mTexture[0]); + + //------------------------------------------------------------- + // now render the dot + //------------------------------------------------------------- + gGL.color4fv( LLColor4( 1.0f, 1.0f, 1.0f, DOT_OPACITY ).mV ); + + gGL.begin( LLRender::TRIANGLE_STRIP ); + gGL.texCoord2i( 0, 0 ); gGL.vertex3fv( bottomLeft.mV ); + gGL.texCoord2i( 1, 0 ); gGL.vertex3fv( bottomRight.mV ); + gGL.texCoord2i( 0, 1 ); gGL.vertex3fv( topLeft.mV ); + gGL.end(); + + gGL.begin( LLRender::TRIANGLE_STRIP ); + gGL.texCoord2i( 1, 0 ); gGL.vertex3fv( bottomRight.mV ); + gGL.texCoord2i( 1, 1 ); gGL.vertex3fv( topRight.mV ); + gGL.texCoord2i( 0, 1 ); gGL.vertex3fv( topLeft.mV ); + gGL.end(); + + + + //-------------------------------------------------------------------------------------- + // if currently speaking, trigger waves (1 through 6) based on speaking amplitude + //-------------------------------------------------------------------------------------- + if ( mCurrentlySpeaking ) + { + F32 min = 0.2f; + F32 max = 0.7f; + F32 fraction = ( mSpeakingAmplitude - min ) / ( max - min ); + + // in case mSpeakingAmplitude > max.... + if ( fraction > 1.0f ) + { + fraction = 1.0f; + } + + S32 level = 1 + (int)( fraction * ( NUM_VOICE_SYMBOL_WAVES - 2 ) ); + + for (int i=0; i<level+1; i++) + { + mSoundSymbol.mWaveActive [i] = true; + mSoundSymbol.mWaveOpacity [i] = 1.0f; + mSoundSymbol.mWaveFadeOutStartTime [i] = mCurrentTime; + } + + } // if currently speaking + + //--------------------------------------------------- + // determine color + //--------------------------------------------------- + F32 red = 0.0f; + F32 green = 0.0f; + F32 blue = 0.0f; + if ( mSpeakingAmplitude < RED_THRESHOLD ) + { + if ( mSpeakingAmplitude < GREEN_THRESHOLD ) + { + red = BASE_BRIGHTNESS; + green = BASE_BRIGHTNESS; + blue = BASE_BRIGHTNESS; + } + else + { + //--------------------------------------------------- + // fade from gray to bright green + //--------------------------------------------------- + F32 fraction = ( mSpeakingAmplitude - GREEN_THRESHOLD ) / ( 1.0f - GREEN_THRESHOLD ); + red = BASE_BRIGHTNESS - ( fraction * BASE_BRIGHTNESS ); + green = BASE_BRIGHTNESS + fraction * ( 1.0f - BASE_BRIGHTNESS ); + blue = BASE_BRIGHTNESS - ( fraction * BASE_BRIGHTNESS ); + } + } + else + { + //--------------------------------------------------- + // redish + //--------------------------------------------------- + red = 1.0f; + green = 0.2f; + blue = 0.2f; + } + + for (int i=0; i<NUM_VOICE_SYMBOL_WAVES; i++) + { + if ( mSoundSymbol.mWaveActive[i] ) + { + F32 fadeOutFraction = (F32)( mCurrentTime - mSoundSymbol.mWaveFadeOutStartTime[i] ) / FADE_OUT_DURATION; + + mSoundSymbol.mWaveOpacity[i] = 1.0f - fadeOutFraction; + + if ( mSoundSymbol.mWaveOpacity[i] < 0.0f ) + { + mSoundSymbol.mWaveFadeOutStartTime [i] = mCurrentTime; + mSoundSymbol.mWaveOpacity [i] = 0.0f; + mSoundSymbol.mWaveActive [i] = false; + } + + //---------------------------------------------------------------------------------- + // This is where we calculate the expansion of the waves - that is, the + // rate at which they are scaled greater than 1.0 so that they grow over time. + //---------------------------------------------------------------------------------- + F32 timeSlice = (F32)( mCurrentTime - mPreviousTime ); + F32 waveSpeed = mSpeakingAmplitude * WAVE_MOTION_RATE; + mSoundSymbol.mWaveExpansion[i] *= ( 1.0f + EXPANSION_RATE * timeSlice * waveSpeed ); + + if ( mSoundSymbol.mWaveExpansion[i] > EXPANSION_MAX ) + { + mSoundSymbol.mWaveExpansion[i] = 1.0f; + } + + //---------------------------------------------------------------------------------- + // create geometry for the wave billboard textures + //---------------------------------------------------------------------------------- + F32 width = i * WAVE_WIDTH_SCALE * mSoundSymbol.mWaveExpansion[i]; + F32 height = i * WAVE_HEIGHT_SCALE * mSoundSymbol.mWaveExpansion[i]; + + LLVector3 l = camera->getLeftAxis() * width; + LLVector3 u = camera->getUpAxis() * height; + + LLVector3 bottomLeft = mSoundSymbol.mPosition + l - u; + LLVector3 bottomRight = mSoundSymbol.mPosition - l - u; + LLVector3 topLeft = mSoundSymbol.mPosition + l + u; + LLVector3 topRight = mSoundSymbol.mPosition - l + u; + + gGL.color4fv( LLColor4( red, green, blue, mSoundSymbol.mWaveOpacity[i] ).mV ); + gGL.getTexUnit(0)->bind(mSoundSymbol.mTexture[i]); + + + //--------------------------------------------------- + // now, render the mofo + //--------------------------------------------------- + gGL.begin( LLRender::TRIANGLE_STRIP ); + gGL.texCoord2i( 0, 0 ); gGL.vertex3fv( bottomLeft.mV ); + gGL.texCoord2i( 1, 0 ); gGL.vertex3fv( bottomRight.mV ); + gGL.texCoord2i( 0, 1 ); gGL.vertex3fv( topLeft.mV ); + gGL.end(); + + gGL.begin( LLRender::TRIANGLE_STRIP ); + gGL.texCoord2i( 1, 0 ); gGL.vertex3fv( bottomRight.mV ); + gGL.texCoord2i( 1, 1 ); gGL.vertex3fv( topRight.mV ); + gGL.texCoord2i( 0, 1 ); gGL.vertex3fv( topLeft.mV ); + gGL.end(); + + } //if ( mSoundSymbol.mWaveActive[i] ) + + }// for loop + + }//if ( mSoundSymbol.mActive ) + +}//--------------------------------------------------- + +//--------------------------------------------------- +void LLVoiceVisualizer::setVoiceSourceWorldPosition( const LLVector3 &p ) +{ + mVoiceSourceWorldPosition = p; + +}//--------------------------------------------------- +#endif // XXX_STINSON_CHUI_REWORK + +//--------------------------------------------------- +VoiceGesticulationLevel LLVoiceVisualizer::getCurrentGesticulationLevel() +{ + VoiceGesticulationLevel gesticulationLevel = VOICE_GESTICULATION_LEVEL_OFF; //default + + //----------------------------------------------------------------------------------------- + // Within the range of gesticulation amplitudes, the sound signal is split into + // three equal amplitude regimes, each specifying one of three gesticulation levels. + //----------------------------------------------------------------------------------------- + F32 range = mMaxGesticulationAmplitude - mMinGesticulationAmplitude; + + if ( mSpeakingAmplitude > mMinGesticulationAmplitude + range * 0.5f ) { gesticulationLevel = VOICE_GESTICULATION_LEVEL_HIGH; } + else if ( mSpeakingAmplitude > mMinGesticulationAmplitude + range * 0.25f ) { gesticulationLevel = VOICE_GESTICULATION_LEVEL_MEDIUM; } + else if ( mSpeakingAmplitude > mMinGesticulationAmplitude + range * 0.00000f ) { gesticulationLevel = VOICE_GESTICULATION_LEVEL_LOW; } + + return gesticulationLevel; + +}//--------------------------------------------------- + + + +//------------------------------------ +// Destructor +//------------------------------------ +LLVoiceVisualizer::~LLVoiceVisualizer() +{ +}//---------------------------------------------- + + +#ifdef XXX_STINSON_CHUI_REWORK +//--------------------------------------------------- +// "packData" is inherited from HUDEffect +//--------------------------------------------------- +void LLVoiceVisualizer::packData(LLMessageSystem *mesgsys) +{ + // Pack the default data + LLHUDEffect::packData(mesgsys); + + // TODO -- pack the relevant data for voice effects + // we'll come up with some cool configurations....TBD + //U8 packed_data[41]; + //mesgsys->addBinaryDataFast(_PREHASH_TypeData, packed_data, 41); + U8 packed_data = 0; + mesgsys->addBinaryDataFast(_PREHASH_TypeData, &packed_data, 1); +} + + +//--------------------------------------------------- +// "unpackData" is inherited from HUDEffect +//--------------------------------------------------- +void LLVoiceVisualizer::unpackData(LLMessageSystem *mesgsys, S32 blocknum) +{ + // TODO -- find the speaker, unpack binary data, set the properties of this effect + /* + LLHUDEffect::unpackData(mesgsys, blocknum); + LLUUID source_id; + LLUUID target_id; + S32 size = mesgsys->getSizeFast(_PREHASH_Effect, blocknum, _PREHASH_TypeData); + if (size != 1) + { + llwarns << "Voice effect with bad size " << size << llendl; + return; + } + mesgsys->getBinaryDataFast(_PREHASH_Effect, _PREHASH_TypeData, packed_data, 1, blocknum); + */ +} + + +//------------------------------------------------------------------ +// this method is inherited from HUD Effect +//------------------------------------------------------------------ +void LLVoiceVisualizer::markDead() +{ + mCurrentlySpeaking = false; + mVoiceEnabled = false; + mSoundSymbol.mActive = false; + + LLHUDEffect::markDead(); +}//------------------------------------------------------------------ + +#endif // XXX_STINSON_CHUI_REWORK diff --git a/indra/newview/llvoicevisualizer.h b/indra/newview/llvoicevisualizer.h index 6258de163d..5da592c48e 100644 --- a/indra/newview/llvoicevisualizer.h +++ b/indra/newview/llvoicevisualizer.h @@ -42,6 +42,7 @@ #ifndef LL_VOICE_VISUALIZER_H #define LL_VOICE_VISUALIZER_H +#define XXX_STINSON_CHUI_REWORK // temporarily re-enabling the in-world voice-dot #ifdef XXX_STINSON_CHUI_REWORK #include "llhudeffect.h" #else // XXX_STINSON_CHUI_REWORK diff --git a/indra/newview/llvopartgroup.cpp b/indra/newview/llvopartgroup.cpp index e21358b65a..a2794bec56 100644 --- a/indra/newview/llvopartgroup.cpp +++ b/indra/newview/llvopartgroup.cpp @@ -149,8 +149,8 @@ bool ll_is_part_idx_allocated(S32 idx, S32* start, S32* end) void LLVOPartGroup::freeVBSlot(S32 idx) { llassert(idx < LL_MAX_PARTICLE_COUNT && idx >= 0); - llassert(sVBSlotCursor > sVBSlotFree); - llassert(ll_is_part_idx_allocated(idx, sVBSlotCursor, sVBSlotFree+LL_MAX_PARTICLE_COUNT)); + //llassert(sVBSlotCursor > sVBSlotFree); + //llassert(ll_is_part_idx_allocated(idx, sVBSlotCursor, sVBSlotFree+LL_MAX_PARTICLE_COUNT)); if (sVBSlotCursor > sVBSlotFree) { diff --git a/indra/newview/skins/default/xui/en/floater_im_session.xml b/indra/newview/skins/default/xui/en/floater_im_session.xml index 09c1510004..675967035f 100644 --- a/indra/newview/skins/default/xui/en/floater_im_session.xml +++ b/indra/newview/skins/default/xui/en/floater_im_session.xml @@ -15,7 +15,8 @@ can_resize="true" can_tear_off="false" min_width="250" - min_height="190"> + min_height="190" + positioning="relative"> <floater.string name="NearbyChatTitle" value="Nearby Chat"/> |