diff options
41 files changed, 959 insertions, 515 deletions
@@ -493,3 +493,4 @@ bcc2770e21c125e0bab59141c51db9145aec068d 3.7.17-release  2729c1daf0257d68a40bdbc4acf1a16184974bbd 3.7.18-release  82973b38a6c9a457333e3519e4f2b16bb5eedf47 3.7.19-release  27094824773b907c2e559396e6f9ec3a963de52d 3.7.20-release +9ecab4b0c7d8614767724a3422d3c1dca6bd4e4f 3.7.21-release diff --git a/doc/contributions.txt b/doc/contributions.txt index 435521fad1..3720774c59 100755 --- a/doc/contributions.txt +++ b/doc/contributions.txt @@ -324,6 +324,7 @@ Cinder Roxley      STORM-2035      STORM-2036      STORM-2037 +    STORM-2053  Clara Young  Coaldust Numbers      VWR-1095 @@ -890,6 +891,8 @@ Mm Alder  	VWR-4794  	VWR-13578  Mo Hax +Moon Metty +	STORM-2078  Mourna Biziou  Mr Greggan  	VWR-445 @@ -994,6 +997,7 @@ Nicky Perian  	STORM-1087  	STORM-1090  	STORM-1828 +    STORM-2080  Nicoladie Gymnast  NiranV Dean      STORM-2040 @@ -1056,6 +1060,10 @@ Peekay Semyorka  	VWR-79  Pell Smit  	MAINT-4323 +	STORM-2069 +	STORM-2070 +	STORM-2071 +	STORM-2072  Peter Lameth  	VWR-7331  PeterPunk Mooney @@ -1399,6 +1407,7 @@ Whirly Fizzle  	MAINT-873  	STORM-1930  	BUG-6659 +	STORM-2078  Whoops Babii  	VWR-631  	VWR-1640 diff --git a/indra/llappearance/llavatarappearance.cpp b/indra/llappearance/llavatarappearance.cpp index c0ad8315af..d1eb389013 100755 --- a/indra/llappearance/llavatarappearance.cpp +++ b/indra/llappearance/llavatarappearance.cpp @@ -675,6 +675,42 @@ void LLAvatarAppearance::clearSkeleton()  	mSkeleton.clear();  } +//------------------------------------------------------------------------ +// addPelvisFixup +//------------------------------------------------------------------------ +void LLAvatarAppearance::addPelvisFixup( F32 fixup, const LLUUID& mesh_id )  +{ +	LLVector3 pos(0.0,0.0,fixup); +	mPelvisFixups.add(mesh_id,pos); +} + +//------------------------------------------------------------------------ +// addPelvisFixup +//------------------------------------------------------------------------ +void LLAvatarAppearance::removePelvisFixup( const LLUUID& mesh_id ) +{ +	mPelvisFixups.remove(mesh_id); +} + +//------------------------------------------------------------------------ +// hasPelvisFixup +//------------------------------------------------------------------------ +bool LLAvatarAppearance::hasPelvisFixup( F32& fixup, LLUUID& mesh_id ) const +{ +	LLVector3 pos; +	if (mPelvisFixups.findActiveOverride(mesh_id,pos)) +	{ +		fixup = pos[2]; +		return true; +	} +	return false; +} + +bool LLAvatarAppearance::hasPelvisFixup( F32& fixup ) const +{ +	LLUUID mesh_id; +	return hasPelvisFixup( fixup, mesh_id ); +}  //-----------------------------------------------------------------------------  // LLAvatarAppearance::buildCharacter()  // Deferred initialization and rebuild of the avatar. diff --git a/indra/llappearance/llavatarappearance.h b/indra/llappearance/llavatarappearance.h index 1e898026c0..a0ef49b7cb 100755 --- a/indra/llappearance/llavatarappearance.h +++ b/indra/llappearance/llavatarappearance.h @@ -152,11 +152,17 @@ protected:  	BOOL				mIsBuilt; // state of deferred character building  	typedef std::vector<LLAvatarJoint*> avatar_joint_list_t;  	avatar_joint_list_t	mSkeleton; -	 +	LLPosOverrideMap	mPelvisFixups; +  	//--------------------------------------------------------------------  	// Pelvis height adjustment members.  	//--------------------------------------------------------------------  public: +	void				addPelvisFixup( F32 fixup, const LLUUID& mesh_id ); +	void 				removePelvisFixup( const LLUUID& mesh_id ); +	bool 				hasPelvisFixup( F32& fixup, LLUUID& mesh_id ) const; +	bool 				hasPelvisFixup( F32& fixup ) const; +	  	LLVector3			mBodySize;  	LLVector3			mAvatarOffset;  protected: diff --git a/indra/llcharacter/lljoint.cpp b/indra/llcharacter/lljoint.cpp index 97293bf134..5bee4da7c0 100755 --- a/indra/llcharacter/lljoint.cpp +++ b/indra/llcharacter/lljoint.cpp @@ -36,18 +36,62 @@  S32 LLJoint::sNumUpdates = 0;  S32 LLJoint::sNumTouches = 0; +template <class T>  +bool attachment_map_iter_compare_key(const T& a, const T& b) +{ +	return a.first < b.first; +} -//----------------------------------------------------------------------------- -// LLJoint::AttachmentOverrideRecord::AttachmentOverrideRecord() -//----------------------------------------------------------------------------- -LLJoint::AttachmentOverrideRecord::AttachmentOverrideRecord() +bool LLPosOverrideMap::findActiveOverride(LLUUID& mesh_id, LLVector3& pos) const  { +	pos = LLVector3(0,0,0); +	mesh_id = LLUUID(); +	bool found = false; +	 +	map_type::const_iterator it = std::max_element(m_map.begin(), +												   m_map.end(), +												   attachment_map_iter_compare_key<map_type::value_type>); +	if (it != m_map.end()) +	{ +		found = true; +		pos = it->second; +		mesh_id = it->first; +	} +	return found;  } -template <class T>  -bool attachment_map_iter_compare_key(const T& a, const T& b) +void LLPosOverrideMap::showJointPosOverrides( std::ostringstream& os ) const  { -	return a.first < b.first; +	map_type::const_iterator max_it = std::max_element(m_map.begin(), +													   m_map.end(), +													   attachment_map_iter_compare_key<map_type::value_type>); +	for (map_type::const_iterator it = m_map.begin(); +		 it != m_map.end(); ++it) +	{ +		const LLVector3& pos = it->second; +		os << " " << "[" << it->first <<": " << pos << "]" << ((it==max_it) ? "*" : ""); +	} +} + +U32 LLPosOverrideMap::count() const +{ +	return m_map.size(); +} + +void LLPosOverrideMap::add(const LLUUID& mesh_id, const LLVector3& pos) +{ +	m_map[mesh_id] = pos; +} + +bool LLPosOverrideMap::remove(const LLUUID& mesh_id) +{ +	U32 remove_count = m_map.erase(mesh_id); +	return (remove_count > 0); +} + +void LLPosOverrideMap::clear() +{ +	m_map.clear();  }  //----------------------------------------------------------------------------- @@ -244,16 +288,35 @@ const LLVector3& LLJoint::getPosition()  	return mXform.getPosition();  } +bool do_debug_joint(const std::string& name) +{ +	return true; +}  //--------------------------------------------------------------------  // setPosition()  //--------------------------------------------------------------------  void LLJoint::setPosition( const LLVector3& pos )  { +	if (pos != getPosition()) +	{ +		if (do_debug_joint(getName())) +		{ +			LL_DEBUGS("Avatar") << " joint " << getName() << " set pos " << pos << LL_ENDL; +		} +	}  	mXform.setPosition(pos);  	touch(MATRIX_DIRTY | POSITION_DIRTY);  } +void showJointPosOverrides( const LLJoint& joint, const std::string& note, const std::string& av_info ) +{ +        std::ostringstream os; +        os << joint.m_posBeforeOverrides; +        joint.m_attachmentOverrides.showJointPosOverrides(os); +        LL_DEBUGS("Avatar") << av_info << " joint " << joint.getName() << " " << note << " " << os.str() << LL_ENDL; +} +  //--------------------------------------------------------------------  // addAttachmentPosOverride()  //-------------------------------------------------------------------- @@ -263,15 +326,19 @@ void LLJoint::addAttachmentPosOverride( const LLVector3& pos, const LLUUID& mesh  	{  		return;  	} -	if (m_attachmentOverrides.empty()) +	if (!m_attachmentOverrides.count())  	{ -		LL_DEBUGS("Avatar") << "av " << av_info << " joint " << getName() << " saving m_posBeforeOverrides " << getPosition() << LL_ENDL; +		if (do_debug_joint(getName())) +		{ +			LL_DEBUGS("Avatar") << "av " << av_info << " joint " << getName() << " saving m_posBeforeOverrides " << getPosition() << LL_ENDL; +		}  		m_posBeforeOverrides = getPosition();  	} -	AttachmentOverrideRecord rec; -	rec.pos = pos; -	m_attachmentOverrides[mesh_id] = rec; -	LL_DEBUGS("Avatar") << "av " << av_info << " joint " << getName() << " addAttachmentPosOverride for mesh " << mesh_id << " pos " << pos << LL_ENDL; +	m_attachmentOverrides.add(mesh_id,pos); +	if (do_debug_joint(getName())) +	{ +		LL_DEBUGS("Avatar") << "av " << av_info << " joint " << getName() << " addAttachmentPosOverride for mesh " << mesh_id << " pos " << pos << LL_ENDL; +	}  	updatePos(av_info);  } @@ -284,13 +351,37 @@ void LLJoint::removeAttachmentPosOverride( const LLUUID& mesh_id, const std::str  	{  		return;  	} -	attachment_map_t::iterator it = m_attachmentOverrides.find(mesh_id); -	if (it != m_attachmentOverrides.end()) +	if (m_attachmentOverrides.remove(mesh_id))  	{ -		LL_DEBUGS("Avatar") << "av " << av_info << " joint " << getName() << " removeAttachmentPosOverride for " << mesh_id << LL_ENDL; -		m_attachmentOverrides.erase(it); +		if (do_debug_joint(getName())) +		{ +			LL_DEBUGS("Avatar") << "av " << av_info << " joint " << getName() +								<< " removeAttachmentPosOverride for " << mesh_id << LL_ENDL; +			showJointPosOverrides(*this, "remove", av_info); +		} +		updatePos(av_info); +	} +} + +//-------------------------------------------------------------------- + // hasAttachmentPosOverride() + //-------------------------------------------------------------------- +bool LLJoint::hasAttachmentPosOverride( LLVector3& pos, LLUUID& mesh_id ) const +{ +	return m_attachmentOverrides.findActiveOverride(mesh_id,pos); +} + +//-------------------------------------------------------------------- +// clearAttachmentPosOverrides() +//-------------------------------------------------------------------- +void LLJoint::clearAttachmentPosOverrides() +{ +	if (m_attachmentOverrides.count()) +	{ +		m_attachmentOverrides.clear(); +		setPosition(m_posBeforeOverrides); +		setId( LLUUID::null );  	} -	updatePos(av_info);  }  //-------------------------------------------------------------------- @@ -298,15 +389,12 @@ void LLJoint::removeAttachmentPosOverride( const LLUUID& mesh_id, const std::str  //--------------------------------------------------------------------  void LLJoint::updatePos(const std::string& av_info)  { -	LLVector3 pos; -	attachment_map_t::iterator it = std::max_element(m_attachmentOverrides.begin(), -													 m_attachmentOverrides.end(), -													 attachment_map_iter_compare_key<LLJoint::attachment_map_t::value_type>); -	if (it != m_attachmentOverrides.end()) +	LLVector3 pos, found_pos; +	LLUUID mesh_id; +	if (m_attachmentOverrides.findActiveOverride(mesh_id,found_pos))  	{ -		AttachmentOverrideRecord& rec = it->second; -		LL_DEBUGS("Avatar") << "av " << av_info << " joint " << getName() << " updatePos, winner of " << m_attachmentOverrides.size() << " is mesh " << it->first << " pos " << rec.pos << LL_ENDL; -		pos = rec.pos; +		LL_DEBUGS("Avatar") << "av " << av_info << " joint " << getName() << " updatePos, winner of " << m_attachmentOverrides.count() << " is mesh " << mesh_id << " pos " << found_pos << LL_ENDL; +		pos = found_pos;  	}  	else  	{ diff --git a/indra/llcharacter/lljoint.h b/indra/llcharacter/lljoint.h index 951cafad94..2abe1d6db1 100755 --- a/indra/llcharacter/lljoint.h +++ b/indra/llcharacter/lljoint.h @@ -46,6 +46,21 @@ const U32 LL_FACE_JOINT_NUM = 30;  const S32 LL_CHARACTER_MAX_PRIORITY = 7;  const F32 LL_MAX_PELVIS_OFFSET = 5.f; +class LLPosOverrideMap +{ +public: +	LLPosOverrideMap() {} +	bool findActiveOverride(LLUUID& mesh_id, LLVector3& pos) const; +	void showJointPosOverrides(std::ostringstream& os) const; +	U32 count() const; +	void add(const LLUUID& mesh_id, const LLVector3& pos); +	bool remove(const LLUUID& mesh_id); +	void clear(); +private: +	typedef std::map<LLUUID,LLVector3> map_type; +	map_type m_map; +}; +  //-----------------------------------------------------------------------------  // class LLJoint  //----------------------------------------------------------------------------- @@ -99,13 +114,7 @@ public:  	static S32		sNumTouches;  	static S32		sNumUpdates; -	struct AttachmentOverrideRecord -	{ -		AttachmentOverrideRecord(); -		LLVector3 pos; -	}; -	typedef std::map<LLUUID,AttachmentOverrideRecord> attachment_map_t; -	attachment_map_t m_attachmentOverrides; +	LLPosOverrideMap m_attachmentOverrides;  	LLVector3 m_posBeforeOverrides;  	void updatePos(const std::string& av_info); @@ -193,6 +202,8 @@ public:  	void addAttachmentPosOverride( const LLVector3& pos, const LLUUID& mesh_id, const std::string& av_info );  	void removeAttachmentPosOverride( const LLUUID& mesh_id, const std::string& av_info ); +	bool hasAttachmentPosOverride( LLVector3& pos, LLUUID& mesh_id ) const; +	void clearAttachmentPosOverrides();  	//Accessor for the joint id  	LLUUID getId( void ) { return mId; } diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp index a89ec675b4..b2be3cc3b6 100755 --- a/indra/llrender/llshadermgr.cpp +++ b/indra/llrender/llshadermgr.cpp @@ -674,12 +674,17 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade  	if (defines)  	{  		for (boost::unordered_map<std::string,std::string>::iterator iter = defines->begin(); iter != defines->end(); ++iter) -	{ -		std::string define = "#define " + iter->first + " " + iter->second + "\n"; -		text[count++] = (GLcharARB *) strdup(define.c_str()); -	} +		{ +			std::string define = "#define " + iter->first + " " + iter->second + "\n"; +			text[count++] = (GLcharARB *) strdup(define.c_str()); +		}  	} +	if( gGLManager.mIsATI ) +	{ +		text[ count++ ] = strdup( "#define IS_AMD_CARD 1\n" ); +	} +	  	if (texture_index_channels > 0 && type == GL_FRAGMENT_SHADER_ARB)  	{  		//use specified number of texture channels for indexed texture rendering diff --git a/indra/llwindow/llopenglview-objc.h b/indra/llwindow/llopenglview-objc.h index f1fab3b2c6..072d40f739 100644 --- a/indra/llwindow/llopenglview-objc.h +++ b/indra/llwindow/llopenglview-objc.h @@ -79,6 +79,7 @@  @interface LLNonInlineTextView : NSTextView  {  	LLOpenGLView *glview; +    unichar mKeyPressed;  }  - (void) setGLView:(LLOpenGLView*)view; diff --git a/indra/llwindow/llopenglview-objc.mm b/indra/llwindow/llopenglview-objc.mm index 06b96dd1ea..9e7093782e 100644 --- a/indra/llwindow/llopenglview-objc.mm +++ b/indra/llwindow/llopenglview-objc.mm @@ -104,20 +104,20 @@ attributedStringInfo getSegments(NSAttributedString *str)  - (unsigned long)getVramSize  {      CGLRendererInfoObj info = 0; -	GLint vram_bytes = 0; +	GLint vram_mbytes = 0;      int num_renderers = 0;      CGLError the_err = CGLQueryRendererInfo (CGDisplayIDToOpenGLDisplayMask(kCGDirectMainDisplay), &info, &num_renderers);      if(0 == the_err)      { -        CGLDescribeRenderer (info, 0, kCGLRPTextureMemory, &vram_bytes); +        CGLDescribeRenderer (info, 0, kCGLRPTextureMemoryMegabytes, &vram_mbytes);          CGLDestroyRendererInfo (info);      }      else      { -        vram_bytes = (256 << 20); +        vram_mbytes = 256;      } -	return (unsigned long)vram_bytes / 1048576; // We need this in megabytes. +	return (unsigned long)vram_mbytes;  }  - (void)viewDidMoveToWindow @@ -297,14 +297,14 @@ attributedStringInfo getSegments(NSAttributedString *str)          !([theEvent modifierFlags] & NSFunctionKeyMask) &&          !([theEvent modifierFlags] & NSHelpKeyMask))      { -        callRightMouseDown(mMousePos, mModifiers); +        callRightMouseDown(mMousePos, [theEvent modifierFlags]);          mSimulatedRightClick = true;      } else {          if ([theEvent clickCount] >= 2)          { -            callDoubleClick(mMousePos, mModifiers); +            callDoubleClick(mMousePos, [theEvent modifierFlags]);          } else if ([theEvent clickCount] == 1) { -            callLeftMouseDown(mMousePos, mModifiers); +            callLeftMouseDown(mMousePos, [theEvent modifierFlags]);          }      }  } @@ -313,21 +313,21 @@ attributedStringInfo getSegments(NSAttributedString *str)  {      if (mSimulatedRightClick)      { -        callRightMouseUp(mMousePos, mModifiers); +        callRightMouseUp(mMousePos, [theEvent modifierFlags]);          mSimulatedRightClick = false;      } else { -        callLeftMouseUp(mMousePos, mModifiers); +        callLeftMouseUp(mMousePos, [theEvent modifierFlags]);      }  }  - (void) rightMouseDown:(NSEvent *)theEvent  { -	callRightMouseDown(mMousePos, mModifiers); +	callRightMouseDown(mMousePos, [theEvent modifierFlags]);  }  - (void) rightMouseUp:(NSEvent *)theEvent  { -	callRightMouseUp(mMousePos, mModifiers); +	callRightMouseUp(mMousePos, [theEvent modifierFlags]);  }  - (void)mouseMoved:(NSEvent *)theEvent @@ -368,12 +368,12 @@ attributedStringInfo getSegments(NSAttributedString *str)  - (void) otherMouseDown:(NSEvent *)theEvent  { -	callMiddleMouseDown(mMousePos, mModifiers); +	callMiddleMouseDown(mMousePos, [theEvent modifierFlags]);  }  - (void) otherMouseUp:(NSEvent *)theEvent  { -	callMiddleMouseUp(mMousePos, mModifiers); +	callMiddleMouseUp(mMousePos, [theEvent modifierFlags]);  }  - (void) rightMouseDragged:(NSEvent *)theEvent @@ -398,22 +398,27 @@ attributedStringInfo getSegments(NSAttributedString *str)  - (void) keyUp:(NSEvent *)theEvent  { -	callKeyUp([theEvent keyCode], mModifiers); +	callKeyUp([theEvent keyCode], [theEvent modifierFlags]);  }  - (void) keyDown:(NSEvent *)theEvent  {      uint keycode = [theEvent keyCode]; +    // We must not depend on flagsChange event to detect modifier flags changed, +    // must depend on the modifire flags in the event parameter. +    // Because flagsChange event handler misses event when other window is activated, +    // e.g. OS Window for upload something or Input Window... +    // mModifiers instance variable is for insertText: or insertText:replacementRange:  (by Pell Smit) +	mModifiers = [theEvent modifierFlags];      bool acceptsText = mHasMarkedText ? false : callKeyDown(keycode, mModifiers); +    unichar ch;      if (acceptsText &&          !mMarkedTextAllowed && +        !(mModifiers & (NSControlKeyMask | NSCommandKeyMask)) &&  // commands don't invoke InputWindow          ![(LLAppDelegate*)[NSApp delegate] romanScript] && -        [[theEvent charactersIgnoringModifiers] characterAtIndex:0] != NSDeleteCharacter && -        [[theEvent charactersIgnoringModifiers] characterAtIndex:0] != NSBackspaceCharacter && -        [[theEvent charactersIgnoringModifiers] characterAtIndex:0] != NSDownArrowFunctionKey && -        [[theEvent charactersIgnoringModifiers] characterAtIndex:0] != NSUpArrowFunctionKey && -        [[theEvent charactersIgnoringModifiers] characterAtIndex:0] != NSLeftArrowFunctionKey && -        [[theEvent charactersIgnoringModifiers] characterAtIndex:0] != NSRightArrowFunctionKey) +        (ch = [[theEvent charactersIgnoringModifiers] characterAtIndex:0]) > ' ' && +        ch != NSDeleteCharacter && +        (ch < 0xF700 || ch > 0xF8FF))  // 0xF700-0xF8FF: reserved for function keys on the keyboard(from NSEvent.h)      {          [(LLAppDelegate*)[NSApp delegate] showInputWindow:true withEvent:theEvent];      } else @@ -530,31 +535,58 @@ attributedStringInfo getSegments(NSAttributedString *str)  - (void)setMarkedText:(id)aString selectedRange:(NSRange)selectedRange replacementRange:(NSRange)replacementRange  { -    if ([aString class] == NSClassFromString(@"NSConcreteMutableAttributedString")) +    // Apple says aString can be either an NSString or NSAttributedString instance. +    // But actually it's NSConcreteMutableAttributedString or __NSCFConstantString. +    // I observed aString was __NSCFConstantString only aString was null string(zero length). +    // Apple also says when aString is an NSString object, +    // the receiver is expected to render the marked text with distinguishing appearance. +    // So I tried to make attributedStringInfo, but it won't be used...   (Pell Smit) + +    if (mMarkedTextAllowed)      { -        if (mMarkedTextAllowed) +        unsigned int selected[2] = { +            selectedRange.location, +            selectedRange.length +        }; +         +        unsigned int replacement[2] = { +            replacementRange.location, +            replacementRange.length +        }; +         +        int string_length = [aString length]; +        unichar text[string_length]; +        attributedStringInfo segments; +        // I used 'respondsToSelector:@selector(string)' +        // to judge aString is an attributed string or not. +        if ([aString respondsToSelector:@selector(string)]) +        { +            // aString is attibuted +            [[aString string] getCharacters:text range:NSMakeRange(0, string_length)]; +            segments = getSegments((NSAttributedString *)aString); +        } +        else +        { +            // aString is not attributed +            [aString getCharacters:text range:NSMakeRange(0, string_length)]; +            segments.seg_lengths.push_back(string_length); +            segments.seg_standouts.push_back(true); +        } +        setMarkedText(text, selected, replacement, string_length, segments); +        if (string_length > 0)          { -            unsigned int selected[2] = { -                selectedRange.location, -                selectedRange.length -            }; -             -            unsigned int replacement[2] = { -                replacementRange.location, -                replacementRange.length -            }; -             -            unichar text[[aString length]]; -            [[aString mutableString] getCharacters:text range:NSMakeRange(0, [aString length])]; -            attributedStringInfo segments = getSegments((NSAttributedString *)aString); -            setMarkedText(text, selected, replacement, [aString length], segments);              mHasMarkedText = TRUE; -            mMarkedTextLength = [aString length]; -        } else { -            if (mHasMarkedText) -            { -                [self unmarkText]; -            } +            mMarkedTextLength = string_length; +        } +        else +        { +            // we must clear the marked text when aString is null. +            [self unmarkText]; +        } +    } else { +        if (mHasMarkedText) +        { +            [self unmarkText];          }      }  } @@ -673,37 +705,63 @@ attributedStringInfo getSegments(NSAttributedString *str)  @implementation LLNonInlineTextView +/*  Input Window is a legacy of 20 century, so we want to remove related classes. +    But unfortunately, Viwer web browser has no support for modern inline input, +    we need to leave these classes... +    We will be back to get rid of Input Window after fixing viewer web browser. + +    How Input Window should work: +        1) Input Window must not be empty. +          It must close when it become empty result of edithing. +        2) Input Window must not close when it still has input data. +          It must keep open user types next char before commit.         by Pell Smit +*/ +  - (void) setGLView:(LLOpenGLView *)view  {  	glview = view;  } -- (void) insertText:(id)insertString +- (void)keyDown:(NSEvent *)theEvent  { -	[[self inputContext] discardMarkedText]; -    [self setString:@""]; -    [_window orderOut:_window]; -	[self insertText:insertString replacementRange:NSMakeRange(0, [insertString length])]; +    // mKeyPressed is used later to determine whethere Input Window should close or not +    mKeyPressed = [[theEvent charactersIgnoringModifiers] characterAtIndex:0]; +    // setMarkedText and insertText is called indirectly from inside keyDown: method +    [super keyDown:theEvent];  } -- (void) insertText:(id)aString replacementRange:(NSRange)replacementRange +// setMarkedText: is called for incomplete input(on the way to conversion). +- (void)setMarkedText:(id)aString selectedRange:(NSRange)selectedRange replacementRange:(NSRange)replacementRange  { -	[glview insertText:aString replacementRange:replacementRange]; +    [super setMarkedText:aString selectedRange:selectedRange replacementRange:replacementRange]; +    if ([aString length] == 0)      // this means Input Widow becomes empty +    { +        [_window orderOut:_window];     // Close this to avoid empty Input Window +    }  } -- (void) insertNewline:(id)sender +// insertText: is called for inserting commited text. +// There are two ways to be called here: +//      a) explicitly commited (must close) +//          In case of user typed commit key(usually return key) or delete key or something +//      b) automatically commited (must not close) +//          In case of user typed next letter after conversion +- (void) insertText:(id)aString replacementRange:(NSRange)replacementRange  { -	[[self textStorage] setValue:@""]; -	[[self inputContext] discardMarkedText]; +    [[self inputContext] discardMarkedText];      [self setString:@""]; -} - -- (void)doCommandBySelector:(SEL)aSelector -{ -	if (aSelector == @selector(insertNewline:)) -	{ -		[self insertNewline:self]; -	} +    [glview insertText:aString replacementRange:replacementRange]; +    if (mKeyPressed == NSEnterCharacter || +        mKeyPressed == NSBackspaceCharacter || +        mKeyPressed == NSTabCharacter || +        mKeyPressed == NSNewlineCharacter || +        mKeyPressed == NSCarriageReturnCharacter || +        mKeyPressed == NSDeleteCharacter || +        (mKeyPressed >= 0xF700 && mKeyPressed <= 0xF8FF)) +    { +        // this is case a) of above comment +        [_window orderOut:_window];     // to avoid empty Input Window +    }  }  @end diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp index 9ed298a481..1f577b117e 100755 --- a/indra/llwindow/llwindowmacosx.cpp +++ b/indra/llwindow/llwindowmacosx.cpp @@ -230,7 +230,10 @@ void callFocus()  void callFocusLost()  { -	gWindowImplementation->getCallbacks()->handleFocusLost(gWindowImplementation); +	if (gWindowImplementation) +	{ +		gWindowImplementation->getCallbacks()->handleFocusLost(gWindowImplementation); +	}  }  void callRightMouseDown(float *pos, MASK mask) @@ -1826,8 +1829,6 @@ static long getDictLong (CFDictionaryRef refDict, CFStringRef key)  void LLWindowMacOSX::allowLanguageTextInput(LLPreeditor *preeditor, BOOL b)  { -    allowDirectMarkedTextInput(b, mGLView); -	  	if (preeditor != mPreeditor && !b)  	{  		// This condition may occur by a call to @@ -1857,6 +1858,7 @@ void LLWindowMacOSX::allowLanguageTextInput(LLPreeditor *preeditor, BOOL b)  		return;  	}  	mLanguageTextInputAllowed = b; +    allowDirectMarkedTextInput(b, mGLView); // mLanguageTextInputAllowed and mMarkedTextAllowed should be updated at once (by Pell Smit  }  void LLWindowMacOSX::interruptLanguageTextInput() diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt index c6cff55cf7..b49c354524 100644 --- a/indra/newview/VIEWER_VERSION.txt +++ b/indra/newview/VIEWER_VERSION.txt @@ -1 +1 @@ -3.7.21 +3.7.22 diff --git a/indra/newview/app_settings/shaders/class1/avatar/avatarSkinV.glsl b/indra/newview/app_settings/shaders/class1/avatar/avatarSkinV.glsl index bc63d07d72..767fad016c 100755 --- a/indra/newview/app_settings/shaders/class1/avatar/avatarSkinV.glsl +++ b/indra/newview/app_settings/shaders/class1/avatar/avatarSkinV.glsl @@ -40,4 +40,10 @@ mat4 getSkinnedTransform()  	ret[3] = vec4(0,0,0,1);  	return ret; + +#ifdef IS_AMD_CARD +	// If it's AMD make sure the GLSL compiler sees the arrays referenced once by static index. Otherwise it seems to optimise the storage awawy which leads to unfun crashes and artifacts. +	vec4 dummy1 = matrixPalette[0]; +	vec4 dummy2 = matrixPalette[44]; +#endif  } diff --git a/indra/newview/app_settings/shaders/class1/avatar/objectSkinV.glsl b/indra/newview/app_settings/shaders/class1/avatar/objectSkinV.glsl index 57129c3bd1..6cd38d8ef5 100755 --- a/indra/newview/app_settings/shaders/class1/avatar/objectSkinV.glsl +++ b/indra/newview/app_settings/shaders/class1/avatar/objectSkinV.glsl @@ -63,5 +63,14 @@ mat4 getObjectSkinnedTransform()  	ret[3] = vec4(trans, 1.0);  	return ret; + +#ifdef IS_AMD_CARD +   // If it's AMD make sure the GLSL compiler sees the arrays referenced once by static index. Otherwise it seems to optimise the storage awawy which leads to unfun crashes and artifacts. +   mat3 dummy1 = matrixPalette[0]; +   vec3 dummy2 = translationPalette[0]; +   mat3 dummy3 = matrixPalette[51]; +   vec3 dummy4 = translationPalette[51]; +#endif +  } diff --git a/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl index a4f54dff70..5264d6e1b4 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl @@ -132,5 +132,11 @@ void main()  	col.y *= col.y;  	frag_color = col; + +#ifdef IS_AMD_CARD +	// If it's AMD make sure the GLSL compiler sees the arrays referenced once by static index. Otherwise it seems to optimise the storage awawy which leads to unfun crashes and artifacts. +	vec3 dummy1 = kern[0]; +	vec3 dummy2 = kern[3]; +#endif  } diff --git a/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl index 236567219b..1a464fec5d 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl @@ -161,4 +161,12 @@ void main()  	frag_color.rgb = out_col;  	frag_color.a = 0.0; + +#ifdef IS_AMD_CARD +	// If it's AMD make sure the GLSL compiler sees the arrays referenced once by static index. Otherwise it seems to optimise the storage awawy which leads to unfun crashes and artifacts. +	vec4 dummy1 = light[0]; +	vec4 dummy2 = light_col[0]; +	vec4 dummy3 = light[LIGHT_COUNT-1]; +	vec4 dummy4 = light_col[LIGHT_COUNT-1]; +#endif  } diff --git a/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl index 0e6ab80d4d..c08e9d361a 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl @@ -127,13 +127,17 @@ vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)  	vec4 ret = texture2DLod(projectionMap, tc, lod);  	ret.rgb = srgb_to_linear(ret.rgb); -	vec2 dist = tc-vec2(0.5); +	vec2 dist = vec2(0.5) - abs(tc-vec2(0.5)); -	float det = max(1.0-lod/(proj_lod*0.5), 0.0); +	float det = min(lod/(proj_lod*0.5), 1.0); -	float d = dot(dist,dist); -		 -	ret *= min(clamp((0.25-d)/0.25, 0.0, 1.0)+det, 1.0); +	float d = min(dist.x, dist.y); +     +    d *= min(1, d * (proj_lod - lod)); +	 +	float edge = 0.25*det; +     +	ret *= clamp(d/edge, 0.0, 1.0);  	return ret;  } @@ -311,19 +315,17 @@ void main()  			vec3 pfinal = pos + ref * dot(pdelta, proj_n)/ds;  			vec4 stc = (proj_mat * vec4(pfinal.xyz, 1.0)); -			stc /= stc.w; +              			if (stc.z > 0.0)  			{ -				float fatten = clamp(envIntensity*envIntensity+envIntensity*0.25, 0.25, 1.0); -				 -				stc.xy = (stc.xy - vec2(0.5)) * fatten + vec2(0.5); +                stc /= stc.w;  				if (stc.x < 1.0 &&  					stc.y < 1.0 &&  					stc.x > 0.0 &&  					stc.y > 0.0)  				{ -					col += color.rgb*texture2DLodSpecular(projectionMap, stc.xy, proj_lod).rgb*spec.rgb;										 +					col += color.rgb * texture2DLodSpecular(projectionMap, stc.xy, (1 - spec.a) * (proj_lod * 0.6)).rgb * envIntensity;  				}  			}  		} diff --git a/indra/newview/app_settings/shaders/class1/deferred/postgiF.glsl b/indra/newview/app_settings/shaders/class1/deferred/postgiF.glsl index 96f9628424..018ced4cad 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/postgiF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/postgiF.glsl @@ -99,4 +99,10 @@ void main()  	col = col*col*blur_quad.x + col*blur_quad.y + blur_quad.z;  	frag_color.rgb = col; + +#ifdef IS_AMD_CARD +	// If it's AMD make sure the GLSL compiler sees the arrays referenced once by static index. Otherwise it seems to optimise the storage awawy which leads to unfun crashes and artifacts. +	vec2 dummy1 = kern[0]; +	vec2 dummy2 = kern[31]; +#endif  } diff --git a/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl index 8d8a6c9dde..f50635a139 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl @@ -130,15 +130,19 @@ vec4 correctWithGamma(vec4 col)  vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)  {  	vec4 ret = texture2DLod(projectionMap, tc, lod); -	ret = correctWithGamma(ret); +	ret.rgb = srgb_to_linear(ret.rgb); -	vec2 dist = tc-vec2(0.5); +	vec2 dist = vec2(0.5) - abs(tc-vec2(0.5)); -	float det = max(1.0-lod/(proj_lod*0.5), 0.0); +	float det = min(lod/(proj_lod*0.5), 1.0); -	float d = dot(dist,dist); -		 -	ret *= min(clamp((0.25-d)/0.25, 0.0, 1.0)+det, 1.0); +	float d = min(dist.x, dist.y); +     +    d *= min(1, d * (proj_lod - lod)); +	 +	float edge = 0.25*det; +     +	ret *= clamp(d/edge, 0.0, 1.0);  	return ret;  } @@ -322,19 +326,14 @@ void main()  			if (stc.z > 0.0)  			{ -				stc.xy /= stc.w; - -				float fatten = clamp(envIntensity*envIntensity+envIntensity*0.5, 0.25, 1.0); -				 -				//stc.xy = (stc.xy - vec2(0.5)) * fatten + vec2(0.5); -				stc.xy = (stc.xy - vec2(0.5)) * fatten + vec2(0.5); +				stc /= stc.w;  				if (stc.x < 1.0 &&  					stc.y < 1.0 &&  					stc.x > 0.0 &&  					stc.y > 0.0)  				{ -					col += color.rgb*texture2DLodSpecular(projectionMap, stc.xy, proj_lod-envIntensity*proj_lod).rgb*spec.rgb;										 +					col += color.rgb * texture2DLodSpecular(projectionMap, stc.xy, (1 - spec.a) * (proj_lod * 0.6)).rgb * envIntensity;  				}  			}  		} diff --git a/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl index c20e00163c..94bd07bec6 100755 --- a/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl @@ -131,15 +131,19 @@ vec4 correctWithGamma(vec4 col)  vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)  {  	vec4 ret = texture2DLod(projectionMap, tc, lod); -	ret = correctWithGamma(ret); - -	vec2 dist = tc-vec2(0.5); +	ret.rgb = srgb_to_linear(ret.rgb); -	float det = max(1.0-lod/(proj_lod*0.5), 0.0); +	vec2 dist = vec2(0.5) - abs(tc-vec2(0.5)); -	float d = dot(dist,dist); -		 -	ret *= min(clamp((0.25-d)/0.25, 0.0, 1.0)+det, 1.0); +	float det = min(lod/(proj_lod*0.5), 1.0); +	 +	float d = min(dist.x, dist.y); +     +    d *= min(1, d * (proj_lod - lod)); +	 +	float edge = 0.25*det; +     +	ret *= clamp(d/edge, 0.0, 1.0);  	return ret;  } @@ -334,25 +338,21 @@ void main()  			vec3 pfinal = pos + ref * dot(pdelta, proj_n)/ds;  			vec4 stc = (proj_mat * vec4(pfinal.xyz, 1.0)); -			stc /= stc.w;  			if (stc.z > 0.0)  			{ -				float fatten = clamp(envIntensity*envIntensity+envIntensity*0.25, 0.25, 1.0); - -				stc.xy = (stc.xy - vec2(0.5)) * fatten + vec2(0.5); +                stc /= stc.w;  				if (stc.x < 1.0 &&  					stc.y < 1.0 &&  					stc.x > 0.0 &&  					stc.y > 0.0)  				{ -					col += color.rgb*texture2DLodSpecular(projectionMap, stc.xy, proj_lod).rgb*shadow*spec.rgb;										 +					col += color.rgb * texture2DLodSpecular(projectionMap, stc.xy, (1 - spec.a) * (proj_lod * 0.6)).rgb * shadow * envIntensity;  				}  			}  		}  	} -	  	//not sure why, but this line prevents MATBUG-194  	col = max(col, vec3(0.0)); diff --git a/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl index 7689b72d20..92e1ac95a6 100755 --- a/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl @@ -131,15 +131,19 @@ vec4 correctWithGamma(vec4 col)  vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)  {  	vec4 ret = texture2DLod(projectionMap, tc, lod); -	ret = correctWithGamma(ret); +	ret.rgb = srgb_to_linear(ret.rgb); -	vec2 dist = tc-vec2(0.5); +	vec2 dist = vec2(0.5) - abs(tc-vec2(0.5)); -	float det = max(1.0-lod/(proj_lod*0.5), 0.0); +	float det = min(lod/(proj_lod*0.5), 1.0); -	float d = dot(dist,dist); -		 -	ret *= min(clamp((0.25-d)/0.25, 0.0, 1.0)+det, 1.0); +	float d = min(dist.x, dist.y); +     +    d *= min(1, d * (proj_lod - lod)); +	 +	float edge = 0.25*det; +     +	ret *= clamp(d/edge, 0.0, 1.0);  	return ret;  } @@ -336,19 +340,14 @@ void main()  			if (stc.z > 0.0)  			{ -				stc.xy /= stc.w; - -				float fatten = clamp(envIntensity*envIntensity+envIntensity*0.5, 0.25, 1.0); -				 -				//stc.xy = (stc.xy - vec2(0.5)) * fatten + vec2(0.5); -				stc.xy = (stc.xy - vec2(0.5)) * fatten + vec2(0.5); +				stc /= stc.w;  				if (stc.x < 1.0 &&  					stc.y < 1.0 &&  					stc.x > 0.0 &&  					stc.y > 0.0)  				{ -					col += color.rgb*texture2DLodSpecular(projectionMap, stc.xy, proj_lod-envIntensity*proj_lod).rgb*shadow*spec.rgb;										 +					col += color.rgb * texture2DLodSpecular(projectionMap, stc.xy, (1 - spec.a) * (proj_lod * 0.6)).rgb * shadow * envIntensity;  				}  			}  		} diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp index 3928bbadc8..f06ffb4fb3 100755 --- a/indra/newview/llagentwearables.cpp +++ b/indra/newview/llagentwearables.cpp @@ -1088,7 +1088,6 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it  	if (isAgentAvatarValid())  	{  		gAgentAvatarp->setCompositeUpdatesEnabled(TRUE); -		gAgentAvatarp->updateVisualParams();  		// If we have not yet declouded, we may want to use  		// baked texture UUIDs sent from the first objectUpdate message @@ -1106,6 +1105,12 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it  	notifyLoadingFinished(); +	// Copy wearable params to avatar. +	gAgentAvatarp->writeWearablesToAvatar(); + +	// Then update the avatar based on the copied params. +	gAgentAvatarp->updateVisualParams(); +  	gAgentAvatarp->dumpAvatarTEs("setWearableOutfit");  	LL_DEBUGS("Avatar") << "setWearableOutfit() end" << LL_ENDL; @@ -1248,9 +1253,12 @@ void LLAgentWearables::userRemoveWearablesOfType(const LLWearableType::EType &ty  	}  } -// Combines userRemoveMulipleAttachments() and userAttachMultipleAttachments() logic to -// get attachments into desired state with minimal number of adds/removes. -void LLAgentWearables::userUpdateAttachments(LLInventoryModel::item_array_t& obj_item_array) +// Given a desired set of attachments, find what objects need to be +// removed, and what additional inventory items need to be added. +void LLAgentWearables::findAttachmentsAddRemoveInfo(LLInventoryModel::item_array_t& obj_item_array, +													llvo_vec_t& objects_to_remove, +													llvo_vec_t& objects_to_retain, +													LLInventoryModel::item_array_t& items_to_add)  {  	// Possible cases:  	// already wearing but not in request set -> take off. @@ -1269,7 +1277,6 @@ void LLAgentWearables::userUpdateAttachments(LLInventoryModel::item_array_t& obj  	}  	// Build up list of objects to be removed and items currently attached. -	llvo_vec_t objects_to_remove;  	for (LLVOAvatar::attachment_map_t::iterator iter = gAgentAvatarp->mAttachmentPoints.begin();   		 iter != gAgentAvatarp->mAttachmentPoints.end();)  	{ @@ -1304,12 +1311,12 @@ void LLAgentWearables::userUpdateAttachments(LLInventoryModel::item_array_t& obj  				{  					// LL_INFOS() << "found object to keep, id " << objectp->getID() << ", item " << objectp->getAttachmentItemID() << LL_ENDL;  					current_item_ids.insert(object_item_id); +					objects_to_retain.push_back(objectp);  				}  			}  		}  	} -	LLInventoryModel::item_array_t items_to_add;  	for (LLInventoryModel::item_array_t::iterator it = obj_item_array.begin();  		 it != obj_item_array.end();  		 ++it) @@ -1328,12 +1335,6 @@ void LLAgentWearables::userUpdateAttachments(LLInventoryModel::item_array_t& obj  	// S32 remove_count = objects_to_remove.size();  	// S32 add_count = items_to_add.size();  	// LL_INFOS() << "remove " << remove_count << " add " << add_count << LL_ENDL; - -	// Remove everything in objects_to_remove -	userRemoveMultipleAttachments(objects_to_remove); - -	// Add everything in items_to_add -	userAttachMultipleAttachments(items_to_add);  }  void LLAgentWearables::userRemoveMultipleAttachments(llvo_vec_t& objects_to_remove) @@ -1353,6 +1354,7 @@ void LLAgentWearables::userRemoveMultipleAttachments(llvo_vec_t& objects_to_remo  		 ++it)  	{  		LLViewerObject *objectp = *it; +		//gAgentAvatarp->resetJointPositionsOnDetach(objectp);  		gMessageSystem->nextBlockFast(_PREHASH_ObjectData);  		gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, objectp->getLocalID());  	} diff --git a/indra/newview/llagentwearables.h b/indra/newview/llagentwearables.h index cdb1bdbe05..1004482020 100755 --- a/indra/newview/llagentwearables.h +++ b/indra/newview/llagentwearables.h @@ -178,7 +178,10 @@ public:  	typedef std::vector<LLViewerObject*> llvo_vec_t; -	static void 	userUpdateAttachments(LLInventoryModel::item_array_t& obj_item_array); +	static void     findAttachmentsAddRemoveInfo(LLInventoryModel::item_array_t& obj_item_array, +												 llvo_vec_t& objects_to_remove, +												 llvo_vec_t& objects_to_retain, +												 LLInventoryModel::item_array_t& items_to_add);  	static void		userRemoveMultipleAttachments(llvo_vec_t& llvo_array);  	static void		userAttachMultipleAttachments(LLInventoryModel::item_array_t& obj_item_array); diff --git a/indra/newview/llaisapi.cpp b/indra/newview/llaisapi.cpp index 96de15bf75..9d887a61f1 100755 --- a/indra/newview/llaisapi.cpp +++ b/indra/newview/llaisapi.cpp @@ -34,6 +34,7 @@  #include "llsdutil.h"  #include "llviewerregion.h"  #include "llinventoryobserver.h" +#include "llviewercontrol.h"  ///----------------------------------------------------------------------------  /// Classes for AISv3 support. diff --git a/indra/newview/llappdelegate-objc.mm b/indra/newview/llappdelegate-objc.mm index 549df80fa1..549df80fa1 100644..100755 --- a/indra/newview/llappdelegate-objc.mm +++ b/indra/newview/llappdelegate-objc.mm diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index e35cf011c7..d7ef5fcba7 100755 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -807,15 +807,48 @@ void LLWearableHoldingPattern::onAllComplete()  		}  	} -	// Update wearables. -	LL_INFOS("Avatar") << self_av_string() << "HP " << index() << " updating agent wearables with " << mResolved << " wearable items " << LL_ENDL; -	LLAppearanceMgr::instance().updateAgentWearables(this); -	 -	// Update attachments to match those requested.  	if (isAgentAvatarValid())  	{  		LL_DEBUGS("Avatar") << self_av_string() << "Updating " << mObjItems.size() << " attachments" << LL_ENDL; -		LLAgentWearables::userUpdateAttachments(mObjItems); +		LLAgentWearables::llvo_vec_t objects_to_remove; +		LLAgentWearables::llvo_vec_t objects_to_retain; +		LLInventoryModel::item_array_t items_to_add; + +		LLAgentWearables::findAttachmentsAddRemoveInfo(mObjItems, +													   objects_to_remove, +													   objects_to_retain, +													   items_to_add); + +		LL_DEBUGS("Avatar") << self_av_string() << "Removing " << objects_to_remove.size() +							<< " attachments" << LL_ENDL; + +		// Here we remove the attachment pos overrides for *all* +		// attachments, even those that are not being removed. This is +		// needed to get joint positions all slammed down to their +		// pre-attachment states. +		gAgentAvatarp->clearAttachmentPosOverrides(); + +		// Take off the attachments that will no longer be in the outfit. +		LLAgentWearables::userRemoveMultipleAttachments(objects_to_remove); +		 +		// Update wearables. +		LL_INFOS("Avatar") << self_av_string() << "HP " << index() << " updating agent wearables with " +						   << mResolved << " wearable items " << LL_ENDL; +		LLAppearanceMgr::instance().updateAgentWearables(this); +		 +		// Restore attachment pos overrides for the attachments that +		// are remaining in the outfit. +		for (LLAgentWearables::llvo_vec_t::iterator it = objects_to_retain.begin(); +			 it != objects_to_retain.end(); +			 ++it) +		{ +			LLViewerObject *objectp = *it; +			gAgentAvatarp->addAttachmentPosOverridesForObject(objectp); +		} +		 +		// Add new attachments to match those requested. +		LL_DEBUGS("Avatar") << self_av_string() << "Adding " << items_to_add.size() << " attachments" << LL_ENDL; +		LLAgentWearables::userAttachMultipleAttachments(items_to_add);  	}  	if (isFetchCompleted() && isMissingCompleted()) @@ -2699,7 +2732,12 @@ void LLAppearanceMgr::removeCOFItemLinks(const LLUUID& item_id, LLPointer<LLInve  		const LLInventoryItem* item = item_array.at(i).get();  		if (item->getIsLinkType() && item->getLinkedUUID() == item_id)  		{ -			remove_inventory_item(item->getUUID(), cb); +			bool immediate_delete = false; +			if (item->getType() == LLAssetType::AT_OBJECT) +			{ +				immediate_delete = true; +			} +			remove_inventory_item(item->getUUID(), cb, immediate_delete);  		}  	}  } diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index afd5b84537..ab96201a63 100755 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -1626,7 +1626,8 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, LLFace*  			{  				F32 w = weight[j][k]; -				idx[k] = llclamp((S32) floorf(w), 0, 63); +				idx[k] = llclamp((S32) floorf(w), 0, JOINT_COUNT-1); +  				wght[k] = w - floorf(w);  				scale += wght[k];  			} diff --git a/indra/newview/llfilepicker.cpp b/indra/newview/llfilepicker.cpp index 5debf71744..ef50594feb 100755 --- a/indra/newview/llfilepicker.cpp +++ b/indra/newview/llfilepicker.cpp @@ -600,6 +600,9 @@ std::vector<std::string>* LLFilePicker::navOpenFilterProc(ELoadFilter filter) //              allowedv->push_back("slg");              break;  #endif +        case FFLOAD_XML: +            allowedv->push_back("xml"); +            break;          case FFLOAD_RAW:              allowedv->push_back("raw");              break; @@ -702,7 +705,14 @@ bool	LLFilePicker::doNavSaveDialog(ESaveFilter filter, const std::string& filena  			creator = "\?\?\?\?";  			extension = "slg";  			break; -#endif		 +#endif	 +			 +		case FFSAVE_XML: +			type = "\?\?\?\?"; +			creator = "\?\?\?\?"; +			extension = "xml"; +			break; +			  		case FFSAVE_RAW:  			type = "\?\?\?\?";  			creator = "\?\?\?\?"; @@ -1100,6 +1110,12 @@ static std::string add_anim_filter_to_gtkchooser(GtkWindow *picker)  	return filtername;  } +static std::string add_xml_filter_to_gtkchooser(GtkWindow *picker) +{ +	return add_simple_pattern_filter_to_gtkchooser(picker,  "*.xml", +												   LLTrans::getString("xml_files") + " (*.xml)"); +} +  static std::string add_collada_filter_to_gtkchooser(GtkWindow *picker)  {  	return add_simple_pattern_filter_to_gtkchooser(picker,  "*.dae", @@ -1293,6 +1309,9 @@ BOOL LLFilePicker::getOpenFile( ELoadFilter filter, bool blocking )  		case FFLOAD_ANIM:  			filtername = add_anim_filter_to_gtkchooser(picker);  			break; +		case FFLOAD_XML: +			filtername = add_xml_filter_to_gtkchooser(picker); +			break;  		case FFLOAD_COLLADA:  			filtername = add_collada_filter_to_gtkchooser(picker);  			break; diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index e81689f69c..e0a998c369 100755 --- a/indra/newview/llfloatermodelpreview.cpp +++ b/indra/newview/llfloatermodelpreview.cpp @@ -3249,7 +3249,11 @@ U32 LLModelPreview::calcResourceCost()  	if ( mFMP && mFMP->childGetValue("upload_joints").asBoolean() )  	{ -		getPreviewAvatar()->setPelvisOffset( mPelvisZOffset ); +		// FIXME if preview avatar ever gets reused, this fake mesh ID stuff will fail. +		// see also call to addAttachmentPosOverride. +		LLUUID fake_mesh_id; +		fake_mesh_id.generate(); +		getPreviewAvatar()->addPelvisFixup( mPelvisZOffset, fake_mesh_id );  	}  	F32 streaming_cost = 0.f; diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index 085986dc68..1910656066 100755 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -5344,16 +5344,20 @@ std::string LLObjectBridge::getLabelSuffix() const  		{  			return LLItemBridge::getLabelSuffix() + LLTrans::getString("worn");  		} -		std::string attachment_point_name = gAgentAvatarp->getAttachedPointName(mUUID); -		if (attachment_point_name == LLStringUtil::null) // Error condition, invalid attach point +		std::string attachment_point_name; +		if (gAgentAvatarp->getAttachedPointName(mUUID, attachment_point_name))  		{ -			attachment_point_name = "Invalid Attachment"; -		} -		// e.g. "(worn on ...)" / "(attached to ...)" -		LLStringUtil::format_map_t args; -		args["[ATTACHMENT_POINT]"] =  LLTrans::getString(attachment_point_name); +			LLStringUtil::format_map_t args; +			args["[ATTACHMENT_POINT]"] =  LLTrans::getString(attachment_point_name); -		return LLItemBridge::getLabelSuffix() + LLTrans::getString("WornOnAttachmentPoint", args); +			return LLItemBridge::getLabelSuffix() + LLTrans::getString("WornOnAttachmentPoint", args); +		} +		else +		{ +			LLStringUtil::format_map_t args; +			args["[ATTACHMENT_ERROR]"] =  LLTrans::getString(attachment_point_name); +			return LLItemBridge::getLabelSuffix() + LLTrans::getString("AttachmentErrorMessage", args); +		}  	}  	return LLItemBridge::getLabelSuffix();  } diff --git a/indra/newview/llmaniprotate.cpp b/indra/newview/llmaniprotate.cpp index 7861573908..b2350e5a75 100755 --- a/indra/newview/llmaniprotate.cpp +++ b/indra/newview/llmaniprotate.cpp @@ -1240,10 +1240,10 @@ LLQuaternion LLManipRotate::dragUnconstrained( S32 x, S32 y )  	F32 dist_from_sphere_center = sqrt(delta_x * delta_x + delta_y * delta_y);  	LLVector3 axis = mMouseDown % mMouseCur; +	F32 angle = atan2(sqrtf(axis * axis), mMouseDown * mMouseCur);  	axis.normVec(); -	F32 angle = acos(mMouseDown * mMouseCur);  	LLQuaternion sphere_rot( angle, axis ); - +	  	if (is_approx_zero(1.f - mMouseDown * mMouseCur))  	{  		return LLQuaternion::DEFAULT; @@ -1638,9 +1638,9 @@ LLQuaternion LLManipRotate::dragConstrained( S32 x, S32 y )  			mInSnapRegime = FALSE;  		} -		angle = acos(mMouseCur * mMouseDown); - -		F32 dir = (mMouseDown % mMouseCur) * constraint_axis;  // cross product +		LLVector3 cross_product = mMouseDown % mMouseCur; +		angle = atan2(sqrtf(cross_product * cross_product), mMouseCur * mMouseDown); +		F32 dir = cross_product * constraint_axis;  // cross product  		if( dir < 0.f )  		{  			angle *= -1.f; diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp index d364fce45a..d6c8ba10f6 100755 --- a/indra/newview/llviewerinventory.cpp +++ b/indra/newview/llviewerinventory.cpp @@ -1456,7 +1456,8 @@ void update_inventory_category(  void remove_inventory_items(  	LLInventoryObject::object_list_t& items_to_kill, -	LLPointer<LLInventoryCallback> cb) +	LLPointer<LLInventoryCallback> cb +	)  {  	for (LLInventoryObject::object_list_t::iterator it = items_to_kill.begin();  		 it != items_to_kill.end(); @@ -1468,12 +1469,13 @@ void remove_inventory_items(  void remove_inventory_item(  	const LLUUID& item_id, -	LLPointer<LLInventoryCallback> cb) +	LLPointer<LLInventoryCallback> cb, +	bool immediate_delete)  {  	LLPointer<LLInventoryObject> obj = gInventory.getItem(item_id);  	if (obj)  	{ -		remove_inventory_item(obj, cb); +		remove_inventory_item(obj, cb, immediate_delete);  	}  	else  	{ @@ -1483,7 +1485,8 @@ void remove_inventory_item(  void remove_inventory_item(  	LLPointer<LLInventoryObject> obj, -	LLPointer<LLInventoryCallback> cb) +	LLPointer<LLInventoryCallback> cb, +	bool immediate_delete)  {  	if(obj)  	{ @@ -1493,6 +1496,11 @@ void remove_inventory_item(  		{  			LLPointer<AISCommand> cmd_ptr = new RemoveItemCommand(item_id, cb);  			cmd_ptr->run_command(); + +			if (immediate_delete) +			{ +				gInventory.onObjectDeletedFromServer(item_id); +			}  		}  		else // no cap  		{ diff --git a/indra/newview/llviewerinventory.h b/indra/newview/llviewerinventory.h index d345c49cfb..ca92565600 100755 --- a/indra/newview/llviewerinventory.h +++ b/indra/newview/llviewerinventory.h @@ -394,11 +394,13 @@ void remove_inventory_items(  void remove_inventory_item(  	LLPointer<LLInventoryObject> obj, -	LLPointer<LLInventoryCallback> cb); +	LLPointer<LLInventoryCallback> cb, +	bool immediate_delete = false);  void remove_inventory_item(  	const LLUUID& item_id, -	LLPointer<LLInventoryCallback> cb); +	LLPointer<LLInventoryCallback> cb, +	bool immediate_delete = false);  void remove_inventory_category(  	const LLUUID& cat_id, diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index 690d6aebe2..87424cd584 100755 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -359,10 +359,17 @@ void LLViewerObject::markDead()  		//LL_INFOS() << "Marking self " << mLocalID << " as dead." << LL_ENDL;  		// Root object of this hierarchy unlinks itself. +		LLVOAvatar *av = getAvatarAncestor();  		if (getParent())  		{  			((LLViewerObject *)getParent())->removeChild(this);  		} +		LLUUID mesh_id; +		if (av && LLVOAvatar::getRiggedMeshID(this,mesh_id)) +		{ +			// This case is needed for indirectly attached mesh objects. +			av->resetJointPositionsOnDetach(mesh_id); +		}  		// Mark itself as dead  		mDead = TRUE; @@ -5015,6 +5022,22 @@ LLVOAvatar* LLViewerObject::asAvatar()  	return NULL;  } +// If this object is directly or indirectly parented by an avatar, return it. +LLVOAvatar* LLViewerObject::getAvatarAncestor() +{ +	LLViewerObject *pobj = (LLViewerObject*) getParent(); +	while (pobj) +	{ +		LLVOAvatar *av = pobj->asAvatar(); +		if (av) +		{ +			return av; +		} +		pobj =  (LLViewerObject*) pobj->getParent(); +	} +	return NULL; +} +  BOOL LLViewerObject::isParticleSource() const  {  	return !mPartSourcep.isNull() && !mPartSourcep->isDead(); diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index 22ac4ce0db..05c87c153b 100755 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -135,6 +135,8 @@ public:  	virtual LLVOAvatar* asAvatar(); +	LLVOAvatar* getAvatarAncestor(); +  	static void initVOClasses();  	static void cleanupVOClasses(); diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 157c402795..444a26779a 100755 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -464,7 +464,10 @@ public:  		mCharacter = character;  		BOOL success = true; -		if ( !mChestState->setJoint( character->getJoint( "mChest" ) ) ) { success = false; } +		if ( !mChestState->setJoint( character->getJoint( "mChest" ) ) ) +		{ +			success = false; +		}  		if ( success )  		{ @@ -708,7 +711,6 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id,  	mVisualComplexity(0),  	mVisualComplexityStale(TRUE),  	mLoadedCallbacksPaused(FALSE), -	mHasPelvisOffset( FALSE ),  	mRenderUnloadedAvatar(LLCachedControl<bool>(gSavedSettings, "RenderUnloadedAvatar", false)),  	mLastRezzedStatus(-1),  	mIsEditingAppearance(FALSE), @@ -770,10 +772,6 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id,  	mRuthTimer.reset();  	mRuthDebugTimer.reset();  	mDebugExistenceTimer.reset(); -	mPelvisOffset = LLVector3(0.0f,0.0f,0.0f); -	mLastPelvisToFoot = 0.0f; -	mPelvisFixup = 0.0f; -	mLastPelvisFixup = 0.0f;      if(LLSceneMonitor::getInstance()->isEnabled())  	{ @@ -819,14 +817,14 @@ void LLVOAvatar::debugAvatarRezTime(std::string notification_name, std::string c  //------------------------------------------------------------------------  LLVOAvatar::~LLVOAvatar()  { -		if (!mFullyLoaded) -		{ +	if (!mFullyLoaded) +	{  		debugAvatarRezTime("AvatarRezLeftCloudNotification","left after ruth seconds as cloud"); -		} -		else -		{ +	} +	else +	{  		debugAvatarRezTime("AvatarRezLeftNotification","left sometime after declouding"); -		} +	}  	logPendingPhases(); @@ -980,10 +978,11 @@ void LLVOAvatar::getNearbyRezzedStats(std::vector<S32>& counts)  		 iter != LLCharacter::sInstances.end(); ++iter)  	{  		LLVOAvatar* inst = (LLVOAvatar*) *iter; -		if (!inst) -			continue; -		S32 rez_status = inst->getRezzedStatus(); -		counts[rez_status]++; +		if (inst) +		{ +			S32 rez_status = inst->getRezzedStatus(); +			counts[rez_status]++; +		}  	}  } @@ -1258,17 +1257,18 @@ const LLVector3 LLVOAvatar::getRenderPosition() const  	}  	else if (isRoot())  	{ -		if ( !mHasPelvisOffset ) -		{ -			return mDrawable->getPositionAgent(); -		} -		else +		F32 fixup; +		if ( hasPelvisFixup( fixup) )  		{  			//Apply a pelvis fixup (as defined by the avs skin)  			LLVector3 pos = mDrawable->getPositionAgent(); -			pos[VZ] += mPelvisFixup; +			pos[VZ] += fixup;  			return pos;  		} +		else +		{ +			return mDrawable->getPositionAgent(); +		}  	}  	else  	{ @@ -1353,38 +1353,36 @@ void LLVOAvatar::getSpatialExtents(LLVector4a& newMin, LLVector4a& newMax)  	{  		LLViewerJointAttachment* attachment = iter->second; -		if (!attachment->getValid()) -		{ -			continue ; -		} - -		for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); -			 attachment_iter != attachment->mAttachedObjects.end(); -			 ++attachment_iter) +		if (attachment->getValid())  		{ -			const LLViewerObject* attached_object = (*attachment_iter); -			if (attached_object && !attached_object->isHUDAttachment()) +			for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); +				 attachment_iter != attachment->mAttachedObjects.end(); +				 ++attachment_iter)  			{ -				LLDrawable* drawable = attached_object->mDrawable; -				if (drawable && !drawable->isState(LLDrawable::RIGGED)) +				const LLViewerObject* attached_object = (*attachment_iter); +				if (attached_object && !attached_object->isHUDAttachment())  				{ -					LLSpatialBridge* bridge = drawable->getSpatialBridge(); -					if (bridge) +					LLDrawable* drawable = attached_object->mDrawable; +					if (drawable && !drawable->isState(LLDrawable::RIGGED))  					{ -						const LLVector4a* ext = bridge->getSpatialExtents(); -						LLVector4a distance; -						distance.setSub(ext[1], ext[0]); -						LLVector4a max_span(max_attachment_span); +						LLSpatialBridge* bridge = drawable->getSpatialBridge(); +						if (bridge) +						{ +							const LLVector4a* ext = bridge->getSpatialExtents(); +							LLVector4a distance; +							distance.setSub(ext[1], ext[0]); +							LLVector4a max_span(max_attachment_span); -						S32 lt = distance.lessThan(max_span).getGatheredBits() & 0x7; +							S32 lt = distance.lessThan(max_span).getGatheredBits() & 0x7; -						// Only add the prim to spatial extents calculations if it isn't a megaprim. -						// max_attachment_span calculated at the start of the function  -						// (currently 5 times our max prim size)  -						if (lt == 0x7) -						{ -							update_min_max(newMin,newMax,ext[0]); -							update_min_max(newMin,newMax,ext[1]); +							// Only add the prim to spatial extents calculations if it isn't a megaprim. +							// max_attachment_span calculated at the start of the function  +							// (currently 5 times our max prim size)  +							if (lt == 0x7) +							{ +								update_min_max(newMin,newMax,ext[0]); +								update_min_max(newMin,newMax,ext[1]); +							}  						}  					}  				} @@ -1961,7 +1959,7 @@ U32 LLVOAvatar::processUpdateMessage(LLMessageSystem *mesgsys,  		if (has_name && getNVPair("FirstName"))  		{  			mDebugExistenceTimer.reset(); -		debugAvatarRezTime("AvatarRezArrivedNotification","avatar arrived"); +			debugAvatarRezTime("AvatarRezArrivedNotification","avatar arrived");  		}  	if(retval & LLViewerObject::INVALID_UPDATE) @@ -1973,9 +1971,6 @@ U32 LLVOAvatar::processUpdateMessage(LLMessageSystem *mesgsys,  		}  	} -	//LL_INFOS() << getRotation() << LL_ENDL; -	//LL_INFOS() << getPosition() << LL_ENDL; -  	return retval;  } @@ -1991,7 +1986,7 @@ LLViewerFetchedTexture *LLVOAvatar::getBakedTextureImage(const U8 te, const LLUU  		result = gTextureList.findImage(uuid);  	}  	if (!result) -{ +	{  		const std::string url = getImageURL(te,uuid);  		if (url.empty()) @@ -3336,7 +3331,7 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)  			removeAnimationData("Walk Speed");  		}  		mMotionController.setTimeStep(time_step); -//		LL_INFOS() << "Setting timestep to " << time_quantum * pixel_area_scale << LL_ENDL; +		//		LL_INFOS() << "Setting timestep to " << time_quantum * pixel_area_scale << LL_ENDL;  	}  	if (getParent() && !mIsSitting) @@ -3477,7 +3472,6 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)  						fwdDir.normalize();  					}  				} -				  			}  			LLQuaternion root_rotation = mRoot->getWorldMatrix().quaternion(); @@ -3593,10 +3587,14 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)  	// update animations  	if (mSpecialRenderMode == 1) // Animation Preview +	{  		updateMotions(LLCharacter::FORCE_UPDATE); +	}  	else +	{  		updateMotions(LLCharacter::NORMAL_UPDATE); - +	} +	  	// update head position  	updateHeadOffset(); @@ -3693,10 +3691,6 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)  	//mesh vertices need to be reskinned  	mNeedsSkin = TRUE; - - -		 -	  	return TRUE;  }  //----------------------------------------------------------------------------- @@ -3724,21 +3718,6 @@ void LLVOAvatar::updateHeadOffset()  	}  }  //------------------------------------------------------------------------ -// setPelvisOffset -//------------------------------------------------------------------------ -void LLVOAvatar::setPelvisOffset( bool hasOffset, const LLVector3& offsetAmount, F32 pelvisFixup )  -{ -	mHasPelvisOffset = hasOffset; -	if ( mHasPelvisOffset ) -	{	 -		//Store off last pelvis to foot value -		mLastPelvisToFoot = mPelvisToFoot;		 -		mPelvisOffset	  = offsetAmount; -		mLastPelvisFixup  = mPelvisFixup; -		mPelvisFixup	  = pelvisFixup; -	} -} -//------------------------------------------------------------------------  // postPelvisSetRecalc  //------------------------------------------------------------------------  void LLVOAvatar::postPelvisSetRecalc( void ) @@ -3748,15 +3727,6 @@ void LLVOAvatar::postPelvisSetRecalc( void )  	dirtyMesh(2);  }  //------------------------------------------------------------------------ -// setPelvisOffset -//------------------------------------------------------------------------ -void LLVOAvatar::setPelvisOffset( F32 pelvisFixupAmount ) -{		 -	mHasPelvisOffset  = true; -	mLastPelvisFixup  = mPelvisFixup;	 -	mPelvisFixup	  = pelvisFixupAmount;	 -} -//------------------------------------------------------------------------  // updateVisibility()  //------------------------------------------------------------------------  void LLVOAvatar::updateVisibility() @@ -3976,13 +3946,13 @@ U32 LLVOAvatar::renderSkinned()  			if (face)  			{  				LLVertexBuffer* vb = face->getVertexBuffer(); -			if (vb) -			{ -				vb->flush(); +				if (vb) +				{ +					vb->flush(); +				}  			}  		}  	} -	}  	else  	{  		mNeedsSkin = FALSE; @@ -4162,7 +4132,7 @@ U32 LLVOAvatar::renderTransparent(BOOL first_pass)  		{  			LLViewerJoint* hair_mesh = getViewerJoint(MESH_ID_HAIR);  			if (hair_mesh) -		{ +			{  				num_indices += hair_mesh->render(mAdjustedPixelArea, first_pass, mIsDummy);  			}  			first_pass = FALSE; @@ -5073,6 +5043,158 @@ LLJoint *LLVOAvatar::getJoint( const std::string &name )  	return jointp;  } + +//----------------------------------------------------------------------------- +// getRiggedMeshID +// +// If viewer object is a rigged mesh, set the mesh id and return true. +// Otherwise, null out the id and return false. +//----------------------------------------------------------------------------- +// static +bool LLVOAvatar::getRiggedMeshID(LLViewerObject* pVO, LLUUID& mesh_id) +{ +	mesh_id.setNull(); +	 +	//If a VO has a skin that we'll reset the joint positions to their default +	if ( pVO && pVO->mDrawable ) +	{ +		LLVOVolume* pVObj = pVO->mDrawable->getVOVolume(); +		if ( pVObj ) +		{ +			const LLMeshSkinInfo* pSkinData = gMeshRepo.getSkinInfo( pVObj->getVolume()->getParams().getSculptID(), pVObj ); +			if (pSkinData  +				&& pSkinData->mJointNames.size() > JOINT_COUNT_REQUIRED_FOR_FULLRIG	// full rig +				&& pSkinData->mAlternateBindMatrix.size() > 0 ) +					{				 +						mesh_id = pSkinData->mMeshID; +						return true; +					} +		} +	} +	return false; +} + +void LLVOAvatar::clearAttachmentPosOverrides() +{ +	//Subsequent joints are relative to pelvis +	avatar_joint_list_t::iterator iter = mSkeleton.begin(); +	avatar_joint_list_t::iterator end  = mSkeleton.end(); + +	for (; iter != end; ++iter) +	{ +		LLJoint* pJoint = (*iter); +		pJoint->clearAttachmentPosOverrides(); +	} +} + +//----------------------------------------------------------------------------- +// addAttachmentPosOverridesForObject +//----------------------------------------------------------------------------- +void LLVOAvatar::addAttachmentPosOverridesForObject(LLViewerObject *vo) +{ +	LLVOAvatar *av = vo->getAvatarAncestor(); +	if (!av || (av != this)) +	{ +		LL_WARNS("Avatar") << "called with invalid avatar" << LL_ENDL; +	} +		 +	// Process all children +	LLViewerObject::const_child_list_t& children = vo->getChildren(); +	for (LLViewerObject::const_child_list_t::const_iterator it = children.begin(); +		 it != children.end(); ++it) +	{ +		LLViewerObject *childp = *it; +		addAttachmentPosOverridesForObject(childp); +	} + +	LLVOVolume *vobj = dynamic_cast<LLVOVolume*>(vo); +	bool pelvisGotSet = false; + +	if (!vobj) +	{ +		return; +	} +	if (vobj->isMesh() && +		((vobj->getVolume() && !vobj->getVolume()->isMeshAssetLoaded()) || !gMeshRepo.meshRezEnabled())) +	{ +		return; +	} +	LLUUID currentId = vobj->getVolume()->getParams().getSculptID();						 +	const LLMeshSkinInfo*  pSkinData = gMeshRepo.getSkinInfo( currentId, vobj ); + +	if ( vobj && vobj->isAttachment() && vobj->isMesh() && pSkinData ) +	{ +		const int bindCnt = pSkinData->mAlternateBindMatrix.size();								 +		if ( bindCnt > 0 ) +		{					 +			const int jointCnt = pSkinData->mJointNames.size(); +			const F32 pelvisZOffset = pSkinData->mPelvisOffset; +			const LLUUID& mesh_id = pSkinData->mMeshID; +			bool fullRig = (jointCnt>=JOINT_COUNT_REQUIRED_FOR_FULLRIG) ? true : false;								 +			if ( fullRig ) +			{								 +				for ( int i=0; i<jointCnt; ++i ) +				{ +					std::string lookingForJoint = pSkinData->mJointNames[i].c_str(); +					LLJoint* pJoint = getJoint( lookingForJoint ); +					if ( pJoint && pJoint->getId() != currentId ) +					{   									 +						pJoint->setId( currentId ); +						const LLVector3& jointPos = pSkinData->mAlternateBindMatrix[i].getTranslation();									 +						//Set the joint position +						pJoint->addAttachmentPosOverride( jointPos, mesh_id, avString() ); +									 +						//If joint is a pelvis then handle old/new pelvis to foot values +						if ( lookingForJoint == "mPelvis" ) +						{	 +							pelvisGotSet = true;											 +						}										 +					}										 +				}																 +				if (pelvisZOffset != 0.0F) +				{ +					addPelvisFixup( pelvisZOffset, mesh_id ); +					pelvisGotSet = true;											 +				} +			}							 +		} +	} +					 +	//Rebuild body data if we altered joints/pelvis +	if ( pelvisGotSet )  +	{ +		postPelvisSetRecalc(); +	}		 +} + +//----------------------------------------------------------------------------- +// resetJointPositionsOnDetach +//----------------------------------------------------------------------------- +void LLVOAvatar::resetJointPositionsOnDetach(LLViewerObject *vo) +{ +	LLVOAvatar *av = vo->getAvatarAncestor(); +	if (!av || (av != this)) +	{ +		LL_WARNS("Avatar") << "called with invalid avatar" << LL_ENDL; +	} +		 +	// Process all children +	LLViewerObject::const_child_list_t& children = vo->getChildren(); +	for (LLViewerObject::const_child_list_t::const_iterator it = children.begin(); +		 it != children.end(); ++it) +	{ +		LLViewerObject *childp = *it; +		resetJointPositionsOnDetach(childp); +	} + +	// Process self. +	LLUUID mesh_id; +	if (getRiggedMeshID(vo,mesh_id)) +	{ +		resetJointPositionsOnDetach(mesh_id); +	} +} +  //-----------------------------------------------------------------------------  // resetJointPositionsOnDetach  //----------------------------------------------------------------------------- @@ -5088,22 +5210,18 @@ void LLVOAvatar::resetJointPositionsOnDetach(const LLUUID& mesh_id)  	{  		LLJoint* pJoint = (*iter);  		//Reset joints except for pelvis -		if ( pJoint && pJoint != pJointPelvis) +		if ( pJoint )  		{			  			pJoint->setId( LLUUID::null );  			pJoint->removeAttachmentPosOverride(mesh_id, avString());  		}		 -		else  		if ( pJoint && pJoint == pJointPelvis)  		{ -			pJoint->setId( LLUUID::null ); +			removePelvisFixup( mesh_id );  			pJoint->setPosition( LLVector3( 0.0f, 0.0f, 0.0f) );  		}		  	}	 -	//make sure we don't apply the joint offset -	mHasPelvisOffset = false; -	mPelvisFixup	 = mLastPelvisFixup;  	postPelvisSetRecalc();	  }  //----------------------------------------------------------------------------- @@ -5228,8 +5346,8 @@ BOOL LLVOAvatar::loadSkeletonNode ()  {  	if (!LLAvatarAppearance::loadSkeletonNode())  	{ -				return FALSE; -			} +		return FALSE; +	}  	// ATTACHMENTS  	{ @@ -5750,31 +5868,18 @@ void LLVOAvatar::rebuildRiggedAttachments( void )  //-----------------------------------------------------------------------------  void LLVOAvatar::cleanupAttachedMesh( LLViewerObject* pVO )  { -	//If a VO has a skin that we'll reset the joint positions to their default -	if ( pVO && pVO->mDrawable ) +	LLUUID mesh_id; +	if (getRiggedMeshID(pVO, mesh_id))  	{ -		LLVOVolume* pVObj = pVO->mDrawable->getVOVolume(); -		if ( pVObj ) +		resetJointPositionsOnDetach(mesh_id); +		if ( gAgentCamera.cameraCustomizeAvatar() )  		{ -			const LLMeshSkinInfo* pSkinData = gMeshRepo.getSkinInfo( pVObj->getVolume()->getParams().getSculptID(), pVObj ); -			if (pSkinData  -				&& pSkinData->mJointNames.size() > JOINT_COUNT_REQUIRED_FOR_FULLRIG	// full rig -				&& pSkinData->mAlternateBindMatrix.size() > 0 ) -					{				 -						const LLUUID& mesh_id = pSkinData->mMeshID; -						LLVOAvatar::resetJointPositionsOnDetach(mesh_id);							 -						//Need to handle the repositioning of the cam, updating rig data etc during outfit editing  -						//This handles the case where we detach a replacement rig. -						if ( gAgentCamera.cameraCustomizeAvatar() ) -						{ -							gAgent.unpauseAnimation(); -							//Still want to refocus on head bone -							gAgentCamera.changeCameraToCustomizeAvatar(); -						} -					} -				} -			}				 +			gAgent.unpauseAnimation(); +			//Still want to refocus on head bone +			gAgentCamera.changeCameraToCustomizeAvatar();  		} +	} +}  //-----------------------------------------------------------------------------  // detachObject() @@ -5981,27 +6086,24 @@ BOOL LLVOAvatar::isWearingWearableType(LLWearableType::EType type) const  			break; // Do nothing  	} -	/* switch(type) -		case LLWearableType::WT_SHIRT: -			indicator_te = TEX_UPPER_SHIRT; */  	for (LLAvatarAppearanceDictionary::Textures::const_iterator tex_iter = LLAvatarAppearanceDictionary::getInstance()->getTextures().begin();  		 tex_iter != LLAvatarAppearanceDictionary::getInstance()->getTextures().end();  		 ++tex_iter)  	{  		const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = tex_iter->second;  		if (texture_dict->mWearableType == type) -	{ +		{  			// Thus, you must check to see if the corresponding baked texture is defined.  			// NOTE: this is a poor substitute if you actually want to know about individual pieces of clothing  			// this works for detecting a skirt (most important), but is ineffective at any piece of clothing that  			// gets baked into a texture that always exists (upper or lower).  			if (texture_dict->mIsUsedByBakedTexture) -	{ +			{  				const EBakedTextureIndex baked_index = texture_dict->mBakedTextureIndex;  				return isTextureDefined(LLAvatarAppearanceDictionary::getInstance()->getBakedTexture(baked_index)->mTextureIndex); -	} +			}  			return FALSE; -	} +		}  	}  	return FALSE;  } @@ -6071,7 +6173,7 @@ void LLVOAvatar::onGlobalColorChanged(const LLTexGlobalColor* global_color)  	}   	else if (global_color == mTexEyeColor)  	{ -//		LL_INFOS() << "invalidateComposite cause: onGlobalColorChanged( eyecolor )" << LL_ENDL;  +		// LL_INFOS() << "invalidateComposite cause: onGlobalColorChanged( eyecolor )" << LL_ENDL;   		invalidateComposite( mBakedTextureDatas[BAKED_EYES].mTexLayerSet);  	}  	updateMeshTextures(); @@ -6131,9 +6233,9 @@ void LLVOAvatar::updateRezzedStatusTimers()  		{  			// load level has decreased. start phase timers for higher load levels.  			for (S32 i = rez_status+1; i <= mLastRezzedStatus; i++) -		{ +			{  				startPhase("load_" + LLVOAvatar::rezStatusToString(i)); -		} +			}  		}  		else if (rez_status > mLastRezzedStatus)  		{ @@ -6142,16 +6244,15 @@ void LLVOAvatar::updateRezzedStatusTimers()  			{  				stopPhase("load_" + LLVOAvatar::rezStatusToString(i));  				stopPhase("first_load_" + LLVOAvatar::rezStatusToString(i), false); -		} +			}  			if (rez_status == 3) -		{ +			{  				// "fully loaded", mark any pending appearance change complete.  				selfStopPhase("update_appearance_from_cof");  				selfStopPhase("wear_inventory_category", false);  				selfStopPhase("process_initial_wearables_update", false);  			}  		} -		  		mLastRezzedStatus = rez_status;  	}  } @@ -6213,7 +6314,7 @@ void LLVOAvatar::stopPhase(const std::string& phase_name, bool err_check)  void LLVOAvatar::logPendingPhases()  {  	if (!isAgentAvatarValid()) -		{ +	{  		return;  	} @@ -6229,14 +6330,14 @@ void LLVOAvatar::logPendingPhases()  			if (!completed)  			{  				logMetricsTimerRecord(phase_name, elapsed, completed); -		} +			}  		}  	} -		} +}  //static  void LLVOAvatar::logPendingPhasesAllAvatars() -		{ +{  	for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin();  		 iter != LLCharacter::sInstances.end(); ++iter)  	{ @@ -6247,14 +6348,14 @@ void LLVOAvatar::logPendingPhasesAllAvatars()  		}  		inst->logPendingPhases();  	} -		} +}  void LLVOAvatar::logMetricsTimerRecord(const std::string& phase_name, F32 elapsed, bool completed) -		{ +{  	if (!isAgentAvatarValid()) -		{ +	{  		return; -		} +	}  	LLSD record;  	record["timer_name"] = phase_name; @@ -6263,10 +6364,10 @@ void LLVOAvatar::logMetricsTimerRecord(const std::string& phase_name, F32 elapse  	record["completed"] = completed;  	U32 grid_x(0), grid_y(0);  	if (getRegion()) -		{ +	{  		record["central_bake_version"] = LLSD::Integer(getRegion()->getCentralBakeVersion());  		grid_from_region_handle(getRegion()->getHandle(), &grid_x, &grid_y); -		} +	}  	record["grid_x"] = LLSD::Integer(grid_x);  	record["grid_y"] = LLSD::Integer(grid_y);  	record["is_using_server_bakes"] = true; @@ -6327,8 +6428,8 @@ BOOL LLVOAvatar::processFullyLoadedChange(bool loading)  	mFullyLoaded = (mFullyLoadedTimer.getElapsedTimeF32() > PAUSE); -		if (!mPreviousFullyLoaded && !loading && mFullyLoaded) -		{ +	if (!mPreviousFullyLoaded && !loading && mFullyLoaded) +	{  		debugAvatarRezTime("AvatarRezNotification","fully loaded");  	} @@ -6384,9 +6485,7 @@ void LLVOAvatar::debugColorizeSubMeshes(U32 i, const LLColor4& color)  			LLAvatarJointMesh* mesh = (*iter);  			if (mesh)  			{ -				{ -					mesh->setColor(color); -				} +				mesh->setColor(color);  			}  		}  	} @@ -6486,7 +6585,7 @@ void LLVOAvatar::updateMeshTextures()  		LLViewerTexLayerSet* layerset = getTexLayerSet(i);  		if (use_lkg_baked_layer[i] && !isUsingLocalAppearance() ) -	{ +		{  			LLViewerFetchedTexture* baked_img = LLViewerTextureManager::getFetchedTexture(mBakedTextureDatas[i].mLastTextureID);  			mBakedTextureDatas[i].mIsUsed = TRUE; @@ -6495,12 +6594,12 @@ void LLVOAvatar::updateMeshTextures()  			avatar_joint_mesh_list_t::iterator iter = mBakedTextureDatas[i].mJointMeshes.begin();  			avatar_joint_mesh_list_t::iterator end  = mBakedTextureDatas[i].mJointMeshes.end();  			for (; iter != end; ++iter) -	{ +			{  				LLAvatarJointMesh* mesh = (*iter);  				if (mesh) -		{ +				{  					mesh->setTexture( baked_img ); -			} +				}  			}  		}  		else if (!isUsingLocalAppearance() && is_layer_baked[i]) @@ -6529,9 +6628,9 @@ void LLVOAvatar::updateMeshTextures()  				baked_img->setLoadedCallback(onBakedTextureLoaded, SWITCH_TO_BAKED_DISCARD, FALSE, FALSE, new LLUUID( mID ),   					src_callback_list, paused ); -                               // this could add paused texture callbacks -                               mLoadedCallbacksPaused |= paused;  -                               checkTextureLoading(); +				// this could add paused texture callbacks +				mLoadedCallbacksPaused |= paused;  +				checkTextureLoading();  			}  		}  		else if (layerset && isUsingLocalAppearance()) @@ -6550,7 +6649,7 @@ void LLVOAvatar::updateMeshTextures()  				if (mesh)  				{  					mesh->setLayerSet( layerset ); -			} +				}  			}  		}  		else @@ -6572,7 +6671,7 @@ void LLVOAvatar::updateMeshTextures()  		{  			LLAvatarJointMesh* mesh = (*iter);  			if (mesh) -		{ +			{  				mesh->setColor( color );  				mesh->setTexture( hair_img );  			} @@ -6668,13 +6767,13 @@ void LLVOAvatar::applyMorphMask(U8* tex_data, S32 width, S32 height, S32 num_com  	for (morph_list_t::const_iterator iter = mBakedTextureDatas[index].mMaskedMorphs.begin();  		 iter != mBakedTextureDatas[index].mMaskedMorphs.end(); ++iter) -{ +	{  		const LLMaskedMorph* maskedMorph = (*iter);  		LLPolyMorphTarget* morph_target = dynamic_cast<LLPolyMorphTarget*>(maskedMorph->mMorphTarget);  		if (morph_target) -	{ +		{  			morph_target->applyMask(tex_data, width, height, num_components, maskedMorph->mInvert); -} +		}  	}  } @@ -6973,9 +7072,9 @@ void LLVOAvatar::dumpAppearanceMsgParams( const std::string& dump_prefix,  	outfile.open(fullpath, LL_APR_WB );  	apr_file_t* file = outfile.getFileHandle();  	if (!file) -		{ -			return; -		} +	{ +		return; +	}  	else  	{  		LL_DEBUGS("Avatar") << "dumping appearance message to " << fullpath << LL_ENDL; @@ -7010,7 +7109,7 @@ void LLVOAvatar::dumpAppearanceMsgParams( const std::string& dump_prefix,  		apr_file_printf( file, "\t\t<texture te=\"%i\" uuid=\"%s\"/>\n", i, uuid_str.c_str());  	}  	apr_file_printf(file, "</textures>\n"); -	} +}  void LLVOAvatar::parseAppearanceMessage(LLMessageSystem* mesgsys, LLAppearanceMessageContents& contents)  { @@ -7539,12 +7638,12 @@ void LLVOAvatar::useBakedTexture( const LLUUID& id )  				avatar_joint_mesh_list_t::iterator iter = mBakedTextureDatas[i].mJointMeshes.begin();  				avatar_joint_mesh_list_t::iterator end  = mBakedTextureDatas[i].mJointMeshes.end();  				for (; iter != end; ++iter) -			{ +				{  					LLAvatarJointMesh* mesh = (*iter);  					if (mesh) -			{ +					{  						mesh->setTexture( image_baked ); -			} +					}  				}  			} @@ -7568,14 +7667,13 @@ void LLVOAvatar::useBakedTexture( const LLUUID& id )  				{  					LLAvatarJointMesh* mesh = (*iter);  					if (mesh) -				{ +					{  						mesh->setColor( LLColor4::white );  					}  				}  			}  		}  	} -  	dirtyMesh();  } @@ -7587,7 +7685,7 @@ std::string get_sequential_numbered_file_name(const std::string& prefix,  	file_num_type::iterator it = file_nums.find(prefix);  	S32 num = 0;  	if (it != file_nums.end()) -{ +	{  		num = it->second;  	}  	file_nums[prefix] = num+1; @@ -7620,44 +7718,61 @@ void LLVOAvatar::dumpArchetypeXML(const std::string& prefix, bool group_by_weara  	LLAPRFile outfile;  	std::string fullpath = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,outfilename); -	outfile.open(fullpath, LL_APR_WB ); -	apr_file_t* file = outfile.getFileHandle(); -	if (!file) -	{ -		return; -	} -	else +	if (APR_SUCCESS == outfile.open(fullpath, LL_APR_WB ))  	{ +		apr_file_t* file = outfile.getFileHandle();  		LL_INFOS() << "xmlfile write handle obtained : " << fullpath << LL_ENDL; -	} -	apr_file_printf( file, "<?xml version=\"1.0\" encoding=\"US-ASCII\" standalone=\"yes\"?>\n" ); -	apr_file_printf( file, "<linden_genepool version=\"1.0\">\n" ); -	apr_file_printf( file, "\n\t<archetype name=\"???\">\n" ); +		apr_file_printf( file, "<?xml version=\"1.0\" encoding=\"US-ASCII\" standalone=\"yes\"?>\n" ); +		apr_file_printf( file, "<linden_genepool version=\"1.0\">\n" ); +		apr_file_printf( file, "\n\t<archetype name=\"???\">\n" ); -	if (group_by_wearables) -	{ -		for (S32 type = LLWearableType::WT_SHAPE; type < LLWearableType::WT_COUNT; type++) -	{ -		const std::string& wearable_name = LLWearableType::getTypeName((LLWearableType::EType)type); -		apr_file_printf( file, "\n\t\t<!-- wearable: %s -->\n", wearable_name.c_str() ); - -			for (LLVisualParam* param = getFirstVisualParam(); param; param = getNextVisualParam()) +		if (group_by_wearables)  		{ -			LLViewerVisualParam* viewer_param = (LLViewerVisualParam*)param; -			if( (viewer_param->getWearableType() == type) &&  -				(viewer_param->isTweakable() ) ) +			for (S32 type = LLWearableType::WT_SHAPE; type < LLWearableType::WT_COUNT; type++)  			{ -					dump_visual_param(file, viewer_param, viewer_param->getWeight()); +				const std::string& wearable_name = LLWearableType::getTypeName((LLWearableType::EType)type); +				apr_file_printf( file, "\n\t\t<!-- wearable: %s -->\n", wearable_name.c_str() ); + +				for (LLVisualParam* param = getFirstVisualParam(); param; param = getNextVisualParam()) +				{ +					LLViewerVisualParam* viewer_param = (LLViewerVisualParam*)param; +					if( (viewer_param->getWearableType() == type) &&  +					   (viewer_param->isTweakable() ) ) +					{ +						dump_visual_param(file, viewer_param, viewer_param->getWeight()); +					} +				} + +				for (U8 te = 0; te < TEX_NUM_INDICES; te++) +				{ +					if (LLAvatarAppearanceDictionary::getTEWearableType((ETextureIndex)te) == type) +					{ +						// MULTIPLE_WEARABLES: extend to multiple wearables? +						LLViewerTexture* te_image = getImage((ETextureIndex)te, 0); +						if( te_image ) +						{ +							std::string uuid_str; +							te_image->getID().toString( uuid_str ); +							apr_file_printf( file, "\t\t<texture te=\"%i\" uuid=\"%s\"/>\n", te, uuid_str.c_str()); +						} +					} +				}  			}  		} - -		for (U8 te = 0; te < TEX_NUM_INDICES; te++) +		else   		{ -				if (LLAvatarAppearanceDictionary::getTEWearableType((ETextureIndex)te) == type) +			// Just dump all params sequentially. +			for (LLVisualParam* param = getFirstVisualParam(); param; param = getNextVisualParam()) +			{ +				LLViewerVisualParam* viewer_param = (LLViewerVisualParam*)param; +				dump_visual_param(file, viewer_param, viewer_param->getWeight()); +			} + +			for (U8 te = 0; te < TEX_NUM_INDICES; te++)  			{  				// MULTIPLE_WEARABLES: extend to multiple wearables? -					LLViewerTexture* te_image = getImage((ETextureIndex)te, 0); +				LLViewerTexture* te_image = getImage((ETextureIndex)te, 0);  				if( te_image )  				{  					std::string uuid_str; @@ -7666,51 +7781,48 @@ void LLVOAvatar::dumpArchetypeXML(const std::string& prefix, bool group_by_weara  				}  			}  		} -	} -		} -	else  -	{ -		// Just dump all params sequentially. -		for (LLVisualParam* param = getFirstVisualParam(); param; param = getNextVisualParam()) + +		avatar_joint_list_t::iterator iter = mSkeleton.begin(); +		avatar_joint_list_t::iterator end  = mSkeleton.end(); +		for (; iter != end; ++iter)  		{ -			LLViewerVisualParam* viewer_param = (LLViewerVisualParam*)param; -			dump_visual_param(file, viewer_param, viewer_param->getWeight()); +			LLJoint* pJoint = (*iter); +			const LLVector3& pos = pJoint->getPosition(); +			const LLVector3& scale = pJoint->getScale(); +			apr_file_printf( file, "\t\t<joint name=\"%s\" position=\"%f %f %f\" scale=\"%f %f %f\"/>\n",  +							 pJoint->getName().c_str(), pos[0], pos[1], pos[2], scale[0], scale[1], scale[2]);  		} -		for (U8 te = 0; te < TEX_NUM_INDICES; te++) +		for (iter = mSkeleton.begin(); iter != end; ++iter)  		{ +			LLJoint* pJoint = (*iter); +		 +			LLVector3 pos; +			LLUUID mesh_id; + +			if (pJoint->hasAttachmentPosOverride(pos,mesh_id))  			{ -				// MULTIPLE_WEARABLES: extend to multiple wearables? -				LLViewerTexture* te_image = getImage((ETextureIndex)te, 0); -				if( te_image ) -				{ -					std::string uuid_str; -					te_image->getID().toString( uuid_str ); -					apr_file_printf( file, "\t\t<texture te=\"%i\" uuid=\"%s\"/>\n", te, uuid_str.c_str()); -				} +				apr_file_printf( file, "\t\t<joint_offset name=\"%s\" position=\"%f %f %f\" mesh_id=\"%s\"/>\n",  +								 pJoint->getName().c_str(), pos[0], pos[1], pos[2], mesh_id.asString().c_str());  			}  		} +		F32 pelvis_fixup; +		LLUUID mesh_id; +		if (hasPelvisFixup(pelvis_fixup, mesh_id)) +		{ +			apr_file_printf( file, "\t\t<pelvis_fixup z=\"%f\" mesh_id=\"%s\"/>\n",  +							 pelvis_fixup, mesh_id.asString().c_str()); +		} -	} -	avatar_joint_list_t::iterator iter = mSkeleton.begin(); -	avatar_joint_list_t::iterator end  = mSkeleton.end(); -	for (; iter != end; ++iter) -	{ -		LLJoint* pJoint = (*iter); -		const LLVector3& pos = pJoint->getPosition(); -		const LLVector3& scale = pJoint->getScale(); -		apr_file_printf( file, "\t\t<joint name=\"%s\" position=\"%f %f %f\" scale=\"%f %f %f\"/>\n",  -						 pJoint->getName().c_str(), pos[0], pos[1], pos[2], scale[0], scale[1], scale[2]); -	} - -	apr_file_printf( file, "\t</archetype>\n" ); -	apr_file_printf( file, "\n</linden_genepool>\n" ); +		apr_file_printf( file, "\t</archetype>\n" ); +		apr_file_printf( file, "\n</linden_genepool>\n" ); -	bool ultra_verbose = false; -	if (isSelf() && ultra_verbose) -	{ -		// show the cloned params inside the wearables as well. -		gAgentAvatarp->dumpWearableInfo(outfile); +		bool ultra_verbose = false; +		if (isSelf() && ultra_verbose) +		{ +			// show the cloned params inside the wearables as well. +			gAgentAvatarp->dumpWearableInfo(outfile); +		}  	}  	// File will close when handle goes out of scope  } @@ -7826,7 +7938,7 @@ void LLVOAvatar::startAppearanceAnimation()  // virtual  void LLVOAvatar::removeMissingBakedTextures() -			{ +{  }  //virtual @@ -8080,7 +8192,6 @@ void LLVOAvatar::calculateUpdateRenderCost()  					}  				}  			} -  		}  		// Diagnostic output to identify all avatar-related textures. @@ -8092,9 +8203,8 @@ void LLVOAvatar::calculateUpdateRenderCost()  			for (LLVOVolume::texture_cost_t::iterator it = textures.begin(); it != textures.end(); ++it)  			{  				LLUUID image_id = it->first; -				if( image_id.isNull() || image_id == IMG_DEFAULT || image_id == IMG_DEFAULT_AVATAR) -					continue; -				if (all_textures.find(image_id) == all_textures.end()) +				if( ! (image_id.isNull() || image_id == IMG_DEFAULT || image_id == IMG_DEFAULT_AVATAR) +				   && (all_textures.find(image_id) == all_textures.end()))  				{  					// attachment texture not previously seen.  					LL_INFOS() << "attachment_texture: " << image_id.asString() << LL_ENDL; @@ -8160,15 +8270,17 @@ LLColor4 LLVOAvatar::calcMutedAVColor(F32 value, S32 range_low, S32 range_high)  // static  BOOL LLVOAvatar::isIndexLocalTexture(ETextureIndex index)  { -	if (index < 0 || index >= TEX_NUM_INDICES) return false; -	return LLAvatarAppearanceDictionary::getInstance()->getTexture(index)->mIsLocalTexture; +	return (index < 0 || index >= TEX_NUM_INDICES) +		? false +		: LLAvatarAppearanceDictionary::getInstance()->getTexture(index)->mIsLocalTexture;  }  // static  BOOL LLVOAvatar::isIndexBakedTexture(ETextureIndex index)  { -	if (index < 0 || index >= TEX_NUM_INDICES) return false; -	return LLAvatarAppearanceDictionary::getInstance()->getTexture(index)->mIsBakedTexture; +	return (index < 0 || index >= TEX_NUM_INDICES) +		? false +		: LLAvatarAppearanceDictionary::getInstance()->getTexture(index)->mIsBakedTexture;  }  const std::string LLVOAvatar::getBakedStatusForPrintout() const @@ -8218,7 +8330,7 @@ BOOL LLVOAvatar::isTextureDefined(LLAvatarAppearanceDefines::ETextureIndex te, U  	{  		return FALSE;  	} - +	  	if( !getImage( te, index ) )  	{  		LL_WARNS() << "getImage( " << te << ", " << index << " ) returned 0" << LL_ENDL; diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index 0fde732b6f..2223acc893 100755 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -200,7 +200,10 @@ public:  	virtual LLJoint*		getJoint(const std::string &name); +	void 					addAttachmentPosOverridesForObject(LLViewerObject *vo);  	void					resetJointPositionsOnDetach(const LLUUID& mesh_id); +	void					resetJointPositionsOnDetach(LLViewerObject *vo); +	void					clearAttachmentPosOverrides();  	/*virtual*/ const LLUUID&	getID() const;  	/*virtual*/ void			addDebugText(const std::string& text); @@ -357,19 +360,11 @@ protected:  	/*virtual*/ LLAvatarJointMesh*	createAvatarJointMesh(); // Returns LLViewerJointMesh  public:  	void				updateHeadOffset(); -	void				setPelvisOffset( bool hasOffset, const LLVector3& translation, F32 offset ) ; -	bool				hasPelvisOffset( void ) { return mHasPelvisOffset; }  	void				postPelvisSetRecalc( void ); -	void				setPelvisOffset( F32 pelvixFixupAmount );  	/*virtual*/ BOOL	loadSkeletonNode();  	/*virtual*/ void	buildCharacter(); -	bool				mHasPelvisOffset; -	LLVector3			mPelvisOffset; -	F32					mLastPelvisToFoot; -	F32					mPelvisFixup; -	F32					mLastPelvisFixup;  	LLVector3			mCurRootToHeadOffset;  	LLVector3			mTargetRootToHeadOffset; @@ -720,6 +715,7 @@ public:  	void 				clampAttachmentPositions();  	virtual const LLViewerJointAttachment* attachObject(LLViewerObject *viewer_object);  	virtual BOOL 		detachObject(LLViewerObject *viewer_object); +	static bool		    getRiggedMeshID( LLViewerObject* pVO, LLUUID& mesh_id );  	void				cleanupAttachedMesh( LLViewerObject* pVO );  	static LLVOAvatar*  findAvatarFromAttachment(LLViewerObject* obj);  	/*virtual*/ BOOL	isWearingWearableType(LLWearableType::EType type ) const; diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp index 02494d5091..3f3cd25f95 100755 --- a/indra/newview/llvoavatarself.cpp +++ b/indra/newview/llvoavatarself.cpp @@ -262,7 +262,7 @@ void LLVOAvatarSelf::markDead()  {  	BOOL success = LLVOAvatar::loadAvatar(); -	// set all parameters sotred directly in the avatar to have +	// set all parameters stored directly in the avatar to have  	// the isSelfParam to be TRUE - this is used to prevent  	// them from being animated or trigger accidental rebakes  	// when we copy params from the wearable to the base avatar. @@ -718,13 +718,8 @@ void LLVOAvatarSelf::updateVisualParams()  	LLVOAvatar::updateVisualParams();  } -/*virtual*/ -void LLVOAvatarSelf::idleUpdateAppearanceAnimation() +void LLVOAvatarSelf::writeWearablesToAvatar()  { -	// Animate all top-level wearable visual parameters -	gAgentWearables.animateAllWearableParams(calcMorphAmount()); - -	// apply wearable visual params to avatar  	for (U32 type = 0; type < LLWearableType::WT_COUNT; type++)  	{  		LLWearable *wearable = gAgentWearables.getTopWearable((LLWearableType::EType)type); @@ -734,6 +729,17 @@ void LLVOAvatarSelf::idleUpdateAppearanceAnimation()  		}  	} +} + +/*virtual*/ +void LLVOAvatarSelf::idleUpdateAppearanceAnimation() +{ +	// Animate all top-level wearable visual parameters +	gAgentWearables.animateAllWearableParams(calcMorphAmount()); + +	// Apply wearable visual params to avatar +	writeWearablesToAvatar(); +  	//allow avatar to process updates  	LLVOAvatar::idleUpdateAppearanceAnimation(); @@ -1101,9 +1107,19 @@ LLViewerObject* LLVOAvatarSelf::getWornAttachment(const LLUUID& inv_item_id)  	return NULL;  } -const std::string LLVOAvatarSelf::getAttachedPointName(const LLUUID& inv_item_id) const +bool LLVOAvatarSelf::getAttachedPointName(const LLUUID& inv_item_id, std::string& name) const  { +	if (!gInventory.getItem(inv_item_id)) +	{ +		name = "ATTACHMENT_MISSING_ITEM"; +		return false; +	}  	const LLUUID& base_inv_item_id = gInventory.getLinkedItemID(inv_item_id); +	if (!gInventory.getItem(base_inv_item_id)) +	{ +		name = "ATTACHMENT_MISSING_BASE_ITEM"; +		return false; +	}  	for (attachment_map_t::const_iterator iter = mAttachmentPoints.begin();   		 iter != mAttachmentPoints.end();   		 ++iter) @@ -1111,11 +1127,13 @@ const std::string LLVOAvatarSelf::getAttachedPointName(const LLUUID& inv_item_id  		const LLViewerJointAttachment* attachment = iter->second;  		if (attachment->getAttachedObject(base_inv_item_id))  		{ -			return attachment->getName(); +			name = attachment->getName(); +			return true;  		}  	} -	return LLStringUtil::null; +	name = "ATTACHMENT_NOT_ATTACHED"; +	return false;  }  //virtual @@ -1150,8 +1168,6 @@ BOOL LLVOAvatarSelf::detachObject(LLViewerObject *viewer_object)  	const LLUUID attachment_id = viewer_object->getAttachmentItemID();  	if ( LLVOAvatar::detachObject(viewer_object) )  	{ -		LLVOAvatar::cleanupAttachedMesh( viewer_object ); -		  		// the simulator should automatically handle permission revocation  		stopMotionFromSource(attachment_id); diff --git a/indra/newview/llvoavatarself.h b/indra/newview/llvoavatarself.h index ad73dd89b7..5f36872575 100755 --- a/indra/newview/llvoavatarself.h +++ b/indra/newview/llvoavatarself.h @@ -87,12 +87,11 @@ public:  	/*virtual*/ void 		requestStopMotion(LLMotion* motion);  	/*virtual*/ LLJoint*	getJoint(const std::string &name); -				void		resetJointPositions( void ); -	  	/*virtual*/ BOOL setVisualParamWeight(const LLVisualParam *which_param, F32 weight);  	/*virtual*/ BOOL setVisualParamWeight(const char* param_name, F32 weight);  	/*virtual*/ BOOL setVisualParamWeight(S32 index, F32 weight);  	/*virtual*/ void updateVisualParams(); +	void writeWearablesToAvatar();  	/*virtual*/ void idleUpdateAppearanceAnimation();  private: @@ -294,7 +293,7 @@ public:  	void				addAttachmentRequest(const LLUUID& inv_item_id);  	void				removeAttachmentRequest(const LLUUID& inv_item_id);  	LLViewerObject* 	getWornAttachment(const LLUUID& inv_item_id); -	const std::string   getAttachedPointName(const LLUUID& inv_item_id) const; +	bool				getAttachedPointName(const LLUUID& inv_item_id, std::string& name) const;  	/*virtual*/ const LLViewerJointAttachment *attachObject(LLViewerObject *viewer_object);  	/*virtual*/ BOOL 	detachObject(LLViewerObject *viewer_object);  	static BOOL			detachAttachmentIntoInventory(const LLUUID& item_id); diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 6839bed761..008ef792e0 100755 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -4541,7 +4541,9 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)  	//Determine if we've received skininfo that contains an  	//alternate bind matrix - if it does then apply the translational component  	//to the joints of the avatar. +#if 0  	bool pelvisGotSet = false; +#endif  	{  		LL_RECORD_BLOCK_TIME(FTM_REBUILD_VOLUME_FACE_LIST); @@ -4626,54 +4628,12 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)  					//get drawpool of avatar with rigged face  					LLDrawPoolAvatar* pool = get_avatar_drawpool(vobj);				 +					// FIXME should this be inside the face loop? +					// doesn't seem to depend on any per-face state.  					if ( pAvatarVO )  					{ -						LLUUID currentId = vobj->getVolume()->getParams().getSculptID();						 -						const LLMeshSkinInfo*  pSkinData = gMeshRepo.getSkinInfo( currentId, vobj ); -						if ( pSkinData ) -						{ -							const int bindCnt = pSkinData->mAlternateBindMatrix.size();								 -							if ( bindCnt > 0 ) -							{					 -								const int jointCnt = pSkinData->mJointNames.size(); -								const F32 pelvisZOffset = pSkinData->mPelvisOffset; -								bool fullRig = (jointCnt>=JOINT_COUNT_REQUIRED_FOR_FULLRIG) ? true : false;								 -								if ( fullRig ) -								{								 -									for ( int i=0; i<jointCnt; ++i ) -									{ -										std::string lookingForJoint = pSkinData->mJointNames[i].c_str(); -										LLJoint* pJoint = pAvatarVO->getJoint( lookingForJoint ); -										if ( pJoint && pJoint->getId() != currentId ) -										{   									 -											pJoint->setId( currentId ); -											const LLVector3& jointPos = pSkinData->mAlternateBindMatrix[i].getTranslation();									 -											 -											//Set the joint position -											const LLUUID& mesh_id = pSkinData->mMeshID; -											pJoint->addAttachmentPosOverride( jointPos, mesh_id, pAvatarVO->avString() ); -									 -											//If joint is a pelvis then handle old/new pelvis to foot values -											if ( lookingForJoint == "mPelvis" ) -											{	 -												if ( !pAvatarVO->hasPelvisOffset() ) -												{										 -													pAvatarVO->setPelvisOffset( true, jointPos, pelvisZOffset ); -													pelvisGotSet = true;											 -												}										 -											}										 -										}										 -									}																 -								}							 -							} -						} +						pAvatarVO->addAttachmentPosOverridesForObject(vobj);  					} -					 -					//Rebuild body data if we altered joints/pelvis -					if ( pelvisGotSet && pAvatarVO )  -					{ -						pAvatarVO->postPelvisSetRecalc(); -					}		  					if (pool)  					{ @@ -5031,14 +4991,6 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)  			}  		} - -		 -		 -			 -		 -					 - -		  	}  	group->mBufferUsage = useage; diff --git a/indra/newview/llwearableitemslist.cpp b/indra/newview/llwearableitemslist.cpp index ca60b79f9d..fac0fd63ee 100755 --- a/indra/newview/llwearableitemslist.cpp +++ b/indra/newview/llwearableitemslist.cpp @@ -364,8 +364,14 @@ void LLPanelAttachmentListItem::updateItem(const std::string& name,  	LLViewerInventoryItem* inv_item = getItem();  	if (inv_item && isAgentAvatarValid() && gAgentAvatarp->isWearingAttachment(inv_item->getLinkedUUID()))  	{ -		std::string joint = LLTrans::getString(gAgentAvatarp->getAttachedPointName(inv_item->getLinkedUUID())); -		title_joint =  title_joint + " (" + joint + ")"; +		std::string found_name; +		bool found = gAgentAvatarp->getAttachedPointName(inv_item->getLinkedUUID(),found_name); +		std::string trans_name = LLTrans::getString(found_name); +		if (!found) +		{ +			LL_WARNS() << "invalid attachment joint, err " << found_name << LL_ENDL; +		} +		title_joint =  title_joint + " (" + trans_name + ")";  	}  	LLPanelInventoryListItemBase::updateItem(title_joint, item_state); diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index cc2f645b8e..f77678e5f8 100755 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -2307,6 +2307,7 @@ The [[MARKETPLACE_CREATE_STORE_URL] Marketplace store] is returning errors.  	<string name="LoadingContents">Loading contents...</string>  	<string name="NoContents">No contents</string>  	<string name="WornOnAttachmentPoint" value=" (worn on [ATTACHMENT_POINT])" /> +	<string name="AttachmentErrorMessage" value=" ([ATTACHMENT_ERROR])" />  	<string name="ActiveGesture" value="[GESLABEL] (active)"/>  	<!-- Inventory permissions -->  	<string name="PermYes">Yes</string> @@ -2433,9 +2434,12 @@ The [[MARKETPLACE_CREATE_STORE_URL] Marketplace store] is returning errors.  	<string name="Stomach">Stomach</string>  	<string name="Left Pec">Left Pec</string>  	<string name="Right Pec">Right Pec</string> -    <string name="Neck">Neck</string> -    <string name="Avatar Center">Avatar Center</string> +        <string name="Neck">Neck</string> +        <string name="Avatar Center">Avatar Center</string>  	<string name="Invalid Attachment">Invalid Attachment Point</string> +	<string name="ATTACHMENT_MISSING_ITEM">Error: missing item</string> +	<string name="ATTACHMENT_MISSING_BASE_ITEM">Error: missing base item</string> +	<string name="ATTACHMENT_NOT_ATTACHED">Error: object is in current outfit but not attached</string>    <!-- Avatar age computation, see LLDateUtil::ageFromDate -->    <string name="YearsMonthsOld">[AGEYEARS] [AGEMONTHS] old</string>  | 
