Merge LL V3.7.21
commit
99cbf150a0
2
.hgtags
2
.hgtags
|
|
@ -522,3 +522,5 @@ a7872554f3665588f1e8347d472cec3a299254b3 3.7.14-release
|
|||
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
|
||||
|
|
|
|||
|
|
@ -324,6 +324,7 @@ Cinder Roxley
|
|||
STORM-2035
|
||||
STORM-2036
|
||||
STORM-2037
|
||||
STORM-2053
|
||||
Clara Young
|
||||
Coaldust Numbers
|
||||
VWR-1095
|
||||
|
|
@ -889,6 +890,8 @@ Mm Alder
|
|||
VWR-4794
|
||||
VWR-13578
|
||||
Mo Hax
|
||||
Moon Metty
|
||||
STORM-2078
|
||||
Mourna Biziou
|
||||
Mr Greggan
|
||||
VWR-445
|
||||
|
|
@ -993,6 +996,7 @@ Nicky Perian
|
|||
STORM-1087
|
||||
STORM-1090
|
||||
STORM-1828
|
||||
STORM-2080
|
||||
Nicoladie Gymnast
|
||||
NiranV Dean
|
||||
STORM-2040
|
||||
|
|
@ -1053,6 +1057,11 @@ Peekay Semyorka
|
|||
VWR-19
|
||||
VWR-49
|
||||
VWR-79
|
||||
Pell Smit
|
||||
STORM-2069
|
||||
STORM-2070
|
||||
STORM-2071
|
||||
STORM-2072
|
||||
Peter Lameth
|
||||
VWR-7331
|
||||
PeterPunk Mooney
|
||||
|
|
@ -1399,6 +1408,7 @@ Whirly Fizzle
|
|||
MAINT-873
|
||||
STORM-1930
|
||||
BUG-6659
|
||||
STORM-2078
|
||||
Whoops Babii
|
||||
VWR-631
|
||||
VWR-1640
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -79,6 +79,7 @@
|
|||
@interface LLNonInlineTextView : NSTextView
|
||||
{
|
||||
LLOpenGLView *glview;
|
||||
unichar mKeyPressed;
|
||||
}
|
||||
|
||||
- (void) setGLView:(LLOpenGLView*)view;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -284,53 +284,46 @@ attributedStringInfo getSegments(NSAttributedString *str)
|
|||
|
||||
- (void) mouseDown:(NSEvent *)theEvent
|
||||
{
|
||||
mModifiers = [theEvent modifierFlags]; // <FS:ND/> Make sure we're grabbing current modifiers, or they might get stuck until another one is pressed.
|
||||
|
||||
// Apparently people still use this?
|
||||
if ([theEvent modifierFlags] & NSCommandKeyMask &&
|
||||
!([theEvent modifierFlags] & (NSControlKeyMask | NSShiftKeyMask
|
||||
| NSAlternateKeyMask | NSAlphaShiftKeyMask
|
||||
| NSFunctionKeyMask | NSHelpKeyMask)
|
||||
)
|
||||
)
|
||||
{
|
||||
callRightMouseDown(mMousePos, mModifiers);
|
||||
!([theEvent modifierFlags] & NSControlKeyMask) &&
|
||||
!([theEvent modifierFlags] & NSShiftKeyMask) &&
|
||||
!([theEvent modifierFlags] & NSAlternateKeyMask) &&
|
||||
!([theEvent modifierFlags] & NSAlphaShiftKeyMask) &&
|
||||
!([theEvent modifierFlags] & NSFunctionKeyMask) &&
|
||||
!([theEvent modifierFlags] & NSHelpKeyMask))
|
||||
{
|
||||
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]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void) mouseUp:(NSEvent *)theEvent
|
||||
{
|
||||
mModifiers = [theEvent modifierFlags]; // <FS:ND/> Make sure we're grabbing current modifiers, or they might get stuck until another one is pressed.
|
||||
|
||||
if (mSimulatedRightClick)
|
||||
{
|
||||
callRightMouseUp(mMousePos, mModifiers);
|
||||
callRightMouseUp(mMousePos, [theEvent modifierFlags]);
|
||||
mSimulatedRightClick = false;
|
||||
} else {
|
||||
callLeftMouseUp(mMousePos, mModifiers);
|
||||
callLeftMouseUp(mMousePos, [theEvent modifierFlags]);
|
||||
}
|
||||
}
|
||||
|
||||
- (void) rightMouseDown:(NSEvent *)theEvent
|
||||
{
|
||||
mModifiers = [theEvent modifierFlags]; // <FS:ND/> Make sure we're grabbing current modifiers, or they might get stuck until another one is pressed.
|
||||
|
||||
callRightMouseDown(mMousePos, mModifiers);
|
||||
callRightMouseDown(mMousePos, [theEvent modifierFlags]);
|
||||
}
|
||||
|
||||
- (void) rightMouseUp:(NSEvent *)theEvent
|
||||
{
|
||||
mModifiers = [theEvent modifierFlags]; // <FS:ND/> Make sure we're grabbing current modifiers, or they might get stuck until another one is pressed.
|
||||
|
||||
callRightMouseUp(mMousePos, mModifiers);
|
||||
callRightMouseUp(mMousePos, [theEvent modifierFlags]);
|
||||
}
|
||||
|
||||
// <FS:LO> Fix FIRE-14282/BUG-6875 with the solution provided in LL's jira.
|
||||
|
|
@ -378,16 +371,12 @@ attributedStringInfo getSegments(NSAttributedString *str)
|
|||
|
||||
- (void) otherMouseDown:(NSEvent *)theEvent
|
||||
{
|
||||
mModifiers = [theEvent modifierFlags]; // <FS:ND/> Make sure we're grabbing current modifiers, or they might get stuck until another one is pressed.
|
||||
|
||||
callMiddleMouseDown(mMousePos, mModifiers);
|
||||
callMiddleMouseDown(mMousePos, [theEvent modifierFlags]);
|
||||
}
|
||||
|
||||
- (void) otherMouseUp:(NSEvent *)theEvent
|
||||
{
|
||||
mModifiers = [theEvent modifierFlags]; // <FS:ND/> Make sure we're grabbing current modifiers, or they might get stuck until another one is pressed.
|
||||
|
||||
callMiddleMouseUp(mMousePos, mModifiers);
|
||||
callMiddleMouseUp(mMousePos, [theEvent modifierFlags]);
|
||||
}
|
||||
|
||||
- (void) otherMouseDragged:(NSEvent *)theEvent
|
||||
|
|
@ -407,33 +396,41 @@ attributedStringInfo getSegments(NSAttributedString *str)
|
|||
|
||||
- (void) keyUp:(NSEvent *)theEvent
|
||||
{
|
||||
mModifiers = [theEvent modifierFlags]; // <FS:ND/> Make sure we're grabbing current modifiers, or they might get stuck until another one is pressed.
|
||||
|
||||
callKeyUp([theEvent keyCode], mModifiers);
|
||||
callKeyUp([theEvent keyCode], [theEvent modifierFlags]);
|
||||
}
|
||||
|
||||
- (void) keyDown:(NSEvent *)theEvent
|
||||
{
|
||||
mModifiers = [theEvent modifierFlags]; // <FS:ND/> Make sure we're grabbing current modifiers, or they might get stuck until another one is pressed.
|
||||
|
||||
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
|
||||
} else
|
||||
{
|
||||
[[self inputContext] handleEvent:theEvent];
|
||||
}
|
||||
|
||||
// OS X intentionally does not send us key-up information on cmd-key combinations.
|
||||
// This behaviour is not a bug, and only applies to cmd-combinations (no others).
|
||||
// Since SL assumes we receive those, we fake it here.
|
||||
if (mModifiers & NSCommandKeyMask && !mHasMarkedText)
|
||||
{
|
||||
callKeyUp([theEvent keyCode], mModifiers);
|
||||
}
|
||||
}
|
||||
|
||||
- (void)flagsChanged:(NSEvent *)theEvent
|
||||
|
|
@ -536,31 +533,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];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -626,7 +650,9 @@ attributedStringInfo getSegments(NSAttributedString *str)
|
|||
|
||||
- (void) insertNewline:(id)sender
|
||||
{
|
||||
if (!(mModifiers & (NSCommandKeyMask | NSShiftKeyMask | NSAlternateKeyMask)))
|
||||
if (!(mModifiers & NSCommandKeyMask) &&
|
||||
!(mModifiers & NSShiftKeyMask) &&
|
||||
!(mModifiers & NSAlternateKeyMask))
|
||||
{
|
||||
callUnicodeCallback(13, 0);
|
||||
} else {
|
||||
|
|
@ -677,37 +703,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];
|
||||
}
|
||||
|
||||
// setMarkedText: is called for incomplete input(on the way to conversion).
|
||||
- (void)setMarkedText:(id)aString selectedRange:(NSRange)selectedRange replacementRange:(NSRange)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
|
||||
}
|
||||
}
|
||||
|
||||
// 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
|
||||
{
|
||||
[glview insertText:aString replacementRange:replacementRange];
|
||||
}
|
||||
|
||||
- (void) insertNewline:(id)sender
|
||||
{
|
||||
[[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
|
||||
|
|
|
|||
|
|
@ -1861,8 +1861,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
|
||||
|
|
@ -1892,6 +1890,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()
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 * envIntensity;
|
||||
col += color.rgb * texture2DLodSpecular(projectionMap, stc.xy, (1 - spec.a) * (proj_lod * 0.6)).rgb * envIntensity;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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).rgb * envIntensity;
|
||||
col += color.rgb * texture2DLodSpecular(projectionMap, stc.xy, (1 - spec.a) * (proj_lod * 0.6)).rgb * envIntensity;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 * envIntensity;
|
||||
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));
|
||||
|
|
|
|||
|
|
@ -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).rgb * shadow * envIntensity;
|
||||
col += color.rgb * texture2DLodSpecular(projectionMap, stc.xy, (1 - spec.a) * (proj_lod * 0.6)).rgb * shadow * envIntensity;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1751,10 +1751,8 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, LLFace*
|
|||
{
|
||||
F32 w = weight[j][k];
|
||||
|
||||
// <FS:ND> proper bounds checking, the maximum changed from 64 to 52(JOINT_COUNT).
|
||||
// idx[k] = llclamp((S32) floorf(w), 0, 63);
|
||||
idx[k] = llclamp((S32) floorf(w), 0, JOINT_COUNT-1);
|
||||
// </FS:ND>
|
||||
|
||||
|
||||
wght[k] = w - floorf(w);
|
||||
scale += wght[k];
|
||||
|
|
|
|||
|
|
@ -671,6 +671,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;
|
||||
|
|
@ -782,7 +785,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 = "\?\?\?\?";
|
||||
|
|
@ -1230,6 +1240,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",
|
||||
|
|
@ -1450,6 +1466,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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -475,7 +475,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 )
|
||||
{
|
||||
|
|
@ -831,14 +834,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");
|
||||
}
|
||||
}
|
||||
|
||||
// <FS:ND> only call logPendingPhases if we're still alive. Otherwise this can lead to shutdown crashes
|
||||
|
||||
|
|
@ -997,10 +1000,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]++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1410,38 +1414,36 @@ void LLVOAvatar::getSpatialExtents(LLVector4a& newMin, LLVector4a& newMax)
|
|||
{
|
||||
LLViewerJointAttachment* attachment = iter->second;
|
||||
|
||||
if (!attachment->getValid())
|
||||
if (attachment->getValid())
|
||||
{
|
||||
continue ;
|
||||
}
|
||||
|
||||
for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
|
||||
attachment_iter != attachment->mAttachedObjects.end();
|
||||
++attachment_iter)
|
||||
{
|
||||
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);
|
||||
|
||||
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)
|
||||
LLSpatialBridge* bridge = drawable->getSpatialBridge();
|
||||
if (bridge)
|
||||
{
|
||||
update_min_max(newMin,newMax,ext[0]);
|
||||
update_min_max(newMin,newMax,ext[1]);
|
||||
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;
|
||||
|
||||
// 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]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2027,7 +2029,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)
|
||||
|
|
@ -2039,9 +2041,6 @@ U32 LLVOAvatar::processUpdateMessage(LLMessageSystem *mesgsys,
|
|||
}
|
||||
}
|
||||
|
||||
//LL_INFOS() << getRotation() << LL_ENDL;
|
||||
//LL_INFOS() << getPosition() << LL_ENDL;
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
|
@ -2057,7 +2056,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())
|
||||
|
|
@ -3720,7 +3719,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;
|
||||
}
|
||||
// <FS:Zi> Optionally disable the usage of timesteps, testing if this affects performance or
|
||||
// creates animation issues - FIRE-3657
|
||||
|
|
@ -3872,7 +3871,6 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)
|
|||
fwdDir.normalize();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
LLQuaternion root_rotation = mRoot->getWorldMatrix().quaternion();
|
||||
|
|
@ -3988,10 +3986,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();
|
||||
|
||||
|
|
@ -4092,10 +4094,6 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)
|
|||
|
||||
//mesh vertices need to be reskinned
|
||||
mNeedsSkin = TRUE;
|
||||
|
||||
|
||||
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
@ -4375,13 +4373,13 @@ U32 LLVOAvatar::renderSkinned()
|
|||
if (face)
|
||||
{
|
||||
LLVertexBuffer* vb = face->getVertexBuffer();
|
||||
if (vb)
|
||||
{
|
||||
vb->flush();
|
||||
if (vb)
|
||||
{
|
||||
vb->flush();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mNeedsSkin = FALSE;
|
||||
|
|
@ -4561,7 +4559,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;
|
||||
|
|
@ -5659,8 +5657,8 @@ BOOL LLVOAvatar::loadSkeletonNode ()
|
|||
{
|
||||
if (!LLAvatarAppearance::loadSkeletonNode())
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// ATTACHMENTS
|
||||
{
|
||||
|
|
@ -6458,9 +6456,6 @@ BOOL LLVOAvatar::isWearingWearableType(LLWearableType::EType type) const
|
|||
break; // Do nothing
|
||||
}
|
||||
|
||||
/* switch(type)
|
||||
case LLWearableType::WT_SHIRT:
|
||||
indicator_te = TEX_UPPER_SHIRT; */
|
||||
|
||||
// <FS:ND> Gets called quite a lot from processObjectUpdates. Remove the frequent getInstance calls.
|
||||
|
||||
|
|
@ -6475,18 +6470,18 @@ BOOL LLVOAvatar::isWearingWearableType(LLWearableType::EType type) const
|
|||
{
|
||||
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;
|
||||
}
|
||||
|
|
@ -6556,7 +6551,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();
|
||||
|
|
@ -6627,9 +6622,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)
|
||||
{
|
||||
|
|
@ -6638,16 +6633,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;
|
||||
}
|
||||
}
|
||||
|
|
@ -6709,7 +6703,7 @@ void LLVOAvatar::stopPhase(const std::string& phase_name, bool err_check)
|
|||
void LLVOAvatar::logPendingPhases()
|
||||
{
|
||||
if (!isAgentAvatarValid())
|
||||
{
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -6725,14 +6719,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)
|
||||
{
|
||||
|
|
@ -6743,14 +6737,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;
|
||||
|
|
@ -6759,10 +6753,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;
|
||||
|
|
@ -6890,9 +6884,7 @@ void LLVOAvatar::debugColorizeSubMeshes(U32 i, const LLColor4& color)
|
|||
LLAvatarJointMesh* mesh = (*iter);
|
||||
if (mesh)
|
||||
{
|
||||
{
|
||||
mesh->setColor(color);
|
||||
}
|
||||
mesh->setColor(color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -6992,7 +6984,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;
|
||||
|
||||
|
|
@ -7001,12 +6993,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])
|
||||
|
|
@ -7035,9 +7027,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())
|
||||
|
|
@ -7056,7 +7048,7 @@ void LLVOAvatar::updateMeshTextures()
|
|||
if (mesh)
|
||||
{
|
||||
mesh->setLayerSet( layerset );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
@ -7078,7 +7070,7 @@ void LLVOAvatar::updateMeshTextures()
|
|||
{
|
||||
LLAvatarJointMesh* mesh = (*iter);
|
||||
if (mesh)
|
||||
{
|
||||
{
|
||||
mesh->setColor( color );
|
||||
mesh->setTexture( hair_img );
|
||||
}
|
||||
|
|
@ -7174,13 +7166,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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -7487,9 +7479,9 @@ void LLVOAvatar::dumpAppearanceMsgParams( const std::string& dump_prefix,
|
|||
// </FS:ND>
|
||||
|
||||
if (!file)
|
||||
{
|
||||
return;
|
||||
}
|
||||
{
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_DEBUGS("Avatar") << "dumping appearance message to " << fullpath << LL_ENDL;
|
||||
|
|
@ -7524,7 +7516,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)
|
||||
{
|
||||
|
|
@ -8074,12 +8066,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 );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -8103,14 +8095,13 @@ void LLVOAvatar::useBakedTexture( const LLUUID& id )
|
|||
{
|
||||
LLAvatarJointMesh* mesh = (*iter);
|
||||
if (mesh)
|
||||
{
|
||||
{
|
||||
mesh->setColor( LLColor4::white );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dirtyMesh();
|
||||
}
|
||||
|
||||
|
|
@ -8122,7 +8113,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;
|
||||
|
|
@ -8165,80 +8156,67 @@ void LLVOAvatar::dumpArchetypeXML(const std::string& prefix, bool group_by_weara
|
|||
LLAPRFile outfile;
|
||||
// <FS:CR> FIRE-8893 - Dump archetype xml to user defined location
|
||||
//std::string fullpath = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,outfilename);
|
||||
//outfile.open(fullpath, LL_APR_WB );
|
||||
std::string fullpath = file_picker.getFirstFile();
|
||||
outfile.open(fullpath, LL_APR_WB);
|
||||
// </FS:CR>
|
||||
|
||||
// <FS:ND> Remove LLVolatileAPRPool/apr_file_t and use FILE* instead
|
||||
//apr_file_t* file = outfile.getFileHandle();
|
||||
LLAPRFile::tFiletype* file = outfile.getFileHandle();
|
||||
// </FS:ND>
|
||||
|
||||
if (!file)
|
||||
if (APR_SUCCESS == outfile.open(fullpath, LL_APR_WB ))
|
||||
{
|
||||
// <FS:CR> FIRE-8893 - Dump archetype xml to user defined location
|
||||
LL_WARNS("DumpArchetypeXML") << "No file to dump to!" << LL_ENDL;
|
||||
// </FS:CR>
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
// <FS:CR> FIRE-8893 - Dump archetype xml to user defined location
|
||||
// <FS:ND> Remove LLVolatileAPRPool/apr_file_t and use FILE* instead
|
||||
//apr_file_t* file = outfile.getFileHandle();
|
||||
LLAPRFile::tFiletype* file = outfile.getFileHandle();
|
||||
// </FS:ND>
|
||||
|
||||
// <FS:CR> FIRE-8893 - Dump archetype xml to user defined location
|
||||
//LL_INFOS() << "xmlfile write handle obtained : " << fullpath << LL_ENDL;
|
||||
LL_INFOS("DumpArchetypeXML") << "xmlfile write handle obtained : " << fullpath << LL_ENDL;
|
||||
// </FS:CR>
|
||||
// </FS:CR>
|
||||
|
||||
}
|
||||
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 (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 )
|
||||
for (LLVisualParam* param = getFirstVisualParam(); param; param = getNextVisualParam())
|
||||
{
|
||||
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());
|
||||
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());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Just dump all params sequentially.
|
||||
for (LLVisualParam* param = getFirstVisualParam(); param; param = getNextVisualParam())
|
||||
else
|
||||
{
|
||||
LLViewerVisualParam* viewer_param = (LLViewerVisualParam*)param;
|
||||
dump_visual_param(file, viewer_param, viewer_param->getWeight());
|
||||
}
|
||||
// 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++)
|
||||
{
|
||||
for (U8 te = 0; te < TEX_NUM_INDICES; te++)
|
||||
{
|
||||
// MULTIPLE_WEARABLES: extend to multiple wearables?
|
||||
LLViewerTexture* te_image = getImage((ETextureIndex)te, 0);
|
||||
|
|
@ -8250,24 +8228,24 @@ void LLVOAvatar::dumpArchetypeXML(const std::string& prefix, bool group_by_weara
|
|||
}
|
||||
}
|
||||
}
|
||||
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);
|
||||
}
|
||||
outfile.close();
|
||||
|
||||
bool ultra_verbose = false;
|
||||
if (isSelf() && ultra_verbose)
|
||||
{
|
||||
// show the cloned params inside the wearables as well.
|
||||
gAgentAvatarp->dumpWearableInfo(outfile);
|
||||
// <FS:CR> FIRE-8893 - Dump archetype xml to user defined location
|
||||
LL_INFOS("DumpArchetypeXML") << "Archetype xml written successfully!" << LL_ENDL;
|
||||
LLSD args;
|
||||
args["FILENAME"] = fullpath;
|
||||
LLNotificationsUtil::add("DumpArchetypeSuccess", args);
|
||||
// </FS:CR>
|
||||
}
|
||||
// File will close when handle goes out of scope
|
||||
// <FS:CR> FIRE-8893 - Dump archetype xml to user defined location
|
||||
LL_INFOS("DumpArchetypeXML") << "Archetype xml written successfully!" << LL_ENDL;
|
||||
LLSD args;
|
||||
args["FILENAME"] = fullpath;
|
||||
LLNotificationsUtil::add("DumpArchetypeSuccess", args);
|
||||
// </FS:CR>
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -8381,7 +8359,7 @@ void LLVOAvatar::startAppearanceAnimation()
|
|||
|
||||
// virtual
|
||||
void LLVOAvatar::removeMissingBakedTextures()
|
||||
{
|
||||
{
|
||||
}
|
||||
|
||||
//virtual
|
||||
|
|
@ -8635,7 +8613,6 @@ void LLVOAvatar::calculateUpdateRenderCost()
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Diagnostic output to identify all avatar-related textures.
|
||||
|
|
@ -8647,9 +8624,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;
|
||||
|
|
@ -8715,15 +8691,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
|
||||
|
|
@ -8773,7 +8751,7 @@ BOOL LLVOAvatar::isTextureDefined(LLAvatarAppearanceDefines::ETextureIndex te, U
|
|||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
if( !getImage( te, index ) )
|
||||
{
|
||||
LL_WARNS() << "getImage( " << te << ", " << index << " ) returned 0" << LL_ENDL;
|
||||
|
|
|
|||
Loading…
Reference in New Issue